View unanswered posts | View active topics It is currently Wed Mar 29, 2017 7:24 am

Reply to topic  [ 4 posts ] 
OTA update 
Author Message

Joined: Tue Apr 08, 2014 4:49 pm
Posts: 3
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?

Tue Apr 08, 2014 7:31 pm

Joined: Tue Apr 08, 2014 4:49 pm
Posts: 3
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];

Tue Apr 08, 2014 7:43 pm
Site Admin

Joined: Thu Aug 02, 2012 11:36 am
Posts: 166
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?


Sun Apr 13, 2014 12:14 pm
Profile WWW

Joined: Tue Apr 08, 2014 4:49 pm
Posts: 3
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.

Mon Apr 14, 2014 3:55 pm
Display posts from previous:  Sort by  
Reply to topic   [ 4 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software for PTF.