关于hci command的发送问题
最近在做公司蓝牙产品的long range测试(Gateway与tag之间的通信),芯片采用是nrf52840,刚开始采用的芯片层的烧写代码及测试,用的是SES,现在需要在gateway的hci-uart上实现—phy物理层更新。
先查看蓝牙的lib库
先在hci.h和hcilib.h中查看有不有相应的函数,经查看没有,看样子需要自己写,,
按照:
1、查找要发送的命令和产生的事件
2、创建对应的结构体
3、填充参数
4、通过hci_send_req()函数发送
查找命令和事件
经过在蓝牙规范中查看的出对应的命令和事件
创建结构体
接下来就是更加参数创建结构体和定义ogf和ocf:
#define OGF_CONTROLLER_COMMANDS 0x08
#define OCF_SET_PHY 0x0032
typedef struct
{
uint16_t conn_handle;
uint8_t all_phys;
uint8_t tx_phys;
uint8_t rx_phys;
uint16_t phy_optinos;
}__attribute__ ((packed)) le_set_phy_cp;
#define LE_SET_PHY_SIZE 7
#define EVT_HCI_LE_PHY_UPDATE_COMPLETE 0x0c
typedef struct
{
uint8_t status;
uint16_t conn_handle;
uint8_t tx_phy;
uint8_t rx_phy;
}__attribute__ ((packed)) evt_phy_update_complete;
#define EVT_PHY_UPDATE_COMPLETE_SIZE 5
这里需要注意的是evt事件中的Subevent_Code不需要写在结构体中,而是在后面填充到hci_request结构体中
填充参数
接下来需要填充参数在通过hci_send_req函数发送。
首先查看hci_request结构体:
struct hci_request {
uint16_t ogf;
uint16_t ocf;
int event;
void *cparam;
int clen;
void *rparam;
int rlen;
};
定义在hci_lib.h中。然后根据参数填充对应的值就行
int hci_set_phy(int dd,uint16_t handle,uint8_t all_phys,uint8_t tx_phy,uint8_t rx_phy,
uint8_t phy_options,int to)
{
struct hci_request rq;
le_set_phy_cp set_phy_cp;
evt_phy_update_complete phy_update_complete_rp;
memset(&set_phy_cp,0,sizeof(set_phy_cp));
set_phy_cp.conn_handle=handle;
set_phy_cp.all_phys=all_phys;
set_phy_cp.tx_phys=tx_phy;
set_phy_cp.rx_phys=rx_phy;
set_phy_cp.phy_optinos=phy_options;
memset(&rq,0,sizeof(rq));
rq.ogf=OGF_CONTROLLER_COMMANDS;
rq.ocf=OCF_SET_PHY;
rq.event=EVT_HCI_LE_PHY_UPDATE_COMPLETE;
rq.cparam=&set_phy_cp;
rq.clen=LE_SET_PHY_SIZE;
rq.rparam=&phy_update_complete_rp;
rq.rlen=EVT_PHY_UPDATE_COMPLETE_SIZE;
if (hci_send_req(dd,&rq,to)<0)
{
perror("\n hci_send_req()");
return -1;
}
printf("rx_phy=%d,tx_phy=%d,status=%d\r\n",
phy_update_complete_rp.rx_phy,phy_update_complete_rp.tx_phy,phy_update_complete_rp.status);
return 0;
}
参数中的dd通过hci_get_route函数获取
handle是连接句柄通过hci_le_creat_conn函数获取
运行结果
打印结果:
btmon监测结果:
中间隔了一些其他事件,就没截图到一起了
2019.10.25