2010-07-22 65 views
7

可能重複:
Service discovery failed exception using Bluetooth on Android建立一個PC藍牙服務器爲Android

好吧,我已經讀了很多話題過去兩三天,似乎沒有任何已經問過這個。

我正在爲我的andriod設備編寫PC端服務器,這是爲了交換一些信息和一般調試。最終,我將連接到一個SPP設備來控制一個微控制器。

我已經管理,使用以下(Android到PC)連接到rfcomm頻道11,並在我的android設備和我的電腦之間交換數據。方法m = device.getClass()。getMethod(「createRfcommSocket」,new Class [] {int.class});}方法m = device.getClass()。 tmp =(BluetoothSocket)m.invoke(device,Integer.valueOf(11));

我嘗試過createRfcommSocketToServiceRecord(UUID)方法,絕對沒有運氣。

對於PC端來說,我一直在使用Linux的C Bluez協議棧。我有以下的代碼,註冊服務,並打開一個服務器套接字:

int main(int argc, char **argv) 
{ 
    struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 }; 
    char buf[1024] = { 0 }; 
    char str[1024] = { 0 }; 
    int s, client, bytes_read; 
    sdp_session_t *session; 
    socklen_t opt = sizeof(rem_addr); 

    session = register_service(); 
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 
    loc_addr.rc_family = AF_BLUETOOTH; 
    loc_addr.rc_bdaddr = *BDADDR_ANY; 
    loc_addr.rc_channel = (uint8_t) 11; 
    bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr)); 
    listen(s, 1); 
    client = accept(s, (struct sockaddr *)&rem_addr, &opt); 
    ba2str(&rem_addr.rc_bdaddr, buf); 
    fprintf(stderr, "accepted connection from %s\n", buf); 
    memset(buf, 0, sizeof(buf)); 
    bytes_read = read(client, buf, sizeof(buf)); 
    if(bytes_read > 0) { 
    printf("received [%s]\n", buf); 
    } 
    sprintf(str,"to Android."); 
    printf("sent [%s]\n",str); 
    write(client, str, sizeof(str)); 
    close(client); 
    close(s); 
    sdp_close(session); 

    return 0; 
} 

    sdp_session_t *register_service() 
{ 

    uint32_t svc_uuid_int[] = { 0x00000000,0x00000000,0x00000000,0x00000000 }; 
    uint8_t rfcomm_channel = 11; 
    const char *service_name = "Remote Host"; 
    const char *service_dsc = "What the remote should be connecting to."; 
    const char *service_prov = "Your mother"; 

    uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid; 
    sdp_list_t *l2cap_list = 0, 
       *rfcomm_list = 0, 
       *root_list = 0, 
       *proto_list = 0, 
       *access_proto_list = 0; 
    sdp_data_t *channel = 0, *psm = 0; 

    sdp_record_t *record = sdp_record_alloc(); 

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

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

    // set rfcomm information 
    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); 

    // attach protocol information to service record 
    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, service_dsc); 

    int err = 0; 
    sdp_session_t *session = 0; 

    // connect to the local SDP server, register the service record, and 
    // disconnect 
    session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); 
    err = 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); 

    return session; 
}

而另一段代碼,除了「sdptool可以瀏覽本地」,可verifty該服務記錄在PC上運行:

