我得到SDP後,大量的頭髮拉動工作。代碼如下。這是在https://people.csail.mit.edu/albert/bluez-intro/x604.html
後的一個例子,這對我來說似乎不必要的複雜。一個「計算機科學家狂放!」的案例。對於像這樣常見和簡單的事情,他們應該包括一個便利的包裝。
// getchan - get channel for specified service
// CONVENIENCE DEFINITIONS TO (IMHO) MAKE CODE MORE READABLE
#define BYTE uint8_t
#define UUID uuid_t
#define LIST sdp_list_t
#define SESSION sdp_session_t
#define RECORD sdp_record_t
#define DATA sdp_data_t
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "unistd.h"
#include "stdlib.h"
#include "bluetooth/bluetooth.h"
#include "bluetooth/sdp.h"
#include "bluetooth/sdp_lib.h"
#define DEV_ADDR "E4:12:1D:96:10:EF" // MAC address of service device
main(
int argc,
char **argv)
{
// Server UUID: "d8308c4e-9469-4051-8adc-7a2663e415e2"
static BYTE uuid[16] = { // UUID as byte array
0xd8, 0x30, 0x8c, 0x4e, 0x94, 0x69, 0x40, 0x51,
0x8a, 0xdc, 0x7a, 0x26, 0x63, 0xe4, 0x15, 0xe2
};
int chan;
chan = GetServiceChannel(uuid);
if(chan > 0) {
printf("specified service is on channel %d\n", chan);
}
else {
fprintf(stderr, " can't find channel\n");
}
exit(0);
}
int
GetServiceChannel(
BYTE *uuid) // uuid of service as 16 bytes
{
SESSION *s;
UUID svc_uuid;
LIST *response_list,*search_list,*attrid_list,*r;
RECORD *rec;
int range;
int n;
BYTE addr[6]; // define my own addr type
int chan=0;
// CONNECT TO SDP SERVER
// (Note: device must be ON but server need not be running)
str2ba(DEV_ADDR, (bdaddr_t *)&addr);
s = sdp_connect(BDADDR_ANY, (bdaddr_t *)&addr, SDP_RETRY_IF_BUSY);
if(!s) {
fprintf(stderr, "can't connect to sdp server\n");
return(0);
}
// CREATE QUERY LISTS
sdp_uuid128_create(&svc_uuid, uuid);
search_list = sdp_list_append(NULL, &svc_uuid);
range = 0x0000ffff; // start at 0000, end at ffff
attrid_list = sdp_list_append(NULL, &range);
// SEARCH FOR RECORDS
// (Note: Server must be running)
n = sdp_service_search_attr_req(
s, search_list, SDP_ATTR_REQ_RANGE, attrid_list, &response_list);
if(n) {
fprintf(stderr, "search failed.\n");
return(0);;
}
// CHECK IF ANY RESPONSES
n = sdp_list_len(response_list);
if(n <= 0) {
fprintf(stderr, "no responses.\n");
return(0);;
}
// PROCESS RESPONSES
r = response_list;
while(r) { // loop thru all responses
sdp_record_t *rec;
LIST *proto_list,*p;
rec = (RECORD *)r->data;
n = sdp_get_access_protos(rec, &proto_list);
if(n) {
fprintf(stderr, "can't get access protocols.\n");
return(0);
}
p = proto_list;
while(p) { // loop thru all protocols
LIST *pds;
int proto=0;
pds = (LIST *)p->data;
while(pds) { // loop thru all pds
DATA *d;
int dtd;
d = pds->data; // get data ptr of pds
while(d) { // loop over all data
dtd = d->dtd; // get dtd of data
switch(dtd) { // which dtd?
case SDP_UUID16:
case SDP_UUID32:
case SDP_UUID128:
proto = sdp_uuid_to_proto(&d->val.uuid); // get proto #
break;
case SDP_UINT8:
if(proto == RFCOMM_UUID) { // proto is rfcomm?
chan = d->val.uint8; // save chan num
}
break;
}
d = d->next; // advance to next data unit
}
pds = pds->next; // advance to next pds
}
sdp_list_free((LIST *)p->data, 0);
p = p->next; // advance to next protocol
}
sdp_list_free(proto_list, 0);
r = r->next; // advance to next response
}
return(chan);
// Return chan number [1-30] or 0 if not found
}
要:
gcc getchan.c -o getchan -l bluetooth
我一半試圖從1-31連接到每個信道數計算出答案。我在通道3,4,5,6上獲得了成功的連接。我的Android應用程序顯示連接數爲6.因此(顯然)活動Android服務器的每個UUID映射到一個通道編號。當然問題是如何確定合適的頻道號碼。我相信答案是使用「服務發現協議」(SDP)。我還沒有弄清楚如何做到這一點,但至少隧道盡頭有燈光。只要我(希望)弄清楚,我會盡快發佈一個完整的答案。 – DontPanic