迷迷糊糊的话 2024-06-05 19:23 采纳率: 33.3%
浏览 18

bluez 4.95 inquiry RSSI信息

使用bluez 4.95 想要在设备inquiry 过程中,获取到查询到设备的rssi 信息,该怎么做,蓝牙求指点
目前的实现如下

 if ((dd = hci_open_dev(dev_id)) < 0) {
        printf("Fail to open hci dev\n");
        goto error;
    }
    if (ioctl(dd, HCIDEVUP, 0) < 0) {
        if (EALREADY == errno) {
            printf("ate already hci dev up\n");
        } else {
            printf("ate hci dev up fail\n");
            goto error;
        }
    }
    
    /*inquiry device*/
    ii = (inquiry_info*)malloc(MAX_BT_RSP * sizeof(inquiry_info));
    if(!ii) {
        printf("malloc fail!\n");
        goto error;
    }
    for(test_count = 0 ;test_count < MAX_BT_SCAN_TIMES;test_count++){
        flag = 0;
        memset(ii, 0, MAX_BT_RSP * sizeof(inquiry_info));
        num_rsp = hci_inquiry(dev_id, BT_SCAN_TIME, MAX_BT_RSP, NULL, &ii, IREQ_CACHE_FLUSH);
        printf("This is the %d test, Query the number of devices is %d\n",test_count,num_rsp);
        if (num_rsp <= 0) {
            continue ;
        }

        /*Compare MAC*/
        for (temp_i = 0; temp_i < num_rsp; temp_i++) {
            memset(tmp_mac_val, 0, TEMP_MAC_ARR_LEN);
            ba2str(&(ii + temp_i)->bdaddr, tmp_mac_val);
            for (temp_j = 0; temp_j < index; temp_j++) {
                printf("%s<--->%s",tmp_mac_val,dst_mac_arr[temp_j]);
                if (!strcmp(tmp_mac_val, dst_mac_arr[temp_j])) {
                    printf("  TRUE\n");
                    flag++;
                }else{
                    printf("\n");
                }
            }
        }
        if(flag == index){
             break;
        }
    }
    hci_close_dev(dd);
    free(ii);
    ii = NULL;


但是发现查询到的设备信息中不含着rssi信息

typedef struct {
    bdaddr_t    bdaddr;
    uint8_t        pscan_rep_mode;
    uint8_t        pscan_period_mode;
    uint8_t        pscan_mode;
    uint8_t        dev_class[3];
    uint16_t    clock_offset;
} __attribute__ ((packed)) inquiry_info;

然后查阅网上资料说蓝牙查询模式不同获取事件信息是不同的

img

然后在相关源码的地方发现该内容

img


然后查找到对应事件

static gboolean io_security_event(GIOChannel *chan, GIOCondition cond,
                                gpointer data)
{
  printf("========io_security_event====================\n");
    unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf;
    int type, index = GPOINTER_TO_INT(data);
    struct dev_info *dev = &devs[index];
    struct hci_dev_info di;
    ssize_t len;
    hci_event_hdr *eh;
    evt_cmd_status *evt;
    int fd;

    if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
        stop_hci_dev(index);
        return FALSE;
    }

    fd = g_io_channel_unix_get_fd(chan);

    len = read(fd, buf, sizeof(buf));
    if (len < 0) {
        if (errno == EAGAIN)
            return TRUE;
        stop_hci_dev(index);
        return FALSE;
    }

    type = *ptr++;

    if (type != HCI_EVENT_PKT)
        return TRUE;

    eh = (hci_event_hdr *) ptr;
    ptr += HCI_EVENT_HDR_SIZE;

    memset(&di, 0, sizeof(di));
    if (hci_devinfo(index, &di) == 0) {
        bacpy(&dev->bdaddr, &di.bdaddr);

        if (ignore_device(&di))
            return TRUE;
    }

  printf("=====123=============eh->evt: 0x%x\n", eh->evt);

    switch (eh->evt) {
    case EVT_CMD_STATUS:
        cmd_status(index, ptr);
        break;

    case EVT_CMD_COMPLETE:
        cmd_complete(index, ptr);
        break;

    case EVT_REMOTE_NAME_REQ_COMPLETE:
        remote_name_information(index, ptr);
        break;

    case EVT_READ_REMOTE_VERSION_COMPLETE:
        remote_version_information(index, ptr);
        break;

    case EVT_READ_REMOTE_FEATURES_COMPLETE:
        remote_features_information(index, ptr);
        break;

    case EVT_REMOTE_HOST_FEATURES_NOTIFY:
        remote_features_notify(index, ptr);
        break;

    case EVT_INQUIRY_COMPLETE:
        evt = (evt_cmd_status *) ptr;
        inquiry_complete_evt(index, evt->status);
        break;

    case EVT_INQUIRY_RESULT:
        inquiry_result(index, eh->plen, ptr);
        break;

    case EVT_INQUIRY_RESULT_WITH_RSSI:
        inquiry_result_with_rssi(index, eh->plen, ptr);
        break;

    case EVT_EXTENDED_INQUIRY_RESULT:
        extended_inquiry_result(index, eh->plen, ptr);
        break;

    case EVT_CONN_COMPLETE:
        conn_complete(index, ptr);
        break;

    case EVT_DISCONN_COMPLETE:
        disconn_complete(index, ptr);
        break;

    case EVT_AUTH_COMPLETE:
        auth_complete(index, ptr);
        break;

    case EVT_SIMPLE_PAIRING_COMPLETE:
        simple_pairing_complete(index, ptr);
        break;

    case EVT_CONN_REQUEST:
        conn_request(index, ptr);
        break;
    case EVT_LE_META_EVENT:
        le_metaevent(index, ptr);
        break;
    case EVT_PIN_CODE_REQ:
        pin_code_request(index, (bdaddr_t *) ptr);
        break;

    case EVT_LINK_KEY_REQ:
        link_key_request(index, (bdaddr_t *) ptr);
        break;

    case EVT_LINK_KEY_NOTIFY:
        link_key_notify(index, ptr);
        break;

    case EVT_RETURN_LINK_KEYS:
        return_link_keys(index, ptr);
        break;

    case EVT_IO_CAPABILITY_REQUEST:
        io_capa_request(index, ptr);
        break;

    case EVT_IO_CAPABILITY_RESPONSE:
        io_capa_response(index, ptr);
        break;

    case EVT_USER_CONFIRM_REQUEST:
        user_confirm_request(index, ptr);
        break;

    case EVT_USER_PASSKEY_REQUEST:
        user_passkey_request(index, ptr);
        break;

    case EVT_USER_PASSKEY_NOTIFY:
        user_passkey_notify(index, ptr);
        break;

    case EVT_REMOTE_OOB_DATA_REQUEST:
        remote_oob_data_request(index, (bdaddr_t *) ptr);
        break;
    }

    return TRUE;
}

