CC2642 读取和设置FEATURES

一、读取本地Features,然后更改它的值

1、调用HCI_LE_ReadLocalSupportedFeaturesCmd,这个接口对应的事件是HCI_LE_READ_LOCAL_SUPPORTED_FEATURES,这个事件是在HCI_COMMAND_COMPLETE_EVENT_CODE(hciEvt_CmdComplete_t)里面

/**
 * Read the LE locally supported features.
 *
 * @par Corresponding Events
 * @ref hciEvt_CmdComplete_t with cmdOpcode
 *      @ref HCI_LE_READ_LOCAL_SUPPORTED_FEATURES
 *
 * @return @ref HCI_SUCCESS
 */
extern hciStatus_t HCI_LE_ReadLocalSupportedFeaturesCmd( void );

2、触发事件HCI_COMMAND_COMPLETE_EVENT_CODE->HCI_LE_READ_LOCAL_SUPPORTED_FEATURES

static uint8_t SimplePeripheral_processStackMsg(ICall_Hdr *pMsg)
{
  // Always dealloc pMsg unless set otherwise
  uint8_t safeToDealloc = TRUE;

  switch (pMsg->event)
  {
    case HCI_GAP_EVENT_EVENT:
    {
      // Process HCI message
      switch(pMsg->status)
      {
        // Process HCI Command Complete Events here
        case HCI_COMMAND_COMPLETE_EVENT_CODE:
        {
          SimplePeripheral_processCmdCompleteEvt((hciEvt_CmdComplete_t *) pMsg);
        }break;
      }

    }break;
  }

  return (safeToDealloc);
}

static void SimplePeripheral_processCmdCompleteEvt(hciEvt_CmdComplete_t *pMsg)
{
  switch (pMsg->cmdOpcode)
  {
    case HCI_LE_READ_LOCAL_SUPPORTED_FEATURES:
    {
      u_printf("HCI_LE_READ_LOCAL_SUPPORTED_FEATURES\r\n");    

      // 0:    Status
      // 1..8: Local Supported Features
      u_printf_hex((char *)pMsg->pReturnParam,9);

    }break;

  }
}

3、通过查看HCI_LE_READ_LOCAL_SUPPORTED_FEATURES事件发送源码,可以知道返回的数据格式

hciStatus_t HCI_LE_ReadLocalSupportedFeaturesCmd( void )
{
  // 0:    Status
  // 1..8: Local Supported Features
  uint8 rtnParam[9];

  rtnParam[0] = MAP_LL_ReadLocalSupportedFeatures( &(rtnParam[1]) );

  MAP_HCI_CommandCompleteEvent( HCI_LE_READ_LOCAL_SUPPORTED_FEATURES,
                                sizeof(rtnParam),
                                rtnParam );

  return( HCI_SUCCESS );
}

4、更改本地Features值,读取到本地Features之后,更改它的值

    case HCI_LE_READ_LOCAL_SUPPORTED_FEATURES:
    {
      u_printf("HCI_LE_READ_LOCAL_SUPPORTED_FEATURES\r\n");    

      // 0:    Status
      // 1..8: Local Supported Features
      u_printf_hex((char *)pMsg->pReturnParam,9);

      uint8_t featSet[8];
      memcpy( featSet, &pMsg->pReturnParam[1], 8);

      // Clear the CSA#2 feature bit
      CLR_FEATURE_FLAG( featSet[1], LL_FEATURE_CHAN_ALGO_2 );

      // Enable CTE
      SET_FEATURE_FLAG( featSet[2], LL_FEATURE_CONNECTION_CTE_REQUEST );
      SET_FEATURE_FLAG( featSet[2], LL_FEATURE_CONNECTION_CTE_RESPONSE );
      SET_FEATURE_FLAG( featSet[2], LL_FEATURE_ANTENNA_SWITCHING_DURING_CTE_RX );
      SET_FEATURE_FLAG( featSet[2], LL_FEATURE_RECEIVING_CTE );

      HCI_EXT_SetLocalSupportedFeaturesCmd(featSet);

    }break;