int main(int argc, char **argv) 
{ 
    uuid_t svc_uuid; 
    uint32_t svc_uuid_int[] = { 0x00000000,0x00000000,0x00000000,0x00000000 }; 
    int err; 
    bdaddr_t target; 
    sdp_list_t *response_list = NULL, *search_list, *attrid_list; 
    sdp_session_t *session = 0; 

    str2ba("01:23:45:67:89:AB", &target); 

    // connect to the SDP server running on the remote machine 
    session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); 

    // specify the UUID of the application we're searching for 
    sdp_uuid128_create(&svc_uuid, &svc_uuid_int); 
    search_list = sdp_list_append(NULL, &svc_uuid); 

    // specify that we want a list of all the matching applications' attributes 
    uint32_t range = 0x0000ffff; 
    attrid_list = sdp_list_append(NULL, &range); 

    // get a list of service records that have UUID 0xabcd 
    err = sdp_service_search_attr_req(session, search_list, \ 
      SDP_ATTR_REQ_RANGE, attrid_list, &response_list); 

    sdp_list_t *r = response_list; 

    // go through each of the service records 
    for (; r; r = r->next) { 
     sdp_record_t *rec = (sdp_record_t*) r->data; 
     sdp_list_t *proto_list; 

     // get a list of the protocol sequences 
     if(sdp_get_access_protos(rec, &proto_list) == 0) { 
     sdp_list_t *p = proto_list; 

     // go through each protocol sequence 
     for(; p ; p = p->next) { 
      sdp_list_t *pds = (sdp_list_t*)p->data; 

      // go through each protocol list of the protocol sequence 
      for(; pds ; pds = pds->next) { 

       // check the protocol attributes 
       sdp_data_t *d = (sdp_data_t*)pds->data; 
       int proto = 0; 
       for(; d; d = d->next) { 
        switch(d->dtd) { 
         case SDP_UUID16: 
         case SDP_UUID32: 
         case SDP_UUID128: 
          proto = sdp_uuid_to_proto(&d->val.uuid); 
          break; 
         case SDP_UINT8: 
          if(proto == RFCOMM_UUID) { 
           printf("rfcomm channel: %d\n",d->val.int8); 
          } 
          break; 
        } 
       } 
      } 
      sdp_list_free((sdp_list_t*)p->data, 0); 
     } 
     sdp_list_free(proto_list, 0); 

     } 

     printf("found service record 0x%x\n", rec->handle); 
     sdp_record_free(rec); 
    } 

    sdp_close(session); 
}

Output: 
$ ./search 
rfcomm channel: 11 
found service record 0x10008 

sdptool: 
Service Name: Remote Host 
Service Description: What the remote should be connecting to. 
Service Provider: Your mother 
Service RecHandle: 0x10008 
Protocol Descriptor List: 
    "L2CAP" (0x0100) 
    "RFCOMM" (0x0003) 
    Channel: 11 

而對於logcat的我得到這個:


