ch583/ch582/ch573/ch571 central(主机)程序

发布时间 2023-05-04 16:41:09作者: 小舟从此逝_1

本程序是在CH582m上运行的,

一、主从连接

主机这里可以根据从机的MAC地址进行连接。static uint8_t PeerAddrDef[B_ADDR_LEN] = {0x02, 0x02, 0x03, 0xE4, 0xC2, 0x84};

一般从机在使用的时候不做其他配置时使用的是芯片本身的MAC地址,可以通过修改从机端对应的MAC地址和主机进行连接const uint8_t MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};

这里的MAC地址要注意大小端的问题。

主机工作流程:

主机初始化:

设置通用访问配置文件: 设置通用访问配置参数值。使用此函数更改默认的通用访问配置参数值。

GAP_SetParamValue(TGAP_DISC_SCAN, DEFAULT_SCAN_DURATION); 设置执行扫描的最小时间,将此参数设置为0将关闭超时时间。扫描时间这里是1.5s时间单位是625us,例程中的宏定义是2400,每隔10ms扫描一次直到连接上。
GAP_SetParamValue(TGAP_CONN_EST_INT_MIN, DEFAULT_MIN_CONNECTION_INTERVAL);//设置链路层连接间隔,这里是最小连接间隔
GAP_SetParamValue(TGAP_CONN_EST_INT_MAX, DEFAULT_MAX_CONNECTION_INTERVAL);这里是最大连接间隔
GAP_SetParamValue(TGAP_CONN_EST_SUPERV_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);连接超时时间管理

绑定功能的管理:

{
uint32_t passkey = DEFAULT_PASSCODE;
uint8_t pairMode = DEFAULT_PAIRING_MODE;
uint8_t mitm = DEFAULT_MITM_MODE;
uint8_t ioCap = DEFAULT_IO_CAPABILITIES;
uint8_t bonding = DEFAULT_BONDING_MODE;

GAPBondMgr_SetParameter(GAPBOND_CENT_DEFAULT_PASSCODE, sizeof(uint32_t), &passkey);
GAPBondMgr_SetParameter(GAPBOND_CENT_PAIRING_MODE, sizeof(uint8_t), &pairMode);
GAPBondMgr_SetParameter(GAPBOND_CENT_MITM_PROTECTION, sizeof(uint8_t), &mitm);
GAPBondMgr_SetParameter(GAPBOND_CENT_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
GAPBondMgr_SetParameter(GAPBOND_CENT_BONDING_ENABLED, sizeof(uint8_t), &bonding);
}

GATT_InitClient();初始化通用规范属性客户端

在初始化函数里首先是:centralTaskId = TMOS_ProcessEventRegister(Central_ProcessEvent);注册进程事件回调函数。

注意橘红色标记的地方:定位到对应的位置,会看到这样一段函数

/*********************************************************************
* @fn Central_ProcessEvent
*
* @brief Central Application Task event processor. This function
* is called to process all events for the task. Events
* include timers, messages and any other user defined events.
* 中央应用程序任务事件处理器。调用此函数来处理任务的所有事件。事件包括定时器、消息和任何其他用户定义的事件。
* @param task_id - The TMOS assigned task ID.
* @param events - events to process. This is a bit map and can
* contain more than one event.
*
* @return events not processed
*/

本段函数主要做三类工作

一:第一次运行系统工作,调用了函数GAPRole_CentralStartDevice(centralTaskId, &centralBondCB, &centralRoleCB);

二:开始扫描工作,调用了centralStartDiscovery();

三:系统的事件消息工作central_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);