5、Features一共8个字节,每个字节对应如下

/*
** Bluetooth LE Feature Support
** Core Specification, Vol. 6, Part B, Section 4.6
*/

// Feature Set Related
#define LL_MAX_FEATURE_SET_SIZE                        8         // in bytes
//
#define LL_FEATURE_NONE                                0x00
// Byte 0
#define LL_FEATURE_ENCRYPTION                          0x01
#define LL_FEATURE_CONN_PARAMS_REQ                     0x02
#define LL_FEATURE_REJECT_EXT_IND                      0x04
#define LL_FEATURE_SLV_FEATURES_EXCHANGE               0x08
#define LL_FEATURE_PING                                0x10
#define LL_FEATURE_DATA_PACKET_LENGTH_EXTENSION        0x20
#define LL_FEATURE_PRIVACY                             0x40
#define LL_FEATURE_EXTENDED_SCANNER_FILTER_POLICIES    0x80
// Byte 1
#define LL_FEATURE_2M_PHY                              0x01
#define LL_FEATURE_STABLE_MODULATION_INDEX_TX          0x02
#define LL_FEATURE_STABLE_MODULATION_INDEX_RX          0x04
#define LL_FEATURE_CODED_PHY                           0x08
#define LL_FEATURE_EXTENDED_ADVERTISING                0x10
#define LL_FEATURE_PERIODIC_ADVERTISING                0x20
#define LL_FEATURE_CHAN_ALGO_2                         0x40
#define LL_FEATURE_LE_POWER_CLASS_1                    0x80
// Byte 2
#define LL_FEATURE_MINIMUM_NUMBER_OF_USED_CHANNELS     0x01
#define LL_FEATURE_CONNECTION_CTE_REQUEST              0x02  // support CTE request procedure as initiator
#define LL_FEATURE_CONNECTION_CTE_RESPONSE             0x04  // support CTE request procedure as responder
#define LL_FEATURE_CONNECTIONLESS_CTE_TRANSMITTER      0x08
#define LL_FEATURE_CONNECTIONLESS_CTE_RECEIVER         0x10
#define LL_FEATURE_ANTENNA_SWITCHING_DURING_CTE_TX     0x20  // support LL_FEATURE_RECEIVING_CTE and switching antennas for AoD
#define LL_FEATURE_ANTENNA_SWITCHING_DURING_CTE_RX     0x40  // support LL_FEATURE_RECEIVING_CTE and switching antennas for AoA
#define LL_FEATURE_RECEIVING_CTE                       0x80  // support receiving CTE in data PDUs and IQ sampling
// Byte 3
#define LL_FEATURE_PERIODIC_ADV_SYNC_TRANSFER_SEND     0x01
#define LL_FEATURE_PERIODIC_ADV_SYNC_TRANSFER_RECV     0x02
#define LL_FEATURE_SLEEP_CLOCK_ACCURACY_UPDATES        0x04
#define LL_FEATURE_REMOTE_PUBLIC_KEY_VALIDATION        0x08
#define LL_FEATURE_RESERVED4                           0x10
#define LL_FEATURE_RESERVED5                           0x20
#define LL_FEATURE_RESERVED6                           0x40
#define LL_FEATURE_RESERVED7                           0x80
// Byte 4 - Byte 7
#define LL_FEATURE_RESERVED0                           0x01
#define LL_FEATURE_RESERVED1                           0x02
#define LL_FEATURE_RESERVED2                           0x04
#define LL_FEATURE_RESERVED3                           0x08
#define LL_FEATURE_RESERVED4                           0x10
#define LL_FEATURE_RESERVED5                           0x20
#define LL_FEATURE_RESERVED6                           0x40
#define LL_FEATURE_RESERVED7                           0x80

可以通过下面的宏,操作对应的位

