2016-12-13 2 views
2

Ich versuche, eine Bluetooth-Verbindung von einem Raspberry Pi 3B (Debian Linux) auf einen Android-App zu erstellen. Mein Problem ist, dass das Android-Framework (AFAIK) die Verwendung einer UUID erfordert, z. createRfcommSocketToServiceRecord (UUID). Code-Auszug:Wie von Linux auf Android Bluetooth-Buchse verbinden

// CREATE SPP SOCKET 
mSock = device.createRfcommSocketToServiceRecord(uuid); 
if(mSock == null) { 
    return(-1); 
} 
// TRY TO CONNECT 
mSock.connect(); 

Der obige Code funktioniert gut Android-zu-Android.

Linux auf der anderen Seite erfordern nur eine „RC-Kanalnummer“ (eine ganze Zahl). Das Folgende ist ein Beispielcode von MIT:

#include <stdio.h> 
#include <unistd.h> 
#include <sys/socket.h> 
#include <bluetooth/bluetooth.h> 
#include <bluetooth/rfcomm.h> 

int main(int argc, char **argv) 
{ 
    struct sockaddr_rc addr = { 0 }; 
    int s, status; 
    char dest[18] = "XX:XX:XX:XX:XX:XX"; // android address here 

    // allocate a socket 
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 

    // set the connection parameters (who to connect to) 
    addr.rc_family = AF_BLUETOOTH; 
    addr.rc_channel = (uint8_t) 1; 
    str2ba(dest, &addr.rc_bdaddr); 

    // connect to server 
    status = connect(s, (struct sockaddr *)&addr, sizeof(addr)); 

    // send a message 
    if(status == 0) { 
     status = write(s, "hello!", 6); 
    } 

    if(status < 0) perror("uh oh"); 

    close(s); 
    return 0; 
} 

Ich kann nicht herausfinden, wie diese zwei Welten zu überbrücken.
Hilfe!

+0

ich versucht, die Antwort Hälfte herausgefunden zu jeder Kanalnummer 1 bis 31 zu verbinden. Ich habe eine erfolgreiche Verbindung auf den Kanälen 3, 4, 5, 6. Meine Android App-Verbindung So für 6 angegeben (scheinbar) jede UUID für einen aktiven Android Server auf eine Kanalnummer zugeordnet wird. Die Frage ist natürlich, wie man die entsprechende Kanalnummer ermittelt. Ich glaube, die Antwort ist die Verwendung des "Service Discovery Protocol" (SDP). Ich habe nicht recht herausgefunden, wie das geht, aber am Ende des Tunnels ist Licht. Ich werde eine vollständige Antwort veröffentlichen, sobald ich (hoffentlich) es herausgefunden habe. – DontPanic

Antwort

0

Ich habe SDP nach vielen Haareziehen zu arbeiten. Der Code ist unten. Es wurde bei https://people.csail.mit.edu/albert/bluez-intro/x604.html

nach einem Beispiel ausgebildete

Dies ist für mich unnötig kompliziert zu sein scheint. Ein Fall von "Computerwissenschaftler wild gegangen!". Für etwas so allgemein und einfach wie das sollten sie einen Convenience-Wrapper enthalten.

// 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 
} 

zu machen:

gcc getchan.c -o getchan -l bluetooth 
Verwandte Themen