Hi,
In my application, GATT DB is created using commands sent over UART from a controller. I, in no way, use the standard profiles or even the custom services/characteristics provided by the Dialog SDK. I am now done with populating the GATT database and starting the advertisement. I can see the accessory in nRF application and am able to connect to it.
Now, I want to catch read, write and all other events/requests (mtu info, connection, disconnection, indication) so that I can act on them. Can I do that in user_catch_rest_hndl()
If yes, what are the exact events I need to handle? I tried with GATTC_WRITE_CMD_IND, GATTC_READ_IND, GATTC_READ_CMD_IND but the control doesn't reach there (added breakpoints to check)
If not, then what is the right way of doing this?
Thanks,
Hrishikesh
Hi dhrishi,
The indications that you are refering to the GATTC_WRITE_CMD_IND, etc are commands that are send from the BLE stack and then conveyed to the applications in order to reach the catch_rest_handler function. Since you are implementing something completely custom you wont be able to use the infastructure that the SDK provides for the custom profiles. I am not sure how exactly you are creating the database or on which tasks you have assigned the profile that you have created. So i can only assume the reasons that you dont get the indications. If you have the BLE_CUSTOM1_SERVER definition in order for the custom task to be created but you are still using the basic implementation of the custs_profile that the SDK provides then perhaps the messages are served and handled by the existing implementation of custom profile and thats why you dont get anything in the catch_rest function. Try to set to 1 the EXCLUDE_DLG_CUSTS1 definition and check if the catch_function is executed.
Thanks MT_dialog
I will try to set EXCLUDE_DLG_CUSTS1 to 1 and execute.
I have assigned the profile to TASK_APP and I do not have BLE_CUSTOM1_SERVER.
Commands used for GATT database creation:
struct gattm_add_svc_req *req = KE_MSG_ALLOC(GATTM_ADD_SVC_REQ, TASK_ATTM, TASK_APP,
gattm_add_svc_req);
struct gattm_add_attribute_req *req = KE_MSG_ALLOC(GATTM_ADD_ATTRIBUTE_REQ,
TASK_ATTM, TASK_APP, gattm_add_attribute_req);
struct gattm_att_set_value_req *req = KE_MSG_ALLOC(GATTM_ATT_SET_VALUE_REQ, TASK_ATTM, TASK_APP,
gattm_att_set_value_req);
In this case, what are the events that the stack will provide to the application for read/write/indicate/MTU negotiation?
Can they be caught in user_catch_rest_hndl() or is there any other method for the same.
Hi dhrishi,
All the messages that the kernel doesn't handle are conveyed to the TASK_APP (if that is the destination of the message), so if, when you have created the service with the GATTM_ADD_SVC_REQ the task_id member of the structure its been populated with the TASK_APP task then all the messages regarding this database can be handled by the user_catch_rest_hndl() function. Regarding which messages you can handle, messages from the GATTC that have as the destination the TASK_APP and also GAPC, GAPM, messages can be handled, including the GATTC_WRITE_CMD_IND for the writing and the MTU_EXCHANGE, regarding the reading, i dont think that you will be able to get that message since its supported currently only by the RW profiles.
Thanks MT_dialog
So, if I have created a custom database sending kernel messages using TASK_APP and not using any of the standard profiles, then how do I handle the read message.
Also, after populating the database and starting the advertisement, when the central (nRF app on a smartphone) connects what I see is:
I get a message with msgid 0x11 in user_catch_rest_hndl(). When I checked the SDK it maps to GATTM_DESTROY_DB_RSP. Is anything wrong in here? When do we get this message?
Also, for same value 0x11 I see that it maps to GATTC_WRITE_CMD_CFM. So, which one is to be considered.
In short I see multiple messages for one value. With the tasks that I have used for my GATT database configuration, could you please let me know which messages (from which files in SDK) I need to consider
I did not get the MTU info message. How do I get the value of current MTU for the communication?
Is the below call mandatory? Or can this have an effect?
attmdb_svc_set_permission(svc_hdl, PERM(SVC, ENABLE));
我没有在beginni残疾人服务ng nor enabled it. Is it required even in case of a custom database population? Can not using the above call lead to the problem above?
When I write from the central device, I get message 0x0e which is GATTC_WRITE_CMD_IND (I suppose). Is it correct?
When I read from the central device, I get no mesage in user_catch_rest_hndl(). How do I handle read then?
Hi dhrishi,
Regarding the reading as i ve mentioned above, is not possible, you wont be able to get the GATTC_READ_IND in the user_catch_rest_hndl() function, the message is not conveyed to the application. What is done in SDK5.0.4 in order to get the read commands is that a new message is added (ATTS_READ_REQ_IND). So what you can do is to register the TASK_APP for that message by using the dg_register_task_for_read_request(TASK_APP);, by doing that you will be able to catch the ATTS_READ_REQ_IND in the user_catch_rest_hndl() and check the handle that is read. Also you will have to respond to that message using the dg_atts_read_cfm() function (if you dont respond this will result in a disconnection).
The message that you get 0x11 corresponds to the GATTM_DESTROY_DB_RSP that means that at some point possibly when you connect you invoke the GATTM_DESTROY_DB_REQ since this is the response that you get, but its not only the message that counts you will have to check also the task that the message comes from. If you dont invoke the destroy database i dont think that the database destruction confirmation is what you see.
Regarding the fact that you dont get any of the messages in the TASK_APP (MTU_EXCHANGE, GATTC_WRITE_CMD_IND), when sending the GATTM_ADD_SVC_REQ have you declared the task_id as the TASK_APP ? Other than that i can not guess any other reason exept that there something wrong with the creation of the database (the fact that you get a response to the database destroy command doens't look good, if this is what you get). Regarding if its a GATTC_WRITE_CMD_CFM, this is not the indication that you get when you perform a write, also since its a GATTC_ confirmation that means that this should occur when you receive a GATTC_CMP_EVT (if you issue a command you should get the completetion), so you first have to catch the case of the GATTC_CMP_EVT and then you can check the req_type parameters in order to determine the event that completed. This is valid for most the messages that you get.
The set permissions invocation is not mandatory, if you have not disabled the service upon creation (as the examples in the AN-B-029 do), then its not obligatory to invoke the enabling of the permissions. On the other hand if you have disable the service and not enable it upon connection, then you will not be able to read or write the characteristics.
If you write from the central device the proper message that you should get is the GATTC_WRITE_CMD_IND, and you should be able to catch it outside a GATTC_CMP_EVT.
Regarding the reading of the characteristic please check at the beggining of your question.
Thanks MT_dialog
Hi,
的帮助下dg_register_task_for_read_request(TASK_APP) for each service, when I write from some central device I get ATTS_READ_REQ_IND in the user_catch_rest_hndl(). With your explanation above, I see that dg_atts_read_cfm() needs to be used with appropriate status code and the actual read response is sent internally. If I want to send data from the application itself, is it possible?
I mean, I do not store the characteristic value in DA14580 GATT database. I get the actual value over UART as a response from a controller when I forward this read request which was received. Is there a mechanism/API I can use to send the read response (along with the data) entirely on my own.
About the write request, if I have a characteristic of type uint8_t and if a central device writes 2 bytes (uint16_t) on it then what does the SDK do?
What I see is, in that case I do not get the GATTC_WRITE_CMD_IND event. Is there a check about the data type and/or size before the event is generated?
About the GATT database, all the services, characteristics and descriptors are added with dest_id as TASK_ATTM and src_id as TASK_APP.
About 0x11 event, I see that when any central connects to my device which is a peripheral, I get 0x11 event almost 2-3 times. What can this be then? I am not invoking GATTM_DESTROY_DB_REQ from my code.
Also, what is the explicit event that is received for MTU exchange. I could not find it in the events. I basically want the negotiated MTU value for the current connection to be sent to the controller.
I am unable to understand your below statement:
If you write from the central device the proper message that you should get is the GATTC_WRITE_CMD_IND, and you should be able to catch it outside a GATTC_CMP_EVT.
Can you please give me a sample example of a read or write request of a peripheral device using above GATTC_CMP_EVT and GATTC_WRITE_CMD_IND in user_catch_rest_hndl()? In short the use of GATTC_CMP_EVT in the function.
Hi dhrishi,
The dg_register_task_for_read_request, is function that it is used in order to have an indication to your application when a central reads the characteristic and not when it writes it. Regarding your second question, if it is possible to send data along with the confirmation when the device reads the database, this is not possible, as i ve mentioned this is a patch and data send to the central are taken from the database of the device and not provided from the application.
If you send value of an invalid length for the characteristic the stack will return an error directly at the central, it wont get to application level for you to handle this kind of case, it will just inform the central that he has send an invalid attribute value length message.
Regarding the 0x11 check the task that the command has as a source in order to check what this command actually is. Regarding the MTU, please check the RW-BLE-GATT-IS.pdf the MTU request is initiated by a GATT_EXC_MTU_REQ and the completion is signaled with a GATTC_CMP_EVT with the corresponding operation.
Regarding the GATTC_WRITE_CMD_IND what i mean is that you just have to catch it in the catch_rest_handler you dont have to catch the GATTC_CMP_EVT first and then check the operation, in case you were doing something like that, just use the switch() with a case of GATTC_WRITE_CMD_IND.
Thanks MT_dialog