通过BLE通知接收数据包

时间:2014-06-11 19:54:47

标签: ios notifications core-bluetooth

通过BLE通知接收多个数据包时,iOS只允许我访问发送的最终数据包。我正在使用YMSCoreBluetooth连接到具有多种服务的BLE外围设备,每种服务都具有多种特性。我连接到外围设备,发现服务并发现这些服务的特性而没有问题。我的目标是订阅某些特征的通知,并通过通知接收一系列数据包。我的订阅成功,我可以通过在我的代码中使用NSLog来看到我收到包含数据的通知。问题在于,当我从每个通知中访问数据时,每个通知都只向我提供最后一个发送数据包中包含的数据。

我接收通知的代码如下:

- (void)notifyCharacteristicHandler:(YMSCBCharacteristic *)characteristic error:(NSError *)error
{
    if (error) {
        NSLog(@"Error: Error in handling notification.\n%@", error);
    }
    else if ([characteristic.name isEqualToString:@"InterestingChar"]) {
        if (self.firstNotify) {
            self.mutableData = [[NSMutableData alloc] init];
            self.firstNotify = NO;
        }
        NSData *data = [[NSData alloc] init];
        data = characteristic.cbCharacteristic.value;

        [self.mutableData appendData:data];

        self.notifyCounter++;
        NSLog(@"Notify received! Count: %ld \nData =%@",(long)self.notifyCounter,self.mutableData);
    }
    else NSLog(@"Other notification received");
}

例如,如果我收到5条包含以下数据的通知:

1 ababababab

2 bcbcbcbcbc

3 cdcdcdcdcd

4 dedededede

5 efefefefef

我的NSLog将打印出efefefefef作为第一个通知数据,efefefefef efefefefef为第二个,等等,为每个后续通知附加最后一个数据值。

我正在尝试使用BLE尽快从外设发送通知。连接间隔在20ms到40ms之间(iOS要求的范围至少为20ms),每个连接间隔发送三个数据包。

编辑:

Paulw11的建议很精彩。我通过修改YMSCB&did'pdpdalValueForCharacteristic'来解决这个问题。获取特征值的方法,并将其与指向特征本身的指针一起传递给' notifyCharacteristicHandler'方法。修改后的方法现在看起来如下:

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    __weak YMSCBPeripheral *this = self;
    NSData *value = characteristic.value;
    _YMS_PERFORM_ON_MAIN_THREAD(^{
        YMSCBService *btService = [this findService:characteristic.service];
        YMSCBCharacteristic *yc = [btService findCharacteristic:characteristic];

        if (yc.cbCharacteristic.isNotifying) {
            [btService notifyCharacteristicHandler:yc value:value error:error];

        } else {
            if ([yc.readCallbacks count] > 0) {
                [yc executeReadCallback:characteristic.value error:error];
            }
        }

        if ([this.delegate respondsToSelector:@selector(peripheral:didUpdateValueForCharacteristic:error:)]) {
            [this.delegate peripheral:peripheral didUpdateValueForCharacteristic:characteristic error:error];
        }
    });
}

你显然还需要修改' notifyCharacteristicHandler'接受新参数的方法。

1 个答案:

答案 0 :(得分:1)

查看YMSCoreBluetooth库的内部didUpdateValueForCharacteristic委托方法,它使用“在主线程上执行”将数据发送到您的方法,并且它不捕获数据 - 它只是发送一个引用特性。此外,它通过在主线程上执行线性搜索来对特性执行“findCharacteristic”,即使这可以在当前线程上输入委托方法时立即完成。虽然这不是一个非常大的阵列,但似乎这个库并没有考虑到性能而创建。

我怀疑你有一个计时问题 - 当你的方法执行时,特征中的数据已被覆盖。如果您可以控制外围设备,请将其减速以进行测试以查看问题是否消失。

如果它与时序相关,那么您可以尝试直接的Core-Bluetooth实现,或尝试修改YMSCoreBluetooth以便它更早地捕获数据 - 也许如果它在{{1}开始时创建了外设的副本并将它发送到你的方法它会工作。