Open jim-ber opened 6 years ago
It is not allowed by bluetooth specs to have more than one service with the same UUID, correct me if im wrong, but you can have multiple characteristics with the same UUID (this is implemented in this library) and it will work with your example. Body sensor location is described in descriptor so each characteristic can have own dscriptor that will tell where sensor is attached.
I am going to check spec and get back to you! But I have not seen anywhere that specifies that creating multiple services with the same UUID isn't permitted. Considering that services can be uniquely identified on the GATT Server side by handle, I don't really see a technical impediment either.
Here is what I have found: 1 2 3
Let me do some research into the spec and I'll post my findings.
What I have found so far here under 4.4.2: Discover Primary Service by Service UUID says that a specific primary service may exist multiple times on a server.
I thought ive read somewhere its not possible, but your finding is very good. Thanks.
I will investigate if its possible to add this with current esp-idf and will try to add this, just need some time.
From my early tests i can say that esp-idf is not allowing it:
I (716) BT_GATT: GATTS_StartService
I (725) BT_GATT: GATTS_StartService
E (726) BT_GATT: Active Service Found
E (729) BT_GATT: Duplicate Service start - Service already started
I (738) BT_APPL: BTA_DmSetBleAdvParamsAll: 32, 64
Thank you for all your help! @chegewara
I just found this in the executeCreate method in BLEService.
srvc_id.id.inst_id = 0;
I haven't tried it yet but maybe incrementing that instance id when adding a service with the same uuid may fix the issue?
I just checked the esp-idf here and this snippet seems to indicate that it might:
/*******************************************************************************
**
** Function GATTS_CreateService
**
** Description This function is called to reserve a block of handles for a service.
**
** *** It should be called only once per service instance ***
**
** Parameter gatt_if : application if
** p_svc_uuid : service UUID
** svc_inst : instance of the service inside the application
** num_handles : number of handles needed by the service.
** is_pri : is a primary service or not.
**
** Returns service handle if sucessful, otherwise 0.
**
*******************************************************************************/
UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
UINT16 svc_inst, UINT16 num_handles, BOOLEAN is_pri)
I also think it explains your comment in espressif/esp-idf#2005 . since GATTS_CreateService returns the s_handle for the existing service if it finds a match. I am guessing it has to match all three parameters in line 64, including svc_instance.
Good finding, seems that new handle value is created with changed srvc_id.id.inst_id
. I have early version of this, could you test it and give some feedback? I will push it to my repo before i create PR.
https://github.com/chegewara/esp32-snippets
I can tonight. I'll post back with some feedback. Thanks!
Just for testing purpose it works only with two services with the same uuid.
For multiple services with the same uuid additional parameter has been added. It requires that programmer keep properly create service with this parameter:
BLEService* pService2 = pServer->createService(BLEUUID("03b80e5a-ede8-4b33-a751-6ce34ec4c700"), 15, 2);
BLEService* pService3 = pServer->createService(BLEUUID("03b80e5a-ede8-4b33-a751-6ce34ec4c700"), 15, 3);
Last parameter is type of uint8_t and can have value from 0 to 255.
@chegewara Sorry about the delay. Tested it and it works (tested it up to 16 services).
Thanks!
@jim-ber I just found issue that needs to be addressed with latest PR. This part of code does not test against srvc_id.id.inst_id
:
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEServer.cpp#L220-L221
@chegewara I'll fix it tonight. Thanks for pointing that out!
Hi all, I'm trying to do the same thing (2 services with the same UUID) using the attribute tables. The function that crate that (esp_ble_gatts_create_attr_tab()) is ok because there is an argument srvc_inst_id, and so I can call it 2 times with different service instances. My problem is that in the event generated (ESP_GATTS_CREAT_ATTR_TAB_EVT) I can't find a reference to the service instance in order to save the handles in different places: gatts_add_attr_tab_evt_param contains only a esp_bt_uuid_t not a esp_gatt_srvc_id_t like the gatts_create_evt_param where instance ID can be found. Is there a way to resolve this or can't be done using attr tables? Thanks!
Hi @frazan-un if i remember multiple services with the same uuid is not finished in this library yet.
About srvc_inst_id in ESP_GATTS_CREAT_ATTR_TAB_EVT
you can ask espressif devs on esp-idf github issues tracker. I believe they will add it or explain how to write code without it if its not needed.
Currently, the BLEServer::createService will not allow the creation of services with the same UUID as a previously added service. It would be useful to add multiple instances of the same service. For example, a medical device could aggregate readings from multiple heart rate sensors throughout the body and display them in a single BLE Device (with different Body Sensor Location characteristics).