KB: Advertising RSL10 as an Accessory to iOS


[RSL10 - Knowledge Base]


By design, there are specific advertising guidelines that you are required to follow to avoid being filtered by an iOS device. This is intended partially as a security measure within the Apple ecosystem, but also to set a standard regarding the information that a Peripheral device must provide to the Central. We will discuss the two mandatory advertising configurations required to appear on the default iOS Bluetooth Scanner below.


Advertising Packet & Scan Response

Per Apple’s Guidelines, advertising packets and scan response packets sent out by Peripheral Accessories are required to include several parameter values shared between the two, as well as the corresponding flags indicating that these parameters are present. A list of the parameters and values that are required is shown below:

  • Flags
  • Accessory Primary Service UUID
  • Transmit Power
  • Device Complete/Shortened Local Name

Our Bluetooth Low Energy stack and abstraction code offers a straightforward method of preparing these advertising and scan response packets, so that they can easily be included within the Advertising command itself. A snippet of code that outlines the process of creating these packets for the Heart Rate Profile Service is provided below:

    /* Union passed to the Stack when issuing a GAPM_START_ADVERTISE_CMD */
    union gapm_adv_info app_adv_info;

    uint8_t hrp_uuid[2]  = { 0x0D, 0x18 }; /* 16-bit HRP Service UUID*/

    /* Set advertising data as service UUID */
    app_adv_info.host.adv_data_len = 0;
    GAPM_AddAdvData(GAP_AD_TYPE_SERVICE_16_BIT_DATA, hrp_uuid,
                    sizeof(hrp_uuid), app_adv_info.host.adv_data,
                    &app_adv_info.host.adv_data_len);

    uint8_t tx_power[1] = { 0 }; /* Transmission Power of the Peripheral Device*/
    uint8_t dev_name[20]   = "PeripheralHeartRate"; /* Complete Local Device Name */

    /* Set scan response data as TX Power and Complete Device Name */
    app_adv_info.host.scan_rsp_data_len = 0;
	GAPM_AddAdvData(GAP_AD_TYPE_TRANSMIT_POWER, tx_power,
					sizeof(tx_power), app_adv_info.host.scan_rsp_data,
					&app_adv_info.host.scan_rsp_data_len);
    GAPM_AddAdvData(GAP_AD_TYPE_COMPLETE_NAME, devName,
                    sizeof(dev_name)-1, app_adv_info.host.scan_rsp_data,
                    &app_adv_info.host.scan_rsp_data_len);

Private Resolvable Address (PRA)

To enhance the security of the Apple Environment further, your Peripheral Accessory is required to make use of a Private Resolvable Address type. This type of address reduces the probability that your device can be tracked via its Advertising address, by requiring new random addresses to be generated and set on a certain time interval. This address type is also Resolvable, which means it can exchange security keys with a Central and save the information for later connectivity, removing the need to share keys again and allowing the Central iOS to immediately resolve the Accessories’ true address in the future. More information about PRA and other Address Types is available in the CEVA RW-BLE-GAP-IS_2mbps document, found in our RSL10 Documentation Package.

Below is another code snippet, which outlines the specific parameter and value changes required within the structures passed into the stack, resulting in:

  • Properly initializing the address type within the device configurations
  • Properly pack the advertising command with the address type
  • Assign the app_adv_info.host.adv_data and app_adv_info.host.scan_rsp_data data, packed in the code above, to be sent out during advertising operations
/* Structure passed to the Stack on BLE Device Configuration */
struct gapm_set_dev_config_cmd devConfigCmd =
{
    ...
    .renew_dur = 150, /* Renewal Duration in Seconds */
    .addr_type = GAPM_CFG_ADDR_HOST_PRIVACY, /* Private Resolvable  Address Type */
    ...
};

/* Structure passed to the Stack on BLE Advertising Start*/
struct gapm_start_advertise_cmd advertiseCmd =
{
    .op = {
        ...
         /* Address Type of this device is Private Resolvable */
        .addr_src = GAPM_GEN_RSLV_ADDR, 
        ...
    },
    ...
    .info.host = {
        ...
        /* Advertising data as set above */
        .adv_data = app_adv_info.host.adv_data, 
        /* Advertising data length as set above */
        .adv_data_len = app_adv_info.host.adv_data_len, 
        /* Scan response data as set above */
        .scan_rsp_data = app_adv_info.host.scan_rsp_data, 
        /* Scan response data length as set above */
        .scan_rsp_data_len = app_adv_info.host.scan_rsp_data_len, 
        ...
    }
...
};