uint16_t Central_ProcessEvent(uint8_t task_id, uint16_t events)
{
    if(events & SYS_EVENT_MSG)
    {
        uint8_t *pMsg;

        if((pMsg = tmos_msg_receive(centralTaskId)) != NULL)
        {
            central_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
            // Release the TMOS message
            tmos_msg_deallocate(pMsg);
        }
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }

    if(events & START_DEVICE_EVT)
    {
        // Start the Device  启动设备
        GAPRole_CentralStartDevice(centralTaskId, &centralBondCB, &centralRoleCB);
        return (events ^ START_DEVICE_EVT);
    }

    //终止现有连接
    if(events & ESTABLISH_LINK_TIMEOUT_EVT)
    {
        GAPRole_TerminateLink(INVALID_CONNHANDLE);
        return (events ^ ESTABLISH_LINK_TIMEOUT_EVT);
    }

    //
    if(events & START_SVC_DISCOVERY_EVT)
    {
        // start service discovery  启动服务发现
        centralStartDiscovery();
        return (events ^ START_SVC_DISCOVERY_EVT);
    }

    if(events & START_PARAM_UPDATE_EVT)
    {
        // start connect parameter update  开始连接参数更新
        GAPRole_UpdateLink(centralConnHandle,
                           DEFAULT_UPDATE_MIN_CONN_INTERVAL,
                           DEFAULT_UPDATE_MAX_CONN_INTERVAL,
                           DEFAULT_UPDATE_SLAVE_LATENCY,
                           DEFAULT_UPDATE_CONN_TIMEOUT);
        return (events ^ START_PARAM_UPDATE_EVT);
    }

    if(events & START_PHY_UPDATE_EVT)
    {
        // start phy update
        PRINT("PHY Update %x...\n", GAPRole_UpdatePHY(centralConnHandle, 0, 
                    GAP_PHY_BIT_LE_2M, GAP_PHY_BIT_LE_2M, GAP_PHY_OPTIONS_NOPRE));

        return (events ^ START_PHY_UPDATE_EVT);
    }

    if(events & START_READ_OR_WRITE_EVT)
    {
        if(centralProcedureInProgress == FALSE)
        {
            if(centralDoWrite)
            {
                // Do a write
                attWriteReq_t req;
                // 命令标志
                req.cmd = FALSE;
                //签名状态(不包括(0),有效(1),无效(2))
                req.sig = FALSE;
                //要写入的属性的句柄(必须是第一个字段)
                req.handle = centralCharHdl;
                //写入值的长度
                req.len = 1;
                //要写入的属性的值 长度是0~MTU-3
                req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0);

                if(req.pValue != NULL)
                {
                    *req.pValue = centralCharVal;

                    if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
                    {
                        centralProcedureInProgress = TRUE;
                        centralDoWrite = !centralDoWrite;
                        tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY);
                    }
                    else
                    {
                        GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
                    }
                }
            }
            else
            {
                // Do a read
                attReadReq_t req;

                req.handle = centralCharHdl;
                if(GATT_ReadCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
                {
                    centralProcedureInProgress = TRUE;
                    centralDoWrite = !centralDoWrite;
                }
            }
        }
        return (events ^ START_READ_OR_WRITE_EVT);
    }

    if(events & START_WRITE_CCCD_EVT)
    {
        if(centralProcedureInProgress == FALSE)
        {
            // Do a write
            attWriteReq_t req;

            req.cmd = FALSE;
            req.sig = FALSE;
            //发现的客户端特征配置句柄
            req.handle = centralCCCDHdl;
            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;
                }
                else
                {
                    GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
                }
            }
        }
        return (events ^ START_WRITE_CCCD_EVT);
    }

    if(events & START_READ_RSSI_EVT)
    {
        GAPRole_ReadRssiCmd(centralConnHandle);
        tmos_start_task(centralTaskId, START_READ_RSSI_EVT, DEFAULT_RSSI_PERIOD);
        return (events ^ START_READ_RSSI_EVT);
    }

    // Discard unknown events
    return 0;
}

centralRssICB(接收的信号强度指示)的回调函数

 static void centralEventCB(gapRoleEvent_t *pEvent)主角色功能事件回调函数。包含BLE的连接过程

本函数包括的事件主要是:“初始化完成事件”,"发现设备事件",“连接完成事件”,“连接超时事件”,“更新事件”

static void centralPairStateCB(uint16_t connHandle, uint8_t state, uint8_t status) 配对时的回调函数

static void centralPasscodeCB(uint8_t *deviceAddr, uint16_t connectionHandle,
uint8_t uiInputs, uint8_t uiOutputs) 连接时需要使用有密码的函数。

static void centralStartDiscovery(void) 通过此发现从机UUID服务