当前位置: 首页 > article >正文

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);
      }


http://www.kler.cn/news/17045.html

相关文章:

  • path/to/sdkmanager --install “cmdline-tools;latest“
  • k8s搭建教程
  • 内网渗透(六十一)之Kerberosating攻击
  • MySQL知识学习02(MySQL索引详解)
  • 【软考高级】2022年系统分析师综合知识
  • [java]云HIS运维运营分系统功能实现(springboot框架)
  • 【Java笔试强训 4】
  • 08-Vue技术栈之过度与动画
  • 如何使用CSS和JS实现一个响应式的滚动时间轴
  • 你最关心的4个零代码问题,ChatGPT 帮你解答了!
  • Python基础合集 练习22 (错误与异常处理语句2)
  • 【Spring6】| Spring6整合JUnit
  • 【Git】‘git‘ 不是内部或外部命令,也不是可运行的程序
  • 2016 ICPC合肥站 传递 HDU-5961(拓扑排序 / bitset / 暴力(可hack))
  • 相交链表 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
  • 2.6 浮点运算方法和浮点运算器
  • c++ 入门概述
  • WEB攻防通用漏洞跨域CORS资源JSONP回调域名接管劫持
  • CSS布局基础(CSS书写顺序 导航栏写法 常见问题)
  • SQL 语句性能优化策略
  • 【谷粒商城之消息队列RabbitMQ】
  • nullptr和NULL的区别
  • Photoshop如何使用选区之实例演示?
  • Java中顺序表详解
  • 自动驾驶行业观察之2023上海车展-----智驾供应链(1)
  • E. Train Hard, Win Easy(数学推导 + 前缀和)
  • JAVA-实现简易图书管理系统
  • leetcode 面试题 02.04. 分割链表
  • YonLinker连接集成平台构建新一代产业互联根基
  • babysql