【问题标题】:BlueZ unable to accept incoming connection while advertising with SDP due to bluetoothd由于蓝牙,BlueZ 在使用 SDP 进行广告时无法接受传入连接
【发布时间】:2020-04-13 06:35:11
【问题描述】:

我正在尝试使用 Pi 来模拟使用 BlueZ C api 的蓝牙设备。我能够单独 1)配置 SDP 服务器以宣传正确的服务,以及 2)侦听并建立 L2CAP 连接。但是,我无法同时进行这两项操作。

问题是sdp_record_register() will segfault 除非bluetoothd 正在运行并处于兼容模式。然而,accept() won't return for the Bluetooth socket 如果bluetoothd 正在运行,因为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 上的连接(因为这意味着它的代理仍然可以处理配对),但我不知道该怎么做。

【问题讨论】:

    标签: c bluetooth raspberry-pi bluez


    【解决方案1】:

    (不满意但正确的)答案是不使用hci* API。该 API 显然已被弃用,因此不会修复像该段错误这样的错误。正确的方法是使用 DBus API。该 API 几乎与 hci API 一样繁琐,但至少已记录在案。

    在替换掉我用 glib-2.0 提供的 gdbus API 编写的大量基于hci 的代码以设置 SDP 服务后,我终于能够同时宣传服务和连接.我的套接字代码无需修改即可工作。

    【讨论】:

      猜你喜欢
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 2015-06-08
      • 2014-04-27
      • 1970-01-01
      • 2023-03-22
      • 2018-12-31
      • 1970-01-01
      相关资源
      最近更新 更多