Skip to content

Commit 16a5c06

Browse files
committed
[hal] cellular add/remove urc handler
1 parent 997ca98 commit 16a5c06

File tree

5 files changed

+117
-27
lines changed

5 files changed

+117
-27
lines changed

hal/inc/cellular_hal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,16 @@ int cellular_update_status(void* reserved);
282282
*/
283283
int cellular_enable_updates(void* reserved);
284284

285+
/**
286+
* Add URC handler
287+
*/
288+
int cellular_add_urc_handler(const char* prefix, hal_cellular_urc_callback_t cb, void* context);
289+
290+
/**
291+
* Remove URC handler
292+
*/
293+
int cellular_remove_urc_handler(const char* prefix);
294+
285295
#ifdef __cplusplus
286296
}
287297
#endif

hal/inc/cellular_hal_constants.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ typedef int (*_CALLBACKPTR_MDM)(int type, const char* buf, int len, void* param)
3737

3838
typedef void (*_CELLULAR_SMS_CB_MDM)(void* data, int index);
3939

40+
typedef int (*hal_cellular_urc_callback_t)(const char* data, void* context);
41+
4042
#ifdef __cplusplus
4143
// Todo - is storing raw string pointers correct here? These will only be valid
4244
// If they are stored as constants in the application.

hal/network/ncp/cellular/cellular_hal.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "ifapi.h"
2424

2525
#include "system_network.h" // FIXME: For network_interface_index
26+
#include "spark_wiring_vector.h"
2627

2728
#include "str_util.h"
2829
#include "endian_util.h"
@@ -108,6 +109,32 @@ hal_net_access_tech_t fromCellularAccessTechnology(CellularAccessTechnology rat)
108109
}
109110
}
110111

112+
struct CellularHalUrcHandler {
113+
const char* prefix;
114+
hal_cellular_urc_callback_t callback;
115+
void* context;
116+
};
117+
118+
Vector<CellularHalUrcHandler> sUrcHandlers;
119+
120+
static int commonUrcHandler(AtResponseReader* reader, const char* prefix, void* data) {
121+
auto handler = static_cast<CellularHalUrcHandler*>(data);
122+
123+
const size_t atResponseSize = 64;
124+
std::unique_ptr<char[]> atResponse(new(std::nothrow) char[atResponseSize]);
125+
CHECK_TRUE(atResponse.get(), SYSTEM_ERROR_NO_MEMORY);
126+
127+
const auto n = reader->readLine(atResponse.get(), atResponseSize - 1);
128+
if (n < 0) {
129+
return n;
130+
}
131+
atResponse[n] = '\0';
132+
handler->callback(atResponse.get(), handler->context);
133+
atResponse.reset();
134+
135+
return SYSTEM_ERROR_NONE;
136+
}
137+
111138
} // unnamed
112139

