FOTA with custom services

We want to use the FOTA Image system with our custom application. There are custom BLE services in this app. But the FOTA user’s guide indicates:

Is there an example to illustrate how to add custom services and characteristics with FOTA system?

Best regards,

Hi Yann,
The FOTA Service can be used alongside with other custom services but it requires some modifications from the basic FOTA example.
The difference is that all attributes defined by all custom services (including FOTA) must be inserted into single attribute array that can be passed to the GATTM_AddAttributeDatabase function in one go.

As an example, this has been done in the firmware for the Lighting Kit platform which uses 3 custom services + FOTA service.
The source code for the platform is part of BDK CMSIS-Pack, example: Lighting Kit Firmware (FL7760, RTOS, FOTA).
The creation of attribute database is located in source/module/lk_ble_custom_attdb.c file.

Lighting Kit page+pack: Link

Hi Lukas,
thanks for you answer.
I will take a look at this example.

i have added all custom services in the same array before the use of the GATTM_AddAttributeDatabase function. but at the discovery of services, the BLE client only see the first service and not the second service (DFU service). the second one is included in the first and it is seen as a secondary service (not a primary).
it seems I’m missing something.
is there another example like the “ble_peripheral_server_bond” but with 2 or more custom services (without RTOS and BDK) even without FOTA?
Best regards,

Did you find out how to do this?

There was an error in the function GATTM_addAttibuteDatabase in the ble_gatt.c file from the “ble_peripheral_server_bond” example.
It’s missing att-idx++; at the end of the loop, so there are a dead loop case if one more one service.
best regards,

1 Like

But my version of this file already has att_idx++

This is my function, defined inside /RTE/Device/RSL10/ble_gatt.c

void GATTM_AddAttributeDatabase(const struct att_db_desc *att_db,
                                uint16_t att_db_len)
    struct gattm_add_svc_req *req;
    uint8_t nb_att;
    uint8_t cs_nb_att = 0;
    uint8_t att_idx = 1;

    gatt_env.att_db = att_db;
    gatt_env.att_db_len = att_db_len;

    while(att_idx < att_db_len)
        /* Count the number of attributes in the current service */
        for (nb_att = 0; att_idx < att_db_len && !att_db[att_idx].is_service; nb_att++, att_idx++);

                               TASK_GATTM, TASK_APP, gattm_add_svc_req,
                               nb_att * sizeof(struct gattm_att_desc));

        /* Fill the GATTM_ADD_SVC_REQ message to add a new custom service */
        req->svc_desc.start_hdl = 0;
        req->svc_desc.task_id = TASK_APP;
        req->svc_desc.perm = att_db[cs_nb_att].att.perm;
        req->svc_desc.nb_att = nb_att;
        memcpy(&req->svc_desc.uuid[0], &att_db[cs_nb_att++].att.uuid, ATT_UUID_128_LEN);

        for (uint8_t i = 0; i < nb_att; i++)
            memcpy(&req->svc_desc.atts[i], &att_db[cs_nb_att++].att,
                   sizeof(struct gattm_att_desc));


This is default code from CMSIS pack 3.5.285. Is this the same as your function? If it is I think this should be correct.

It was with the 3.2.608 package.
so normally, you have no problem and it should work fine.
Best regards.

1 Like