sd_ble_gatts_hvx indication sets len 0 and doesn't call onCharacteristicChanged on Adroid App

Hi,

I trying to send indication supplied with some data to my Android app (which BTW works fine with other BLE devices) as an answer to characteristic write command

Here is my sequence of calls:

Android:

1) Discover services and characteristic

2) Write 0x3 to CCCD (0x2902) of required characteristic to enable notifications and indications

3) Enable characteristic notifications

4) Write characteristic

nRF52:

1) create services, characteristic and CCCD

2) upone receiving BLE_GATTS_EVT_WRITE set new characteristic  value with sd_ble_gatts_value_set

3) call sd_ble_gatts_hvx with p_data as NULL (returns success)

 

Unfortunately Android callback onCharacteristicChanged is never called and p_len member of ble_gatts_hvx_params_t passed to sd_ble_gatts_hvx remains 0

Here is my add characteristic function:

static void add_characteristic(uint16_t svc_handle, uint16_t cuuid, ble_gatts_char_handles_t *p_char_handle) {      
    ble_uuid_t char_uuid;
    memset(&char_uuid, 0, sizeof(ble_uuid_t));
    char_uuid.uuid = cuuid;
    char_uuid.type = BLE_UUID_TYPE_BLE;

    ble_gatts_attr_md_t cccd_md;
    memset(&cccd_md, 0, sizeof(ble_gatts_attr_md_t));
    cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    cccd_md.vlen = 0; 
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
    
    ble_gatts_attr_md_t attr_md;
    memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    attr_md.vlen       = 1;
    attr_md.vloc       = BLE_GATTS_VLOC_USER;
  
    ble_gatts_char_md_t char_md;
    memset(&char_md,0,sizeof(ble_gatts_char_md_t));
    char_md.char_props.indicate = 1;
    char_md.char_props.notify = 0;
    char_md.char_props.read = 0;
    char_md.char_props.write = 1;        
    char_md.char_props.write_wo_resp = 0;
    char_md.char_props.auth_signed_wr = 1;
    char_md.p_cccd_md = &cccd_md;    
    
    

    ble_gatts_attr_t  attr_char_value;
    memset(&attr_char_value, 0, sizeof(ble_gatts_attr_t));
    attr_char_value.p_uuid    = &char_uuid;
    attr_char_value.p_attr_md = &attr_md;    
    attr_char_value.max_len   = 500;
    attr_char_value.init_len  = 1;
    attr_char_value.init_offs = 0;    
    

    uint32_t err = sd_ble_gatts_characteristic_add(svc_handle, &char_md, &attr_char_value, p_char_handle);
    if (err != NRF_SUCCESS) printf("\tsd_ble_gatts_characteristic_add(%04x) ERROR: %d\n",cuuid,err);
}

Here is my write response function called on BLE_GATTS_EVT_WRITE 

static void write_response(uint16_t conn_handle, uint16_t char_handle, uint16_t len, uint8_t *data){
    ble_gatts_hvx_params_t params;
    uint16_t wr_len =0;
    memset(&params, 0, sizeof(ble_gatts_hvx_params_t));
    params.handle = char_handle;
    params.type = BLE_GATT_HVX_INDICATION;
    params.p_len = &wr_len;
    params.p_data = NULL;
    params.offset = 0;    

    ble_gatts_value_t pvalue;
    memset(&pvalue, 0, sizeof(ble_gatts_value_t));
    pvalue.len = len;
    pvalue.offset = 0;
    pvalue.p_value = data;

    uint32_t err = sd_ble_gatts_value_set(conn_handle, char_handle, &pvalue);
    if (err != NRF_SUCCESS) printf("\tsd_ble_gatts_value_set ERROR: %x\n",err); // else printf("\tsd_ble_gatts_value_set OK: %d\n",pvalue.len);
    
    printf("\twrite_response: conn_h: %d, cchar_h: %d, len=%d\n", conn_handle, char_handle, len);
    err = sd_ble_gatts_hvx(conn_handle, &params);
    if (err != NRF_SUCCESS) printf("\tsd_ble_gatts_hvx ERROR: %x\n",err); else printf("\tsd_ble_gatts_hvx OK: %d\n",wr_len);
   
}

What am I missing?

Parents
No Data
Reply
  • ... and another discovery that is not documented!

    apparently ble_gatts_hvx_params_t member p_len had to be set to less or equal to current MTU-3. In this case indication will be sent

    Why is that? And why documentation doesn't say a word about it?

Children
No Data
Related