基于CH585的蓝牙主机快连程序修改说明_可拿到特定handle值进行定向通讯

一般地,如果蓝牙从机设备是自己开发的程序,并且可以拿到关键的notify的句柄值,便可以跳过枚举流程,连接后直接进行通讯测试(一般用于产测环节)。

 

一、准备工作

1、在不知道从机设备的通知句柄时,以CH585的HID_Keyboard例程为例,找到HidDev_WriteAttrCB函数,在其中增加打印:

如果从机使用的是Peripheral例程,则可以在simpleProfile_WriteAttrCB中添加句柄打印,方法同下;

image

 

 2、从机程序中可以看到有两个notify特征属性,在烧录从机固件后,配对电脑时,可在HidDev_WriteAttrCB中获取到handle值,便于下文在编写主机程序时定向打开notify权限,并且接收notify数据;

image

 

image

 

 

 二、编写主机程序

1、定向连接,可通过广播包数据匹配,找到GAP_DEVICE_INFO_EVENT事件进行改写,

①定义目标数组用于比对(参照从机例程):

// Advertising data
static uint8_t advertData[] = {
    // flags
    0x02, // length of this data
    GAP_ADTYPE_FLAGS,
    GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

    // appearance
    0x03, // length of this data
    GAP_ADTYPE_APPEARANCE,
    LO_UINT16(GAP_APPEARE_HID_KEYBOARD),
    HI_UINT16(GAP_APPEARE_HID_KEYBOARD),
};

 

②改写centralEventCB函数,定义设备类型变量

static uint8_t PeerAddrType = 0;         //!< Address Type: @ref GAP_ADDR_TYPE_DEFINES

 


/*
******************************************************************** * @fn centralEventCB * * @brief Central event callback function. * * @param pEvent - pointer to event structure * * @return none */ static void centralEventCB(gapRoleEvent_t *pEvent) { switch(pEvent->gap.opcode) { case GAP_DEVICE_INIT_DONE_EVENT: { PRINT("Discovering...\n"); GAPRole_CentralStartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST); } break; case GAP_DEVICE_INFO_EVENT: { if(tmos_memcmp(advertData, pEvent->deviceInfo.pEvtData, 7))//比对扫描到的设备广播数据是否符合目标设备 { for(uint8_t i=0;i<6;i++) { PRINT("%x ",pEvent->deviceInfo.addr[i]); } PRINT("\n"); if( pEvent->deviceInfo.rssi > (-50))//限制RSSI,只允许连接一定距离内的设备,约1m { PeerAddrType = pEvent->deviceInfo.addrType; tmos_memcpy(PeerAddrDef, pEvent->deviceInfo.addr, 6);//将地址赋值 GAPRole_CentralCancelDiscovery();//停止主机扫描 } else { PRINT("Device %d - Addr %x %x %x %x %x %x \n", pEvent->deviceInfo.rssi, centralDevList[centralScanRes - 1].addr[0], centralDevList[centralScanRes - 1].addr[1], centralDevList[centralScanRes - 1].addr[2], centralDevList[centralScanRes - 1].addr[3], centralDevList[centralScanRes - 1].addr[4], centralDevList[centralScanRes - 1].addr[5]); } } } break; case GAP_DEVICE_DISCOVERY_EVENT: { // Peer device not found if(tmos_isbufset(PeerAddrDef, 0, 6))//如果地址为全0,则代表设备未搜寻到 { PRINT("Device not found...\n"); centralScanRes = 0; GAPRole_CentralStartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST); PRINT("Discovering...\n"); } // Peer device found else { PRINT("Device found...\n"); GAPRole_CentralEstablishLink(DEFAULT_LINK_HIGH_DUTY_CYCLE, DEFAULT_LINK_WHITE_LIST, PeerAddrType, PeerAddrDef);           //找到目标设备,发起连接 // Start establish link timeout event tmos_start_task(centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT, ESTABLISH_LINK_TIMEOUT); PRINT("Connecting...\n"); } } break; case GAP_LINK_ESTABLISHED_EVENT: { tmos_memset(PeerAddrDef, 0, 6); tmos_stop_task(centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT); if(pEvent->gap.hdr.status == SUCCESS) { centralState = BLE_STATE_CONNECTED; centralConnHandle = pEvent->linkCmpl.connectionHandle; centralProcedureInProgress = FALSE;// See if start RSSI polling if(centralRssi) { tmos_start_task(centralTaskId, START_READ_RSSI_EVT, DEFAULT_RSSI_PERIOD); } PRINT("Connected...\n"); } else { PRINT("Connect Failed...Reason:%X\n", pEvent->gap.hdr.status); PRINT("Discovering...\n"); centralScanRes = 0; GAPRole_CentralStartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST); } } break; case GAP_LINK_TERMINATED_EVENT: { centralState = BLE_STATE_IDLE; centralConnHandle = GAP_CONNHANDLE_INIT; centralDiscState = BLE_DISC_STATE_IDLE; centralScanRes = 0; centralProcedureInProgress = FALSE; tmos_stop_task(centralTaskId, START_READ_RSSI_EVT); PRINT("Disconnected...Reason:%x\n", pEvent->linkTerminate.reason); PRINT("Discovering...\n"); tmos_memset(PeerAddrDef, 0, 6); GAPRole_CentralStartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST); } break; case GAP_LINK_PARAM_UPDATE_EVENT: { PRINT("Param Update...\n"); } break; case GAP_PHY_UPDATE_EVENT: { PRINT("PHY Update...\n"); } break; case GAP_EXT_ADV_DEVICE_INFO_EVENT: { // // Display device addr // PRINT("Recv ext adv \n"); // // Add device to list // centralAddDeviceInfo(pEvent->deviceExtAdvInfo.addr, pEvent->deviceExtAdvInfo.addrType); } break; case GAP_DIRECT_DEVICE_INFO_EVENT: { // Display device addr PRINT("Recv direct adv \n"); // Add device to list centralAddDeviceInfo(pEvent->deviceDirectInfo.addr, pEvent->deviceDirectInfo.addrType); } break; default: break; } }

 

2、可将其中的START_WRITE_CCCD_EVT任务改写为如下所示,并在centralPairStateCB中开启循环执行:

image

 

    if(events & START_WRITE_CCCD_EVT)
    {
        PRINT("Procedure : %x\n",centralProcedureInProgress);
        if(centralProcedureInProgress == FALSE)//等待上一次流程结束
        {
            // Do a write
            attWriteReq_t req;
            req.cmd = FALSE;
            req.sig = FALSE;
            switch (write_count)//有两个notify handle待开启,在打开成功一个后count会自动减一;
            {
                case 2:
                    req.handle = 0x37;
                    break;
                case 1:
                    req.handle = 0x3a;
                    break;
                default:
                    return (events ^ START_WRITE_CCCD_EVT);
                    break;

            }
            req.len = 2;
            req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0);
            if(req.pValue != NULL)
            {
                req.pValue[0] = 1;
                req.pValue[1] = 0;

                if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
                {
                    centralProcedureInProgress = TRUE;//执行完一次任务后将标志写1
                }
                else
                {
                    GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
                }
            }
        }
        return (events ^ START_WRITE_CCCD_EVT);
    }

 

3、打开通知后进入回调,获取打开是否成功,以及收到的通知数据打印出来

image

 

 

三、测试结果

image

 

测试文件可通过网盘获取:

链接: https://pan.baidu.com/s/1iRbtvmBCPFWHTUA48EXfKw?pwd=h6cd 提取码: h6cd

 

posted @ 2026-03-24 16:04  oTvTo  阅读(6)  评论(0)    收藏  举报