Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Data transmission method by "Write" from central to multi-role

Hello.
I am developing with reference to multi-roll and central sample projects. One of the functions I want to implement is to send data from central to multi-role.

How to send data
・ Notify
・ Read
・ Write
I think that there are three, but because it is not sent regularly, “Write” was adopted.
Write used in the central project is to make Central start Notify for multi-role. The data is transmitted as 2-byte data as the CCCD value.
The structure used for transmission is shown below.

    p_msg-> req.write_req.gattc_params.handle = handle_cccd;
    p_msg-> req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH; ⇒2
    p_msg-> req.write_req.gattc_params.p_value = p_msg-> req.write_req.gattc_value;
    p_msg-> req.write_req.gattc_params.offset = 0;
    p_msg-> req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
    p_msg-> req.write_req.gattc_value [0] = LSB_16 (cccd_val);
    p_msg-> req.write_req.gattc_value [1] = MSB_16 (cccd_val);
    p_msg-> conn_handle = conn_handle;
    p_msg-> type = WRITE_REQ;

In this structure, the data is related
1.p_msg-> req.write_req.gattc_params.len
2.p_msg-> req.write_req.gattc_params.p_value
I thought. However, when len = 4 and p_value was set to "test", the operation on the central side stopped.
So return len = 2 and change write_op
When changed from BLE_GATT_OP_WRITE_REQ to BLE_GATT_OP_WRITE_CMD and executed,
BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE
Is displayed, but nothing is displayed on the multi-roll side. (When BLE_GATT_OP_WRITE_REQ, "BLE_GATTS_EVT_WRITE" was received)
To summarize the questions so far,
・ How to send 3 bytes or more data by Write?
・When using BLE_GATT_OP_WRITE_CMD as the method, which event is called on the multi-roll side (reception side)?
please teach me. Thank you.

The environment is as follows.
SoftDevice: S132
IDE: SES
BLE Device: NRF52832
SDK version: 15.30
Central project: ble_peripheral⇒ble_app_hrs_c
multirole project: experimental⇒ble_app_multirole_lesc

  • How to send 3 bytes or more data by Write?

    You can do this by simply setting write_params.len = 3. But I am curious to why the central device stops when you set len=4 and value="test". I tested this with the ble_app_uart_c example, and it worked fine. However, the CCCD value is supposed to be either 0x01 (notification) or 0x02 (indication), not "test".

    Could you try to debug your project and figure out why the project stops. What is the return value of sd_ble_gattc_write(..)?

     

    When using BLE_GATT_OP_WRITE_CMD as the method, which event is called on the multi-roll side (reception side)?
    please teach me. Thank you.

     Check out the message sequence charts for the server side (reception), where you will see what events will be generated after an "ATT Write Command":

    Best regards,

    Simon

  • Hello Simon.
    When I tried debugging, it was a problem before "sd_ble_gattc_write (..)". The place that is frozen is "BLE_GATTC_EVT_READ_RSP" in "gatt_cache_manager.c". The cause of the exception was "HardFault".
    In addition to the length specification, this phenomenon may have occurred in the contents of 2-character text data. For example.
    len = 2, p_value = "es" ⇒success
    len = 2, p_value = "ts" ⇒failure
    We are currently investigating the cause. If you have any advice, thank you.
    Also, what is the configuration of “ble_app_uart_c” that Mr. Simon tried?
    central⇒ble_app_uart_c
    peripheral⇒ble_app_uart

    Also, please tell us what content you changed and tested.
    Thank you.

  • I am not able to recreate your error. Could you explain how to recreate your error or upload a minimal example? However, as mention earlier, it is not the intention to send any other values than 0x00, 0x01 or 0x02 to the CCCD. Can you explain what your goal is? What are you trying to achieve with this?

    Best regards,

    Simon

  • Hello, Simon.
    Sorry for the late reply.
    I was doing another task in parallel. It has not been solved yet.
    What I want to do is:
    1. Multi-roll module scans peripheral module
    2. Send device information of the scanned peripheral module to the central module.
    3. Select some of the device information received on the central module side and execute “Write” to the multi-roll module
    4. The received multi-role module connects to the peripheral module that matches the received data.
    is.

    This time I want to implement the contents of No.3.

  • Kova said:
    3. Select some of the device information received on the central module side and execute “Write” to the multi-roll module

    There are different ways of achieving this, one way is to simply create one service with two characteristics on the multirole side. Call sd_ble_gatts_service_add(..) only once, and call characteristic_add(..) two times after that, using the service handle. For the first characteristic, you enable notifications (for sending data from multirole to central). For the other characteristic, you only enable the write property (for sending data from central to multirole). Then you end up with something like this:

    You can also create a service with only one characteristic, like endnode is arguing for here. Then you use that characteristic to transfer data both ways, which require you to add both the notify and the write property to that characteristic.

    I think this you are trying to implement the last approach. But you should NOT use the CCCD to transfer data from the central (client) to the multirole (server).  You should ONLY write to the CCCD if you want to enable/disable notifications/indications for a characteristic. Which will enable/disable a server to notify/indicate the associated characteristic value to the client. If you are only using one characterstics (with notify and write property) you should use the characteristic handle when sending data (WRITE) from the central to the multirole, and NOT the cccd handle. I would recommend you to read through the BLE Characteristic Tutorial, which explains this in more detail.

    Best regards,

    Simon

Related