Hi,
I need to send BLE notifications to the central from the peripheral application in case of a characteristic value change. What is the API that needs to be used for the same? Is there an example available anywhere?
Also, how to handle write on CCC descriptor to enable or disable the indications (GATT_CCC_START_IND, GATT_CCC_STOP_NTFIND) in the application itself.
Thanks,
Hrishikesh
Device:
Hi dhrishi,
You can check the ble_app_peripheral example for checking how to send notifications. The example uses the custs profile for sending notifications but you can go down to the actual sending data of the profile and check how the profile is sending the actual data. The command used for the profile is CUSTS1_VAL_NTF_REQ and the callback triggered is the custs1_val_ntf_req_handler() function. The actual command that sends the notification is the prf_server_send_event() function (the command is invoked after changing the value in the database attmdb_att_set_value() since it sends the value that is in the database).
关于你提到的第二个问题,我不确定我的联合国derstand the question i suppose that you mean how to catch the event where the central actually writes to the CCC characteristic, the callback that triggers when a writing event comes is the GATTC_WRITE_CMD_IND callback and the profile will have to check the value send and write it in the database, you can check how the profile is handling this in the gattc_write_cmd_ind_handler().
Thaks MT_dialog
Hi,
Thanks for your reply.
Note: I have created the GATT database in the application using data from the UART commands from an external MCU using KE_MSG_ALLOC commands (TASK_ATTM and TASK_APP) In short, no standard profile or custom profile provided by the Dialog SDK is used by me.
I checked prf_server_send_event() function. The first parameter to this is: prf_env_struct *p_env
What do I send in here? Do you want me to locally create a variable of type prf_env_struct and populate its members. In that case what will be the values of:
appid: ??
prfid: ??
conidx: current connection id ?
Hi dhrishi,
The prf_server_send_event() function essentially uses the GATTC_SEND_EVT_CMD with the corresponding parameters. Most of the parameters are held in the examples in a structure that holds available information for the profile used, the app_id is the TASK_APP, the profile id is the profile id that issues the command, in that case is the CUSTS1_TASK and the conidx is the connection index of the current connection. Most of those information populate the structure upon enabling the custs1 profile. In your case you can get the conidx from the app_env structure, and since you have no profile layer you should be able to use TASK_APP as a prfid.
Thanks MT_dialog
Hi,
I tried the following code to send out a zero length indication (BLE connection is active) when a characteristic value is updated locally.
Although, I do not see the central/controller sending out a read request to fetch the new value. What can be wrong in this?
By default, does the indicate request send the new value too? If yes, I don't want that. I want to send a zero length indication as required by the central side. Is that possible? If yes, how do we do that?
uint16_t handle; /* Handle is the handle of the characteristic whose value has changed */
struct gattc_send_evt_cmd *req = KE_MSG_ALLOC(GATTC_SEND_EVT_CMD,
KE_BUILD_ID(TASK_GATTC, app_connection_idx), TASK_APP, gattc_send_evt_cmd);
req->req_type = GATTC_INDICATE;
req->handle = handle;
ke_msg_send(req);
What change is required in the above code to send zero length indication?
Hi dhrishi,
To start with the indications are initiated from the peripheral (just like notifications but with application confirmation when the value reaches the peripheral) and not the central, the peripheral can only send indications towards the central and not the other way around, so in order to send an indication from a peripheral you just have to send that message from your application, the central doesn't read the indicatable value, it is just the peripheral that indicates that value to the central, the central just confirms that he received the message send from the peripheral.
The GATTC_SEND_EVT_CMD message when instructed to send an indication you will have fill in the handle of the attribute that you would like to send, if the value of the characteristic is zero length, i dont see any problem in sending that.
I did the following test, i ve set the "Indicatable" characteristic, in the ble_app_peripheral, to have the size of 0, and created a timer callback that sends a CUSTS1_VAL_IND_REQ periodically other than that i left the project as is, so whenever i enabled the indications i could see on the sniffer that the indication left the device properly and the central was sending back the proper confirmation.
Thanks MT_dialog
Hi,
Thanks for your reply. I already got it working and I did it exactly the same way you mentioned. Before sending the indication, I set the corresponding characteristic value length as zero. As a result, a zero length indication is sent and it works fine. Thanks for your help.
Thanks,
Hrishikesh