繁体   English   中英

通过BLE通知接收数据包

[英]Receive data packets via BLE Notifications

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

我的接收通知的代码如下:

- (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个阿巴巴巴布

2 bcbcbcbcbc

3张

4个

5 efefefefef

我的NSLog将为第一个通知数据打印efefefefef,为第二个打印输出efefefefef efefefefef,依此类推,为每个后续通知附加最后一个数据值。

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

编辑:

Paulw11的建议效果很好。 我通过修改YMSCB的'didUpdateValueForCharacteristic'方法来解决该问题,以获得特性的值,并将其与指向特性本身的指针一起传递给'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'方法以接受新的参数。

查看YMSCoreBluetooth库的内部didUpdateValueForCharacteristic委托方法,它将使用“在主线程上执行”将数据发送到您的方法,并且它不会捕获数据-只是发送对特征的引用。 同样,它可以通过在主线程上的数组上执行线性搜索来对特征执行“ findCharacteristic”,即使这可以在当前线程上输入委托方法后立即完成。 当然,这不会是一个很大的数组,但是似乎该库并不是在考虑性能的情况下创建的。

我怀疑您存在时序问题-到您的方法在执行特征数据时所用的时间已被覆盖。 如果您可以控制外围设备,请立即降低速度以进行测试,以查看问题是否消失。

如果与时间相关,那么您可以尝试直接的Core-Bluetooth实现,或者尝试对YMSCoreBluetooth进行修改,以便它可以较早地捕获数据-也许是如果它在didUpdateValueForCharacteristic的开头创建了外围设备的didUpdateValueForCharacteristic并将其发送到您的方法它会工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM