|
23 | 23 | #include "ifapi.h" |
24 | 24 |
|
25 | 25 | #include "system_network.h" // FIXME: For network_interface_index |
| 26 | +#include "spark_wiring_vector.h" |
26 | 27 |
|
27 | 28 | #include "str_util.h" |
28 | 29 | #include "endian_util.h" |
|
35 | 36 | #include "cellular_enums_hal.h" |
36 | 37 | #include "cellular_ncp_dev_mapping.h" |
37 | 38 |
|
| 39 | +#include "ncp_fw_update.h" |
| 40 | + |
38 | 41 | #include <limits> |
39 | 42 |
|
40 | 43 | namespace { |
@@ -106,6 +109,37 @@ hal_net_access_tech_t fromCellularAccessTechnology(CellularAccessTechnology rat) |
106 | 109 | } |
107 | 110 | } |
108 | 111 |
|
| 112 | +struct CellularHalUrcHandler { |
| 113 | + CellularHalUrcHandler(const char* prefix, hal_cellular_urc_callback_t callback, void* context) : |
| 114 | + prefix(prefix), |
| 115 | + callback(callback), |
| 116 | + context(context) { |
| 117 | + } |
| 118 | + const char* prefix; |
| 119 | + hal_cellular_urc_callback_t callback; |
| 120 | + void* context; |
| 121 | +}; |
| 122 | + |
| 123 | +Vector<std::unique_ptr<CellularHalUrcHandler>> sUrcHandlers; |
| 124 | + |
| 125 | +static int commonUrcHandler(AtResponseReader* reader, const char* prefix, void* data) { |
| 126 | + auto handler = static_cast<CellularHalUrcHandler*>(data); |
| 127 | + |
| 128 | + const size_t atResponseSize = 64; |
| 129 | + std::unique_ptr<char[]> atResponse(new(std::nothrow) char[atResponseSize]); |
| 130 | + CHECK_TRUE(atResponse.get(), SYSTEM_ERROR_NO_MEMORY); |
| 131 | + |
| 132 | + const auto n = reader->readLine(atResponse.get(), atResponseSize - 1); |
| 133 | + if (n < 0) { |
| 134 | + return n; |
| 135 | + } |
| 136 | + atResponse[n] = '\0'; |
| 137 | + handler->callback(atResponse.get(), handler->context); |
| 138 | + atResponse.reset(); |
| 139 | + |
| 140 | + return SYSTEM_ERROR_NONE; |
| 141 | +} |
| 142 | + |
109 | 143 | } // unnamed |
110 | 144 |
|
111 | 145 | int cellular_on(void* reserved) { |
@@ -506,6 +540,43 @@ int cellular_command(_CALLBACKPTR_MDM cb, void* param, system_tick_t timeout_ms, |
506 | 540 | return mdmTypeToResult(mdmType); |
507 | 541 | } |
508 | 542 |
|
| 543 | +int cellular_add_urc_handler(const char* prefix, hal_cellular_urc_callback_t cb, void* context) { |
| 544 | + const auto mgr = cellularNetworkManager(); |
| 545 | + CHECK_TRUE(mgr, SYSTEM_ERROR_UNKNOWN); |
| 546 | + const auto client = mgr->ncpClient(); |
| 547 | + CHECK_TRUE(client, SYSTEM_ERROR_UNKNOWN); |
| 548 | + const auto parser = client->atParser(); |
| 549 | + |
| 550 | + const NcpClientLock lock(client); |
| 551 | + |
| 552 | + auto entry = std::make_unique<CellularHalUrcHandler>(prefix, cb, context); |
| 553 | + CHECK_TRUE(entry, SYSTEM_ERROR_NO_MEMORY); |
| 554 | + sUrcHandlers.append(std::move(entry)); |
| 555 | + auto handler = sUrcHandlers.last().get(); |
| 556 | + |
| 557 | + return parser->addUrcHandler(prefix, commonUrcHandler, handler); |
| 558 | +} |
| 559 | + |
| 560 | +int cellular_remove_urc_handler(const char* prefix) { |
| 561 | + const auto mgr = cellularNetworkManager(); |
| 562 | + CHECK_TRUE(mgr, SYSTEM_ERROR_UNKNOWN); |
| 563 | + const auto client = mgr->ncpClient(); |
| 564 | + CHECK_TRUE(client, SYSTEM_ERROR_UNKNOWN); |
| 565 | + const auto parser = client->atParser(); |
| 566 | + |
| 567 | + const NcpClientLock lock(client); |
| 568 | + |
| 569 | + parser->removeUrcHandler(prefix); |
| 570 | + for (int i = 0; i < sUrcHandlers.size(); ++i) { |
| 571 | + if (strcmp(sUrcHandlers.at(i).get()->prefix, prefix) == 0) { |
| 572 | + sUrcHandlers.removeAt(i); |
| 573 | + break; |
| 574 | + } |
| 575 | + } |
| 576 | + |
| 577 | + return SYSTEM_ERROR_NONE; |
| 578 | +} |
| 579 | + |
509 | 580 | int cellular_data_usage_set(CellularDataHal* data, void* reserved) { |
510 | 581 | return SYSTEM_ERROR_NOT_SUPPORTED; |
511 | 582 | } |
@@ -608,3 +679,28 @@ int cellular_start_ncp_firmware_update(bool update, void* reserved) { |
608 | 679 | CHECK(client->startNcpFwUpdate(update)); |
609 | 680 | return SYSTEM_ERROR_NONE; |
610 | 681 | } |
| 682 | + |
| 683 | +int cellular_get_ncp_firmware_version(uint32_t* version, void* reserved) { |
| 684 | + const auto mgr = cellularNetworkManager(); |
| 685 | + CHECK_TRUE(mgr, SYSTEM_ERROR_UNKNOWN); |
| 686 | + const auto client = mgr->ncpClient(); |
| 687 | + CHECK_TRUE(client, SYSTEM_ERROR_UNKNOWN); |
| 688 | + CHECK(client->getNcpFirmwareVersion(version)); |
| 689 | + return SYSTEM_ERROR_NONE; |
| 690 | +} |
| 691 | + |
| 692 | +int cellular_update_status(void* reserved) { |
| 693 | +#if HAL_PLATFORM_NCP_FW_UPDATE |
| 694 | + return services::SaraNcpFwUpdate::instance()->updateStatus(); |
| 695 | +#else |
| 696 | + return SYSTEM_ERROR_NOT_SUPPORTED; |
| 697 | +#endif |
| 698 | +} |
| 699 | + |
| 700 | +int cellular_enable_updates(void* reserved) { |
| 701 | +#if HAL_PLATFORM_NCP_FW_UPDATE |
| 702 | + return services::SaraNcpFwUpdate::instance()->enableUpdates(); |
| 703 | +#else |
| 704 | + return SYSTEM_ERROR_NOT_SUPPORTED; |
| 705 | +#endif |
| 706 | +} |
0 commit comments