关于低功耗蓝牙的连接参数更新

首先要明确:连接参数是由主机端确定的,从机端可以发起更新连接参数的请求。主机端可以直接下发连接参数,而从机端则只能是发起更新请求并附带想要的连接参数范围。

在初始化中将想要的连接参数设置进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>

顺便贴一下回调函数的调用:
gap.h中

<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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值