How to connect from Linux to Android Bluetooth socket

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

I'm trying to create a Bluetooth connection from a Raspberry Pi 3B (Debian Linux) to an Android app. My problem is that the the Android framework (AFAIK) requires use of a UUID, e.g. createRfcommSocketToServiceRecord(UUID). Code excerpt:

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

The code above works fine Android-to-Android.

Linux on the other hand requires just an "rc channel number" (an integer). The following is some sample code from 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; } 

I can't figure out how to bridge these two worlds.
Help!

回答1:

I got SDP to work after a lot of hair-pulling. The code is below. It was fashioned after an example at https://people.csail.mit.edu/albert/bluez-intro/x604.html

This seems unnecessarily complicated to me. A case of "Computer Scientists Gone Wild!". For something as common and simple as this, they should have included a convenience wrapper.

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

To make:

gcc getchan.c -o getchan -l bluetooth 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!