2016-12-13 67 views
2

我正嘗試從Raspberry Pi 3B(Debian Linux)創建一個藍牙連接到Android應用程序。我的問題是Android框架(AFAIK)需要使用UUID,例如createRfcommSocketToServiceRecord(UUID)。代碼摘錄:如何從Linux連接到Android藍牙插座

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

上面的代碼很好地運行Android到Android。

另一方面,Linux只需要一個「rc通道號」(一個整數)。以下是來自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; 
} 

我無法弄清楚如何連接這兩個世界。
幫助!

+0

我一半試圖從1-31連接到每個信道數計算出答案。我在通道3,4,5,6上獲得了成功的連接。我的Android應用程序顯示連接數爲6.因此(顯然)活動Android服務器的每個UUID映射到一個通道編號。當然問題是如何確定合適的頻道號碼。我相信答案是使用「服務發現協議」(SDP)。我還沒有弄清楚如何做到這一點,但至少隧道盡頭有燈光。只要我(希望)弄清楚,我會盡快發佈一個完整的答案。 – DontPanic

回答

0

我得到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