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.

CC2540 - How do I correctly deregister services and free its table memory?

Other Parts Discussed in Thread: CC2540

Hi,

I'm using the TI BLE Stack v1.3.1 running on the SmartRF05 eval board with the CC2540EM board attached. I started with the SimpleBLEPeripheral demo project but have since modified it to match my application's needs.

I am trying to dynamically add and remove services from the CC2540 (application level authentication is used to determine what services to register).

I've used the API functions GATTServApp_FindAttr(...) to get the handle of the service that I want to remove, and GATTServApp_DeregisterService(..) to remove it. The deregister function call seemed to work (returned success and BTool does not see the service that was removed when doing service and characteristic discovery).

What I'm not sure about is how to free the service attribute list returned from the call to GATTServApp_DeregisterService(...) - since the declaration of this API function says it is caller's responsibility to free the service attribute list. I passed in the address of a pointer to a gattAttribute_t structure and after the deregister function returns, it does point to the service's attribute table that was registered. But I'm pretty sure this returned pointer isn't the correct pointer that would be passed to osal_mem_free(...).

How do I free the returned attribute table?

Thanks in advance,

Mike

  • Hi Mike,

    The hostTestRelease project hci_ext_app.c  file as an example (please see freeAttrRecs() function):

     

              // Service is already registered with the GATT Server

              stat = GATT_DeregisterService( handle, &serv );

              if ( stat == SUCCESS )

              {

                freeAttrRecs( &serv );

              }

    /*********************************************************************
    * @fn freeAttrRecs
    *
    * @brief Free attribute records. Also, free UUIDs that were
    * allocated dynamically.
    *
    * @param pServ - GATT service
    *
    * @return none
    */
    static void freeAttrRecs( gattService_t *pServ )
    {
    if ( pServ->attrs != NULL )
    {
    for ( uint8 i = 0; i < pServ->numAttrs; i++ )
    {
    gattAttrType_t *pType = &pServ->attrs[i].type;
    if ( pType->uuid != NULL )
    {
    if ( GATT_FindUUIDRec( (uint8 *)pType->uuid, pType->len ) == NULL )
    {
    // UUID was dynamically allocated; free it
    osal_mem_free( (uint8 *)pType->uuid );
    }
    }
    }

    osal_mem_free( pServ->attrs );

    pServ->attrs = NULL;
    pServ->numAttrs = 0;
    }
    }

    -Greg

  • Hi Greg,

    Thanks for the example. It helps and has gotten me further but I now have some follow up questions.

    In hci_ext_app.c, the app's command handler for the add service GATT extension command will use OSAL to allocate the memory for the service record which is passed to GATT_RegisterService(). So then it makes sense that deallocation of this memory is the app's responsibility.

    In my project, I followed the TI demo structure of using static variables for the service table, which is passed to GATTServApp_RegisterService(). But then in this case, I don't need to deallocate the returned array of attribute records since they weren't allocated using OSAL. Is that correct?

    So following that logic, I now call GATTServApp_DeregisterService(), but I'm not freeing the returned array of attribute records. The OSAL heap seems to be correctly sized after this call - the amount of memory that is allocated after the call to GATTServApp_RegisterService() is the same amount of memory that is deallocated after the call to GATTServApp_DeregisterService(). So there don't seem to be any memory leaks.

    Now the issue that I'm seeing is that when I try to register the service again (after BLE connection and user has done app level authentication), the handle that is returned is not the same handle that was returned on the first service register call. And I see this happening every time I re-register the service. So then I'm concerned that either:

    1) The service table in the stack is not removing (or deallocating) removed services which may be a memory leak, or

    2) That the handle number will exceed the allowed range (0xFFFF) and so can never be registered again. 

    Do you know if this ever increasing handle is a bug in the stack? Or is it due to not deallocating the returned attribute records? Or something else entirely?

    Thanks,

    Mike

  • i have same question as upstair. Does anyone can explain it? 

  • Hi,

    I don't have an explanation for my questions, but I did test it out and eventually, once the handle reaches the 0xFFFF value, GATTServApp_RegisterService() will return an error, and the service will not be able to be added to the service table.

    So dynamically adding and removing services like this does not seem feasible. 

    (Note that I've only tested this on the BLE stack v1.3.2, not the latest).

    Mike 

  • Hi Mike,

    This has not changed in the latest version. Handle numbers always increase on registration. Possibly this could be fixed, so that at least if you deregister the last registered one it could unroll. This will probably not be fixed in the short term and the best suggestion I can offer is to do a reset..

    However, I'm not sure if it's permissible to add a service after a connection has been established, as this will probably confuse most Central devices no end. If you control both sides it should be ok, however.

    If you are concerned about unauthorized access, you could manually insert some checks into the read/write callbacks, to check for some global variable. This is done in the HIDAdvancedRemote project for example for the HID reports in hiddev.c.

    BR,
    Aslak