From 18fd3676d89bce14c6b3eaa4f26dff161bc501cc Mon Sep 17 00:00:00 2001 From: Dmitry Andreev Date: Fri, 4 Aug 2023 22:35:41 -0700 Subject: [PATCH] Arduino Nano 33 IoT large transfer fix (MCU hang bug) uint16_t handle = *(uint16_t*)data hangs Arduino Nano 33 IoT in cases when data pointer is unaligned. This happens when receiving large packets of BLEStringCharacteristic. This doesn't not happen when setting such characteristics from iPhone (iOS) or Android devices, but happens 100% of the time on PC using either Bleak (Python) or QT6 libraries. In those cases data pointer at the time of this call is not two bytes (sizeof(uint16_t)) aligned and dereferencing such pointer hangs the MCU. To resolve the issue we copy that uint16_t handle byte by byte without monkeying with ORs, Shifts or other binary operations to avoid endianness issues on other platforms. --- src/utility/ATT.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utility/ATT.cpp b/src/utility/ATT.cpp index acdf5a9f..3c679e19 100644 --- a/src/utility/ATT.cpp +++ b/src/utility/ATT.cpp @@ -1246,7 +1246,11 @@ void ATTClass::writeReqOrCmd(uint16_t connectionHandle, uint16_t mtu, uint8_t op return; } - uint16_t handle = *(uint16_t*)data; + /// uint16_t handle = *(uint16_t*)data; // This hangs Arduino Nano 33 IoT in cases when data is unaligned + /// mainly when dealing with large packets. Copy the handle byte by byte in endianness independent way. + uint16_t handle; + ((uint8_t *)&handle)[0] = ((uint8_t*)data)[0]; + ((uint8_t *)&handle)[1] = ((uint8_t*)data)[1]; if ((uint16_t)(handle - 1) > GATT.attributeCount()) { if (withResponse) {