[转载]蓝牙4.0 BLE center与peripheral建立连接绑定过程

蓝牙主机从机建立连接绑定过程
center与simplePeripheral建立连接过程
center首先进行osal_init_system()初始化各个任务,SimpleBLECentral_Init->osal_set_event( simpleBLETaskId, START_DEVICE_EVT );进入SimpleBLECentral_ProcessEvent()
调用
VOID GAPCentralRole_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 and status.
gapDeviceInitDoneEvent_t initDone; //!< GAP initialization done.
gapDeviceInfoEvent_t deviceInfo; //!< Discovery device information event structure.
gapDevDiscEvent_t discCmpl; //!< Discovery complete event structure.
gapEstLinkReqEvent_t linkCmpl; //!< Link complete event structure.
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: @ref GAP_ADVERTISEMENT_TYPE_DEFINES
uint8 addrType; //!< address type: @ref GAP_ADDR_TYPE_DEFINES
uint8 addr[B_ADDR_LEN]; //!< Address of the advertisement or SCAN_RSP
int8 rssi; //!< Advertisement or SCAN_RSP RSSI
uint8 dataLen; //!< Length (in bytes) of the data field (evtData)
uint8 *pEvtData; //!< Data field of advertisement or SCAN_RSP
} gapDeviceInfoEvent_t;

center代码是通过设备服务器的uuid来查找设备,一旦找到相应的设备,将设备加入
设备表simpleBLEDevList[]中simpleBLEScanRes扫描到的个数自加一。
typedef struct
{
uint8 eventType; //!< Indicates advertising event type used by the advertiser: GAP_ADVERTISEMENT_TYPE_DEFINES
uint8 addrType; //!< Address Type: @ref GAP_ADDR_TYPE_DEFINES
uint8 addr[B_ADDR_LEN]; //!< Device’s Address
} 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 Private Address.

define ADDRTYPE_PRIVATE_RESOLVE 0x03

     Generate Resolvable Private Address.

case GAP_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,”info\n”,sizeof(“info\n”));//dataLen 数据长度 pEvtData 数据
simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );
}
}
}
break;
此时已经获得了扫描到的设备个数,以及设备地址,还有广告内容等信息。

通过串口发送‘3’来 建立连接
建立连接:
typedef struct
{
uint8 taskID; //!< Requesting App/Profile’s Task ID
uint8 highDutyCycle; //!< TRUE to high duty cycle scan, FALSE if not.
uint8 whiteList; //!< Determines use of the white list: @ref GAP_WHITELIST_DEFINES
uint8 addrTypePeer; //!< Address type of the advertiser: @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 )处理

define GAP_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: @ref GAP_ADDR_TYPE_DEFINES
uint8 devAddr[B_ADDR_LEN]; //!< Device address of link
uint16 connectionHandle; //!< Connection Handle from controller used 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_t GATT_DiscPrimaryServiceByUUID (uint16 connHandle,// 连接的handle
uint8 * pValue, // uuid
uint8 len, // uuid的长度
uint8 taskId // 接收消息的任务ID
)
发送 ATT_FIND_BY_TYPE_VALUE_RSP 或者 ATT_ERROR_RSP由相应任务接收处理
static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )通过此函数进行通过UUID来查找相应的Handle进行对特性值的相关操作。
2.查找所有的服务
bStatus_t GATT_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: @ref GAP_ADDR_TYPE_DEFINES
uint8 devAddr[B_ADDR_LEN]; //!< Device address of link
uint16 connectionHandle; //!< Connection Handle from controller used to ref the device
uint16 connInterval; //!< Connection Interval
uint16 connLatency; //!< Conenction Latency
uint16 connTimeout; //!< Connection Timeout
uint8 clockAccuracy; //!< Clock Accuracy
} gapEstLinkReqEvent_t;
4、绑定过程

《[转载]蓝牙4.0 BLE center与peripheral建立连接绑定过程》 002sNcnygy6KFYPrWNW18&690.jpeg

// Setup the GAP Bond Manager //GAP 绑定管理器设置
{
uint32 passkey = 0; // passkey “000000” //密钥
uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;//配对模式,配置成等待主机的配对请求
uint8 mitm = TRUE;
uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;//只显示设备
uint8 bonding = TRUE;

GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey ); //密钥,范围是 0-999999,默认值为 0

GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode );//告诉绑定管理器是否配对通过,不论它等待一个请求从控制设备或者是自己发起配对.默认的设置是等待一个请求从控制设备. 配对模式:配置成等待主机的配对请求

GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm );//设置中间人保护是否使能.如果使能了,配对请求将鉴定连接在从和主之间.profile默认的值为FALSE,即使应用设置它为TRUE在初始化的时候. 打开密钥保护的配对算法

GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap );//告诉绑定管理器设备的输入和输出的能力.为了判断设备是否有显示屏或者输入键盘这个参数是需要的.然而,默认的值为GAPBOND_IO_CAP_DISPLAY_ONLY,表明设备有一个显示屏但没有键盘.即使设备没有物理意义上的显示器,一个展示的钥匙(在用户指导中)被认为是一个显示器.默认的万能钥匙是一个六位数字字符串”000000”.

GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );//使能绑定.profile默认的值为FALSE,即使SimpleBLEPeripheral应用设置它为TRUE在初始化时.

}

    原文作者:风雨byt
    原文地址: https://www.jianshu.com/p/1cd0038770d6
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