This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

iOS6 BLE Issue

Other Parts Discussed in Thread: CC2540

Hi all,

We have noticed that there is a bug in the UUID generation for peripheral devices (iOS internal representation) in iOS6.

Certain combinations of iDevice address and peripheral BLE address will result in a null pointer exception when user applications try to access e.g. the CFUUIDCreateString method on the UUID. The reason is that the UUID generated for the device (CFUUIDRef *) returned by iOS is nil (0x00000000).

You will notice this as an unexpected termination of the app.

Workarounds:
a) Don't upgrade to iOS6 for now
b) If you encounter the problem, try to change the secondary IEEE address of the device using Flash Programmer.
c) Connect to the peripheral before using the CFUUID.

Best regards,
Aslak

  • Does anyone know if apple is aware of this problem?  I've read of a couple instances of issues in this forum as well as the appdev mailing list.

  • Yes, the BLE guys at Apple are aware of the problem. I don't have any more information now about their work towards addressing the issue, but we'll keep you posted.

  • Hi again,

    A third workaround is to connect to the peripheral before trying to use the iOS-generated UUID.

    After the device is known by iOS, subsequent scan results will provide a working (non-exploding) UUID before it's connected.

    - Aslak

  • Hi Aslak,

    could you please elaborate a bit more this last workaround you suggested?

    If I consider the example for iOS published on the TI wiki, should I invert some of the calls or ignore someone... or what else?

    I am not sure what you mean by connecting without using the iOS generated UUID.... sorry.

    Mik

  • Hi Aslak,
    
    
    I also have this issue, the iphone app will crash when try to connect to the device.
    
    

    c) Connect to the peripheral before using the CFUUID.

    Would you provide more detail information how to workaround on this issue.
    I am using "TI-BLE_RC_Car-iOSProject"
    
    
    Thanks.
    
    
    Keith
  • Hi,

    Have a look at our updated iOS Source, here. TI-iPhone4SBLE-Demo_rev2.zip works for iOS 6.

    Best Regards

  • Hi,

    You can look at the iOS code in the link that Nick just posted. There you will see that I have just commented out parts of the code that print out or uses the UUID for the peripheral as a quick workaround. This is when compared to the old Keyfob-app which demonstrably crashes on iOS6.

    For example in didDiscoverPeripheral in TIBLECBKeyfob.m.

    Best regards,
    Aslak 

  • Hi Aslak,

    yes I've encountered this problem & started printing out the UUID after connection establishment as you've suggested .. works fine now, thanks .. the good thing is that now the UUIDs are stable & not changing like in iOS5.x .. this makes it easier for customized pairing using UUIDs.

    I've also noticed other issues with iOS6:

    1- Disconnection initiated from iOS6 device does not work properly .. takes about >30s to terminate completely .. as a workaround if I want to initiate disconnection from iOS6 device I send a specific command to the target to apply disconnection from target .. that way it disconnects immediately.

    2- After I connect to a device (device-A for example) & disconnect, if I scan again for devices, device-A is found but the name string returned is nil !!

    Did anybody encounter these problems too?

    Aslak, can you please make another thread where all iOS6 BLE issues are listed? Or is it intended in this thread?

    Thanks & regards,

    Moe

  • Hi,

    forget about the 2nd problem (name string) .. it was an error in my code.

    Regards

  • Hi Moe

    We also encounter the disconnect issue. I didn't find time yet to investigate it, but just after upgrading to iOS 6 the disconnect didn't work anymore. (no change or recompile of the application). It looks like the disconnect command is not sent by the iOS6 or not understood by the BLE stack.

    Best,

    Marc

  • Hi, 

    If the disconnect command is not sent properly from the iOS device, the peripheral device will be waiting for supervision timeout which might take up to 30 seconds. Using "Connection parameter update request" from the peripheral device upon connection to change the supervision timeout, will change this delay. Note that there are limitations in the Core spec (and Apple Bluetooth Design Guidlines) on how the parameters can be set.

    Best Regards

  • Hi Nick

    Thank you. In fact it looks like this is a behavior by design of Apple. They changed the behavior of CoreBluetooth such that the disconnect is not sent immediately. See discussions in the Apple Forums:

    https://devforums.apple.com/message/711309#711309

    https://devforums.apple.com/message/741370#741370

    Currently waiting for suggested workarounds. Of course a disconnect issued from the peripheral would do the job, but it is not very nice.

    Best,

    Marc

  • Hi Nick,

    thanks for the update! I applied all the changes to my code.

    Now today I don't have an iOS 6 device in the office, so I tried the new code on iOS 5.x and... unfortunately it does not connect.

    Is that expected?

    So do I have to maintain two versions, one for iOS 6 and one for iOS 5?

    Thanks,

    Mik

  • Hi Michele,

    As Marc above indicated, I found some information on the iOS Dev forum:

    "This is by design. Your app should not make any assumption on the RF link's state when calling cancelPeripheralConnection, as other apps might be communicating with your peripheral. iOS might disconnect the physical link when the system deems it necessary."

    So I guess the disconnect cant really be controlled by the App.

    Best Regards

  • Hi Nick,

    thanks but I am not bothered much about disconnecting the device at this point...

    I talked about connection: I am still not 100% sure if it is my merging of new changes for iOS 6 into existing iOS 5 apps that is broken (possibly, I am cross checking), or rather if the changes for the iOS 6 app cannot be used into iOS 5 devices by design (apart from disconnecting as you highlighted).

    Mik

  • Hi Michele,

    I have not experienced that. The Keyfob app for the iPhone was updated to not use the CFUUID before connection, and it works well for both iOS5 and 6, but I guess that depends on what changes you have made. What changes have you made?

    Updated keyfob app: http://processors.wiki.ti.com/index.php/File:TI-iPhone4SBLE-Demo_rev2.zip

    Aslak

  • Ok,

    I deserve a bit of shame :-)

    In the merging I have done I toke over the new code, which NOW searches for the device name... @"Keyfob" (and in iOS 5 wasn't because it wasn't necessary).

    The code we embedded into our BLE device doesn't make the device discoverable as "Keyfob"....

    So just changing that name (after all the merging obviously) made it work. Sorry!!! :-)

    However,  happy to know that one version of the code will work under iOS 5 and 6.

    Thanks guys.

    mik

  • Hi all,

    just some notes for BLE differences between iOS5.x & iOS6 (other than the disconnection thing mentioned above) .. thought it might be helpful to share:

    1- default connection interval is now 30ms instead of 105ms .. therefore the process for reading Services & Chars is much faster now.

    2- in iOS5.x, the device name returned in the peripheral.name is the name stored in the device Adv data, even after a connection is created .. In iOS6, it seems that the iPhone does not only rely on the device name delivered in the Adv data packet, but then tries to update it after a connection is established, by reading the device_name_attribute. If the smartphone receives info to this attribute, it remains stored & then used for all connection attempts to this device, even after disconnection & even after restarting the Bluetooth Adapter! It's only erased from memory if the iPhone is turned completely off! .. it seems that the iPhone, after connecting to a device & storing its UUID, stores its name internally. This information is not really useful for anybody but I faced it because I've made an error in my code where the device name was not returned properly when the iPhone tried to read the device_name_att :)

    3- device UUID is now stable (after connecting to the device of course) as long as the device name & BD_ADDR remain unchanged.

    Question:

     When I tried to reduce the connection interval value, I noticed that it's reduced in 3*1.25ms steps for both iOS5.x & iOS6 .. but I couldn't go below 18.75ms .. Did Anybody succeed in reducing the conn_int below that? it would be really great if it can go down to 7.5ms like the Razr XT910 :)

    KR, Moe

     

  • Hi Moe,

    1. Yes, how awesome is that!
    A: https://developer.apple.com/hardwaredrivers/BluetoothDesignGuidelines.pdf. Page 18 states the allowable connection parameters.

    Best regards,
    Aslak 

  • Thanks Aslak .. that explains it .. must be >20ms! :)

    KR, Moe

  • Dear Moe/All,

    I am also confused on how to get the definite periperal.name. Do you know how I can program the CC254X in order to make sure I can always get the proper periperial.name during didDiscoverPeripheral? (at least when it is invoked in the 2nd time).

     

    Here is what I have done on my CC2540. Even the following code is used in by cc2540 ble peripheral. I still get null most of the time when I receive call back from diddiscoverperipheral. Does any body get solution?

     

    Thank you and best regards,

     

    Tony

     

    static uint8 scanRspData[] =
    {
      // complete name
      0x0f,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      'a',  
      'b',  
      'c',  
      'd',  
      'e',  
      'f', 
      'g', 
      'h', 
      'i', 
      'j', 
      'k', 
      'l', 
      'm', 
      'n',
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),   // 100ms
      HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), 
      LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),   // 1s
      HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ), 

     

      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm 
    };
     
    static uint8 advertData[] =
    {
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

     

      // service UUID, to notify central devices what services are included
      // in this peripheral
      11,   // length of this data
      GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
      LO_UINT16( SERVICE1_UUID ),
      HI_UINT16( SERVICE1_UUID ),
      LO_UINT16( SERVICE2_UUID ),
      HI_UINT16( SERVICE2_UUID),
      LO_UINT16( SERVICE3_UUID),
      HI_UINT16( SERVICE3_UUID ),
      LO_UINT16( SERVICE4_UUID ),
      HI_UINT16( SERVICE4_UUID),
      LO_UINT16( SERVICE5_UUID),
      HI_UINT16( SERVICE5_UUID ),
    };

     

    GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData), scanRspData);  
    GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
  • Dear Moe/All,

    Do you know how to change the "default interval" to some slower time in order to save some energy of the peripheral devices?

     

    Thank you and best regards,

     

    Tony

  • Hi all,

    FYI: the UUID problem is now solved on the new iOS 6.0.1 .. i.e. UUIDs are now stable and can be read after connection establishment & also before from Adv packet! :)

    @Tony: sorry I did not ignore your question, but unfortunately I cannot help because currently I'm not using CC2540 :(

    Cheers,

    Moe

  • I think the solution is common in both 2540 and 2540. But thanks for  your attention to my questions!

     

  • I know this is quite old, but I discovered today when I installed iOS 6.1.1 beta that the UUID's for peripherals seemed to be reset and where different when reconnected.

    This meant that any 'paired' peripherals through my custom pairing method where no longer paired.

    It seems the only safe way to pair peripherals would be to advertise the BD_ADDR or put it in an advertised characteristic and just compare them within an app.

    Has anyone managed this and have any code that will advertise the BD_ADDR of a CC2540/1?

  • UUIDs seem to work quite stable with me on iOS6.1, just like in 6.0.1 .. I haven't tried iOS6.1.1 beta yet

  • Do you get the same UUID if you delete and reinstall an app?

  • Hi,

    in my little experience rather than uninstalling and reinstall the app, it is enough to power cycle the iPad/iPhone, as it seems to keep a list of device in its memory.

    Usually when I do that I can see all correctly (assuming for example I change the BLE name on the TI chip).

    Mik

  • Sorry, I must have been mistaken.

    I have trialled by deleting app and also reinstalling iOS 6.1.1 and the UUID's did in fact stay the same for my peripherals.
    I don't know what I did when I posted, I guess I must have cleared my NSUserDefualts where I store the UUID's.
  • Hi All,

    I am working on ANCS alert notification on CC2541 using TimeApp profile. I am able to first connect and pair and able to receive the alerts. When i try to disconnect it from the app its getting disconnected in the app, but its not getting disconnected from the iphone bluetooth settings. 

    Its always showing connected when i try to disconnect from the App. Then i have to forget the device from the iphone bluetooth settings inorder to disconnect it.Can anybody tell why this is happening

    Thanks