蓝牙----蓝牙连接建立_连接建立
- 蓝牙连接建立过程图
- 1.主机扫描到广播包
- 1.1判断是否是自己关心的广播包
- 1.2广播地址添加到扫描列表
- 2.主机扫描结束,建立连接
- 3.主从连接成功后,执行连接建立后事件
- 3.1.主机将连接句柄和设备地址添加到连接列表
- 3.2.主机进行GATT服务的发现
- 3.3.从机获取连接句柄,并发起连接参数更新
- 4.从机发起连接参数更新
- 4.1主机收到连接参数更新请求
- 4.2从机进行连接参数更新
蓝牙连接建立过程图
1.主机扫描到广播包
执行注册的回调函数,触发APP层SC_EVT_ADV_REPORT事件
//判断广播包是否是自己关心的if (SimpleCentral_findSvcUuid(SIMPLEPROFILE_SERV_UUID,pAdvRpt->pData, pAdvRpt->dataLen)){//将广播设备的地址和地址类型添加到扫描列表中SimpleCentral_addScanInfo(pAdvRpt->addr, pAdvRpt->addrType);Display_printf(dispHandle, SC_ROW_NON_CONN, 0, "Discovered: %s",Util_convertBdAddr2Str(pAdvRpt->addr));}
1.1判断是否是自己关心的广播包
SimpleCentral_findSvcUuid是查看广播包是否包含自己设置的UUID(SIMPLEPROFILE_SERV_UUID)。
广播包的判断有多种也可以对广播数据判断。
从机的广播数据static uint8_t advertData[] ={0x02, // length of this dataGAP_ADTYPE_FLAGS,DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,// service UUID, to notify central devices what services are included// in this peripheral0x03, // length of this dataGAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not allLO_UINT16(SIMPLEPROFILE_SERV_UUID),HI_UINT16(SIMPLEPROFILE_SERV_UUID)
};
主机扫描UUID判断if ((adType == GAP_ADTYPE_16BIT_MORE) || (adType == GAP_ADTYPE_16BIT_COMPLETE)){pData++;adLen--;// For each UUID in listwhile (adLen >= 2 && pData < pEnd){// Check for matchif ((pData[0] == LO_UINT16(uuid)) && (pData[1] == HI_UINT16(uuid))){// Match foundreturn TRUE;}// Go to nextpData += 2;adLen -= 2;}}
1.2广播地址添加到扫描列表
SimpleCentral_addScanInfo(pAdvRpt->addr, pAdvRpt->addrType);
//添加一个设备到扫描列表
static void SimpleCentral_addScanInfo(uint8_t *pAddr, uint8_t addrType)
{uint8_t i;// If result count not at max// DEFAULT_MAX_SCAN_RES扫描结果的最大数目if (numScanRes < DEFAULT_MAX_SCAN_RES){// Check if device is already in scan resultsfor (i = 0; i < numScanRes; i++){if (memcmp(pAddr, scanList[i].addr , B_ADDR_LEN) == 0){return;}}// Add addr to scan result listmemcpy(scanList[numScanRes].addr, pAddr, B_ADDR_LEN);scanList[numScanRes].addrType = addrType;// Increment scan result countnumScanRes++;}
}
当到达最大扫描数目时,执行GapScan_disable(),并执行回调函数,触发SC_EVT_SCAN_DISABLED事件
2.主机扫描结束,建立连接
处理SC_EVT_SCAN_DISABLED事件,进行GAP连接
GapInit_connect(tempMember->addrType & MASK_ADDRTYPE_ID,tempMember->addr, DEFAULT_INIT_PHY, CONNECTION_TIMEOUT);
3.主从连接成功后,执行连接建立后事件
GapInit_connect成功返回GAP层事件GAP_LINK_Estableished,主机及从机进行事件处理
3.1.主机将连接句柄和设备地址添加到连接列表
SimpleCentral_addConnInfo(connHandle, pAddr);
//添加一个设备到 连接列表
static uint8_t SimpleCentral_addConnInfo(uint16_t connHandle, uint8_t *pAddr)
{uint8_t i;for (i = 0; i < MAX_NUM_BLE_CONNS; i++){if (connList[i].connHandle == CONNHANDLE_INVALID){// Found available entry to put a new connection info inconnList[i].connHandle = connHandle;memcpy(connList[i].addr, pAddr, B_ADDR_LEN);numConn++;break;}}return i;
}
其中connList[]元素结构体定义如下
//连接设备信息
typedef struct
{uint16_t connHandle; // Connection Handle 连接句柄uint8_t addr[B_ADDR_LEN]; // Peer Device Address 连接对端设备地址uint8_t charHandle; // Characteristic Handle 特征值句柄Clock_Struct *pRssiClock; // pointer to clock struct
} connRec_t;
3.2.主机进行GATT服务的发现
蓝牙----蓝牙消息传输_GATT服务发现
3.3.从机获取连接句柄,并发起连接参数更新
SimplePeripheral_addConn(pPkt->connectionHandle);
从机获取连接句柄,并判断是否到达连接数目,选择继续/停止广播
连接参数更新在自定义的SP_SEND_PARAM_UPDATE_DELAY(6S)后,从机发起
//从机获取连接句柄,进行连接参数更新
static uint8_t SimplePeripheral_addConn(uint16_t connHandle)
{uint8_t i;uint8_t status = bleNoResources;// Try to find an available entryfor (i = 0; i < MAX_NUM_BLE_CONNS; i++){if (connList[i].connHandle == CONNHANDLE_INVALID){// Found available entry to put a new connection info inconnList[i].connHandle = connHandle;// Allocate data to send through clock handlerconnList[i].pParamUpdateEventData = ICall_malloc(sizeof(spClockEventData_t) +sizeof (uint16_t));if(connList[i].pParamUpdateEventData){connList[i].pParamUpdateEventData->event = SP_SEND_PARAM_UPDATE_EVT;*((uint16_t *)connList[i].pParamUpdateEventData->data) = connHandle;// Create a clock object and startconnList[i].pUpdateClock= (Clock_Struct*) ICall_malloc(sizeof(Clock_Struct));//启动连接参数更新if (connList[i].pUpdateClock){Util_constructClock(connList[i].pUpdateClock,SimplePeripheral_clockHandler,SP_SEND_PARAM_UPDATE_DELAY, 0, true,(UArg) (connList[i].pParamUpdateEventData));}else{ICall_free(connList[i].pParamUpdateEventData);}}else{status = bleMemAllocError;}// Set default PHY to 1MconnList[i].currPhy = HCI_PHY_1_MBPS;break;}}return status;
}
4.从机发起连接参数更新
从机发送连接参数更新GAP_UpdateLinkParamReq
4.1主机收到连接参数更新请求
主机GAP收到GAP_UPDATE_LINK_PARAM_REQ_EVENT连接请求事件,获取新的连接参数,执行连接请求回应GAP_UpdateLinkParamReqReply。
case GAP_UPDATE_LINK_PARAM_REQ_EVENT:{gapUpdateLinkParamReqReply_t rsp;gapUpdateLinkParamReq_t *pReq;pReq = &((gapUpdateLinkParamReqEvent_t *)pMsg)->req;rsp.connectionHandle = pReq->connectionHandle;rsp.signalIdentifier = pReq->signalIdentifier;//允许连接参数更新if (acceptParamUpdateReq){//收到的 新的连接请求参数rsp.intervalMin = pReq->intervalMin;rsp.intervalMax = pReq->intervalMax;rsp.connLatency = pReq->connLatency;rsp.connTimeout = pReq->connTimeout;rsp.accepted = TRUE;}else{// Reject the request.rsp.accepted = FALSE;}// Send Reply// 连接请求回应VOID GAP_UpdateLinkParamReqReply(&rsp);break;}
连接请求回应GAP_UpdateLinkParamReqReply,触发主机的GAP_LINK_PARAM_UPDATE_EVENT事件,对连接参数更新成功与失败情况进行判决。
4.2从机进行连接参数更新
主机向从机连接请求回应GAP_UpdateLinkParamReqReply后,对连接参数更新成功与失败情况进行判决。