蓝牙主机从机建立连接绑定过程
center与simplePeripheral建立连接过程
center首先进行osal_init_system()初始化各个任务,SimpleBLECentral_Init->osal_set_event( simpleBLETaskId,START_DEVICE_EVT );进入SimpleBLECentral_ProcessEvent()
调用
VOIDGAPCentralRole_StartDevice( (gapCentralRoleCB_t *) &simpleBLERoleCB );//当初始化完成,会发送 GAP_DEVICE_INIT_DONE_EVENT由于注册了simpleBLERoleCB函数,因此发送的event由simpleBLERoleCB函数接收static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent )此时pEvent->gap.opcode=GAP_DEVICE_INIT_DONE_EVENT,相应信息存储于pEvent中
typedef union { gapEventHdr_t gap; //!< GAP_MSG_EVENT andstatus. gapDeviceInitDoneEvent_t initDone; //!< GAP initialization done. gapDeviceInfoEvent_t deviceInfo; //!< Discovery device informationevent structure. gapDevDiscEvent_t discCmpl; //!< Discovery complete eventstructure. gapEstLinkReqEvent_t linkCmpl; //!< Link complete eventstructure. gapLinkUpdateEvent_t linkUpdate; //!< Link update event structure. gapTerminateLinkEvent_t linkTerminate; //!< Link terminated event structure. }gapCentralRoleEvent_t;
联合体,只有deviceInfo里面的数据是正确的
typedef struct { osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status uint8 opcode; //!< GAP_DEVICE_INIT_DONE_EVENT uint8 devAddr[B_ADDR_LEN]; //!< Device's BD_ADDR uint16 dataPktLen; //!<HC_LE_Data_Packet_Length uint8 numDataPkts; //!<HC_Total_Num_LE_Data_Packets } gapDeviceInitDoneEvent_t;
能获得如设备地址等信息
设备初始化完成
通过串口发送'1'触发设备发现
进行设备扫描
GAP_DEVICE_INFO_EVENT 0x0D//!< Sent during the Device Discovery Process when a device is discovered.
GAP_DEVICE_DISCOVERY_EVENT 0x01//!< Sent when the Device Discovery Process is complete.
当发现一个设备时,触发一个设备info事件同样是在simpleBLECentralEventCB处理此时pEvent改变为deviceInfo可以获得广告设备的类型,地址。rssi强度,还有广告数据,内容如下。
typedef struct { osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status uint8 opcode; //!< GAP_DEVICE_INFO_EVENT uint8 eventType; //!< Advertisement Type: @refGAP_ADVERTISEMENT_TYPE_DEFINES uint8 addrType; //!< address type: @refGAP_ADDR_TYPE_DEFINES uint8 addr[B_ADDR_LEN]; //!< Address of the advertisement orSCAN_RSP int8 rssi; //!< Advertisement orSCAN_RSP RSSI uint8 dataLen; //!< Length (in bytes) of thedata field (evtData) uint8 *pEvtData; //!< Data field of advertisementor SCAN_RSP } gapDeviceInfoEvent_t;
center代码是通过设备服务器的uuid来查找设备,一旦找到相应的设备,将设备加入
设备表simpleBLEDevList[]中simpleBLEScanRes扫描到的个数自加一。
typedef struct { uint8 eventType; //!< Indicates advertising event typeused by the advertiser: GAP_ADVERTISEMENT_TYPE_DEFINES uint8 addrType; //!< Address Type: @refGAP_ADDR_TYPE_DEFINES uint8 addr[B_ADDR_LEN]; //!< Device'sAddress } gapDevRec_t;
设备表的结构体
addrType有:
#define ADDRTYPE_PUBLIC 0x00 Use the BD_ADDR. #define ADDRTYPE_STATIC 0x01 Static address. #define ADDRTYPE_PRIVATE_NONRESOLVE 0x02 Generate Non-Resolvable PrivateAddress. #define ADDRTYPE_PRIVATE_RESOLVE 0x03 Generate Resolvable Private Address.
caseGAP_DEVICE_INFO_EVENT: { if ( DEFAULT_DEV_DISC_BY_SVC_UUID ==TRUE ) { if ( simpleBLEFindSvcUuid(SIMPLEPROFILE_SERV_UUID, //通过uuid找到的设备 pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen ) ) { // HalUARTWrite(0,"infon",sizeof("infon"));//dataLen 数据长度 pEvtData 数据 simpleBLEAddDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType ); } } } break;
此时已经获得了扫描到的设备个数,以及设备地址,还有广告内容等信息。
通过串口发送‘3’来 建立连接
建立连接:
typedef struct { uint8 taskID; //!< Requesting App/Profile'sTask ID uint8 highDutyCycle; //!< TRUE to high duty cycle scan,FALSE if not. uint8 whiteList; //!< Determines use of the whitelist: @ref GAP_WHITELIST_DEFINES uint8 addrTypePeer; //!< Address type of theadvertiser: @ref GAP_ADDR_TYPE_DEFINES uint8 peerAddr[B_ADDR_LEN]; //!<Advertiser's address } gapEstLinkReq_t;
调用 GAP_EstablishLinkReq(gapEstLinkReq_t params);完成后发送GAP_LINK_ESTABLISHED_EVENT,由simpleBLECentralEventCB(gapCentralRoleEvent_t *pEvent )处理
#defineGAP_LINK_ESTABLISHED_EVENT 0x05//!< Sent when the Establish Link Request is complete.
用此时pEvent变为:
typedef struct { osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status uint8 opcode; //!<GAP_LINK_ESTABLISHED_EVENT uint8 devAddrType; //!< Device address type: @refGAP_ADDR_TYPE_DEFINES uint8 devAddr[B_ADDR_LEN]; //!< Deviceaddress of link uint16 connectionHandle; //!< Connection Handle from controllerused to ref the device uint16 connInterval; //!< Connection Interval uint16 connLatency; //!< Conenction Latency uint16 connTimeout; //!< Connection Timeout uint8 clockAccuracy; //!< Clock Accuracy }gapEstLinkReqEvent_t;
可以得到设备地址。连接的handle连接完成
连接过程中发送START_DISCOVERY_EVT事件进行服务器发现。就可以对相应的handle,characteristic value进行读写操作,或者用于向主机,从机发送数据。
获得服务器相应特性值的handle有三种方法:
1.通过主服务的uuid(uuid已知)来查找。
bStatus_tGATT_DiscPrimaryServiceByUUID (uint16 connHandle,// 连接的handle uint8 * pValue, // uuid uint8 len, // uuid的长度 uint8 taskId // 接收消息的任务ID )
发送 ATT_FIND_BY_TYPE_VALUE_RSP或者 ATT_ERROR_RSP由相应任务接收处理
static voidsimpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )通过此函数进行通过UUID来查找相应的Handle进行对特性值的相关操作。
2.查找所有的服务
bStatus_tGATT_DiscAllPrimaryServices (uint16 connHandle,//连接handle
uint8 taskId //接收消息的任务ID
)
osal_start_timerEx(simpleBLETaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );
到此连接完成。
3、GATT_DiscAllCharDescs() 这个接口,这个能自动把所有service 查找完,应该能发现你要的UUID。
最后
终止连接:
调用
GAP_TerminateLinkReq(任务id,handle)发送断开连接event
GAP_LINK_TERMINATED_EVENT 又一次调用 simpleBLECentralEventCB(gapCentralRoleEvent_t *pEvent )
typedef struct { osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status uint8 opcode; //!<GAP_LINK_ESTABLISHED_EVENT uint8 devAddrType; //!< Device address type: @refGAP_ADDR_TYPE_DEFINES uint8 devAddr[B_ADDR_LEN]; //!< Deviceaddress of link uint16 connectionHandle; //!< Connection Handle from controllerused to ref the device uint16 connInterval; //!< Connection Interval uint16 connLatency; //!< Conenction Latency uint16 connTimeout; //!< Connection Timeout uint8 clockAccuracy; //!< Clock Accuracy }gapEstLinkReqEvent_t;