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
  • can you give the code snippets for your customer service definition so othat i can try it on my end?

  • SO sorry for the spam on this Ticket... I have again one new finding. If I use BLE_GATT_OP_WRITE_REQ and send only one value it works. I dont get a response with the value and length, but when I read out the characteristic value of the other µC the values are written.

    If I try to use BLE_GATT_OP_PREP_WRITE_REQ I always get the error code BLE_GATT_STATUS_ATTERR_APP_BEGIN                  0x0180

    and I still don´t know what this error code means. Do I have to consider anything special what I forget?

  • If you have taken multirole example as a base, then you are getting this error most likely from the examples\ble_central_and_peripheral\experimental\ble_app_interactive\ble_m.c:1514.

            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
            {
                ble_gatts_evt_rw_authorize_request_t  req;
                ble_gatts_rw_authorize_reply_params_t auth_reply;
    
                req = p_ble_evt->evt.gatts_evt.params.authorize_request;
    
                if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
                {
                    if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                    {
                        if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                        }
                        else
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
                        }
    
                        auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
                        err_code                            = sd_ble_gatts_rw_authorize_reply(
                            p_ble_evt->evt.gatts_evt.conn_handle,
                            &auth_reply);
                        APP_ERROR_CHECK(err_code);
                    }
                }
            }
            break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST

    The RW Authorize request here only is handling write and read normal request and not a prep request. You app needs to handle prepare write differently so most of the examples are not supporting a prepare write for a characteristic that require authorization.

    Why are you using prepare write request here? do you have lot of data to be written?

Reply
  • If you have taken multirole example as a base, then you are getting this error most likely from the examples\ble_central_and_peripheral\experimental\ble_app_interactive\ble_m.c:1514.

            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
            {
                ble_gatts_evt_rw_authorize_request_t  req;
                ble_gatts_rw_authorize_reply_params_t auth_reply;
    
                req = p_ble_evt->evt.gatts_evt.params.authorize_request;
    
                if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
                {
                    if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                    {
                        if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                        }
                        else
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
                        }
    
                        auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
                        err_code                            = sd_ble_gatts_rw_authorize_reply(
                            p_ble_evt->evt.gatts_evt.conn_handle,
                            &auth_reply);
                        APP_ERROR_CHECK(err_code);
                    }
                }
            }
            break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST

    The RW Authorize request here only is handling write and read normal request and not a prep request. You app needs to handle prepare write differently so most of the examples are not supporting a prepare write for a characteristic that require authorization.

    Why are you using prepare write request here? do you have lot of data to be written?

Children
No Data
Related