本文作者的部落格地址:http://blog.sina.com.cn/samzhen1977
作者:Sam (甄峰)
sam_code@hotmail.com
先前的章節談過SDP協議。但沒有具體講如何編程。
BlueZ提供的SDP API,常見的如下:
1.
sdp_session_t *sdp_create(int sk, uint32_t
flags)
參數1:sk: socket
參數2:SDP flags. 取值如下:
#define SDP_RETRY_IF_BUSY 0x01
#define SDP_WAIT_ON_CLOSE 0x02
#define SDP_NON_BLOCKING 0x04
建立一個新的Session為了非同步尋找。
Session結構如下:
typedef struct {
int sock;
int state;
int local;
int flags;
uint16_t tid; // Current
transaction ID
void *priv;
} sdp_session_t;
sdp_create
只是簡單的建立一個空間將Session指標返回。並將sk和flags傳入Session對應
值。
同時,會建立transaction並將指標給priv
.
struct sdp_transaction {
sdp_callback_t *cb;
void
*udata;
uint8_t *reqbuf;
sdp_buf_t rsp_concat_buf;
uint32_t reqsize;
int
err;
};
2.
static inline int sdp_is_local(const bdaddr_t
*device)
察看參數bdaddr是否為本地bdaddr--{0, 0, 0, 0xff, 0xff, 0xff}
如果是本地,則返回1。否則返回0。
3.
static int sdp_connect_local(sdp_session_t
*session)
串連本地。並將socket賦予參數session對應資料。
建立 socket如下。socket(PF_UNIX, SOCK_STREAM, 0)
sa.sun_family = AF_UNIX;
strcpy(sa.sun_path, SDP_UNIX_PATH);
並串連之。
4.
static int sdp_connect_l2cap(const bdaddr_t *src,const
bdaddr_t *dst, sdp_session_t *session)
參數1:src: 源bdaddr.
參數2:dst: 目標bdaddr.
參數3: session: sdp_create所建立的session.
動作:
建立l2cap socket.並串連,同時PSM=0x01(SDP)
並將socket 存入session. 只有與對端串連後,才可以得到SDP資訊。
5.
sdp_session_t *sdp_connect(const bdaddr_t *src,
const bdaddr_t *dst, uint32_t
flags)
參數1:src 源BDAddr。
參數2:dst 目標BDAddr。
參數3:flags 取值如下:
#define SDP_RETRY_IF_BUSY 0x01
#define SDP_WAIT_ON_CLOSE 0x02
#define SDP_NON_BLOCKING 0x04
來源:(http://blog.sina.com.cn/s/blog_602f87700100jaog.html
)
- 實戰Linux Bluetooth編程(九) SDP層編程_samzhen_新浪部落格
注意,SDP_RETRY_IF_BUSY 與SDP_NON_BLOCKING互斥。
此函數會建立session.並建立l2cap socket,串連遠端dst. PSM為1(SDP)。
6.
uuid_t *sdp_uuid16_create(uuid_t *u, uint16_t
val)
將參數2 val copy到參數1 的value.uuid16中去。
7.
sdp_list_t *sdp_list_append(sdp_list_t *p, void
*d)
將參數2 加入參數1 的鏈表中。
參數1是個單向鏈表。將參數2加入此單向鏈表中。如果參數1為空白,則建立一個單向鏈表。
8.
int sdp_service_search_attr_req(sdp_session_t *session,
const sdp_list_t *search, sdp_attrreq_type_t reqtype, const
sdp_list_t *attrids, sdp_list_t **rsp)
這個function非常重要。
參數1:sdp_session_t *session:
此session
中的sock為已SDP串連(l2cap, psm=0x01).
參數2:const sdp_list_t *search:
search是想要尋找SDP
Record的鏈表。如PNP,HID等。
參數3:sdp_attrreq_type_t reqtype
typedef enum {
SDP_ATTR_REQ_INDIVIDUAL = 1,
SDP_ATTR_REQ_RANGE
} sdp_attrreq_type_t;
參數4:const sdp_list_t *attrids。search中指定的SDP
Record中的特徵鏈表。如果想要得到某record中所有特徵。則使用0x0000ffff為內容建立鏈表。
參數5:sdp_list_t **rsp: 得到的Attr的資訊。
這個function是用來client發送request給server。得到符合service search
pattern(參數2)的SDP Record中的Attribute。例如:可以得到PNP,HID
record中的屬性。如VID,PID,以及report等。
此function發送SDP_ServiceSearchAttributeRequest(PDU
ID=0x06),並將search中包含的特徵以及attrids放入參數。並等待SDP_ServiceSearchAttributeResponse。
並將返回的資訊放入參數5中。
參數5的具體解析,則看search是什麼。PNP則查PNP的文檔。HID則查HID——SPEC。
9.
int sdp_close(sdp_session_t *session)
關閉session->sock
附錄1:
PDU格式:(PROTOCOL DATA UNIT FORMAT)