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

A value characteristic can only receive 2 bytes of payload?

Hello, I'm sending a series of data up to 7 bytes from an android phone, but I can only receive the first 5.

I'm asking what are the list of thing to mind if I were trying to receive more?

I'm sending them over GATT, more specifically, gatts_evt.params.write.

At first nothing works out,the p_ble_evt.header.evt_id wasn't even correct (sorry I wasn't able to breakpoint and see the value) Now it is correct, 0x0050 (write)

It became correct after I gradually increased the size of my payload from 2 to 5, then to 7. It was at first not correct when it was 7, but then I reduced the payload to only 2, it worked properly, then to 5, again, worked well, now 7, which SHOULDN'T work, but worked anyway, that is, p_ble_evt.header.evt_id now has the proper value of 0x0050, which is extremely strange since it wasn't that value when the payload was 7 bytes at first, but somehow, it maintains the value 0x0050 after I changed the payload from 2bytes to 5bytes then to 7 bytes.

Now the problem is that although 7 bytes were all sent, I can only recieve the first 5, the remaining 7 could no where be found, probably discarded, although I am not sure which one discarded it, the phone or nrf51.

What did I do wrong? What are the things to mind when configuring a characteristic to solve this?

Update: actually I can only write 2 bytes now for some reason I used to write 7 and have the first 5 properly received, but now I can only do 2 after tampering with characteristic initialization, the actual init parameters are as follows:

	/* BLE GATT metadata */
ble_gatts_char_md_t ble_char_md;

memset(&ble_char_md, 0, sizeof(ble_char_md));
ble_char_md.char_props.write_wo_resp = 1;
ble_char_md.char_props.notify = 1;
//	ble_char_md.char_props.read = 1;
//  ble_char_md.char_props.write =1;
//  ble_char_md.char_props.indicate =1;
//	ble_char_md.char_props.auth_signed_wr =1;
	
ble_char_md.p_cccd_md = NULL;//once commented, now enabled to restore the original config, 12-23
ble_char_md.p_sccd_md = NULL;
ble_char_md.p_char_user_desc = NULL;
ble_char_md.p_user_desc_md = NULL;



/* ATT metadata */

ble_gatts_attr_md_t ble_attr_md;

memset(&ble_attr_md, 0, sizeof(ble_attr_md));

/* No security is required */
ble_attr_md.write_perm.lv = 1;
ble_attr_md.write_perm.sm = 1;

//  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&ble_attr_md.read_perm); 
//  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&ble_attr_md.write_perm); 

//  ble_char_md.p_cccd_md = &ble_attr_md;
//	ble_char_md.char_props.notify   = 1;

ble_attr_md.vloc = BLE_GATTS_VLOC_STACK;
ble_attr_md.rd_auth = 0;
ble_attr_md.wr_auth = 0;
ble_attr_md.vlen = 1;


/* ble characteristic UUID */
ble_uuid_t ble_uuid;

ble_uuid.type = m_mesh_base_uuid_type;
ble_uuid.uuid = MESH_VALUE_CHAR_UUID;

/* ble attribute */
ble_gatts_attr_t ble_attr;
uint8_t default_value = 0;

memset(&ble_attr, 0, sizeof(ble_attr));

ble_attr.init_len = 1;
ble_attr.init_offs = 0;
ble_attr.max_len = sizeof(mesh_gatt_evt_t);
ble_attr.p_attr_md = &ble_attr_md;
ble_attr.p_uuid = &ble_uuid;
ble_attr.p_value = &default_value;

/* add to service */
uint32_t error_code = sd_ble_gatts_characteristic_add(
        m_mesh_service.service_handle,
        &ble_char_md,
        &ble_attr,
        &m_mesh_service.ble_val_char_handles);

if (error_code != NRF_SUCCESS)
{
    return NRF_ERROR_INTERNAL;
}

return NRF_SUCCESS;
  • You shois uld be able to write more than 5 as long as sizeof(mesh_gatt_evt_t) more than 5. Strange that you are getting different values. Are you sure that you the write events you get are to the same attribute? You can check the attribute handle. Maybe add something like this to ble_evt_dispatch():

    if(p_ble_evt->header.evt_id == BLE_GATTS_EVT_WRITE) 
    {
        printf("Write event with handle: %#04x\r\n", p_ble_evt->evt.gatts_evt.params.write.handle);
        printf("Write event with length: %#04x\r\n", p_ble_evt->evt.gatts_evt.params.write.len);
        printf("Write event with data:");
        for(uint32_t i = 0; i < p_ble_evt->evt.gatts_evt.params.write.len-1; i++)
        {
            printf("%#02x, ", p_ble_evt->evt.gatts_evt.params.write.data[i]);
        }
        printf("%#02x\r\n", p_ble_evt->evt.gatts_evt.params.write.data[p_ble_evt->evt.gatts_evt.params.write.len-1]);
    }
    
  • Well what do you know! the len is 0x0002. I'm not coming ON to ya but you got help me out here — what are the things that may affect this property? I send this from an android phone. I thought the length is automatically configured by android apis, no? Here's a link to the breakpoint-pause image: link text

  • Update: the android api is tailoring properly to the length of my packets. (at least according to the breakpoint I just did) It "worked" again, until, of course, it doesn't. Damn I hate this game.

  • So sometimes you get len 2 and sometimes you get len 5 on the same handle, 0x000E? Then I don't think it's something wrong with the firmware on the nRF. Maybe a sniffer trace would provide some more information. You can use the nRF Sniffer.

Related