Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Having more than 4 characteristics causes an error #114

Closed
coder543 opened this issue Oct 6, 2017 · 23 comments
Closed

Having more than 4 characteristics causes an error #114

coder543 opened this issue Oct 6, 2017 · 23 comments
Assignees

Comments

@coder543
Copy link

coder543 commented Oct 6, 2017

with Log Level set to Verbose, I'm trying to add 5 characteristics, each with their own unique UUID. Each characteristic is initialized to an 8-byte NULL sequence with:

BLECharacteristic *characteristic = service->createCharacteristic(
	UUID, perms
);

char value[8] = {0};
characteristic->setValue((uint8_t*)&value, 8);

Interestingly, only 4 characteristics show up at any given time.

As @chegewara found, characteristics 5+ generate an error:

D (1566) BLEDevice: gattServerEventHandler [esp_gatt_if: 3] ... ESP_GATTS_ADD_CHAR_EVT
D (1574) BLEUtils: GATT ServerEvent: ESP_GATTS_ADD_CHAR_EVT
D (1580) BLEUtils: [status: ESP_GATT_ERROR, attr_handle: 0 0x00, service_handle: 40 0x28, char_uuid: 00006234-0000-1000-8000-00805f9b34fb]
@nkolban nkolban self-assigned this Oct 6, 2017
nkolban added a commit that referenced this issue Oct 8, 2017
nkolban added a commit that referenced this issue Oct 8, 2017
@nkolban
Copy link
Owner

nkolban commented Oct 8, 2017

The problem has been found and we have a resolution. The core of the story is a new API that was released in the latest ESP-IDF. The API is called esp_ble_gatts_create_service. The signature of this function changed dramatically. It is now

esp_err_t esp_ble_gatts_create_service(
   esp_gatt_if_t       gatts_if,
   esp_gatt_srvc_id_t* service_id,
   uint16_t            num_handles)

The interesting one from our perspective is "num_handles". I had this hard-coded to 10. When I tested with a value of 20, the error went away. Reading what little docs we have on this API doesn't elaborate much upon it. What I have now done is added an optional attribute to the BLEService constructors that take the number of handles to define. This is exposed in BLEServer::createService() which also has the number of handles parameter (optional ... default = 15).

If we run out of handles, we can increase those with

myBLEServer->createService(myServiceUUID, myMaximumHandles);

Have a re-test with the latest builds and let's see if this resolves the issue. In the meantime, I'll also raise an issue with ESP-IDF to try get better understanding of the lower level API.

@nkolban
Copy link
Owner

nkolban commented Oct 8, 2017

I have now raised ESP-IDF issue 1087 ...

espressif/esp-idf#1087

@chegewara
Copy link
Collaborator

Looks like its working. Nicely done.

@nkolban
Copy link
Owner

nkolban commented Oct 23, 2017

Closing for now. We can always re-open as needed.

@nkolban nkolban closed this as completed Oct 23, 2017
@MikeMint
Copy link

MikeMint commented Dec 28, 2017

Sound strange, but issue comes again.
Code with 5+ characteristics compiles and uploads without errors. Ble apps (Ble scanner and nRF Connect) could see only first 5 characteristics and no more. When I try to access 6th via second esp, I get error - cannot find characteristic.

@nkolban
Copy link
Owner

nkolban commented Dec 28, 2017

Are you running with the latest cpp_utils?

@MikeMint
Copy link

Just checked and it seems that not new one. Thanks a lot. I'll update it and check again.

@chegewara
Copy link
Collaborator

You need to create server with handles parameter

@MikeMint
Copy link

@nkolban Neil, thanks for your help. Now it works better
With such setup I have created 50 characteristics, but again I can see only 45.
BLEService* pService = pServer->createService(BLEUUID(SERVICE_UUID),100);
Is it any limits with characteristics number per service?

@chegewara
Copy link
Collaborator

What the heck you are building that you need 50 characteristics? I dont know about any limitations, but you should ask it on forum. Also im encourage you to try with more than 100 handles, because 50 is for characteristics and you need some for descriptors if you are using any.

@MikeMint
Copy link

@boonkerz Sounds strange, but for some purpose I need to pass 50 parameters :)

@chegewara
Copy link
Collaborator

@MikeMint But you know you can pack parameters and send few parameters in one characteristic? Also you can use some mechanism similar to HID and send all parameters on one characteristic but each parameter will have opcode that will point what parameter it is. This can make application and interface much more simply

@MikeMint
Copy link

@chegewara actually, I need to send/receive several files up to 1000 bytes and I just want to use 50 characteristics to "send" this files one by one in 1 service. Maybe it is not the best way to do it.

@nkolban
Copy link
Owner

nkolban commented Dec 28, 2017

What I'd suggest we do is try and run your app which creates 50 services with debug trace on. The internal logic is that you create your services, then you add characteristics to your service and then you execute a start() request to start the service. If I remember correctly that causes the creation (at that point) of all the characteristics and descriptors. Th ESP-IDF APIs are event based. What that means is that when we perform a request (eg. create a characteristic) that is handed off to the BLE runtime ... which does its stuff and then eventually generates an event that indicates the outcome. These events are written to the trace logs. What I initially want to see is whether or not we getting "OK" responses from each of the requests to create a characteristic.

@chegewara
Copy link
Collaborator

Im not saying its good or bad way to do it, just wanted to show some alternatives.

@chegewara
Copy link
Collaborator

chegewara commented Dec 28, 2017

PS there is limitation. Each attribute (service, characteristic and descriptor) has handle and here is the limitation. Max handle value is 0xffff

@nkolban
Copy link
Owner

nkolban commented Dec 28, 2017

Imagine you want to send X bytes to your BLE server where X can be arbitrary large. Consider creating a protocol where your client performs multiple serial writes of "chunks" of the data. For example ... if the chunk size is 50 bytes, then you will send X/50 chunks.
Instead of having a characteristic that tries to hold X bytes ... don't hold the "value" of the complete data as a characteristic. Instead, on your BLE server where you are reciving the data, write a callback that gets invoked when a chunk arrives and appends that into a growing buffer.

@MikeMint
Copy link

@nkolban Something like send with confirmation? I think, I should try it also. It sounds like better solution. In my point of view, I'd like to do same, but with several registers. So, when all n characteristics is written, I send confirmation and that change values of this characteristics to new one.

@chegewara
Copy link
Collaborator

@MikeMint is there a chance that you can predict if you will be able to change MTU from client side application? I mean, client will be esp32 or some other device that you will programme or it is some 3rd party device and you cant change MTU from it?

@MikeMint
Copy link

@chegewara client will be another esp32 or smartphone. So, the main question how to transfer large data (50+ bytes) over ble.

@chegewara
Copy link
Collaborator

if it will be esp32 then you can setup MTU value (it will negotiate with server) and send even more than 500 bytes at once, so with your approach you will need only 2 characteristics to send 1000 bytes. With smartphones may be harder, but as far as i know all or most new android smartphones can handle MTU to 517. iPhones cant use MTU bigger than 185 i think, but you will need some research about that

@MikeMint
Copy link

@chegewara it will be great solution. I should try this. Thanks a lot for this tip!

@chegewara
Copy link
Collaborator

#325

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants