在我们定义的资料e we have a characteristic that is written over the air by the client/central device. This characteristic is defined in user_custs1_def.h to have a CHAR_LEN of 254 (which is the maximum size that it should ever be). In testing we have found that as long as the new written value is equal in length or shorter than the previous written value, then everything works fine. But if the new value is longer than the previously written value (even though the new value is still much shorter than the initial CHAR_LEN of 254), the write fails and the system starts to behave erratically. For example, after a longer write to this characteristic, that characteristic can no longer be read over the air and the connection to the client becomes unstable.
It appears that in the case when a longer string is being written, the gattc_write_req_ind_handler() function in custs1_task.c is never being called, so the problem is occurring before this point in the code.
How can we implement the desired function? That is, a writable characteristic that can take any value from the client (up to 254 bytes), regardless of the current contents of that characteristic?

Hi mkelwood,
It seems that writing a larger value to the characteristic than the previously written value, is not a problem and I am not able to replicate it. Could you please take a look at DSPS application where we can write 247 bytes of data> In DSPS you are able to have the functionality that you want to have, so please check how the characteristics are implemented in this project.
Thanks, PM_Dialog
Hello PM_Dialog,
Thank you for the response. I have some additional information. My initial conclusion on the problem was incorrect; it is not writes that are longer than previous writes that cause the issue. Rather, it is writes that are longer than (MTU - 3) bytes, which require the Write Long Characteristic Value procedure (Bluetooth spec 5.0 Vol 3 Part G section 4.9.4).
I have attached a screenshot from an OTA capture file showing the issue. The DA14585 is the slave (GATT server) device. The target characteristic has handle 53. After connection and discovery, I write a short (length less than MTU - 3) value to the characteristic, which succeeds (see frames 4468 and 4473). I read back the correct value (frames 6926 and 6932). Then I attempt to write a value which is 21 bytes long (one more than MTU - 3). The GATT client sends a Prepare Write Request (frame 7334, the highlighted frame) and there is no response from the DA14585. The slave is now broken and unresponsive.
I have tried setting the target characteristic permissions to WRITE_REQ and to WRITE_COMMAND. The attached capture was with WRITE_REQ permissions. Using WRITE_COMMAND, the GATT Client will not let me write a long value to the characteristic (it complains about Bad Argument).
So my question now is, why is the Write Long Characteristic Value procedure not working? Why does the DA14585 not respond with a Prepare Write Response? Do I need to do anything special to support Prepare Write/Execute Write sequences from the GATT server side?
Thanks for your help!
我更新SDK 6.0.10.511;the problem with Write Long Characteristic Value persists. The device fails to respond to a Prepare Write Request from the central, and the device is unresponsive until disconnect/reconnect.
Hi mkelwood,
In case you don’t use or you don’t want to MTU exchange, you should implement the Write Long Characteristic Value as the implementation in the ble_app_peripheral example of the SDK. Please, take a look at this example of the SDK. If the length of the characteristic value to be written is greater than 20 bytes, then the user_svc1_long_val_att_info_req_handler() in the user_catch_rest_hndl() function will be triggered. If the length is less than 20 bytes the user_svc1_long_val_wr_ind_handler () will be executed. So, if you want to send more than 20 bytes without MTU exchange, you should do the same implementation as in the user_svc1_long_val_att_info_req_handler() function of the ble_app_peripheral example. Since you do that, the master will send a “Prepare Write Request” and the slave will response with a “Prepare Write Response”. Otherwise, if you want to do a simple write request and send more than 20 bytes, you should increase the MTU size.
Thanks, PM_Dialog
Thank you PM_Dialog for this information! I have implemented the att_info_req_handler code as you suggested, and this has solved the Write Long Characteristic Value issues. The wr_ind_handler is still called after the EXECUTE WRITE command is received; this is the expected and preferred behavior.
I never would have guessed that the att_info_req_handler is the code that makes writing long characteristics work. Even seeing the code in ble_app_peripheral application, I would not have made the connection between this and the Prepare Write/Execute Write sequence. I could not find documentation on this anywhere in either the Dialog or Riviera Waves documents. I wish there was better documentation on some these more obscure callbacks.
Hi mkelwood,
Glad you figured your issue out.
Thanks, PM_Dialog