私は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から各チャンネル番号に接続しようとすることで答えを考え出しました。私のAndroidアプリは6の接続を示していました。アクティブなAndroidサーバーの各UUIDはチャンネル番号にマッピングされています(明らかに)。もちろん、適切なチャネル番号を決定する方法があります。答えは「サービスディスカバリプロトコル」(SDP)を使用することです。私はこれをどうやってやっているのか分かりませんが、少なくともトンネルの終わりには光があります。私は(うまくいけば)それを把握するとすぐに完全な回答を投稿します。 – DontPanic