生活随笔
收集整理的這篇文章主要介紹了
蓝牙L2CAP剖析(二)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一,部分代碼沒有完成,只是模擬一個(gè)面向連接的從建立到斷開的過程,另外,L2CAP的重點(diǎn)狀態(tài)機(jī)和拆包重組沒有模擬
bt_l2cap.h
[cpp]?view plain
?copy ? ? ? ? ? ?? ?? #ifndef?BT_L2CAP_H_H?? #define?BT_L2CAP_H_H?? ?? #include?"bt_cfg.h"?? ?? #ifdef?DEBUG_BT_L2CAP?? #define?DEBUG(x)?{printf?x;}?? #define?BT_L2CAP_DEBUG(x)?DEBUG(x)?? #else?? #define?BT_L2CAP_DEBUG(x)??? #endif?? ?? #define?L2CAP_SIG_CH?0x0001?? #define?L2CAP_CONLESS_CH?0x0002?? ?? ?? #define?L2CAP_DEFAULT_MTU???672?? #define?L2CAP_DEFAULT_FLUSH_TO??0xFFFF?? ?? ?? #define?SDP_PSM?0x0001?? ?? #define?L2CAP_COMMAND_REJ???0x01?? #define?L2CAP_CONN_REQ??????0x02?? #define?L2CAP_CONN_RSP??????0x03?? #define?L2CAP_CONF_REQ??????0x04?? #define?L2CAP_CONF_RSP??????0x05?? #define?L2CAP_DISCONN_REQ???0x06?? #define?L2CAP_DISCONN_RSP???0x07?? #define?L2CAP_ECHO_REQ??????0x08?? #define?L2CAP_ECHO_RSP??????0x09?? #define?L2CAP_INFO_REQ??????0x0a?? #define?L2CAP_INFO_RSP??????0x0b?? ?? ?? #define?L2CAP_CR_SUCCESS????0x0000?? #define?L2CAP_CR_PEND???????0x0001?? #define?L2CAP_CR_NOSUP_PSM??0x0002?? #define?L2CAP_CR_SEC_BLOCK??0x0003?? #define?L2CAP_CR_NO_RSR?????0x0004?? ?? #define?L2CAP_CONF_SUCCESS??0x0000?? #define?L2CAP_CONF_UNACCEPT?0x0001?? #define?L2CAP_CONF_REJECT???0x0002?? #define?L2CAP_CONF_UNKNOWN??0x0003?? ?? ?? #define?L2CAP_CONF_MTU??????0x01?? #define?L2CAP_CONF_FLUSH_TO?0x02?? #define?L2CAP_CONF_QOS??????0x03?? #define?L2CAP_CONF_RFC??????0x04?? #define?L2CAP_CONF_RFC_MODE?0x04?? ?? #pragma?pack(1)?? ?? typedef?struct?{?? ????uint16_t????len;?? ????uint16_t????cid;?? }L2CAP_PDU_HDR_Format;?? ?? typedef?struct?{?? ????L2CAP_PDU_HDR_Format?sig_hdr;?? ????uint8_t?????code;?? ????uint8_t?????ident;?? ????uint16_t????len;?? }L2CAP_SIG_HDR_Format;?? ?? ?? typedef?struct?{?? ????L2CAP_SIG_HDR_Format?com_hdr;?? ????uint16_t????psm;?? ????uint16_t????scid;?? }L2CAP_Con_Req;?? ?? typedef?struct?{?? ????L2CAP_SIG_HDR_Format?com_hdr;?? ????uint16_t????dst_cid;?? ????uint16_t????src_cid;?? ????uint16_t????result;?? ????uint16_t????status;?? }L2CAP_Con_Rsp;?? ?? typedef?struct?{?? ????L2CAP_SIG_HDR_Format?com_hdr;?? ????uint16_t????dst_cid;?? ????uint16_t????flags;?? ????uint8_t?????data[0];?? }L2CAP_Conf_Req;?? ?? typedef?struct?{?? ????L2CAP_SIG_HDR_Format?com_hdr;?? ????uint16_t????src_cid;?? ????uint16_t????flags;?? ????uint16_t????result;?? ????uint8_t?????data[0];?? }L2CAP_Conf_Rsp;?? ?? typedef?struct?{?? ????L2CAP_PDU_HDR_Format?com_hdr;?? ????uint8_t?????data[0];?? }L2CAP_Upper_Layer_data_Format;?? ?? typedef?struct?{?? ????L2CAP_SIG_HDR_Format?com_hdr;?? ????uint16_t????dcid;?? ????uint16_t????scid;?? }L2CAP_Discon_req;?? ?? typedef?struct?{?? ????L2CAP_SIG_HDR_Format?com_hdr;?? ????uint16_t????dcid;?? ????uint16_t????scid;?? }L2CAP_Discon_rsp;?? #pragma?pack()?? ?? ?? ?? int?L2CAP_Send_SIG_Con_Req(uint8_t?ident,uint16_t?psm,uint16_t?scid);?? int?L2CAP_Send_SIG_Conf_Req(uint8_t?ident,uint16_t?dcid,uint16_t?flags,uint8_t?*conf_opt,uint8_t?opt_len);?? int?L2CAP_Send_Upper_Layer_data(uint16_t?cid,uint8_t?*data,uint16_t?length);?? int?L2CAP_Send_SIG_Discon_Req(uint8_t?ident,uint16_t?dcid,uint16_t?scid);?? int?L2CAP_Send_PDU(uint8_t?*PDU,uint32_t?length);?? ?? ?? int?L2CAP_Parse_PDU(uint8_t?*PDU,uint32_t?length);?? int?L2CAP_Parse_SIG_Con_Rsp_PDU(uint8_t?*PDU,uint32_t?length);?? int?L2CAP_Parse_SIG_Conf_Rsp_PDU(uint8_t?*PDU,uint32_t?length);?? int?L2CAP_Parse_SIG_Discon_Rsp_PDU(uint8_t?*PDU,uint32_t?length);?? #endif??
bt_l2cap.c
[cpp]?view plain
?copy #include?"bt_l2cap.h"?? ?? int?L2CAP_Send_SIG_Con_Req(uint8_t?ident,uint16_t?psm,uint16_t?scid)?? {?? ????L2CAP_Con_Req?PDU;?? ????PDU.com_hdr.sig_hdr.cid?=?L2CAP_SIG_CH;?? ????PDU.com_hdr.sig_hdr.len?=?sizeof(L2CAP_Con_Req)?-?sizeof(L2CAP_PDU_HDR_Format);?? ?? ????PDU.com_hdr.code?=?L2CAP_CONN_REQ;?? ????PDU.com_hdr.ident?=?ident;?? ????PDU.com_hdr.len?=?sizeof(L2CAP_Con_Req)?-?sizeof(L2CAP_SIG_HDR_Format);?? ?? ????PDU.psm?=?psm;?? ????PDU.scid?=?scid;?? ????L2CAP_Send_PDU((uint8_t?*)&PDU,sizeof(L2CAP_Con_Req));?? }?? int?L2CAP_Send_SIG_Conf_Req(uint8_t?ident,uint16_t?dcid,uint16_t?flags,uint8_t?*conf_opt,uint8_t?opt_len)?? {?? ????L2CAP_Conf_Req?*PDU?=?(L2CAP_Conf_Req?*)malloc(sizeof(L2CAP_Conf_Req)?+?opt_len);?? ????(PDU->com_hdr).sig_hdr.cid?=?L2CAP_SIG_CH;?? ????(PDU->com_hdr).sig_hdr.len?=?sizeof(L2CAP_Conf_Req)?-?sizeof(L2CAP_PDU_HDR_Format)?+?opt_len;?? ?????? ????(PDU->com_hdr).code?=?L2CAP_CONF_REQ;?? ????(PDU->com_hdr).ident?=?ident;?? ????(PDU->com_hdr).len?=?sizeof(L2CAP_Conf_Req)?-?sizeof(L2CAP_SIG_HDR_Format)?+?opt_len;?? ?????? ????PDU->dst_cid?=?dcid;?? ????PDU->flags?=?flags;?? ????memcpy(PDU->data,conf_opt,opt_len);?? ?? ????L2CAP_Send_PDU(PDU,sizeof(L2CAP_Conf_Req)?+?opt_len);?? }?? ?? int?L2CAP_Send_Upper_Layer_data(uint16_t?cid,uint8_t?*data,uint16_t?length)?? {?? ????L2CAP_Upper_Layer_data_Format?*PDU?=?(L2CAP_Upper_Layer_data_Format?*)malloc(sizeof(L2CAP_Upper_Layer_data_Format)?+?length);?? ????(PDU->com_hdr).cid?=?cid;?? ????(PDU->com_hdr).len?=?sizeof(L2CAP_Upper_Layer_data_Format)?+?length;?? ?? ????memcpy(PDU->data,data,length);????? ????L2CAP_Send_PDU(PDU,sizeof(L2CAP_Upper_Layer_data_Format)?+?length);?? }?? ?? int?L2CAP_Send_SIG_Discon_Req(uint8_t?ident,uint16_t?dcid,uint16_t?scid)?? {?? ????L2CAP_Discon_req?PDU;?? ????PDU.com_hdr.sig_hdr.cid?=?L2CAP_SIG_CH;?? ????PDU.com_hdr.sig_hdr.len?=?sizeof(L2CAP_Discon_req)?-?sizeof(L2CAP_PDU_HDR_Format);?? ?????? ????PDU.com_hdr.code?=?L2CAP_DISCONN_REQ;?? ????PDU.com_hdr.ident?=?ident;?? ????PDU.com_hdr.len?=?sizeof(L2CAP_Con_Req)?-?sizeof(L2CAP_SIG_HDR_Format);?? ?????? ????PDU.dcid?=?dcid;?? ????PDU.scid?=?scid;?? ????L2CAP_Send_PDU((uint8_t?*)&PDU,sizeof(L2CAP_Con_Req));?? }?? int?L2CAP_Send_PDU(uint8_t?*PDU,uint32_t?length)?? {?? ????int?index?=?0;?? ????BT_L2CAP_DEBUG(("?>>?Send?L2CAP?REQ?PDU:"));?? ????for(index?=?0;?index?<?length;?index++)?? ????{?? ????????BT_L2CAP_DEBUG(("0x%02x?",PDU[index]));?? ????}?? ????BT_L2CAP_DEBUG(("\n"));?? }?? ?? ?? int?L2CAP_Parse_PDU(uint8_t?*PDU,uint32_t?length)?? {?? ????L2CAP_PDU_HDR_Format?*TMP_PDU?=?(L2CAP_PDU_HDR_Format?*)PDU;?? ????if((TMP_PDU->cid)?==?L2CAP_SIG_CH)?? ????{?? ????????uint8_t?tmp_code;?? ????????L2CAP_SIG_HDR_Format?*pdu?=?(L2CAP_SIG_HDR_Format?*)PDU;?? ????????BT_L2CAP_DEBUG(("SIG?PDU\n"));???????? ????????tmp_code?=?pdu->code;?? ????????switch(tmp_code)?? ????????{?? ????????????case?L2CAP_CONN_RSP:?? ????????????{?? ????????????????BT_L2CAP_DEBUG(("L2CAP_CONN_RSP\n"));?? ????????????????L2CAP_Parse_SIG_Con_Rsp_PDU(PDU,length);?? ????????????????break;?? ????????????}?? ????????????case?L2CAP_CONF_RSP:?? ????????????{?? ????????????????BT_L2CAP_DEBUG(("L2CAP_CONF_RSP\n"));?? ????????????????L2CAP_Parse_SIG_Conf_Rsp_PDU(PDU,length);?? ????????????????break;?? ????????????}?? ????????????case?L2CAP_DISCONN_RSP:?? ????????????{?? ????????????????BT_L2CAP_DEBUG(("L2CAP_DISCONN_RSP\n"));?? ????????????????L2CAP_Parse_SIG_Discon_Rsp_PDU(PDU,length);?? ????????????????break;?? ????????????}?? ????????????default:?? ????????????{?? ????????????????break;?? ????????????}?? ????????}?? ?????????? ????}?? ????else?? ????{?? ?????????? ????}?? }?? ?? int?L2CAP_Parse_SIG_Con_Rsp_PDU(uint8_t?*PDU,uint32_t?length)?? {?? ????L2CAP_Con_Rsp?*tmp_pdu?=?(L2CAP_Con_Rsp?*)PDU;?? ????if(tmp_pdu->result?==?L2CAP_CR_SUCCESS)?? ????{?? ????????BT_L2CAP_DEBUG(("connect?successful\n"));?? ????}?? ????else?if(tmp_pdu->result?==?L2CAP_CR_PEND)?? ????{?? ????????BT_L2CAP_DEBUG(("connect?pending\n"));?? ????}?? }?? ?? int?L2CAP_Parse_SIG_Conf_Rsp_PDU(uint8_t?*PDU,uint32_t?length)?? {?? ????L2CAP_Conf_Rsp?*tmp_pdu?=?(L2CAP_Conf_Rsp?*)PDU;?? ????if(tmp_pdu->result?==?L2CAP_CONF_SUCCESS)?? ????{?? ????????BT_L2CAP_DEBUG(("config?successful\n"));?? ????}?? ????else?if(tmp_pdu->result?==?L2CAP_CONF_UNACCEPT)?? ????{?? ????????BT_L2CAP_DEBUG(("config?unaccept\n"));?? ????}?? }?? ?? int?L2CAP_Parse_SIG_Discon_Rsp_PDU(uint8_t?*PDU,uint32_t?length)?? {?? ?????? }??
bt_cfg.h
[cpp]?view plain
?copy #ifndef?BT_LMP_CFG_H?? #define?BT_LMP_CFG_H?? ?? #include?<stdlib.h>?? #include?<stdio.h>?? #include?<string.h>?? ?? #define?DEBUG_BT_L2CAP?? ?? typedef?unsigned?char?uint8_t;?? typedef?unsigned?short?uint16_t;?? typedef?unsigned?int?uint32_t;?? ?? ?? ?? typedef??char?int8_t;?? typedef??short?int16_t;?? typedef??int?int32_t;?? ?? #undef?NULL??? #if?defined(__cplusplus)?? #define?NULL?0?? #else?? #define?NULL?((void?*)0)?? #endif?? ?? #endif??
main.c
[cpp]?view plain
?copy #include?<stdio.h>?? #include?"bt_l2cap.h"?? ?? int?main()?? {?? ????uint8_t?con_rsp_pdu[]?=?{0x0C,0x00,0x01,0x00,0x03,0x79,0x08,0x00,0x06,0x08,0x40,0x00,0x00,0x00,0x00,0x00};??? ????uint8_t?conf_option[]?=?{0x01,0x02,0xF4,0x01,0x02,0x02,0xFF,0xFF};?? ????uint8_t?conf_rsp_pdu[]?=?{0x0E,0x00,0x01,0x00,0x05,0x7A,0x0A,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0xF4,0x01};?? ????uint8_t?upper_layer_data[]?=?{0x1,0x1,0x1,0x1,0x1,0x1};?? ????L2CAP_Send_SIG_Con_Req(0x79,SDP_PSM,0x40);?? ????L2CAP_Parse_PDU(con_rsp_pdu,sizeof(con_rsp_pdu));?? ?? ????L2CAP_Send_SIG_Conf_Req(0x79,0x0806,0x0,conf_option,sizeof(conf_option));?? ????L2CAP_Parse_PDU(conf_rsp_pdu,sizeof(conf_rsp_pdu));?? ?? ????L2CAP_Send_Upper_Layer_data(0x40,upper_layer_data,sizeof(upper_layer_data));?? ?? ????L2CAP_Send_SIG_Discon_Req(0x79,0x40,0x0806);?? }??
總結(jié)
以上是生活随笔為你收集整理的蓝牙L2CAP剖析(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。