Problems with sd_ble_gattc_write()

Hello everyone,

I used the Multirole example as base for my code. My target is to make a communication with two NRF52382. I changed the HRS (heart rate servide) to my custom service and custom characteristic. After that I implemented the function sd_ble_gattc_read to the code and this also works. The Central is able to read out the characteristic data (500 bytes) of the Peripheral.

My next target is now to write into the characteristic with the function sd_ble_gattc_write(). My MAX_MTU_SIZE is 103 therefore I checked the MSC for the usage of sd_ble_gattc_write. I made it really similar to the read function, but I get always the err_code =1 which is SVC Handler is Missing. I am not 100% sure what this means and what could cause this problem. As handler for the write function I used the same one like in the read.

void ble_hrs_c_local_data_write(ble_hrs_c_t const *p_ble_hrs_c)
{     

      ble_gattc_write_params_t write_params;
      ret_code_t             err_code;
      uint8_t writestatus = 0;

      uint8_t data_write_one[100];
      uint8_t data_write_two[100];
      uint8_t data_write_three[100];
      uint8_t data_write_four[100];
      uint8_t data_write_five[100];

      for(int i = 0; i<=99; i++)
      {
        data_write_one[i]= 57;
        data_write_two[i]= 57;
        data_write_three[i]= 57;
        data_write_four[i]= 57;
        data_write_five[i]= 57;
        //Data of the own characteristic ist here: hrs_init_params.data
        // Data split into parts
      }

      nrf_delay_ms(300);
        
      write_params.len = 100;
      write_params.offset = 0;
   //  write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE;
       write_params.handle = p_ble_hrs_c->peer_hrs_db.hrm_handle;


       for(int i = 0; i<=5; i++)
       { 
      write_params.write_op = BLE_GATT_OP_PREP_WRITE_REQ;

      switch (writestatus)
      {
      case 0:
      write_params.p_value = &data_write_one[100];
      break;
      case 1:
      write_params.p_value = &data_write_two[100];
      break;
            case 2:
      write_params.p_value = &data_write_three[100];
      break;
            case 3:
      write_params.p_value = &data_write_four[100];
      break;
            case 4:
      write_params.p_value = &data_write_five[100];
      break;
       case 5:
      write_params.write_op = BLE_GATT_OP_EXEC_WRITE_REQ;
      write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE;
      break;
      }
      err_code = sd_ble_gattc_write(p_ble_hrs_c->conn_handle,&write_params);
      
      if(err_code=!0)
      {
      nrf_delay_ms(500);
      
      }
      APP_ERROR_CHECK(err_code);
      
      write_params.offset=write_params.offset+100;
      writestatus= writestatus+1;
      nrf_delay_ms(300);
      }
}

Currently I work with delays because I hadn´t time yet to understand and implement the QWR. Can you also give me some hints how I can improve this?

If you need more Information from the code please inform me. I think I overseen something but I am not able to find it. I hope you guys can help me.

Best regards

Hani

Parents
  • Thank you! Yes this could be a reason. Currently I am advertising  characteristic with 500 bytes and I am able to read them my target was to be able also write these 500 bytes.

    What is the maximal possible data which I can deliver with a normal write and what is the limiting paramter?

    Is it a high effort to implement this into the multirole example?

  • Hani_Montana said:
    What is the maximal possible data which I can deliver with a normal write and what is the limiting paramter?

    The limit is set by what is possible for an attribute value, see the Core spec ATT part (Vol 3, Part F, 3.2.9):

    1.  The longest attribute that can be sent in a single packet is (ATT_MTU-1) octets
      in size.
    2. An attribute value may be defined to be larger than (ATT_MTU-1) octets in
      size.The maximum length of an attribute value shall be 512 octets. If the attribute size is larger than (ATT_MTU - 1) then these becomes a long write (or prepared write like in your case.

    You can have max ATT_MTU to be 247, so I suggest that you split your 500 bytes of data into two parts in your app and send using a normal write command and then reassemble them in your app in the receiver end. The other option is to handle the prepare request in the rw_authorize event.

Reply
  • Hani_Montana said:
    What is the maximal possible data which I can deliver with a normal write and what is the limiting paramter?

    The limit is set by what is possible for an attribute value, see the Core spec ATT part (Vol 3, Part F, 3.2.9):

    1.  The longest attribute that can be sent in a single packet is (ATT_MTU-1) octets
      in size.
    2. An attribute value may be defined to be larger than (ATT_MTU-1) octets in
      size.The maximum length of an attribute value shall be 512 octets. If the attribute size is larger than (ATT_MTU - 1) then these becomes a long write (or prepared write like in your case.

    You can have max ATT_MTU to be 247, so I suggest that you split your 500 bytes of data into two parts in your app and send using a normal write command and then reassemble them in your app in the receiver end. The other option is to handle the prepare request in the rw_authorize event.

Children
No Data
Related