但添加打印后,该事件处理的地方并没有走到
但抓包能看到

img

想请教指点一下,我怎么能在查询设备信息的时候,同时将设备的rssi信号强度也获取到

  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-05 19:23
    关注

    引自免费微信小程序:皆我百晓生

    为了在蓝牙查询过程中获取到RSSI信息,你需要调整你的代码来监听包含RSSI信息的特定事件。根据你提供的代码片段和截图,看起来你已经在设置过滤器时包含了EVT_INQUIRY_RESULT_WITH_RSSI事件,这是一个好的开始。然而,为了确保正确处理这个事件,你需要在io_security_event函数中添加对这个事件的处理逻辑。

    首先,你需要为EVT_INQUIRY_RESULT_WITH_RSSI事件创建一个处理函数,例如inquiry_result_with_rssi_handler。接下来,在io_security_event函数中,当接收到EVT_INQUIRY_RESULT_WITH_RSSI事件时,调用这个新创建的处理函数。

    以下是修改后的代码示例:

    // 添加新的处理函数
    void inquiry_result_with_rssi_handler(int index, const uint8_t *data, uint8_t plen) {
        // 解析RSSI值和其他相关信息
        // 并进行相应的操作
    }
    
    // 修改io_security_event函数
    static gboolean io_security_event(GIOChannel *chan, GIOCondition cond,
                                    gpointer data)
    {
        ...
        case EVT_INQUIRY_RESULT_WITH_RSSI:
            inquiry_result_with_rssi_handler(index, ptr, eh->plen);
            break;
        ...
    }
    

    接下来,你需要解析EVT_INQUIRY_RESULT_WITH_RSSI事件的数据结构。根据蓝牙核心规范,这个事件包含一个inquiry_info结构体,后面跟着设备名称和RSSI值。可以参考以下代码片段来解析数据:

    void inquiry_result_with_rssi_handler(int index, const uint8_t *data, uint8_t plen) {
        inquiry_info info;
        uint8_t rssi;
        char mac_str[18];
    
        // 解析inquiry_info结构体
        memcpy(&info, data, sizeof(inquiry_info));
    
        // 转换MAC地址为字符串
        ba2str(&info.bdaddr, mac_str);
    
        // 获取RSSI值
        rssi = data[sizeof(inquiry_info)];
    
        // 打印或保存RSSI值
        printf("Device MAC: %s, RSSI: %d dBm\n", mac_str, rssi);
    
        // 根据需求,这里可以执行其他操作,比如比较MAC地址等
    }
    

    这段代码会从EVT_INQUIRY_RESULT_WITH_RSSI事件的数据中提取出RSSI值,并将其打印出来。你可以根据实际需求,调整这部分代码以适应你的应用。

    注意:在处理蓝牙事件时,可能需要考虑线程同步和异步回调等问题,确保在主线程或其他适当的地方处理这些事件。此外,如果你在实际运行时遇到问题,可能需要检查蓝牙堆栈配置、驱动程序兼容性以及系统权限等是否正确。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月5日

悬赏问题

  • ¥15 openFOAM DPMFoam
  • ¥15 将查询到的值,赋值到table指定行中
  • ¥50 docker容器内部启动shell脚本多命令
  • ¥15 请问python的selenium怎么设置referer
  • ¥15 请教下, VS QT 环境下, QTOPCUA 的源文件报错,这种情况咋查呢 ?
  • ¥20 UNITY webgl关于文档的上传和下载问题
  • ¥15 安霸cv22 + rtl8211f 千兆,udp传输丢包
  • ¥15 关于区块链和边缘环境搭建的相关问题
  • ¥15 windows远程桌面断卡重连软件卡顿问题
  • ¥30 Unity 实现扫描效果