This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Difference between sd_ble_gatts_sys_attr_set() flags

I am getting killed by the fact I cannot restore the CCCDs on a bonded reconnect and need to rely on the client doing it every connection - a violation of the standard.

I am using the ble_pc_driver.

So out of desperation I am asking what is the difference between doing the set operation with the following flag options?

sd_ble_gatts_sys_attr_set(m_adapter, p_ble_evt->evt.gap_evt.conn_handle, saveDataBuffer,
saveDataLength, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); 

sd_ble_gatts_sys_attr_set(m_adapter, p_ble_evt->evt.gap_evt.conn_handle, saveDataBuffer,
saveDataLength, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);

sd_ble_gatts_sys_attr_set(m_adapter, p_ble_evt->evt.gap_evt.conn_handle, saveDataBuffer,
saveDataLength, BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);

sd_ble_gatts_sys_attr_set(m_adapter, p_ble_evt->evt.gap_evt.conn_handle, saveDataBuffer,
saveDataLength, 0);

The limited documentation on this method does not really explain what these different options will do.

The 'aveDataBuffer' has the results of the 'get' analog of this call obtained during the disconnect event of the previous connection. The contents of saveDataBuffer look valid.

SO far, no matter what I do, I cannot indicate/notify characteristics without having the client 'enable' the CCCDs every connection. 

Anybody know? 

Anybody ever get this to work?

Parents
  • Hi,

    The SoftDevice does not store any information specifically for a bond or peer etc between connections, so this is the responsibility of the user. When using the nRF5 SDK this is handled by the peer manager library. We do not provide any similar library for the PC side (pc-ble-driver), so you have to implement this yourself.

  • I do. I save the data on a disconnect indication and retrieve from a file before I start advertising. That along with pairing info.

    Looks valid

  • Hi,

    I see. Does the data include both user and sys attributes? If you want to do it generically (without knowing), you should modify the flags and try again, as you can see is done in the peer manager implementation in the do while loop in gscm_local_db_cache_apply() in <SDK>\components\ble\peer_manager\gatts_cache_manager.c.

  • I have done all the obvious combinations and from the data I retrieve using the 'get' method during the disconnect (which I save to a file) the combination of both flags seems to be the 'most' correct. At least I see both the service-changed and measurement handles in the array of bytes. When I do just the system flag I only get the service-changed handle.

    But in the end it doesn't matter. When I call the set method I use the same set of flags but it doesn't work. However, I have no way to know what the set method does with these flag settings (at least I can look at the result when I do the get). Should the set call be done with flags = 0 regardless of the flags used in the get? I think I have tried that too and it didn't work either.

  • Hi,

    I see. Can you show the full code you use around sd_ble_gatts_sys_attr_set()? Do you check the return values?

  •         case BLE_GAP_EVT_CONNECTED:
                m_connection_handle = p_ble_evt->evt.gap_evt.conn_handle;
                printf("Connected at time %llu, connection handle 0x%04X\n", (GetTickCount64() - elapsedTimeStart), m_connection_handle);
                fflush(stdout);
                if (saveDataBuffer != NULL)
                {
                    printf("Calling sd_ble_gatts_sys_attr_set with CCCD info\n");
                    err_code = sd_ble_gatts_sys_attr_set(m_adapter, p_ble_evt->evt.gap_evt.conn_handle, saveDataBuffer,
                        saveDataLength, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
                    if (err_code != NRF_SUCCESS)
                    {
                        printf("Failed updating persistent sys attr info. Error code: 0x%02X\n", err_code);
                        fflush(stdout);
                    }
                }
                if (thermParams->commonControls->invokeServiceChanged)
                {
                    invokeServiceChange(m_adapter, m_connection_handle);
                }
                break;
    That's on the connection event

    On the previous disconnect

            case BLE_GAP_EVT_DISCONNECTED:
                printf("Disconnected at time %llu\n", (GetTickCount64() - elapsedTimeStart));
                fflush(stdout);
                // call twice; once to get the size of the data
                // create the buffer,
                // call a second time to load the data into the buffer
                sd_ble_gatts_sys_attr_get(m_adapter, p_ble_evt->evt.gap_evt.conn_handle, NULL, &saveDataLength,
                    BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
                if (saveDataLength > 0)
                {
                    if (saveDataBuffer == NULL)
                    {
                        saveDataBuffer = calloc(1, saveDataLength * sizeof(uint8_t));
                    }
                    err_code = sd_ble_gatts_sys_attr_get(m_adapter, p_ble_evt->evt.gap_evt.conn_handle, saveDataBuffer, &saveDataLength,
                        BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
                    if (err_code != NRF_SUCCESS)
                    {
                        printf("Failed getting persistent sys attr info. Error code: 0x%02X\n", err_code);
                        fflush(stdout);
                    }
                }
                m_connection_handle = BLE_CONN_HANDLE_INVALID;
                m_advertisement_timed_out = true;  // No restart
                sem_post(&disconnectSem);
                if (!therm_abort)   // If disconnect is from PHG
                {
                    printf("Disconnected by PHG\n");
                    pthread_create(&terminateId, NULL, (void *)thermCommandTerminate, false);
                }
                break;

    The 'saveDataBuffer' is what is saved locally in a file. When I look at the saveDataBuffer contents, it looks good, though I do not understand everything in it. I do see the CCCD settings and the handles.

  • Hi,

    This looks OK (assuming there are both user and sys attributes, but if that was a problem you would have printed an error message). Which pc-ble-driver version do you use?

Reply Children
Related