Dr. Michael Kroll's Mobile Computing Forum

OTA update
Page 1 of 1

Author:  nrbrook [ Tue Apr 08, 2014 7:31 pm ]
Post subject:  OTA update

Hi, I'm building my own OTA update for BLE 113 on iOS, but I think there is a couple bugs with CoreBluetooth and I'm curious to know how you have achieved it.

I write to the data characteristic roughly 100kb in 20b chunks in a loop, then write the next control characteristic. Two problems occur.

The first is, when I check the data iOS is sending, it is missing large chunks out. In total it sends only 2kb. This can be resolved by pausing for 0.1s between writes.

The second is, when I write the control characteristic after the data, I get a CBUnknownError. This can be resolved by adding a 1s pause before writing the control end.

If I fix the second problem but not the first, it appears everything has worked, but the device does not actually perform the update from its flash memory as the data is corrupted.

I'm testing on iOS 7.1, have you seen any of these problems? How did you go about performing the update?

Author:  nrbrook [ Tue Apr 08, 2014 7:43 pm ]
Post subject:  Re: OTA update

Here's my code including workarounds.

NSInputStream *is = [NSInputStream inputStreamWithURL:self.updateFile];
    uint8_t buffer[OTA_MAX_BUFFER];
    NSInteger bytesRead;
    NSInteger totalBytesRead = 0;
    [is open];
    while((bytesRead = [is read:buffer maxLength:OTA_MAX_BUFFER])) {
        totalBytesRead += bytesRead;
        if(totalBytesRead > OTA_MAX_DATA) {
            [self writeUpdateControl:ATPeripheralUpdateControlCancel];
            [self failUpdateWithError:ATPeripheralUpdateErrorDataTooLarge];
        [self.peripheral writeValue:[NSData dataWithBytes:buffer length:bytesRead] forCharacteristic:self.updateDataCharacteristic type:CBCharacteristicWriteWithoutResponse];
        [NSThread sleepForTimeInterval:0.1];
    [is close];
    if(totalBytesRead == 0) {
        [self writeUpdateControl:ATPeripheralUpdateControlCancel];
        [self failUpdateWithError:ATPeripheralUpdateErrorCouldNotReadFile];
#if logDebug
    NSLog(@"Wrote OTA data, %ld bytes", (long)totalBytesRead);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1000000000), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self writeUpdateControl:ATPeripheralUpdateControlFinishUpdate];

Author:  mkroll [ Sun Apr 13, 2014 12:14 pm ]
Post subject:  Re: OTA update

try to reduce the OTA_MAX_BUFFER to 16 instead of 20.
If you look into the OTA code provided by bluegiga, the SPI flash chip needs to get the data in 256 byte chunks.
The easiest is to reduce the buffer to 16 bytes, and the 256 bank will be filled after 16 writes.

Does this help?


Author:  nrbrook [ Mon Apr 14, 2014 3:55 pm ]
Post subject:  Re: OTA update

Thanks for the response.

I am using only the new 256k BLE113, so do not use external SPI flash. The problem is in iOS as it does not send all the data. I just wondered if you had implemented the data transfer differently to me. If you have not, then your implementation may be suffering from the same data loss. Using a packet analyser, I can see it takes 75ms (5 retries at 15ms intervals until a successful ACK) to complete one write. This fits with my addition of a 0.1s (100ms) pause between writes. Therefore a complete transfer of a 106kb OTA file should take about 400s or nearly 7 minutes.

Page 1 of 1 All times are UTC + 1 hour [ DST ]
Powered by phpBB® Forum Software © phpBB Group