1
0
mirror of https://github.com/FreeRTOS/coreMQTT synced 2025-05-12 13:24:58 +08:00
coreMQTT/latest/mqtt_transport_interface.html

241 lines
18 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>coreMQTT: Transport Interface</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">coreMQTT<span id="projectnumber">&#160;v2.3.1</span>
</div>
<div id="projectbrief">MQTT 3.1.1 Client Library</div>
</td>
<td> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<span id="MSearchSelect" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()">&#160;</span>
<input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.6 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function(){initNavTree('mqtt_transport_interface.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div><div class="header">
<div class="headertitle"><div class="title">Transport Interface </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>The transport interface definition.</p>
<h1><a class="anchor" id="mqtt_transport_interface_overview"></a>
Transport Interface Overview</h1>
<p>The transport interface is a set of APIs that must be implemented using an external transport layer protocol. The transport interface is defined in <a class="el" href="transport__interface_8h.html">transport_interface.h</a>. This interface allows protocols like MQTT and HTTP to send and receive data over the transport layer. This interface does not handle connection and disconnection to the server of interest. The connection, disconnection, and other transport settings, like timeout and TLS setup, must be handled in the user application. <br />
</p>
<p>The functions that must be implemented are:<br />
</p><ul>
<li><a class="el" href="group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167">Transport Receive</a></li>
<li><a class="el" href="group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5">Transport Send</a></li>
</ul>
<p>Each of the functions above take in an opaque context <a class="el" href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t</a>. The functions above and the context are also grouped together in the <a class="el" href="struct_transport_interface__t.html">TransportInterface_t</a> structure:<br />
<br />
</p><div class="fragment"><div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>TransportInterface</div>
<div class="line">{</div>
<div class="line"> <a class="code hl_typedef" href="group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167">TransportRecv_t</a> recv; </div>
<div class="line"> <a class="code hl_typedef" href="group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5">TransportSend_t</a> send; </div>
<div class="line"> <a class="code hl_typedef" href="group__mqtt__callback__types.html#ga47e779557b0c2db95949ef9526861dfb">TransportWritev_t</a> writev; </div>
<div class="line"> <a class="code hl_typedef" href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t</a> * pNetworkContext; </div>
<div class="line">} <a class="code hl_struct" href="struct_transport_interface__t.html">TransportInterface_t</a>;</div>
<div class="ttc" id="agroup__mqtt__callback__types_html_ga227df31d6daf07e5d833537c12130167"><div class="ttname"><a href="group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167">TransportRecv_t</a></div><div class="ttdeci">int32_t(* TransportRecv_t)(NetworkContext_t *pNetworkContext, void *pBuffer, size_t bytesToRecv)</div><div class="ttdoc">Transport interface for receiving data on the network.</div><div class="ttdef"><b>Definition:</b> transport_interface.h:218</div></div>
<div class="ttc" id="agroup__mqtt__callback__types_html_ga2a39853ff952edd715ab07b33ab2a7c5"><div class="ttname"><a href="group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5">TransportSend_t</a></div><div class="ttdeci">int32_t(* TransportSend_t)(NetworkContext_t *pNetworkContext, const void *pBuffer, size_t bytesToSend)</div><div class="ttdoc">Transport interface for sending data over the network.</div><div class="ttdef"><b>Definition:</b> transport_interface.h:240</div></div>
<div class="ttc" id="agroup__mqtt__callback__types_html_ga47e779557b0c2db95949ef9526861dfb"><div class="ttname"><a href="group__mqtt__callback__types.html#ga47e779557b0c2db95949ef9526861dfb">TransportWritev_t</a></div><div class="ttdeci">int32_t(* TransportWritev_t)(NetworkContext_t *pNetworkContext, TransportOutVector_t *pIoVec, size_t ioVecCount)</div><div class="ttdoc">Transport interface function for &quot;vectored&quot; / scatter-gather based writes. This function is expected ...</div><div class="ttdef"><b>Definition:</b> transport_interface.h:288</div></div>
<div class="ttc" id="agroup__mqtt__struct__types_html_ga7769e434e7811caed8cd6fd7f9ec26ec"><div class="ttname"><a href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t</a></div><div class="ttdeci">struct NetworkContext NetworkContext_t</div><div class="ttdoc">The NetworkContext is an incomplete type. An implementation of this interface must define struct Netw...</div><div class="ttdef"><b>Definition:</b> transport_interface.h:191</div></div>
<div class="ttc" id="astruct_transport_interface__t_html"><div class="ttname"><a href="struct_transport_interface__t.html">TransportInterface_t</a></div><div class="ttdoc">The transport layer interface.</div><div class="ttdef"><b>Definition:</b> transport_interface.h:299</div></div>
</div><!-- fragment --><p> <br />
</p>
<h1><a class="anchor" id="mqtt_transport_interface_implementation"></a>
Implementing the Transport Interface</h1>
<p>The following steps give guidance on implementing the transport interface:</p>
<ol type="1">
<li>Implementing <a class="el" href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t<br />
</a><br />
<div class="fragment"><div class="line"><span class="keyword">struct </span>NetworkContext;</div>
<div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>NetworkContext <a class="code hl_typedef" href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t</a>;</div>
</div><!-- fragment --> <br />
<a class="el" href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t</a> is the incomplete type <b>struct NetworkContext</b>. The implemented struct NetworkContext must contain all of the information that is needed to receive and send data with the <a class="el" href="group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167">TransportRecv_t</a> and the <a class="el" href="group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5">TransportSend_t</a> implementations.<br />
In the case of TLS over TCP, struct NetworkContext is typically implemented with the TCP socket context and a TLS context.<br />
<br />
<b>Example code:</b> <div class="fragment"><div class="line"><span class="keyword">struct </span>NetworkContext</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">struct </span>MyTCPSocketContext tcpSocketContext;</div>
<div class="line"> <span class="keyword">struct </span>MyTLSContext tlsContext;</div>
<div class="line">};</div>
</div><!-- fragment --> <br />
</li>
<li>Implementing <a class="el" href="group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167">TransportRecv_t<br />
</a><br />
<div class="fragment"><div class="line"><span class="keyword">typedef</span> int32_t ( * <a class="code hl_typedef" href="group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167">TransportRecv_t</a> )( <a class="code hl_typedef" href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t</a> * pNetworkContext,</div>
<div class="line"> <span class="keywordtype">void</span> * pBuffer,</div>
<div class="line"> <span class="keywordtype">size_t</span> bytesToRecv );</div>
</div><!-- fragment --> <br />
This function is expected to populate a buffer, with bytes received from the transport, and return the number of bytes placed in the buffer. In the case of TLS over TCP, <a class="el" href="group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167">TransportRecv_t</a> is typically implemented by calling the TLS layer function to receive data. In case of plaintext TCP without TLS, it is typically implemented by calling the TCP layer receive function. <a class="el" href="group__mqtt__callback__types.html#ga227df31d6daf07e5d833537c12130167">TransportRecv_t</a> may be invoked multiple times by the protocol library, if fewer bytes than were requested to receive are returned. <br />
<br />
<b>Example code:</b> <div class="fragment"><div class="line">int32_t myNetworkRecvImplementation( <a class="code hl_typedef" href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t</a> * pNetworkContext,</div>
<div class="line"> <span class="keywordtype">void</span> * pBuffer,</div>
<div class="line"> <span class="keywordtype">size_t</span> bytesToRecv )</div>
<div class="line">{</div>
<div class="line"> int32_t bytesReceived = 0;</div>
<div class="line"> <span class="keywordtype">bool</span> callTlsRecvFunc = <span class="keyword">true</span>;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// For a single byte read request, check if data is available on the network.</span></div>
<div class="line"> <span class="keywordflow">if</span>( bytesToRecv == 1 )</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// If no data is available on the network, do not call TLSRecv</span></div>
<div class="line"> <span class="comment">// to avoid blocking for socket timeout.</span></div>
<div class="line"> <span class="keywordflow">if</span>( TLSRecvCount( pNetworkContext-&gt;tlsContext ) == 0 )</div>
<div class="line"> {</div>
<div class="line"> callTlsRecvFunc = <span class="keyword">false</span>;</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">if</span>( callTlsRecvFunc == <span class="keyword">true</span> )</div>
<div class="line"> {</div>
<div class="line"> bytesReceived = TLSRecv( pNetworkContext-&gt;tlsContext,</div>
<div class="line"> pBuffer,</div>
<div class="line"> bytesToRecv,</div>
<div class="line"> MY_SOCKET_TIMEOUT );</div>
<div class="line"> <span class="keywordflow">if</span>( bytesReceived &lt; 0 )</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// If the error code represents a timeout, then the return</span></div>
<div class="line"> <span class="comment">// code should be translated to zero so that the caller</span></div>
<div class="line"> <span class="comment">// can retry the read operation.</span></div>
<div class="line"> <span class="keywordflow">if</span>( bytesReceived == MY_SOCKET_ERROR_TIMEOUT )</div>
<div class="line"> {</div>
<div class="line"> bytesReceived = 0;</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">// Handle other cases.</span></div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">return</span> bytesReceived;</div>
<div class="line">}</div>
</div><!-- fragment --> <br />
</li>
<li>Implementing <a class="el" href="group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5">TransportSend_t<br />
</a><br />
<div class="fragment"><div class="line"><span class="keyword">typedef</span> int32_t ( * <a class="code hl_typedef" href="group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5">TransportSend_t</a> )( <a class="code hl_typedef" href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t</a> * pNetworkContext,</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">void</span> * pBuffer,</div>
<div class="line"> <span class="keywordtype">size_t</span> bytesToSend );</div>
</div><!-- fragment --> <br />
This function is expected to send the bytes, in the given buffer over the transport, and return the number of bytes sent. In the case of TLS over TCP, <a class="el" href="group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5">TransportSend_t</a> is typically implemented by calling the TLS layer function to send data. In case of plaintext TCP without TLS, it is typically implemented by calling the TCP layer send function. <a class="el" href="group__mqtt__callback__types.html#ga2a39853ff952edd715ab07b33ab2a7c5">TransportSend_t</a> may be invoked multiple times by the protocol library, if fewer bytes than were requested to send are returned. <br />
<br />
<b>Example code:</b> <div class="fragment"><div class="line">int32_t myNetworkSendImplementation( <a class="code hl_typedef" href="group__mqtt__struct__types.html#ga7769e434e7811caed8cd6fd7f9ec26ec">NetworkContext_t</a> * pNetworkContext,</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">void</span> * pBuffer,</div>
<div class="line"> <span class="keywordtype">size_t</span> bytesToSend )</div>
<div class="line">{</div>
<div class="line"> int32_t bytesSent = 0;</div>
<div class="line"> bytesSent = TLSSend( pNetworkContext-&gt;tlsContext,</div>
<div class="line"> pBuffer,</div>
<div class="line"> bytesToSend,</div>
<div class="line"> MY_SOCKET_TIMEOUT );</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// If underlying TCP buffer is full, set the return value to zero</span></div>
<div class="line"> <span class="comment">// so that caller can retry the send operation.</span></div>
<div class="line"> <span class="keywordflow">if</span>( bytesSent == MY_SOCKET_ERROR_BUFFER_FULL )</div>
<div class="line"> {</div>
<div class="line"> bytesSent = 0;</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span>( bytesSent &lt; 0 )</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// Handle socket error.</span></div>
<div class="line"> }</div>
<div class="line"> <span class="comment">// Handle other cases.</span></div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">return</span> bytesSent;</div>
<div class="line">}</div>
</div><!-- fragment --> </li>
</ol>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.6 </li>
</ul>
</div>
</body>
</html>