07-22 15:57:06.087: ERROR/BTLD(215): ****************search UUID = 0000*********** 
07-22 15:57:06.087: INFO//system/bin/btld(209):   btapp_dm_GetRemoteServiceChannel() 
07-22 15:57:06.087: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Wake, 0x8003 #### 
07-22 15:57:06.097: INFO/ActivityManager(88): Displayed activity com.example.socktest/.socktest: 79 ms (total 79 ms) 
07-22 15:57:06.697: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Sleep, 0x8004 #### 
07-22 15:57:07.517: WARN/BTLD(215): ccb timer ticks: 2147483648 
07-22 15:57:07.517: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Wake, 0x8003 #### 
07-22 15:57:07.547: WARN/BTLD(215): info:x10 
07-22 15:57:07.547: INFO/BTL-IFS(215): send_ctrl_msg: [BTL_IFS CTRL] send BTLIF_DTUN_SIGNAL_EVT (CTRL) 10 pbytes (hdl 14) 
07-22 15:57:07.547: DEBUG/DTUN_HCID_BZ4(253):   dtun_dm_sig_link_up() 
07-22 15:57:07.547: INFO/DTUN_HCID_BZ4(253): dtun_dm_sig_link_up: dummy_handle = 342 
07-22 15:57:07.547: DEBUG/ADAPTER(253): adapter_get_device(00:02:72:AB:7C:EE) 
07-22 15:57:07.547: ERROR/BluetoothEventLoop.cpp(88): pollData[0] is revented, check next one 
07-22 15:57:07.547: ERROR/BluetoothEventLoop.cpp(88): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/253/hci0/dev_00_02_72_AB_7C_EE 
07-22 15:57:07.777: WARN/BTLD(215): process_service_search_attr_rsp 
07-22 15:57:07.787: INFO/BTL-IFS(215): send_ctrl_msg: [BTL_IFS CTRL] send BTLIF_DTUN_SIGNAL_EVT (CTRL) 13 pbytes (hdl 14) 
07-22 15:57:07.787: INFO/DTUN_HCID_BZ4(253): dtun_dm_sig_rmt_service_channel: success=0, service=00000000 
07-22 15:57:07.787: ERROR/DTUN_HCID_BZ4(253): discovery unsuccessful! 
07-22 15:57:08.497: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Sleep, 0x8004 #### 
07-22 15:57:09.507: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Wake, 0x8003 #### 
07-22 15:57:09.597: INFO/BTL-IFS(215): send_ctrl_msg: [BTL_IFS CTRL] send BTLIF_DTUN_SIGNAL_EVT (CTRL) 11 pbytes (hdl 14) 
07-22 15:57:09.597: DEBUG/DTUN_HCID_BZ4(253):   dtun_dm_sig_link_down() 
07-22 15:57:09.597: INFO/DTUN_HCID_BZ4(253): dtun_dm_sig_link_down device = 0xf7a0 handle = 342 reason = 22 
07-22 15:57:09.597: ERROR/BluetoothEventLoop.cpp(88): pollData[0] is revented, check next one 
07-22 15:57:09.597: ERROR/BluetoothEventLoop.cpp(88): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/253/hci0/dev_00_02_72_AB_7C_EE 
07-22 15:57:09.597: DEBUG/BluetoothA2dpService(88): Received intent Intent { act=android.bluetooth.device.action.ACL_DISCONNECTED (has extras) } 
07-22 15:57:10.107: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Sleep, 0x8004 #### 
07-22 15:57:12.107: DEBUG/BluetoothService(88): Cleaning up failed UUID channel lookup: 00:02:72:AB:7C:EE 00000000-0000-0000-0000-000000000000 
07-22 15:57:12.107: ERROR/Socket Test(5234): connect() failed 
07-22 15:57:12.107: DEBUG/ASOCKWRP(5234): asocket_abort [31,32,33] 
07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_shutdown: s 31, how 2 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_shutdown: fd (-1:31), bta -1, rc 0, wflags 0x0 
07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): __close_prot_rfcomm: fd 31 
07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): __close_prot_rfcomm: bind not completed on this socket 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): btlif_signal_event: fd (-1:31), bta -1, rc 0, wflags 0x0 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): btlif_signal_event: event BTLIF_BTS_EVT_ABORT matched 
07-22 15:57:12.107: DEBUG/BTL_IFC_WRP(5234): wrp_close_s_only: wrp_close_s_only [31] (31:-1) [] 
07-22 15:57:12.107: DEBUG/BTL_IFC_WRP(5234): wrp_close_s_only: data socket closed 
07-22 15:57:12.107: DEBUG/BTL_IFC_WRP(5234): wsactive_del: delete wsock 31 from active list [ad3e1494] 
07-22 15:57:12.107: DEBUG/BTL_IFC_WRP(5234): wrp_close_s_only: wsock fully closed, return to pool 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): btsk_free: success 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_write: wrote 1 bytes out of 1 on fd 33 
07-22 15:57:12.107: DEBUG/ASOCKWRP(5234): asocket_destroy 
07-22 15:57:12.107: DEBUG/ASOCKWRP(5234): asocket_abort [31,32,33] 
07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_shutdown: s 31, how 2 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_shutdown: btsk not found, normal close (31) 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_write: wrote 1 bytes out of 1 on fd 33 
07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_close: s 33 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_close: btsk not found, normal close (33) 
07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_close: s 32 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_close: btsk not found, normal close (32) 
07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_close: s 31 
07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_close: btsk not found, normal close (31) 
07-22 15:57:12.157: DEBUG/Sensors(88): close_akm, fd=151 
07-22 15:57:12.167: ERROR/CachedBluetoothDevice(477): onUuidChanged: Time since last connect14970690 
07-22 15:57:12.237: DEBUG/Socket Test(5234): -On Stop- 

對不起轟炸你們,看起來像是一個困難的問題,還有很多需要閱讀,但我一直在研究這個問題一段時間,我嘗試了很多不同的東西來實現這個目標。

讓我重申,我可以讓它工作,但不使用服務發現協議。我嘗試了幾種不同的UUID並在兩臺不同的電腦上使用,但我只有HTC Incredible可以測試。

我也聽說過一些傳言,BT堆棧在HTC Droid上不起作用,但至少在PC機互動方面並非如此。

+0

嗨德爾你解決了這個問題,我也面臨同樣的問題 – Haris 2013-08-05 10:48:29

回答

3

SDP註冊碼缺少Class ID List註冊。因爲Android沒有找到提供的服務。

如果在register_service()函數跟隨着添加代碼:

// set the Service class ID 
sdp_list_t service_class = {NULL, &svc_uuid}; 
sdp_set_service_classes(record, &service_class); 

設定完成後一般服務ID線。 Android設備應該找到你的服務。

這與三星Galaxy S與2.2固件工作。但沒有與摩托羅拉Milestone與2.1更新1