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

why doesn't BLE_GATTS_EVT_WRITE ever be invoked?

using nRF51-DK

I'm a noob and currently trying to implement a custom service by modifying the 'Heart Rate Service' example which inclued the 'BAS' which is battery status notification service(from what I understand, anyway).

I've been debugging using a few LEDs connected to pin 5 and 6. Basically, I just configure these two led pin to be SET at the beginning of main() function and then turn them off at specific points in the code to see if it ever reaches there.

Through this method, I have been able to turn off the led when a connection is established. This one could be done by inserting a single line to turn off the led inside the "ble_bas_on_ble_evt" cases like below:

void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt)
{
	
	
    if (p_bas == NULL || p_ble_evt == NULL)
    {
        return;
    }
    
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
		nrf_gpio_pin_clear(DEBUGLED1); // added
            on_connect(p_bas, p_ble_evt);
            break;

        case BLE_GAP_EVT_DISCONNECTED:
            on_disconnect(p_bas, p_ble_evt);
            break;

        case BLE_GATTS_EVT_WRITE:		
            on_write(p_bas, p_ble_evt);
            break;

        default:
						
            // No implementation needed.
            break;
    }
}

Now, I modified the battery_level_char_add() a little bit so that the battery level attribute value could be 'written' as well. (Originally, only read was available)

char_md.char_props.read   = 1;
char_md.char_props.write=1; // added this line to make it writable

I have confirmed that this modification alone was sufficient(i believe so) for me to connect to nRF51-DK with my smartphone through the 'nRF Master Control' app and write some random battery level value (ex: 3%, 9%).

Now here's the real problem: Since the values that I insert from my smartphone app is 'WRITING', I assumed it would definitely trigger a 'BLE_GATTS_EVT_WRITE' in the nRF51-DK(peripheral) side.

Therefore, with my "ble_bas_on_ble_evt" code modified to turn off the led when 'BLE_GATTS_EVT_WRITE' occurs, was expected to work.

void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt)
{
	
		
    if (p_bas == NULL || p_ble_evt == NULL)
    {
        return;
    }
    
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
						
            on_connect(p_bas, p_ble_evt);
            break;

        case BLE_GAP_EVT_DISCONNECTED:
            on_disconnect(p_bas, p_ble_evt);
            break;

        case BLE_GATTS_EVT_WRITE:
	        nrf_gpio_pin_clear(DEBUGLED1);		// added	
            on_write(p_bas, p_ble_evt);
            break;

        default:
						
            // No implementation needed.
            break;
    }
}

However, with this modification, the led does not turn off even when I write new battery level values.

Could someone point out some things that I could have missed?

Parents
  • Hi, 

    Did you found solution? I'm facing the same problem.

    Here is my function to add simple writeable characteristic

    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 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.rd_auth    = 0;
        attr_md.wr_auth    = 0;
        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 = 1;
        char_md.char_props.read = 1;
        char_md.char_props.write = 1;
        
    
        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   = 256;
        attr_char_value.init_len  = 256;
        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);
    }

    But when I perform write from client instead of BLE_GATTS_EVT_WRITE I get some strange event 1 which I suppose is BLE_EVT_TX_COMPLETE

    Is my function correct?

  • Ok... looks like I get BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST with write data instead.

    Isn't it strange?

Reply Children
No Data
Related