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

sd_ble_gatts_rw_authorize_reply() not working

My app uses a proprietary service and characteristic UUIDs; the app needs to completely manage all characteristic reads and writes. With nRF Connect, I can see my service and characteristics. I can even read all my characteristics, but data received is not the data that I provide to sd_ble_gatts_rw_authorize_reply(). I have verified with a sniffer that the nRF ATT_READ_RSP always contains the same data, which is not the data I provided to sd_ble_gatts_rw_authorize_reply(). What am I doing wrong?

sd_ble_gatts_characteristic_add() is set up like this:
  // characteristic metadata
  memset(&char_md, 0, sizeof(char_md));   // defaults all 0 and NULL 
  char_md.char_props.read = 1;
  char_md.char_props.write = 1;

  // attribute metadata
  memset(&attr_md, 0, sizeof(attr_md));
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);   // no security requirement to read
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);  // no security requirement to write
  attr_md.vloc    = BLE_GATTS_VLOC_USER;
  attr_md.rd_auth = 1;        // we want to be called back on every read
  attr_md.wr_auth = 0;
  attr_md.vlen    = 0;

  memset(&attr_char_value, 0, sizeof(attr_char_value));
  ble_uuid.type = myUuidType
  ble_uuid.uuid = myUuid16;
  attr_char_value.p_uuid    = &ble_uuid;
  attr_char_value.p_attr_md = &attr_md;
  attr_char_value.init_len  = 20;
  attr_char_value.init_offs = 0;
  attr_char_value.max_len   = 20;
  attr_char_value.p_value = NULL;
  sd_ble_gatts_characteristic_add(...)

When I receive the BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event with (req.type == BLE_GATTS_AUTHORIZE_TYPE_READ), I provide the attribute data like this:

  static uint8_t   sendBuf[30];
  ble_gatts_rw_authorize_reply_params_t rdReply;
  
  rdReply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
  rdReply.params.read.offset = 0;
  rdReply.params.read.update = 1;           // tried 0 as well, made no difference
  returnLength = getCharValue(sendbuf);     // puts attribute data into sendbuf
  rdReply.params.read.len = returnLength;
  rdReply.params.read.p_data = sendBuf;
  err_code = sd_ble_gatts_rw_authorize_reply(conHandle, &rdReply);
  APP_ERROR_CHECK(err_code);

What am I doing wrong?

Parents
  • I changed the attribute metadata from BLE_GATTS_VLOC_USER to BLE_GATTS_VLOC_STACK and now it works.

    I'm guessing there's some machinery in the stack that requires memory allocated to the attribute data, even though my app is intercepting all reads and writes, managing data storage on its own.

  • It's nice that this has resolved the problem for you, however I'd like to continue using BLE_GATTS_VLOC_USER in my app. It seems, while write requests go through fine, the read requests return data of the correct length, but of invalid content. It appears to return data from the same (invalid) value pointer each time.

    Also, my code worked fine before I decided to move to from BLE_GATTS_VLOC_STACK to BLE_GATTS_VLOC_USER

    Dear Nordic, is there any way to fix this?

    Edit: I'm on S132 7.2.0. Thanks for the "necromancer" achievement on the forum.

Reply
  • It's nice that this has resolved the problem for you, however I'd like to continue using BLE_GATTS_VLOC_USER in my app. It seems, while write requests go through fine, the read requests return data of the correct length, but of invalid content. It appears to return data from the same (invalid) value pointer each time.

    Also, my code worked fine before I decided to move to from BLE_GATTS_VLOC_STACK to BLE_GATTS_VLOC_USER

    Dear Nordic, is there any way to fix this?

    Edit: I'm on S132 7.2.0. Thanks for the "necromancer" achievement on the forum.

Children
Related