#define SET_FEATURE_FLAG( flags, flag ) ((flags) |=  (flag))
#define TST_FEATURE_FLAG( flags, flag ) ((flags) &   (flag))
#define CLR_FEATURE_FLAG( flags, flag ) ((flags) &= ~(flag))

二、读取远端设备的Features

1、调用接口HCI_LE_ReadRemoteUsedFeaturesCmd

2、回调函数如下

static uint8_t SimplePeripheral_processStackMsg(ICall_Hdr *pMsg)
{
  // Always dealloc pMsg unless set otherwise
  uint8_t safeToDealloc = TRUE;

  switch (pMsg->event)
  {
    case HCI_GAP_EVENT_EVENT:
    {
      // Process HCI message
      switch(pMsg->status)
      {
        // Process HCI Command Complete Events here
        case HCI_COMMAND_COMPLETE_EVENT_CODE:
        {
          SimplePeripheral_processCmdCompleteEvt((hciEvt_CmdComplete_t *) pMsg);
        }break;
		
        case HCI_COMMAND_STATUS_EVENT_CODE:
        {
          SimplePeripheral_processCmdStatusEvt((hciEvt_CommandStatus_t *)pMsg);     
        }break;
      }

    }break;
  }

  return (safeToDealloc);
}

static void SimplePeripheral_processCmdCompleteEvt(hciEvt_CmdComplete_t *pMsg)
{
  switch (pMsg->cmdOpcode)
  {
    case HCI_LE_READ_REMOTE_USED_FEATURES:
    {
      u_printf("HCI_LE_READ_REMOTE_USED_FEATURES. sta:%d\r\n",pMsg->pReturnParam[0]);    

    }break;

  }
}

static void SimplePeripheral_processCmdStatusEvt(hciEvt_CommandStatus_t *pMsg)
{
  u_printf("Cmd status: %02x\r\n",pMsg->cmdOpcode);
  switch ( pMsg->cmdOpcode )
  {
    case HCI_LE_READ_REMOTE_USED_FEATURES:
    {
      u_printf("HCI_LE_READ_REMOTE_USED_FEATURES %d\r\n",pMsg->cmdStatus);    

    }break;
	
  }
}

3、通过这个接口的源码可以知道,调用这个接口之后,都会执行HCI_COMMAND_STATUS_EVENT_CODE->HCI_LE_READ_REMOTE_USED_FEATURES事件,结果固定是成功。如果结果失败时还会执行1次HCI_COMMAND_COMPLETE_EVENT_CODE->HCI_LE_READ_REMOTE_USED_FEATURES事件

hciStatus_t HCI_LE_ReadRemoteUsedFeaturesCmd( uint16 connHandle )
{
  hciStatus_t status;

  MAP_HCI_CommandStatusEvent( HCI_SUCCESS, HCI_LE_READ_REMOTE_USED_FEATURES );

  status = MAP_LL_ReadRemoteUsedFeatures( connHandle );

  // check if something went wrong
  // Note: If success is returned, then Command Complete is handled by Callback.
  if ( status != HCI_SUCCESS )
  {
    MAP_HCI_CommandCompleteEvent( HCI_LE_READ_REMOTE_USED_FEATURES,
                                  sizeof(status),
                                  &status );
  }

  return( HCI_SUCCESS );
}

4、理论上读取成功之后会触发HCI_BLE_READ_REMOTE_FEATURE_COMPLETE_EVENT事件,实测没有。

调用HCI_LE_ReadRemoteUsedFeaturesCmd接口之后,可以通过下面代码轮询读取,如果featureRspRcved不等于LL_FEATURE_RSP_DONE,则还没获取成功

      llConnState_t *myfeatPtr;
      myfeatPtr = llDataGetConnPtr(0);	//读取句柄0的设备
      if(myfeatPtr != NULL && myfeatPtr->featureSetInfo.featureRspRcved == LL_FEATURE_RSP_DONE)
      {
        u_printf_hex((char *)myfeatPtr->featureSetInfo.featureSet,LL_MAX_FEATURE_SET_SIZE);
      }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dear_Wally

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值