Я работаю над проектом, для которого требуется Bluetooth 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");