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

Dynamic notification packet size

Considering my use case, the size a certain characteristic is dynamic, and the notification should only contains the exact amount of data, even though locally there should still be 20 bytes of allocated memory. The bytes of interest are the first nBytes of char_val I have tried setting the len field of hvx_params, but that does not seem to work. How can I achieve this goal? Bellow is some relevant code.

uint8_t char_value[20] = {0x00};

void init_char(){
    ...

    ble_gatts_attr_t attr_char_value;
    memset(&attr_char_value, 0, sizeof(attr_char_value));
    attr_char_value.p_uuid = &char_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.max_len     = 20;
    attr_char_value.init_len    = 20;
    attr_char_value.p_value     = char_value;

    ...    
}

void reply_with_data(int nBytes){
    int i=0; 
    for(i=0; i<nBytes; i++)
        char_value[i] += 10;

    if (our_service.conn_handle != BLE_CONN_HANDLE_INVALID){
		SEGGER_RTT_printf(0, "Going to notify.\n");
        uint16_t len = nBytes;
        ble_gatts_hvx_params_t hvx_params;
        memset(&hvx_params, 0, sizeof(hvx_params));

        hvx_params.handle = our_service.char_handles.value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = 0;
        hvx_params.p_len  = &len;
        hvx_params.p_data = char_value;

        sd_ble_gatts_hvx(our_service.conn_handle, &hvx_params);
    }
    else
        SEGGER_RTT_printf(0, "No connection.\n");
}
Parents
  • The characteristic has to be defined as having a variable length. That is done by setting vlen, as shown bellow.

    //Attribute metadata
    ble_gatts_attr_md_t attr_md;
    memset(&attr_md, 0, sizeof(attr_md));
    attr_md.vlen = 1; // <-- This
    attr_md.vloc = BLE_GATTS_VLOC_USER;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    
    ...
    
    //Characteristic value
    ble_gatts_attr_t attr_char_value;
    memset(&attr_char_value, 0, sizeof(attr_char_value));
    attr_char_value.p_uuid = &char_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.max_len     = 20;
    attr_char_value.init_len    = 20;
    attr_char_value.p_value     = char_value;
    
Reply
  • The characteristic has to be defined as having a variable length. That is done by setting vlen, as shown bellow.

    //Attribute metadata
    ble_gatts_attr_md_t attr_md;
    memset(&attr_md, 0, sizeof(attr_md));
    attr_md.vlen = 1; // <-- This
    attr_md.vloc = BLE_GATTS_VLOC_USER;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    
    ...
    
    //Characteristic value
    ble_gatts_attr_t attr_char_value;
    memset(&attr_char_value, 0, sizeof(attr_char_value));
    attr_char_value.p_uuid = &char_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.max_len     = 20;
    attr_char_value.init_len    = 20;
    attr_char_value.p_value     = char_value;
    
Children
Related