簡體   English   中英

由於藍牙,BlueZ 在使用 SDP 進行廣告時無法接受傳入連接

[英]BlueZ unable to accept incoming connection while advertising with SDP due to bluetoothd

我正在嘗試使用 Pi 來模擬使用 BlueZ C api 的藍牙設備。 我可以分別 1)配置 SDP 服務器以宣傳正確的服務,以及 2)偵聽並建立 L2CAP 連接。 但是,我不能同時做這兩個。

問題是sdp_record_register() 將出現段錯誤,除非bluetoothd正在運行且處於兼容模式。 但是,如果bluetoothd正在運行, accept() 將不會返回藍牙套接字,因為bluetoothd會竊取請求。

所以我可以:

  1. 通過運行bluetoothd (在兼容模式下)向 SDP 注冊/宣傳我的服務,但無法接受傳入連接。
  2. 通過不運行bluetoothd能夠接受傳入連接,但無法注冊/宣傳我的服務。

設置 SDP 服務

  int deviceID = hci_get_route(NULL);
  if (deviceID < 0) {
    printf("Error: Bluetooth device not found\n");
    exit(1);
  }

  int bluetoothHCISocket = hci_open_dev(deviceID);
  if (bluetoothHCISocket < 0) {
    perror("hci_open_device");
    exit(2);
  }

  /* some HCI config */

  sdp_session_t *session = sdp_connect(&myBDAddrAny, &myBDAddrLocal, SDP_RETRY_IF_BUSY);
  sdp_record_t record;
  bzero(&record, sizeof(sdp_record_t));
  record.handle = 0x10000;

  /* register all of the attributes for my service */

  printf("Might segfault\n");
  if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
    perror("sdp_record_register");
    exit(7);
  }
  printf("Didn't segfault\n");

這在bluetoothd以兼容模式運行時有效,但當它未運行或以默認模式運行時會出現段錯誤。

接受藍牙連接

  int btSocket = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
  if (btSocket < 0) {
    perror("socket");
    exit(3);
  }
  struct sockaddr_l2 loc_addr = { 0 };
  loc_addr.l2_family = AF_BLUETOOTH;
  loc_addr.l2_bdaddr = myBDAddrAny;
  loc_addr.l2_psm = htobs(0x11);

  if (bind(btSocket, (struct sockaddr *)&loc_addr, sizeof(loc_addr))) {
    perror("bind");
    exit(4);
  }
  if (listen(btSocket, 1)) {
    perror("listen");
    exit(6);
  }

  struct sockaddr_l2 remoteAddress;
  socklen_t socketSize = sizeof(remoteAddress);
  printf("Waiting for connection\n");
  int clientSocket = accept(btSocket, (struct sockaddr *)&remoteAddress, &socketSize);

這將在bluetoothd未運行時正確接受傳入連接,但如果bluetoothd正在運行(在任何模式下), accept()將永遠不會返回。

我一直無法調和這兩個問題。 似乎理想的解決方案是以某種方式告訴bluetoothd忽略 PSM 0x11 上的連接(因為這意味着它的代理仍然可以處理配對),但我不知道該怎么做。

(不滿意但正確)的答案是不使用 hci hci* API。 API 顯然已被棄用,因此不會修復類似段錯誤的錯誤。 正確的方法是使用 DBus API。 那個 API 幾乎和 hci hci一樣麻煩,但至少它是有記錄的。

在將我用 glib-2.0 提供的hci API 編寫的大量基於 hci 的代碼換掉以設置 SDP 服務后,我終於能夠同時宣傳該服務並進行連接。 我的套接字代碼無需修改即可工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM