【问题标题】:IOBluetooth register for channel open notification not firing when channel is opened通道打开时未触发通道打开通知的 IOBluetooth 寄存器
【发布时间】:2017-10-16 05:22:41
【问题描述】:

我正在开发一个需要蓝牙 2.1 的项目,并且我正在尝试制作一个测试客户端来连接到硬件。

所以我一直在翻阅 IOBluetooth 的“文档”,并设法广播了 SDP 服务记录。

在设备 (android) 上打开连接并将数据写入我的计算机可以正常工作(根据远程设备),但我的客户端工具实际上并未调用通知选择器...

直到我停止客户端程序并重新启动它,在这种情况下它会立即触发。

关于如何触发通知(无论它们是否异步)的文档也很少。

我已经绞尽脑汁一个星期了,你有什么想法吗?

虚拟客户端代码:

BTSocketSession.swift

class BTSocketSession {

    var lock : DispatchSemaphore = DispatchSemaphore(value: 0);
    var serviceRecord : IOBluetoothSDPServiceRecord? = nil;
    var channel : IOBluetoothRFCOMMChannel? = nil;
    var notification : IOBluetoothUserNotification? = nil;
    var serverID : BluetoothRFCOMMChannelID = 255;
    var done = false;

    init(serviceRecordPListPath: String) {
        print("Loading Service Dictionary...");
        let serviceDict : NSMutableDictionary = NSMutableDictionary(contentsOfFile: serviceRecordPListPath)!;
        print("Done.");
        print("Publishing service...");
        self.serviceRecord = IOBluetoothSDPServiceRecord.publishedServiceRecord(with: serviceDict as! [AnyHashable : Any]);
        print("Done.");
    }

    func listen() {
        var id = BluetoothRFCOMMChannelID();
        self.serviceRecord?.getRFCOMMChannelID(&id);
        self.serverID = id;
        print(serviceRecord ?? "Derp");
        print(id);
        self.notification = IOBluetoothRFCOMMChannel.register(forChannelOpenNotifications: self, selector: #selector(self.rfcommChannelOpen(notification:channel:)), withChannelID: id, direction: kIOBluetoothUserNotificationChannelDirectionIncoming);
        self.lock.wait();
    }

    func cancel() {
        print("Cancelling service advertisement...");
        if (self.serviceRecord == nil) {
            self.removeServiceRecord();
            self.lock.signal();
            print("Done.");
        } else {
            print("Error: No service broadcasting.");
        }
    }

    private func removeServiceRecord() {
        self.serviceRecord?.remove();
        self.serviceRecord = nil;
        self.notification?.unregister();
        self.notification = nil;
    }

    @objc func rfcommChannelOpen(notification: IOBluetoothUserNotification, channel: IOBluetoothRFCOMMChannel) {
        if (self.serverID != channel.getID()) {
            return;
        }
        print("Notification Recieved!!!");
        print(channel);
        print(notification);
        self.done = true;
        notification.unregister();
        self.removeServiceRecord();
        self.channel = channel;
        self.lock.signal();
    }

}

ma​​in.swift

func main() {
    let q = DispatchQueue(label: "Demo");
    let s = DispatchSemaphore(value: 0);
    let c = BTSocketSession(serviceRecordPListPath: "/path/to/plist");

    q.async {
        print("Waiting for connection event...");
        c.listen();
        print("Done.");
        print("Releasing main thread...");
        s.signal()
        print("Done.");
    }

    s.wait();
    print("Closing channel...");
    c.channel?.close();
    c.cancel();
    print("Done.");
    print("Exiting...");

}

main();
print("Wellp");

【问题讨论】:

    标签: swift macos bluetooth macos-sierra iobluetooth


    【解决方案1】:

    已解决:

    事实证明,在 OSX 中制作命令行/无头应用程序时,您必须使用RunLoop 接口正确注册系统通知,例如蓝牙通道打开通知。

    找到解决方案here

    变化:

    以下允许程序按预期工作。

    func main() {
        let q = DispatchQueue(label: "Demo");
        let c = BTSocketSession(serviceRecordPListPath: "/path/to/plist");
    
        q.async {
            print("Waiting for connection event...");
            c.listen();
            print("Done.");
            print("Releasing main thread...");
            c.channel.close();
            CFRunLoopStop(RunLoop.main.getCFRunLoop());
            print("Done.");
        }
        RunLoop.main.run();
        print("Exiting...");
    }
    
    main();
    print("Wellp");
    

    Life is Wonderful again =) 希望你有美好的一天!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-04
      • 1970-01-01
      • 2016-12-11
      • 2017-09-24
      • 2016-02-17
      相关资源
      最近更新 更多