尝试订阅 CBCharacteristic 时不允许写入错误

Posted

技术标签:

【中文标题】尝试订阅 CBCharacteristic 时不允许写入错误【英文标题】:Writing is not permitted error when attempting to subscribe to CBCharacteristic 【发布时间】:2015-03-13 10:47:21 【问题描述】:

我正在开发一个与蓝牙 LE 设备通信的应用程序,因此我正在使用 CoreBluetooth 来执行此操作。

我正在使用的外围设备公开了 1 个服务,该服务具有两个特性:一个支持指示/通知/写入/写入无响应的串行端口 FIFO 特性;和一个支持写的串口信用特性。

从我的阅读中,我了解到我需要订阅的特性是 FIFO 特性,但是当我调用 [_connectedPeripheral setNotifyValue:YES forCharacteristic:characteristic]; 时,我收到了 Writing is not permitted 错误。

我检查了特征的属性,它具有ReadWriteWithoutResponseNotifyIndicate 属性。

这是我第一次使用 CoreBluetooth,而且我有点蓝牙菜鸟,所以这可能很明显我忽略了,但任何帮助将不胜感激。

编辑:这是代码:

#define SDL440S_SERVICE @"2456E1B9-26E2-8F83-E744-F34F01E9D701"
#define SDL440S_CHARACTERISTIC @"2456E1B9-26E2-8F83-E744-F34F01E9D703"

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral

    NSLog(@"Did connect %@", peripheral.name);
    // _connectedPeripheral is a property...
    if (_connectedPeripheral != peripheral) 
        _connectedPeripheral = peripheral;
    
    _connectedPeripheral.delegate = self;
    [_connectedPeripheral discoverServices:@[[CBUUID UUIDWithString:SDL440S_SERVICE]]];


#pragma mark - <CBPeripheralManager>

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error

    if (peripheral == _connectedPeripheral) 
        for (CBService *service in _connectedPeripheral.services) 
            if ([service.UUID.UUIDString isEqualToString:SDL440S_SERVICE]) 
                [_connectedPeripheral discoverCharacteristics:@[[CBUUID UUIDWithString:SDL440S_CHARACTERISTIC]] forService:service];
            
        
    


- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error

    for (CBCharacteristic *characteristic in service.characteristics) 
        if ([characteristic.UUID.UUIDString isEqualToString:SDL440S_CHARACTERISTIC]) 
            // Subsribe to characteristic
            [_connectedPeripheral setNotifyValue:YES forCharacteristic:characteristic];
        
    


// Getting values

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error

    if (error) 
        NSLog(@"Error changing note state for char: %@.\nError: %@", characteristic, error.localizedDescription);
    

【问题讨论】:

你是如何获得characteristic的?来自didDiscoverCharacteristics 委托方法? 没错。我发现了我感兴趣的外围设备,然后发现了我感兴趣的服务,然后服务的特征使用对特征的引用来订阅通知。 我正在使用由制造组件here的公司定义的协议@ 哪个委托方法给你错误信息?。写入错误对于 setNotify 操作没有意义。 这是didUpdateNotificationStateForCharacteristic:error: 代表CBPeripheralDelegate: - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error if (error) NSLog(@"Error changing note state for char: %@.\nError: %@", characteristic, error.localizedDescription); 【参考方案1】:

如果有人遇到此问题,以供将来参考,这与设备的 credit 特性有关。

我感兴趣的服务暴露了两个特征,一个 credit 特征和一个 FIFO 特征。 (我知道信用特征是标准问题。)问题是我必须先将我想接收的最大数据量写入信用特征,然后才能接收数据并将数据写入FIFO特征。

即:

unsigned char buf[1] = /*relevant data here...*/;
NSData *data = [NSData dataWithBytes:buf length:1];
[peripheral writeValue:data forCharacteristic:creditCharacteristic type:CBCharacteristicWriteWithoutResponse]; 

【讨论】:

你能扩展一下吗?我不明白这个。 我正在与一个暴露了两个特征 (see here for more) 的设备进行通信。 FIFO 特征是处理我感兴趣的数据的特征,但是,您必须(通过信用特征)通知设备您要开始通信。 我能把我的代码发给你,让你看看吗? 50% 的时间都在工作,这太令人沮丧了!!! 我认为最好的办法是打开一个新的 SO 问题。在那里发布您的代码,然后将指向该问题的链接作为评论放在此处。 如何识别哪些特征是 Credit ou FIFO?

以上是关于尝试订阅 CBCharacteristic 时不允许写入错误的主要内容,如果未能解决你的问题,请参考以下文章

iOS 10.0:使用未声明的类型“CBCharacteristic”

书面问题 CBCharacteristic

如何从 CBCharacteristic 中获取准确值?

将 CBCharacteristic 值转换为字符串

iOS-BLE <CBCharacteristic:未指定“无响应写入”属性 - 忽略无响应写入

canActivate 在订阅更改时不响应 Angular 2 路由器 AngularFire2