如何从Linux连接到Android蓝牙插座

时间:2016-12-13 20:41:04

标签: android linux sockets bluetooth

我正在尝试从Raspberry Pi 3B(Debian Linux)创建蓝牙连接到Android应用程序。我的问题是Android框架(AFAIK)需要使用UUID,例如createRfcommSocketToServiceRecord(UUID)。代码摘录:

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

上面的代码适用于Android-to-Android。

另一方面,Linux只需要一个“rc通道号”(整数)。以下是麻省理工学院的一些示例代码:

#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;
}

我无法弄清楚如何弥合这两个世界 救命啊!

1 个答案:

答案 0 :(得分:1)

经过大量的拔毛后,我让SDP工作了。代码如下。它是在https://people.csail.mit.edu/albert/bluez-intro/x604.html

的一个例子之后制作的

这对我来说似乎不必要地复杂化。一个&#34;计算机科学家走向狂野的案例!&#34;。对于像这样普通和简单的东西,它们应该包含一个便利包装器。

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