2010-07-15 80 views
2

我正在编写一个Android应用程序,它应该使用C(或C++)中的bluez库,通过蓝牙与运行Ubuntu的PC上的服务器端交换数据, 。连接Android蓝牙客户端套接字到Ubuntu服务器套接字的问题

当我尝试连接到PC上的服务器套接字时,我的Android应用程序失败(IOException)。

这里基本上是我在Java代码(在Android中,这里充满Eclipse项目:http://dl.dropbox.com/u/2968234/ThinBTClient.zip

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 
private static String address = "00:02:72:B2:85:C7"; // Hard coded for simplicity 
private BluetoothAdapter mBluetoothAdapter = null; 
private BluetoothSocket btSocket = null; 

..... 
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID); 
btSocket.connect(); // This throws IOException after a timeout of 10seconds or so. 

在服务器端(在Ubuntu 8.10),我基本上建立了一个蓝牙服务器插槽,沿着示例bluez/sdp-register.c中描述的路线运行。

下面是我的C++程序。编译它做

g++ -I/usr/include/glib-2.0/ -I/usr/lib/glib-2.0/include -o bt_server bt_server.cpp -lbluetooth 

我可以做反向成功地,即在Android中创建一个服务器套接字,并从Linux的连接,但是这不是我想做的事! 我认为或者问题与我的Ubuntu配置有关,但我似乎无法弄清楚这一点,任何帮助将不胜感激!

#include <stdio.h> 
#include <errno.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/ioctl.h> 
#include <sys/socket.h> 
#include <bluetooth/bluetooth.h> 
#include <bluetooth/bluetooth.h> 
#include <bluetooth/sdp.h> 
#include <bluetooth/sco.h> 
#include <bluetooth/sdp_lib.h> 
#include <bluetooth/rfcomm.h> 
#include <bluetooth/l2cap.h> 
#include <glib.h> 

sdp_session_t* register_service(uint8_t rfcomm_channel) 
{ 
// Adapted from http://www.btessentials.com/examples/bluez/sdp-register.c 
    uint32_t svc_uuid_int[] = { 0x01110000, 0x00100000, 0x80000080, 0xFB349B5F }; 
    const char *service_name = "Roto-Rooter Data Router"; 
    const char *svc_dsc = "An experimental plumbing router"; 
    const char *service_prov = "Roto-Rooter"; 

    uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid, 
      svc_class_uuid; 
    sdp_list_t *l2cap_list = 0, 
       *rfcomm_list = 0, 
       *root_list = 0, 
       *proto_list = 0, 
       *access_proto_list = 0, 
       *svc_class_list = 0, 
       *profile_list = 0; 
    sdp_data_t *channel = 0; 
    sdp_profile_desc_t profile; 
    sdp_record_t record = { 0 }; 
    sdp_session_t *session = 0; 

    // set the general service ID 
    sdp_uuid128_create(&svc_uuid, &svc_uuid_int); 
    sdp_set_service_id(&record, svc_uuid); 

    char str[256] = ""; 
    sdp_uuid2strn(&svc_uuid, str, 256); 
    printf("Registering UUID %s\n", str); 

    // set the service class 
    sdp_uuid16_create(&svc_class_uuid, SERIAL_PORT_SVCLASS_ID); 
    svc_class_list = sdp_list_append(0, &svc_class_uuid); 
    sdp_set_service_classes(&record, svc_class_list); 

    // set the Bluetooth profile information 
    sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID); 
    profile.version = 0x0100; 
    profile_list = sdp_list_append(0, &profile); 
    sdp_set_profile_descs(&record, profile_list); 

    // make the service record publicly browsable 
    sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); 
    root_list = sdp_list_append(0, &root_uuid); 
    sdp_set_browse_groups(&record, root_list); 

    // set l2cap information 
    sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); 
    l2cap_list = sdp_list_append(0, &l2cap_uuid); 
    proto_list = sdp_list_append(0, l2cap_list); 

    // register the RFCOMM channel for RFCOMM sockets 
    sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); 
    channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel); 
    rfcomm_list = sdp_list_append(0, &rfcomm_uuid); 
    sdp_list_append(rfcomm_list, channel); 
    sdp_list_append(proto_list, rfcomm_list); 

    access_proto_list = sdp_list_append(0, proto_list); 
    sdp_set_access_protos(&record, access_proto_list); 

    // set the name, provider, and description 
    sdp_set_info_attr(&record, service_name, service_prov, svc_dsc); 

    // connect to the local SDP server, register the service record, 
    // and disconnect 
    session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); 
    sdp_record_register(session, &record, 0); 

    // cleanup 
    sdp_data_free(channel); 
    sdp_list_free(l2cap_list, 0); 
    sdp_list_free(rfcomm_list, 0); 
    sdp_list_free(root_list, 0); 
    sdp_list_free(access_proto_list, 0); 
    sdp_list_free(svc_class_list, 0); 
    sdp_list_free(profile_list, 0); 

    return session; 
} 

int main(int argc, char **argv) 
{ 
    int port = 3; 
    sdp_session_t* session = register_service(port); 


    struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 }; 
    char buf[1024] = { 0 }; 
    int s, client, bytes_read; 
    socklen_t opt = sizeof(rem_addr); 
    // allocate socket 
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 
    printf("socket() returned %d\n", s); 

    // bind socket to port 1 of the first available 
    // local bluetooth adapter 
    loc_addr.rc_family = AF_BLUETOOTH; 
    loc_addr.rc_bdaddr = *BDADDR_ANY; 
    loc_addr.rc_channel = (uint8_t) port; 
    int r; 
    r = bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr)); 
    printf("bind() on channel %d returned %d\n", port, r); 

    // put socket into listening mode 
    r = listen(s, 1); 
    printf("listen() returned %d\n", r); 

    //sdpRegisterL2cap(port); 

    // accept one connection 
    printf("calling accept()\n"); 
    client = accept(s, (struct sockaddr *)&rem_addr, &opt); 
    printf("accept() returned %d\n", client); 

    ba2str(&rem_addr.rc_bdaddr, buf); 
    fprintf(stderr, "accepted connection from %s\n", buf); 
    memset(buf, 0, sizeof(buf)); 

    // read data from the client 
    bytes_read = read(client, buf, sizeof(buf)); 
    if(bytes_read > 0) { 
     printf("received [%s]\n", buf); 
    } 

    // close connection 
    close(client); 
    close(s); 
    sdp_close(session); 

    return 0; 
} 

回答

0

请确保您所创建的服务器套接字注册在SDP与您的客户端尝试连接相同的UUID你的Ubuntu服务器上。

您可以使用$ sdptool browse 00:02:72:B2:85:C7执行sdp查找/转储,但必须从另一台计算机上运行它。

+0

我试过了,服务器似乎被正确注册在SDP: $ sdptool可以浏览00:02:72:B2:85:C7 服务名称:鼓式Rooter公司数据路由器 服务说明:实验水暖路由器 服务提供者:鼓式拔根 服务RecHandle:0x10004 服务类ID列表: “串行端口”(0x1101) 协议描述符列表: 资料描述符列表: “串行端口”(0x1101) 版本: 0x0100 我仍然得到除离子在我的Android应用程序.. – UlrikK 2010-08-20 12:17:30

0

如果在发生错误之前有10秒的延迟,那么看起来像是超时而不是应用程序/ etc层配置错误。您的PC中的蓝牙适配器是否处于“可连接”模式? (例如,“sudo/usr/sbin/hciconfig ”是否包含PSCAN?)

(顺便说一下,sdp_set_service_classes显然会覆盖之前对sdp_set_service_id的调用)。

相关问题