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 Reply
  • 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.

Children
  • 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?

  • I see. I have reported the issue to the R&D team responsible for the pc-ble-driver. I will let you know how it progresses.

Related