113140
int cellular_on(void* reserved) {
@@ -508,6 +535,45 @@ int cellular_command(_CALLBACKPTR_MDM cb, void* param, system_tick_t timeout_ms,
508535
return mdmTypeToResult(mdmType);
509536
}
510537

538+
int cellular_add_urc_handler(const char* prefix, hal_cellular_urc_callback_t cb, void* context) {
539+
const auto mgr = cellularNetworkManager();
540+
CHECK_TRUE(mgr, SYSTEM_ERROR_UNKNOWN);
541+
const auto client = mgr->ncpClient();
542+
CHECK_TRUE(client, SYSTEM_ERROR_UNKNOWN);
543+
const auto parser = client->atParser();
544+
545+
const NcpClientLock lock(client);
546+
547+
sUrcHandlers.append({
548+
.prefix = prefix,
549+
.callback = cb,
550+
.context = context
551+
});
552+
auto& handler = sUrcHandlers.last();
553+
554+
return parser->addUrcHandler(prefix, commonUrcHandler, &handler);
555+
}
556+
557+
int cellular_remove_urc_handler(const char* prefix) {
558+
const auto mgr = cellularNetworkManager();
559+
CHECK_TRUE(mgr, SYSTEM_ERROR_UNKNOWN);
560+
const auto client = mgr->ncpClient();
561+
CHECK_TRUE(client, SYSTEM_ERROR_UNKNOWN);
562+
const auto parser = client->atParser();
563+
564+
const NcpClientLock lock(client);
565+
566+
parser->removeUrcHandler(prefix);
567+
for (int i = 0; i < sUrcHandlers.size(); ++i) {
568+
if (strcmp(sUrcHandlers.at(i).prefix, prefix) == 0) {
569+
sUrcHandlers.removeAt(i);
570+
break;
571+
}
572+
}
573+
574+
return SYSTEM_ERROR_NONE;
575+
}
576+
511577
int cellular_data_usage_set(CellularDataHal* data, void* reserved) {
512578
return SYSTEM_ERROR_NOT_SUPPORTED;
513579
}

services/src/ncp_fw_update.cpp

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ const int NCP_FW_UUFWINSTALL_COMPLETE = 128;
8484
* };
8585
*/
8686
const SaraNcpFwUpdateConfig SARA_NCP_FW_UPDATE_CONFIG[] = {
87-
// { sizeof(SaraNcpFwUpdateConfig), 3140001, 103140001, "SARA-R510S-01B-00-ES-0314A0001_SARA-R510S-01B-00-XX-0314ENG0099A0001.upd", "09c1a98d03c761bcbea50355f9b2a50f" },
88-
// { sizeof(SaraNcpFwUpdateConfig), 103140001, 3140001, "SARA-R510S-01B-00-XX-0314ENG0099A0001_SARA-R510S-01B-00-ES-0314A0001.upd", "136caf2883457093c9e41fda3c6a44e3" },
89-
// { sizeof(SaraNcpFwUpdateConfig), 2060001, 99010001, "SARA-R510S-00B-01_FW02.06_A00.01_IP_SARA-R510S-00B-01_FW99.01_A00.01.upd", "ccfdc48c0a45198d6e168b30d0740959" },
90-
// { sizeof(SaraNcpFwUpdateConfig), 99010001, 2060001, "SARA-R510S-00B-01_FW99.01_A00.01_SARA-R510S-00B-01_FW02.06_A00.01_IP.upd", "5fd6c0d3d731c097605895b86f28c2cf" },
87+
// { sizeof(SaraNcpFwUpdateConfig), 31400010, 31400011, "SARA-R510S-01B-00-ES-0314A0001_SARA-R510S-01B-00-XX-0314ENG0099A0001.upd", "09c1a98d03c761bcbea50355f9b2a50f" },
88+
// { sizeof(SaraNcpFwUpdateConfig), 31400011, 31400010, "SARA-R510S-01B-00-XX-0314ENG0099A0001_SARA-R510S-01B-00-ES-0314A0001.upd", "136caf2883457093c9e41fda3c6a44e3" },
89+
// { sizeof(SaraNcpFwUpdateConfig), 20600010, 990100010, "SARA-R510S-00B-01_FW02.06_A00.01_IP_SARA-R510S-00B-01_FW99.01_A00.01.upd", "ccfdc48c0a45198d6e168b30d0740959" },
90+
// { sizeof(SaraNcpFwUpdateConfig), 990100010, 20600010, "SARA-R510S-00B-01_FW99.01_A00.01_SARA-R510S-00B-01_FW02.06_A00.01_IP.upd", "5fd6c0d3d731c097605895b86f28c2cf" },
9191
};
9292
const size_t SARA_NCP_FW_UPDATE_CONFIG_SIZE = sizeof(SARA_NCP_FW_UPDATE_CONFIG) / sizeof(SARA_NCP_FW_UPDATE_CONFIG[0]);
9393

