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

characteristic larger than 253 bytes freezes the onRead callback #912

Open
jingoro2112 opened this issue Mar 13, 2025 · 5 comments · May be fixed by #913
Open

characteristic larger than 253 bytes freezes the onRead callback #912

jingoro2112 opened this issue Mar 13, 2025 · 5 comments · May be fixed by #913

Comments

@jingoro2112
Copy link

from standard characteristic read example:

void onRead( NimBLECharacteristic* characteristic, NimBLEConnInfo& connInfo ) override
{
	const uint8_t buf[256] = {0};
	characteristic->setValue( buf, 253 ); // for values of 253 or less, it works as expected, getting a callback for each read request
	characteristic->setValue( buf, 254 ); // onRead() is never called again, despite the client making and receiving a read request
}

Just stumbled across this, It is possible I'm doing something wrong? but there seems to be something magical happening at the 253-4 byte boundary, I suspect an int8 being used with some kind of two-byte header? I have not looked at the source yet, spent too many hours already zeroing in on this problem.

@jingoro2112
Copy link
Author

this is on an esp32 S3 I should have mentioned. I tried with two separate GATT handlers (on the linux/raspberry pi side) and same result.

I swapped out NimBLE for BLEDevice (ArduinoBLE) and the problem went away so it seems certainly related to NimBLE

As a side note I get about 50% more throughput with the ArduinoBLE implementation.

@h2zero
Copy link
Owner

h2zero commented Mar 14, 2025

Thanks for reporting this. The issue appears to be that the client is using a normal read rather than a long read. There is an unfortunate situation with the NimBLE stack itself where the onRead callback would be called successively for the same read operation when a characteristic value is longer than the MTU -3, I have tried to handle this here via detecting a long read PDU so that the application callback is only called once, if the client instead send normal read commands and the characteristic value is more than the MTU - 3 then the callback will not be called. Stuck between a rock and a hard place with this one sadly, my suggestion is to increase the MTU or if possible, use long read commands.

As a side note I get about 50% more throughput with the ArduinoBLE implementation.

This is likely due to the MTU being half the size, increasing it to 517 should fix it.

@jingoro2112
Copy link
Author

jingoro2112 commented Mar 14, 2025 via email

@jingoro2112
Copy link
Author

follow-up: upping the MTU NimBLEDevice::setMTU( 512 ); does fix both the throughput and read issues, thx again for the attention.

I will leave it to you to close/defer this issue since there seems to be an underlying tension.

@h2zero h2zero linked a pull request Mar 14, 2025 that will close this issue
@h2zero
Copy link
Owner

h2zero commented Mar 14, 2025

Thanks for confirming, I have opened #913 to resolve this properly.

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

Successfully merging a pull request may close this issue.

2 participants