How to change value while a central tries to read a specific characteristic?

⚠️
Hi there.. thanks for coming to the forums. Exciting news! we’re now in the process of moving to our new forum platform that will offer better functionality and is contained within the main Dialog website. All posts and accounts have been migrated. We’re now accepting traffic on the new forum only - please POST any new threads at//www.wsdof.com/support. We’ll be fixing bugs / optimising the searching and tagging over the coming days.
8 posts / 0 new
Last post
Offline
Last seen:7 months 2 weeks ago
加入:2018-04-19 13:53
How to change value while a central tries to read a specific characteristic?

Hi Dialog , I need update value while a central tries to read value on specific characteristic,I already apply the RI option in the database definition in the user_custs1_def.c file like this:
// Time Characteristic Value
[SVC1_IDX_TIME_VAL] = {
SVC1_TIME_UUID_128, ATT_UUID_128_LEN, PERM(RD,ENABLE)|PERM(WR, ENABLE) | PERM(WRITE_REQ, ENABLE),
PERM(RI, ENABLE)|DEF_SVC1_TIME_CHAR_LEN
},
But i still not catch the msg on gattc_read_req_ind_handler() function in cust1_task.c file.
Besides, I find that if i apply the RI option ,I can not write value succeed.

Device:
PM_Dialog
Offline
Last seen:19 hours 41 min ago
Staff
加入:2018-02-08 11:03
Hi hm,

Hi hm,

Could you please check the following previous post on the forum?

https://support.dialog-semiconductor.com/forums/post/dialog-smartbond-bluetooth-low-energy-%E2%80%93-software/changing-value-database-dinamically

I followed that post and I added PERM(RI, ENABLE) into the value of the ADC1 characteristic. By doing that, I was able to get the gattc_read_req_ind_handler() function of cust1_task.h triggered when I tried to read the ADC Value 1 Characteristic. I suggest you to check the implementation of the DISS profile which is using a similar option and if the gattc_read_req_ind_handler() function of diss_task.h is triggered when reading a diss characteristic.

Thanks, PM_Dialog

Offline
Last seen:7 months 2 weeks ago
加入:2018-04-19 13:53
Hi Dialog:

Hi Dialog:
I have a further study, and i find if i add PERM(RI, ENABLE) ,the problem is that I can only getonce triggeredof the gattc_read_req_ind_handler() function, and it do not triggered if i read again. And the more important problem is that if I try to exec theattmdb_att_set_value(...)function , it will return a status of 0x06 (ATT_ERR_REQUEST_NOT_SUPPORTED). It means that if my charactoristic apply write permission like this:PERM(RD,ENABLE)|PERM(WR, ENABLE) | PERM(WRITE_REQ, ENABLE), I can not set the charactoristic value.

PM_Dialog
Offline
Last seen:19 hours 41 min ago
Staff
加入:2018-02-08 11:03
Hi hm,

Hi hm,

在我的设置和修改了ADC值特点tic and added the extra permissions that you mentioned, I don’t see what you are mentioning on the post. Just to be clear on that, there is no implementation on the SDK side that will handle this kind of transaction, that means that you will have to take care of the code in the gattc_read_req_ind_handler() since the SDK profile doesn’t convey any message towards the application in order to be aware that somebody read from that specific characteristic. So, regarding the fact that the callback occurs only once, how you are able to determine this ? Are you using breakpoints ? In case the break point hits once, then the link will be lost, and the central on the other side will delay as long as the supervision timeout until it realizes that he is not able to find the slave and issue a disconnection. In the case that the gattc_read_req_ind_handler() didn’t occur after one read the device would be disconnected after 30 seconds (which I don’t think is the case on your side), the reason for the disconnection would be that the confirmation message from the slave wouldn’t be sent. In the case of the SDK this is not the case since when you have the RI feature enabled you always get a slave response even if this is an error due to the incomplete custom profile for handling the RI case. So I trust that the callback occurs, tested that on my side. Regarding the attmdb_att_set_value(), you won’t need this, I suppose that what you would like to implement is that every time you get a read indication you would like to send a different value to the master, so in order to do that you will have to implement it on the gattc_read_req_ind_handler() callback, that means that as soon as the gattc_read_req_ind_handler() is triggered you should perform whatever tasks you would like to compute the value and then allocate and send a GATTC_READ_CFM message that will contain the value that you would like to send to the master (the value should be copied to the cfm->value struct). Please check the example below.

cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, length);

cfm->handle = param->handle;

cfm->status = GAP_ERR_NO_ERROR;

cfm->length = 2;

if (status == GAP_ERR_NO_ERROR)

{

test++;

memcpy(cfm->value, &test, 2);

}

ke_msg_send(cfm);

The test is a global variable that should be increased every time you read a specific characteristic.

Thanks, PM_Dialog

Offline
Last seen:7 months 2 weeks ago
加入:2018-04-19 13:53
Hi ,Dialog:

Hi ,Dialog:
We test as your code and find that just update client characteristic configuration value (test at lightblue.) and the attribute value always "No value".
And by the code in gattc_read_req_ind_handler(custs1_task ), the value to update comes from custs1_get_ccc_value(conidx, att_idx),and it's length is always 2,but the length of
attribute value can as long as 20.Is there something wrong ?
Some code of gattc_read_req_ind_handler:
// If the attribute has been found, status is GAP_ERR_NO_ERROR
if (status == GAP_ERR_NO_ERROR)
{
const struct cust_prf_func_callbacks *callbacks = custs_get_func_callbacks(TASK_ID_CUSTS1);

if (callbacks->att_db[att_idx].uuid_size == ATT_UUID_16_LEN &&
*(uint16_t *)callbacks->att_db[att_idx].uuid == ATT_DESC_CLIENT_CHAR_CFG)
{
ccc_val = custs1_get_ccc_value (conidx,att_idx);
length = 2;
}
else
{
status = PRF_APP_ERROR;
}
}
// Send read response
cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, length);
cfm->handle = param->handle;
cfm->status = status;
cfm->length = length;

if (status == GAP_ERR_NO_ERROR)
{
memcpy(cfm->value, &ccc_val, length);
}
ke_msg_send(cfm);

PM_Dialog
Offline
Last seen:19 hours 41 min ago
Staff
加入:2018-02-08 11:03
Hi hm,

Hi hm,

Let me try to check and replicate your issue and I will let you know as soon as possible.

Thanks, PM_Dialog

PM_Dialog
Offline
Last seen:19 hours 41 min ago
Staff
加入:2018-02-08 11:03
Hi hm,

Hi hm,

The Client Characteristic Configuration length is 2 bytes, and they used for enabling either notifications or indications. I am not able to understand what you mean that the attribute always has “No value”. In case of attribute value characteristics, the max length is 20 bytes (23 - 3 =20bytes) without MTU exchange. There isn’t something wrong, but be aware that the attribute value is 20 because you are not using the MTU exchange.

Thanks, PM_Dialog

Offline
Last seen:7 months 2 weeks ago
加入:2018-04-19 13:53
Hi ,Dialog:

Hi ,Dialog:
I mean that I use lightblue to read a charactoristic,If I set a value for the charactoristic( attmdb_att_set_value (...)) ,I will get a hex value otherwise it will return 'No value' , and then if I press the Read again button, it will read the remote again, now it will return a value again,but the value equals to the first one.I want to set or change the return value while light blue read the charactoristic value every time.