@@ -460,17 +460,18 @@ int SaraNcpFwUpdate::process() {
460460
NCPFW_LOG(INFO, "Disconnecting Cellular...");
461461
// network_disconnect() doesn't wait for final OK response from CFUN=0
462462
// wait for DETACH: +CGEV: ME PDN DEACT 1
463-
// FIXME: Note that this uses internals of the NCP client/parser and that a new cellular_hal API
464-
// should be added for this functionality later, as in all the other places we are using
465-
// cellular_commandas opposed to directly calling into ncp client/parser.
466-
// FIXME
467-
#ifndef UNIT_TEST
468-
auto mgr = cellularNetworkManager();
469-
auto client = mgr->ncpClient();
470-
auto parser = client->atParser();
471-
const NcpClientLock lock(client);
472-
parser->addUrcHandler("+CGEV", cgevCallback, this);
473-
#endif // UNIT_TEST
463+
cellular_add_urc_handler("+CGEV", [](const char* data, void* context) -> int {
464+
const auto self = (SaraNcpFwUpdate*)context;
465+
int profile;
466+
467+
int r = ::sscanf(data, "+CGEV: ME PDN DEACT %d", &profile);
468+
// do not CHECK_TRUE as we intend to ignore +CGEV: ME DETACH
469+
if (r >= 1) {
470+
self->cgevDeactProfile_ = profile;
471+
}
472+
473+
return SYSTEM_ERROR_NONE;
474+
}, this);
474475
cgevDeactProfile_ = 0;
475476
startTimer_ = millis();
476477
network_disconnect(0, NETWORK_DISCONNECT_REASON_USER, 0);
@@ -537,17 +538,25 @@ int SaraNcpFwUpdate::process() {
537538
}
538539
}
539540

540-
// FIXME: Note that this uses internals of the NCP client/parser and that a new cellular_hal API
541-
// should be added for this functionality later, as in all the other places we are using
542-
// cellular_commandas opposed to directly calling into ncp client/parser.
543-
// FIXME
544-
#ifndef UNIT_TEST
545-
auto mgr = cellularNetworkManager();
546-
auto client = mgr->ncpClient();
547-
auto parser = client->atParser();
548-
const NcpClientLock lock(client);
549-
parser->addUrcHandler("+UUHTTPCR", httpRespCallback, this);
550-
#endif // UNIT_TEST
541+
cellular_add_urc_handler("+UUHTTPCR", [](const char* data, void* context) -> int {
542+
const auto self = (SaraNcpFwUpdate*)context;
543+
int a, b, c;
544+
char s[40];
545+
546+
int r = ::sscanf(data, "+UUHTTPCR: %*d,%d,%d,%d,\"%32s\"", &a, &b, &c, s);
547+
CHECK_TRUE(r >= 3, SYSTEM_ERROR_AT_RESPONSE_UNEXPECTED);
548+
549+
self->httpsResp_.valid = false; // make following lines atomic
550+
self->httpsResp_.command = a;
551+
self->httpsResp_.result = b;
552+
self->httpsResp_.status_code = c;
553+
if (r > 3) {
554+
memcpy(self->httpsResp_.md5_sum, &s, sizeof(s));
555+
}
556+
self->httpsResp_.valid = true;
557+
558+
return SYSTEM_ERROR_NONE;
559+
}, this);
551560

552561
NCPFW_LOG(INFO, "Starting download...");
553562
#if SARA_NCP_FW_UPDATE_ENABLE_DOWNLOAD
@@ -575,6 +584,8 @@ int SaraNcpFwUpdate::process() {
575584
}
576585
}
577586
}
587+
588+
cellular_remove_urc_handler("+UUHTTPCR");
578589
#else // SARA_NCP_FW_UPDATE_ENABLE_DOWNLOAD
579590
// DEBUG
580591
modemFirmwareDownloadComplete = true;
@@ -606,6 +617,7 @@ int SaraNcpFwUpdate::process() {
606617
{
607618
if (cgevDeactProfile_ == NCP_FW_UBLOX_DEFAULT_CID) { // Default CID detached
608619
NCPFW_LOG(INFO, "Disconnected Cellular.");
620+
cellular_remove_urc_handler("+CGEV");
609621
saraNcpFwUpdateState_ = FW_UPDATE_STATE_INSTALL_STARTING;
610622
cooldown(1000); // allow other disconnect URCs to pass
611623
}

test/unit_tests/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Building and running tests
77
Create a build directory:
88

99
```bash
10-
rm -rf .build && mkdir .build && cd .build
10+
rm -rf build && mkdir build && cd build
1111
```
1212

1313
Generate build files:

0 commit comments

Comments
 (0)