Hi dialog team,
I am newcomer in BLE and trying to run the ble_app_peripheral project on DA14580 based on SDK5.0.4. (EVK Pro)The central device is iPhone app LightBlue. My final goal is reading accelerator sensor value controlled by iPhone.
As the first step, I want to see if I can catch the events on the DA14580, to do it, several break points are set in the callback functions, like gattc_write_cmd_ind_handler, custs1_val_ind_req_handler and custs1_val_ntf_req_handler in the file custs1_task.c.
After that, If I push "write new value" in LightBlue, then I can see the program stops in the gattc_write_cmd_ind_handler function which is also expected. But if I push "read" in LightBlue, nothing happens in the program. LightBlue shows also "no value" What's the reason?
I know there are already several threads discussed about this issue, for example
- using notification instead of read, because read access directly BLE stack
- SDK 5.0.4 will fix it
- take ble_app_peripheral as reference
and so on
I tried all these, but no success. So
1. Would you please tell me which example code can deal with "read" from LightBlue
2. If there is no such example, would you please tell me which steps should I then do? A little more details will be very helpful for me
3. Is LightBlue the right mobile app for testing "read" ? If not, which app would you recommend me?
Thank you very much
anton
I read the release notes of SDK5.0.4 and find out that GATTC_READ_CMD_IND is now also supported in SDK 5.0.4. So I tried to do the following analog to GATTC_WRITE_CMD_IND:
1. add handler definition for GATTC_READ_CMD_IND in custs1_task.c
{GATTC_READ_CMD_IND, (ke_msg_func_t)gattc_read_cmd_ind_handler}
2. implement gattc_read_cmd_ind_handler in custs1_task.c
In this step I just send the custs1_val_read_ind message (analog to custs1_val_write_ind ) with message ID CUSTS1_VAL_READ_IND
3. I then implement the switch case for reading the 2nd ADC value in user_catch_rest_hndl function in the file user_peripheral.c
...
case CUSTS1_VAL_READ_IND:
{
struct custs1_val_read_ind const *msg_param = (struct custs1_val_read_ind const *)(param);
switch(msg_param->handle)
{
case CUST1_IDX_ADC_VAL_2_VAL:
int sta=0;
break;
default:
break;
}
}break;
...
4. I set the break point at int sta=0, and then run LightBlue to put the "read again" of the ADC 2nd Value. (The connection between iPhone and DA14580 can be established well) As already mentioned above, at this point, I don't see the program jump to the break point, and "no value" shows in LightBlue.
But for "Write" I can see that the program jumps into the write handler, and without break point it can then switch on/off LED.
So it shows me that GATTC_READ_CMD_IND still doesn't work. What's wrong with the "read" handling? Would you please give me more details?
Thanks
anton
Hi,
Please reference RW-BLE-GATT-IS. GATTC_READ_CMD_IND is not a valid command. Please refer to page 21 of Interface specification and use GATTC_READ_IND for your callback.
Additionally, nothing is written to the value characteristics in the barebone version of the ble_app_peripheral. However, the description attributes are written to and read by the Light Blue application. On the application's connection, the iPhone will read all of the description characteristics, and you should get a callback here.
Try substituting that small change up there, then on the 580, try to change the value characteristic and verifying that you can read the value.
Use this handler for setting the value:
static int custs1_val_set_req_handler(ke_msg_id_t const msgid,
struct custs1_val_set_req const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
Hi,
according to your suggestion, I tried to find out firstly where a description characteristic will be read, but no success:
- search for example "CUST1_ADC_VAL_2_USER_DESC" in the whole project ---> show only in customer DB definition (user_custs1_def.c)
- search for "GATTC_READ_IND" in the whole project ---> "GATTC_READ_IND" could be called by the function prf_client_att_info_rsp() in file prf_utils.c
---> but it (prf_client_att_info_rsp()) is never called by other functions.
- set break point in the function prf_client_att_info_rsp() and then run Light Blue, the connection can be established well, but the program doesn't jump
into the function prf_client_att_info_rsp()
Summary:
Up to now I understand with your help that
- GATTC_READ_IND is the event after "read" activated by Light Blue
- custs1_val_set_req_handler() should be used to set the value
But with the help of the ble_app_peripheral project, I still can not catch the read flow
would you please tell me what is the read flow between Light Blue and DA14580 a little more in details regarding description characteristic?
Thanks
It seems that the read request from Light Blue never be delivered to the DA14580 user application layer, that's why I can't catch such events. (but why it is possible for write? ) If it is true, would you please tell me what is the work flow for me to deal with such read request form central device in user application layer on the peripheral side? I already spent one week in this issue, please help me to fix it. Thank you very much
anton
I verified that I can set the ADC_VAL2_CHAR, and I can read it from the lightBlue OS using the custs1_val_set_req.
I've also confirmed what you found, about the message not being delivered to the application layer. I am digging into this and will respond as soon as I find a solution.
I didn't know how to use custs1_val_set_req(), but after studying the DSPS example, I confirmed also that one can set value with custs1_val_set_req. This value can then be read by LightBlue. I am waiting for your solution regarding to the read indication for user application layer. Thanks
Sorry for the delay, just getting some answers on thsi. Also, can I ask why you would need this functionality for your application? Also, have you read farther into the software release notes, that describes registering for the event? Here is the basic principle on how to implement this feature:
***********************************************************************************************************************
The ATTS_READ_REQ_IND message is introduced. The message contains the handle of the attribute that a peer device has requested to read.
A task that requires this mechanism will typically register for ATTS_READ_REQ_IND messages at DB creation time using the dg_register_task_for_read_request() C API.
Upon reception of the ATTS_READ_REQ_IND message the task can modify the ATT DB and then it must reply by calling dg_atts_read_cfm(). There are two use cases:
The task decides that the request request is valid, (optionaly) modifies the value in the DB and finally replies by passing ATT_ERR_NO_ERROR in the status_code argument of dg_atts_read_cfm(). This results to sending the ATT read respone to the peer device.
The task decides that the read request is invalid and responds by passing an ATT error code to dg_atts_read_cfm(). This results to sending the ATT error respone to the peer device.
I want to demonstrate our customer that reading sensor data can be controlled by his iPhone. I though since there is GATTC_WRITE_CMD_IND for write, then there must be an analog indication for read. The part mentioned in release note seems more complex than GATTC_WRITE_CMD_IND, so that I am not sure if it was correct way to do it. Thank you for the hints, at lease I know now the part in release note is the right way. The ticket can be closed.