首先要明确:连接参数是由主机端确定的,从机端可以发起更新连接参数的请求。主机端可以直接下发连接参数,而从机端则只能是发起更新请求并附带想要的连接参数范围。
在初始化中将想要的连接参数设置进osal( 在和iOS设备连接时需要注意一些规则,在前面有提到 ):
<code class="hljs scss has-numbering"><span class="hljs-function">GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, <span class="hljs-function">sizeof( uint8 )</span>, &enable_update_request )</span>; <span class="hljs-function">GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, <span class="hljs-function">sizeof( uint16 )</span>, &desired_min_interval )</span>; <span class="hljs-function">GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, <span class="hljs-function">sizeof( uint16 )</span>, &desired_max_interval )</span>; <span class="hljs-function">GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, <span class="hljs-function">sizeof( uint16 )</span>, &desired_slave_latency )</span>; <span class="hljs-function">GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, <span class="hljs-function">sizeof( uint16 )</span>, &desired_conn_timeout )</span>;</code><ul class="pre-numbering" style=""><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul><ul class="pre-numbering" style=""><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>
追踪下GAPRole_SetParameter函数中这些参数的运作:
<code class="hljs go has-numbering"><span class="hljs-keyword">case</span> GAPROLE_MIN_CONN_INTERVAL: { <span class="hljs-typename">uint16</span> newInterval = *((<span class="hljs-typename">uint16</span>*)pValue); <span class="hljs-keyword">if</span> ( <span class="hljs-built_in">len</span> == sizeof ( <span class="hljs-typename">uint16</span> ) && ( newInterval >= MIN_CONN_INTERVAL ) && ( newInterval <= MAX_CONN_INTERVAL ) ) { gapRole_MinConnInterval = newInterval; } <span class="hljs-keyword">else</span> { ret = bleInvalidRange; } } <span class="hljs-keyword">break</span>;</code><ul class="pre-numbering" style=""><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><ul class="pre-numbering" style=""><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul>
都是存储在全局变量中,那么这些参数是何时发出去的呢?
且看:
在建立连接后会产生一个MSG然后在gapRole_ProcessGAPMsg函数中的GAP_LINK_PARAM_UPDATE_EVENT事件
gap.h中有对这一事件的介绍
<code class="hljs lasso has-numbering"><span class="hljs-keyword">case</span> GAP_LINK_ESTABLISHED_EVENT: { gapEstLinkReqEvent_t <span class="hljs-subst">*</span>pPkt <span class="hljs-subst">=</span> (gapEstLinkReqEvent_t <span class="hljs-subst">*</span>)pMsg; <span class="hljs-keyword">if</span> ( pPkt<span class="hljs-subst">-></span>hdr<span class="hljs-built_in">.</span>status <span class="hljs-subst">==</span> SUCCESS ) { <span class="hljs-literal">VOID</span> osal_memcpy( gapRole_ConnectedDevAddr, pPkt<span class="hljs-subst">-></span>devAddr, B_ADDR_LEN ); gapRole_ConnectionHandle <span class="hljs-subst">=</span> pPkt<span class="hljs-subst">-></span>connectionHandle; gapRole_state <span class="hljs-subst">=</span> GAPROLE_CONNECTED; <span class="hljs-keyword">if</span> ( gapRole_RSSIReadRate ) { <span class="hljs-comment">// Start the RSSI Reads</span> <span class="hljs-literal">VOID</span> osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate ); } <span class="hljs-comment">// Store connection information</span> gapRole_ConnInterval <span class="hljs-subst">=</span> pPkt<span class="hljs-subst">-></span>connInterval; gapRole_ConnSlaveLatency <span class="hljs-subst">=</span> pPkt<span class="hljs-subst">-></span>connLatency; gapRole_ConnTimeout <span class="hljs-subst">=</span> pPkt<span class="hljs-subst">-></span>connTimeout; <span class="hljs-comment">// Check whether update parameter request is enabled</span> <span class="hljs-keyword">if</span> ( gapRole_ParamUpdateEnable <span class="hljs-subst">==</span> <span class="hljs-literal">TRUE</span> ) { <span class="hljs-comment">// Get the minimum time upon connection establishment before the </span> <span class="hljs-comment">// peripheral can start a connection update procedure.</span> uint16 timeout <span class="hljs-subst">=</span> GAP_GetParamValue( TGAP_CONN_PAUSE_PERIPHERAL ); osal_start_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT, timeout<span class="hljs-subst">*</span><span class="hljs-number">1000</span> ); } <span class="hljs-comment">// Notify the Bond Manager to the connection</span> <span class="hljs-literal">VOID</span> GAPBondMgr_LinkEst( pPkt<span class="hljs-subst">-></span>devAddrType, pPkt<span class="hljs-subst">-></span>devAddr, pPkt<span class="hljs-subst">-></span>connectionHandle, GAP_PROFILE_PERIPHERAL ); <span class="hljs-comment">// Set enabler to FALSE; device will become discoverable again when</span> <span class="hljs-comment">// this value gets set to TRUE</span> gapRole_AdvEnabled <span class="hljs-subst">=</span> <span class="hljs-literal">FALSE</span>; } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ( pPkt<span class="hljs-subst">-></span>hdr<span class="hljs-built_in">.</span>status <span class="hljs-subst">==</span> bleGAPConnNotAcceptable ) { <span class="hljs-comment">// Set enabler to FALSE; device will become discoverable again when</span> <span class="hljs-comment">// this value gets set to TRUE</span> gapRole_AdvEnabled <span class="hljs-subst">=</span> <span class="hljs-literal">FALSE</span>; <span class="hljs-comment">// Go to WAITING state, and then start advertising</span> gapRole_state <span class="hljs-subst">=</span> GAPROLE_WAITING; } <span class="hljs-keyword">else</span> { gapRole_state <span class="hljs-subst">=</span> GAPROLE_ERROR; } notify <span class="hljs-subst">=</span> <span class="hljs-literal">TRUE</span>; } break; </code><ul class="pre-numbering" style=""><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li></ul><ul class="pre-numbering" style=""><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li></ul>
osal_start_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT, timeout*1000 );
这个事件便是发起连接参数更新,这个timeout是为了让连接更稳定,在建立连接之后得经过一段稳定的时间在更新参数
有网友的做法是在peripheralStateNotificationCB函数中的GAPROLE_CONNECTED里面添加更新参数的函数手动发起更新请求,不知这种做法是否有风险。
<code class="hljs vala has-numbering">GAPRole_SendUpdateParam( <span class="hljs-keyword">uint16</span> minConnInterval, <span class="hljs-keyword">uint16</span> maxConnInterval, <span class="hljs-keyword">uint16</span> latency, <span class="hljs-keyword">uint16</span> connTimeout, <span class="hljs-keyword">uint8</span> handleFailure );</code><ul class="pre-numbering" style=""><li>1</li><li>2</li></ul><ul class="pre-numbering" style=""><li>1</li><li>2</li></ul>
也可以用下面这个中方式,两者本质都是用gapRole_startConnUpdate( GAPROLE_NO_ACTION );
<code class="hljs objectivec has-numbering"> GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_REQ, <span class="hljs-keyword">sizeof</span> ( uint8 ), <span class="hljs-literal">TRUE</span> );</code><ul class="pre-numbering" style=""><li>1</li><li>2</li></ul><ul class="pre-numbering" style=""><li>1</li><li>2</li></ul>
怎么获取实时连接参数?
好办!
如下函数,注册一个回调函数,然后就可以得到connInterval,connSlaveLatency,connTimeout这三项参数,当参数更新成功是进入回调;因此可以在回调函数里面用LCD,打印,发给APP等等各种方式来展示
<code class="hljs perl has-numbering">GAPRole_RegisterAppCBs( gapRolesParamUpdateCB_t <span class="hljs-variable">*pParamUpdateCB</span> );</code><ul class="pre-numbering" style=""><li>1</li></ul><ul class="pre-numbering" style=""><li>1</li></ul>
顺便贴一下回调函数的调用:
<code class="hljs lasso has-numbering"> <span class="hljs-keyword">case</span> GAP_LINK_PARAM_UPDATE_EVENT: { gapLinkUpdateEvent_t <span class="hljs-subst">*</span>pPkt <span class="hljs-subst">=</span> (gapLinkUpdateEvent_t <span class="hljs-subst">*</span>)pMsg; <span class="hljs-comment">// Cancel connection param update timeout timer (if active)</span> <span class="hljs-literal">VOID</span> osal_stop_timerEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT ); <span class="hljs-keyword">if</span> ( pPkt<span class="hljs-subst">-></span>hdr<span class="hljs-built_in">.</span>status <span class="hljs-subst">==</span> SUCCESS ) { <span class="hljs-comment">// Store new connection parameters</span> gapRole_ConnInterval <span class="hljs-subst">=</span> pPkt<span class="hljs-subst">-></span>connInterval; gapRole_ConnSlaveLatency <span class="hljs-subst">=</span> pPkt<span class="hljs-subst">-></span>connLatency; gapRole_ConnTimeout <span class="hljs-subst">=</span> pPkt<span class="hljs-subst">-></span>connTimeout; <span class="hljs-comment">// Make sure there's no pending connection update procedure</span> <span class="hljs-keyword">if</span> ( osal_get_timeoutEx( gapRole_TaskID, START_CONN_UPDATE_EVT ) <span class="hljs-subst">==</span> <span class="hljs-number">0</span> ) { <span class="hljs-comment">// Notify the application with the new connection parameters</span> <span class="hljs-keyword">if</span> ( pGapRoles_ParamUpdateCB <span class="hljs-subst">!=</span> <span class="hljs-built_in">NULL</span> ) { (<span class="hljs-subst">*</span>pGapRoles_ParamUpdateCB)( gapRole_ConnInterval, gapRole_ConnSlaveLatency, gapRole_ConnTimeout ); } } } } break;</code>