我正在开发一个需要蓝牙 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();
}
}
main.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");