【问题标题】:Bluetooth crashing when using updateValue:forCharacteristic:onSubscribedCentrals on OS X在 OS X 上使用 updateValue:forCharacteristic:onSubscribedCentrals 时蓝牙崩溃
【发布时间】:2014-08-27 01:42:48
【问题描述】:

我编写了一个 iOS 应用程序,其中 iOS 设备既是 BTLE 中心又是外围设备,并且多个设备可以交换数据。我试图将应用程序的外围部分带到 OS X。问题是,一旦我尝试通过updateValue:forCharacteristic:onSubscribedCentrals 将数据从 OS X 外围设备传输到 iOS 中心,OS X 上的 BTLE 几乎完全崩溃。

这意味着:

1) OS X 计算机不再被任何 iOS 设备拾取

2) 外围管理器不再做任何事情 - 没有回调被调用,什么都没有

3) 当我在 OS X 上重新启动应用程序时,外围设备管理器永远不会将其状态更改为 PoweredOn 或任何其他状态

4) 重新启动或使用sudo killall blued 之后,让 BTLE 在 OS X 上再次运行的唯一方法

完全相同的代码在 iOS 上运行良好,我不知道发生了什么。基本上,我正在这样做:

- (instancetype)init {
    self = [super init];
    dispatch_queue_t peripheralQueue = dispatch_queue_create("connichiwaperipheralqueue", DISPATCH_QUEUE_SERIAL);
    self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:peripheralQueue];
    return self;
}

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheralManager {
    if (peripheralManager.state == CBCentralManagerStatePoweredOn) {
        [self.peripheralManager addService:self.advertisedService];
        [self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:BLUETOOTH_SERVICE_UUID]] }];
    }
}

- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
    if (characteristic == self.advertisedInitialCharacteristic) {
        [self _sendInitialToCentral:central];
    }
}

- (void)_sendInitialToCentral:(CBCentral *)central {   
    NSDictionary *sendDictionary = @{ /* some dictionary, but i've also tried with a short, simple string */ };
    NSData *initialData = [NSJSONSerialization dataWithJSONObject:sendDictionary options:NSJSONWritingPrettyPrinted error:nil];
    BOOL didSend = [self.peripheralManager updateValue:initialData forCharacteristic:self.advertisedInitialCharacteristic onSubscribedCentrals:@[central]];
}

,而self.advertisedService 是包含self.advertisedInitialCharacteristic 的服务,而BLUETOOTH_SERVICE_UUID 是iOS 设备正在寻找的UUID。

执行此操作时,iOS 设备会选择 OS X 机器,发现服务,发现特征,然后 OS X 机器执行_sendInitialToCentral:。在这里,didSend 变为 true,但之后 BTLE 基本上停止在机器上执行任何操作,并且新值永远不会到达 iOS 设备。

有什么想法吗?难道我做错了什么?我在这里看不到问题。运行 OS X 10.9.3

更新

只是想补充一点,我刚刚用另一台机器测试了这个,同样的事情正在发生。

更新 2

找到原因:这个问题的原因是我正在将一个 CBCentral 交给updateValue:forCharacteristic:onSubscribedCentrals:。如果我将最后一个参数更改为nil,则会发送数据。问题是我需要将数据发送到特定的中心,我不想广播它们。任何人都知道这里发生了什么以及如何解决这个问题?

【问题讨论】:

  • 您的发送字典中有什么内容?我注意到您说您尝试过短字符串,但有多短? BLE 每次传输限制为 20 个字节
  • 这实际上是我尝试它的原因 - 在 iOS 上,它似乎可以发送超过 20 个字节(不知道为什么,但它有效)。但即使我尝试使用单字符字符串(或空字符串),在 OS X 上也会发生同样的事情。奇怪的是 updateValue:forCharacteristic:onSubscribedCentrals 返回 true,所以我猜它不应该是数据有问题?
  • 是的,似乎 CBCentral 上的 maximumUpdateValueLength 属性指示可以写入多少字节,之后的数据会被截断。您是否从 blued 的 OSX 日志中得到任何信息?
  • 好主意。启动应用程序时,我得到blued[59087]: ****** properties = 0x10, permissions = 0x1, write? 0, w/o res? 0,这似乎代表了广告的特征。但是,发送数据时不会记录任何内容。过了一会儿,我收到另一条消息,但我不能 100% 确定它是否相关:kernel[0]: **** [IOBluetoothHostControllerUSBTransport][SuspendDevice] -- Suspend -- suspendDeviceCallResult = 0x0000 (kIOReturnSuccess) -- 0x6000 ****
  • 发现问题,看我的编辑

标签: ios objective-c macos bluetooth bluetooth-lowenergy


【解决方案1】:

只是回答这个问题:这似乎是小牛队的一个错误。这个问题(以及许多其他 BTLE 问题)在 Yosemite 中完全解决了。

在 Mavericks 上,仅将 nil 传递给 updateValue:forCharacteristic:onSubscribedCentrals 的最后一个参数似乎可以使 BTLE 工作。

【讨论】:

    猜你喜欢
    • 2012-12-12
    • 1970-01-01
    • 2012-06-12
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    相关资源
    最近更新 更多