From 64a810abdb8987e321fb847dca0506389c98cc06 Mon Sep 17 00:00:00 2001 From: Sergey Polyakov Date: Mon, 29 Jun 2026 16:31:51 +0200 Subject: [PATCH] Work around for EG916Q returning too large APDU responses --- hal/network/ncp/cellular/cellular_ncp_client.h | 9 ++++++++- hal/network/ncp_client/quectel/quectel_ncp_client.cpp | 4 ++-- system/src/control/cellular.cpp | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/hal/network/ncp/cellular/cellular_ncp_client.h b/hal/network/ncp/cellular/cellular_ncp_client.h index a4efb4bce3..f72790aa7d 100644 --- a/hal/network/ncp/cellular/cellular_ncp_client.h +++ b/hal/network/ncp/cellular/cellular_ncp_client.h @@ -30,7 +30,14 @@ namespace particle { #if PLATFORM_ID != PLATFORM_GCC -const size_t MAX_APDU_SIZE = 261; // 4 (header) + 1 (Lc) + 255 (data) + 1 (Le) +const size_t MAX_APDU_COMMAND_SIZE = 261; // 4 (header) + 1 (Lc) + 255 (data) + 1 (Le) +const size_t MAX_APDU_RESPONSE_SIZE = 258; // 256 (data) + 2 (status) + +// XXX: Set to a higher value than MAX_APDU_COMMAND_SIZE or MAX_APDU_RESPONSE_SIZE to work around +// EG916Q incorrectly returning too large responses +const size_t APDU_BUFFER_SIZE = 400; + +static_assert(APDU_BUFFER_SIZE >= MAX_APDU_COMMAND_SIZE && APDU_BUFFER_SIZE >= MAX_APDU_RESPONSE_SIZE); struct CellularNcpEvent: NcpEvent { enum Type { diff --git a/hal/network/ncp_client/quectel/quectel_ncp_client.cpp b/hal/network/ncp_client/quectel/quectel_ncp_client.cpp index aaba1a3840..56f0244729 100644 --- a/hal/network/ncp_client/quectel/quectel_ncp_client.cpp +++ b/hal/network/ncp_client/quectel/quectel_ncp_client.cpp @@ -2131,7 +2131,7 @@ int QuectelNcpClient::startNcpFwUpdate(bool update) { } int QuectelNcpClient::sendApdu(const char* cmdBuf, size_t cmdSize, char* respBuf, size_t& respSize, bool autoClose) { - if (cmdSize > MAX_APDU_SIZE) { + if (cmdSize > MAX_APDU_COMMAND_SIZE) { return SYSTEM_ERROR_INVALID_ARGUMENT; } @@ -2170,7 +2170,7 @@ int QuectelNcpClient::sendApdu(const char* cmdBuf, size_t cmdSize, char* respBuf auto cmd = parser_.command(); cmd.printf("AT+CSIM=%d,\"", (int)(cmdSize * 2)); - char strBuf[MAX_APDU_SIZE * 2 + 50]; // Add some room for AT command framing + char strBuf[APDU_BUFFER_SIZE * 2 + 20]; // Add some room for AT command framing toHex(cmdBuf, cmdSize, strBuf, sizeof(strBuf)); cmd.print(strBuf); cmd.print("\""); diff --git a/system/src/control/cellular.cpp b/system/src/control/cellular.cpp index 8f874602bb..ccffb81e6d 100644 --- a/system/src/control/cellular.cpp +++ b/system/src/control/cellular.cpp @@ -138,7 +138,7 @@ int sendApdu(ctrl_request* req) { CHECK(client->on()); struct Context { - char apdu[MAX_APDU_SIZE]; + char apdu[APDU_BUFFER_SIZE]; size_t apduSize; int error; }; @@ -149,7 +149,7 @@ int sendApdu(ctrl_request* req) { pbReq.data.funcs.decode = [](pb_istream_t* stream, const pb_field_iter_t* /* field */, void** arg) { auto ctx = (Context*)*arg; ctx->apduSize = stream->bytes_left; - if (ctx->apduSize > MAX_APDU_SIZE) { + if (ctx->apduSize > MAX_APDU_COMMAND_SIZE) { ctx->error = SYSTEM_ERROR_TOO_LARGE; return false; }