Could you please help to understand which modifications needed to be done to ‘peripheral_server_hid’ example in order to get it working with iOS? I added these modifications above to ble_std.c file but still no luck - iPhone wont show my BT device on Bluetooth list. Android works fine. Any glue? I tried also ble_peripheral_server_PRA example but same issue, iPhone wont show it on BT list. Or is there some other example available where I could find solution?

Thank you!

Hi @linnar,

Are you able to share the firmware that you are developing so we can confirm that all of the requirements outlined above have been implemented correctly?

Also, as an additional test, can you please check if the advertisements are showing up in other third party iOS applications, such as nRF Connect or LightBlue? This will help us determine if this is an underlying iOS scanning issue, or if it directly related to the iOS Bluetooth menu.

Thanks for reply Brandon!

I’m evaluating examples ‘peripheral_server_hid’ and ‘ble_peripheral_server_PRA’ available in latest development pack. My current experience is that these examples are not compatible with iOS/iPhone. Actually Onsemi FOTA tool for iPhone shows these BT devices on list which mean code works well but iPhone BT device list stays empty, no way to make connection. These examples works with Android perfectly. Finally I was able to get example ‘ble_peripheral_server_PRA’ working with iOS after adding additional codes above. I need to get ‘peripheral_server_hid’ example working with iOS but I see this is too complex task, seems there is no easy way to make it compatible with iOS requirements. Or do you have any ‘peripheral_server_hid’ example available which could work with iPhone?

Hi @linnar ,
Could you please try this attached project? It might work with iPhone.
peripheral_server_hid_V2.7z (480.8 KB)

Big thanks Larry! It works!!! :slight_smile:

Hi Larry, I went step deeper and tested your example to see how iPhone receives keyboard clicks. I did Bluetooth connect in Bluetooth setup in iPhone which went successfully - iPhone informs successful connection. Then I started Notes app and pushed button on Bluetooth eval board - unfortunately no keyclick appeared to iPhone. I did same with Android and your sample code worked well - text started to appear to app. Do I miss something with iPhone? Have you tried your example code with iPhone and did you see text appearing to screen at button clicks?

Thank you!

Hi @linnar ,
I can see it works with my iphone s6.
image
You might use hello only in on_semi_banner since Key ENTER and key CAPS could change language for your iphone.

1 Like

Hi Larry, I have iPhone7. Also tested with iPhone12. So far no luck, no keyclicks… Could it be that there is some difference?

Hi @linnar ,
My colleague has tested it with iphone8 plus and iphone XR. It works.
Here is another reference project which has been tested in iphone 12. You also could have a try.

freertos_ble_peripheral_server_bond_1V5(1).zip (977.4 KB)

1 Like

Thanks for code! Actually my need is HID support so I have to find out why it doesn’t work for me. Now I don’t have ideas how to debug that issue. Maybe my SDK environment missing something? Here are compilation results. Could you please test it on your hardware with iPhone?

Thank you!

peripheral_server_hid_V2_output.7z (348.2 KB)

Hi @linnar ,
I have tested your hex file on my RSL10 EVB. It works for my iphone.

Thanks for testing! What app did you use to see ‘hello’ text appearing to screen? I expect text should appear to every place/field where keyboard appears to display, correct?

Hi @linnar ,
correct. I just used google search screen to show the text.

Hi Larry and Martin, thanks for your support!

I finally got my iPhone7 working with HID V2 example. Reason was iOS firmware 14.7 which doesn’t work with this example. It started to work after updating iOS to latest version 15.6.

There is still issue with iPhone13 - I can do pairing but no text appearing to text fields. Phone doesn’t report keyboard connection after pairing as older phones do. Could you please check your example with iPhone 13?

Thank you!

@linnar

This project is meant to be, as customer reference and we don’t have formal HID project in SDK for iPhone at the moment.
That means, we have not done testing for all iPhone versions. ( iPhone 13 ).
You should find the solution for the different iPhone’s versions.

Can you test freertos_ble_peripheral_server_bond_1V5(1).zip with your Phone 13?

freertos_ble_peripheral_server_bond_1V5(1).zip (977.4 KB)

Hi @linnar ,
Our freertos_ble_peripheral_server_bond_1V5(1).zip has been tested on iPhone 12.
If you find it does not work for iPhone 13, it seems that the issue is related with iOS.
You might reach to Apple’s forum to check what is difference between iPhone12 and iPhone 13 and
what new requirements for Accessory of HID.

1 Like