[轉載]藍牙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、綁定過程

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在初始化時.

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容