CBPeripheralManager:didReceiveReadRequest: always request data from offset 0

Hi. I'm strictly following the documentation about requesting value for a characteristic containing large data, as it states:

Note: Use notifications to send a single packet of data to subscribed centrals. That is, when you update a subscribed central, you should send the entire updated value in a single notification, by calling the updateValue:forCharacteristic:onSubscribedCentrals: method only once.

Depending on the size of your characteristic’s value, not all of the data may be transmitted by the notification. If this happens, the situation should be handled on the central side through a call to the readValueForCharacteristic: method of the CBPeripheral class, which can retrieve the entire value.

Source: (https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/PerformingCommonPeripheralRoleTasks/PerformingCommonPeripheralRoleTasks.html#//apple_ref/doc/uid/TP40013257-CH4-SW1)

I'm doing just that. I request the characteristic value with a single request:

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    if (error)
    {
        [self disconnectWithError:error];
        return;
    }

    [service.characteristics enumerateObjectsUsingBlock:^(CBCharacteristic * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)
    {
        NSString * chUUID = obj.UUID.UUIDString;
if ([chUUID isEqualToString:Test_Char])
        {
            self.testCh = obj;
            [peripheral readValueForCharacteristic:obj];
        }
    }];
}

Then on PeripheralManager side I'm implementing the delegate method as suggested:

- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request
{
    if ([request.characteristic.UUID isEqual:self.testCh.UUID])
    {   // test
        if (request.offset > self.testCh.value.length)
        {
            [self.peripheralManager respondToRequest:request
                                          withResult:CBATTErrorInvalidOffset];
            return;
        }

        NSInteger length = self.testCh.value.length - request.offset;
        request.value = [self.testCh.value subdataWithRange:NSMakeRange(request.offset,
                                                                        length)];

        [self.peripheralManager respondToRequest:request
                                      withResult:CBATTErrorSuccess];
        return;
    }

    [self.peripheralManager respondToRequest:request
                                  withResult:CBATTErrorInvalidHandle];

}
code-block

The delegate method get called multiple times, but always with offset 0. Also, peripheral side, I'm receiving without error a truncated value with unexpected length. (552)

Any clues? Is the documentation not being updated with a newest implementation? Thx

CBPeripheralManager:didReceiveReadRequest: always request data from offset 0
 
 
Q