Skip to content

Commit 6afbd81

Browse files
committed
Revert "Remove R510 FOTA support"
This reverts commit a0b92dd.
1 parent a0b92dd commit 6afbd81

File tree

11 files changed

+1398
-68
lines changed

11 files changed

+1398
-68
lines changed

hal/inc/hal_platform.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,10 @@
434434
#define HAL_PLATFORM_NCP_COUNT (0)
435435
#endif // HAL_PLATFORM_NCP_COUNT
436436

437+
#ifndef HAL_PLATFORM_NCP_FW_UPDATE
438+
#define HAL_PLATFORM_NCP_FW_UPDATE (0)
439+
#endif // HAL_PLATFORM_NCP_FW_UPDATE
440+
437441
#ifndef HAL_PLATFORM_WIFI_COMPAT
438442
#define HAL_PLATFORM_WIFI_COMPAT (0)
439443
#endif // HAL_PLATFORM_WIFI_COMPAT

services/inc/diagnostics.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#define DIAG_NAME_NETWORK_CELLULAR_CELL_GLOBAL_IDENTITY_MOBILE_NETWORK_CODE "net:cell:cgi:mnc"
4949
#define DIAG_NAME_NETWORK_CELLULAR_CELL_GLOBAL_IDENTITY_LOCATION_AREA_CODE "net:cell:cgi:lac"
5050
#define DIAG_NAME_NETWORK_CELLULAR_CELL_GLOBAL_IDENTITY_CELL_ID "net:cell:cgi:ci"
51+
#define DIAG_NAME_NETWORK_NCP_FW_UPDATE_STATUS "net:ncpfw:stat"
5152
#define DIAG_NAME_CLOUD_CONNECTION_STATUS "cloud:stat"
5253
#define DIAG_NAME_CLOUD_CONNECTION_ERROR_CODE "cloud:err"
5354
#define DIAG_NAME_CLOUD_DISCONNECTS "cloud:dconn"
@@ -95,6 +96,7 @@ typedef enum diag_id {
9596
DIAG_ID_NETWORK_CELLULAR_CELL_GLOBAL_IDENTITY_MOBILE_NETWORK_CODE = 41, // net:cell:cgi:mnc
9697
DIAG_ID_NETWORK_CELLULAR_CELL_GLOBAL_IDENTITY_LOCATION_AREA_CODE = 42, // net:cell:cgi:lac
9798
DIAG_ID_NETWORK_CELLULAR_CELL_GLOBAL_IDENTITY_CELL_ID = 43, // net:cell:cgi:ci
99+
DIAG_ID_NETWORK_NCP_FW_UPDATE_STATUS = 50, // net:nfu:stat
98100
DIAG_ID_CLOUD_CONNECTION_STATUS = 10, // cloud:stat
99101
DIAG_ID_CLOUD_CONNECTION_ERROR_CODE = 13, // cloud:err
100102
DIAG_ID_CLOUD_DISCONNECTS = 14, // cloud:dconn

services/inc/ncp_fw_update.h

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
/*
2+
* Copyright (c) 2021 Particle Industries, Inc. All rights reserved.
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation, either
7+
* version 3 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#pragma once
19+
20+
#include "hal_platform.h"
21+
#include "system_tick_hal.h"
22+
#include "core_hal.h"
23+
#include "system_defs.h"
24+
#include "system_mode.h"
25+
#include "system_network.h"
26+
#include "cellular_hal.h"
27+
#include "platform_ncp.h"
28+
#include "diagnostics.h"
29+
#include "spark_wiring_diagnostics.h"
30+
#include "ncp_fw_update_dynalib.h"
31+
32+
#if HAL_PLATFORM_NCP
33+
#include "at_parser.h"
34+
#include "at_response.h"
35+
#endif // HAL_PLATFORM_NCP
36+
37+
#if HAL_PLATFORM_NCP_FW_UPDATE
38+
39+
struct NcpFwUpdateCallbacks {
40+
uint16_t size;
41+
uint16_t reserved;
42+
43+
// System.updatesEnabled() / system_update.h
44+
int (*system_get_flag)(system_flag_t flag, uint8_t* value, void*);
45+
46+
// system_cloud.h
47+
bool (*spark_cloud_flag_connected)(void);
48+
void (*spark_cloud_flag_connect)(void);
49+
void (*spark_cloud_flag_disconnect)(void);
50+
51+
// system_cloud_internal.h
52+
bool (*publishEvent)(const char* event, const char* data, unsigned flags);
53+
54+
// system_mode.h
55+
System_Mode_TypeDef (*system_mode)(void);
56+
};
57+
PARTICLE_STATIC_ASSERT(NcpFwUpdateCallbacks_size, sizeof(NcpFwUpdateCallbacks) == (sizeof(void*) * 7));
58+
59+
namespace particle {
60+
61+
namespace services {
62+
63+
const system_tick_t NCP_FW_MODEM_POWER_ON_TIMEOUT = 60000;
64+
const system_tick_t NCP_FW_MODEM_INSTALL_START_TIMEOUT = 5 * 60000;
65+
const system_tick_t NCP_FW_MODEM_INSTALL_FINISH_TIMEOUT = 30 * 60000;
66+
const system_tick_t NCP_FW_MODEM_CLOUD_CONNECT_TIMEOUT = 5 * 60000;
67+
const uint32_t NCP_FW_UBLOX_R510_ENG_VERSION = 100000000;
68+
const int NCP_FW_UUFWINSTALL_COMPLETE = 128;
69+
70+
enum NcpFwUpdateState {
71+
FW_UPDATE_IDLE_STATE = 0,
72+
FW_UPDATE_QUALIFY_FLAGS_STATE = 1,
73+
FW_UPDATE_QUALIFY_MODEM_ON_STATE = 2,
74+
FW_UPDATE_QUALIFY_RETRY_STATE = 3,
75+
FW_UPDATE_SETUP_CLOUD_CONNECT_STATE = 4,
76+
FW_UPDATE_SETUP_CLOUD_CONNECTING_STATE = 5,
77+
FW_UPDATE_SETUP_CLOUD_CONNECTED_STATE = 6,
78+
FW_UPDATE_DOWNLOAD_CLOUD_DISCONNECT_STATE = 7,
79+
FW_UPDATE_DOWNLOAD_CELL_DISCONNECTING_STATE = 8,
80+
FW_UPDATE_DOWNLOAD_CELL_CONNECTING_STATE = 9,
81+
FW_UPDATE_DOWNLOAD_HTTPS_SETUP_STATE = 10,
82+
FW_UPDATE_DOWNLOAD_READY_STATE = 11,
83+
FW_UPDATE_INSTALL_CELL_DISCONNECTING_STATE = 12,
84+
FW_UPDATE_INSTALL_CELL_DISCONNECTED_STATE = 13,
85+
FW_UPDATE_INSTALL_STATE_STARTING = 14,
86+
FW_UPDATE_INSTALL_STATE_WAITING = 15,
87+
FW_UPDATE_FINISHED_POWER_OFF_STATE = 16,
88+
FW_UPDATE_FINISHED_POWERING_OFF_STATE = 17,
89+
FW_UPDATE_FINISHED_CLOUD_CONNECTING_STATE = 18,
90+
FW_UPDATE_FINISHED_CLOUD_CONNECTED_STATE = 19,
91+
FW_UPDATE_FINISHED_IDLE_STATE = 20,
92+
};
93+
94+
enum NcpFwUpdateStatus {
95+
FW_UPDATE_IDLE_STATUS = 0,
96+
FW_UPDATE_DOWNLOADING_STATUS = 1,
97+
FW_UPDATE_UPDATING_STATUS = 2,
98+
FW_UPDATE_SUCCESS_STATUS = 3,
99+
FW_UPDATE_NONE_STATUS = -1, // for diagnostics
100+
FW_UPDATE_FAILED_STATUS = -2,
101+
FW_UPDATE_FAILED_DOWNLOAD_RETRY_MAX_STATUS = -3,
102+
FW_UPDATE_FAILED_START_INSTALL_TIMEOUT_STATUS = -4,
103+
FW_UPDATE_FAILED_INSTALL_AT_ERROR_STATUS = -5,
104+
FW_UPDATE_FAILED_SAME_VERSION_STATUS = -6,
105+
FW_UPDATE_FAILED_INSTALL_TIMEOUT_STATUS = -7,
106+
FW_UPDATE_FAILED_POWER_OFF_TIMEOUT_STATUS = -8,
107+
FW_UPDATE_FAILED_CLOUD_CONNECT_TIMEOUT_STATUS = -9,
108+
FW_UPDATE_FAILED_PUBLISH_RESULT_STATUS = -10,
109+
};
110+
111+
struct HTTPSresponse {
112+
int command;
113+
int result;
114+
int status_code;
115+
char md5_sum[40];
116+
int err_class;
117+
int err_code;
118+
};
119+
120+
const int NCP_FW_DATA_HEADER = 0x5259ADE5;
121+
const int NCP_FW_DATA_FOOTER = 0x1337ACE5;
122+
struct NcpFwUpdateData {
123+
uint32_t header; // NCP_FW_DATA_HEADER;
124+
NcpFwUpdateState state; // FW_UPDATE_IDLE_STATE;
125+
NcpFwUpdateStatus status; // FW_UPDATE_IDLE_STATUS;
126+
int firmwareVersion; // 0;
127+
int startingFirmwareVersion; // 0;
128+
int updateVersion; // 0;
129+
uint8_t isUserConfig; // 0;
130+
NcpFwUpdateConfig userConfigData; // 0;
131+
uint32_t footer; // NCP_FW_DATA_FOOTER;
132+
};
133+
134+
/**
135+
* struct NcpFwUpdateConfig {
136+
* const uint32_t start_version;
137+
* const uint32_t end_version;
138+
* const char filename[256];
139+
* const char md5sum[32];
140+
* };
141+
*/
142+
const NcpFwUpdateConfig NCP_FW_UPDATE_CONFIG[] = {
143+
// { 3140001, 103140001, "SARA-R510S-01B-00-ES-0314A0001_SARA-R510S-01B-00-XX-0314ENG0099A0001.upd", "09c1a98d03c761bcbea50355f9b2a50f" },
144+
// { 103140001, 3140001, "SARA-R510S-01B-00-XX-0314ENG0099A0001_SARA-R510S-01B-00-ES-0314A0001.upd", "136caf2883457093c9e41fda3c6a44e3" },
145+
// { 2060001, 99010001, "SARA-R510S-00B-01_FW02.06_A00.01_IP_SARA-R510S-00B-01_FW99.01_A00.01.upd", "ccfdc48c0a45198d6e168b30d0740959" },
146+
// { 99010001, 2060001, "SARA-R510S-00B-01_FW99.01_A00.01_SARA-R510S-00B-01_FW02.06_A00.01_IP.upd", "5fd6c0d3d731c097605895b86f28c2cf" },
147+
};
148+
149+
const size_t NCP_FW_UPDATE_CONFIG_SIZE = sizeof(NCP_FW_UPDATE_CONFIG) / sizeof(NCP_FW_UPDATE_CONFIG[0]);
150+
151+
class NcpFwUpdate {
152+
public:
153+
/**
154+
* Get the singleton instance of this class.
155+
*/
156+
static NcpFwUpdate* instance();
157+
158+
NcpFwUpdate();
159+
~NcpFwUpdate();
160+
161+
int checkUpdate(const NcpFwUpdateConfig* userConfigData);
162+
void init(NcpFwUpdateCallbacks* callbacks);
163+
int process();
164+
int getStatusDiagnostics();
165+
166+
private:
167+
168+
NcpFwUpdateState ncpFwUpdateState_;
169+
NcpFwUpdateStatus ncpFwUpdateStatus_;
170+
NcpFwUpdateStatus ncpFwUpdateStatusDiagnostics_;
171+
int foatReady_;
172+
system_tick_t startInstallTimer_;
173+
system_tick_t atOkCheckTimer_;
174+
int lastRespCode_;
175+
int atResp_;
176+
int atResponsive_;
177+
int startingFirmwareVersion_;
178+
int firmwareVersion_;
179+
int updateVersion_;
180+
bool isUserConfig_;
181+
system_tick_t cooldownTimer_;
182+
system_tick_t cooldownTimeout_;
183+
bool initialized_;
184+
185+
union {
186+
NcpFwUpdateData var;
187+
uint8_t data[sizeof(NcpFwUpdateData)];
188+
} ncpFwUpdateData_;
189+
190+
/**
191+
* Functional callbacks that provide key system services to this NCP FW Update class.
192+
*/
193+
NcpFwUpdateCallbacks* ncpFwUpdateCallbacks_;
194+
195+
static int cbUUHTTPCR_(int type, const char* buf, int len, HTTPSresponse* data);
196+
static int cbUHTTPER_(int type, const char* buf, int len, HTTPSresponse* data);
197+
static int cbULSTFILE_(int type, const char* buf, int len, int* data);
198+
static int cbATI9_(int type, const char* buf, int len, int* val);
199+
static int cbUPSND_(int type, const char* buf, int len, int* data);
200+
static int cbCOPS_(int type, const char* buf, int len, int* data);
201+
static int httpRespCallback_(AtResponseReader* reader, const char* prefix, void* data);
202+
int getAppFirmwareVersion_();
203+
int setupHTTPSProperties_();
204+
void cooldown_(system_tick_t timer);
205+
void updateCooldown_();
206+
bool inCooldown_();
207+
void validateNcpFwUpdateData_();
208+
int firmwareUpdateForVersion_(const int version);
209+
int saveNcpFwUpdateData_();
210+
int recallNcpFwUpdateData_();
211+
int deleteNcpFwUpdateData_();
212+
};
213+
214+
class NcpFwUpdateDiagnostics: public AbstractUnsignedIntegerDiagnosticData {
215+
public:
216+
NcpFwUpdateDiagnostics() :
217+
AbstractUnsignedIntegerDiagnosticData(DIAG_ID_NETWORK_NCP_FW_UPDATE_STATUS, DIAG_NAME_NETWORK_NCP_FW_UPDATE_STATUS) {
218+
}
219+
220+
virtual int get(IntType& val) override {
221+
val = particle::services::NcpFwUpdate::instance()->getStatusDiagnostics();
222+
return 0; // OK
223+
}
224+
};
225+
226+
} // namespace services
227+
228+
} // namespace particle
229+
230+
#endif // #if HAL_PLATFORM_NCP_FW_UPDATE
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2021 Particle Industries, Inc. All rights reserved.
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation, either
7+
* version 3 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#pragma once
19+
20+
#ifdef __cplusplus
21+
struct NcpFwUpdateConfig {
22+
int start_version;
23+
int end_version;
24+
char filename[255 + 1];
25+
char md5sum[32 + 1];
26+
};
27+
#else
28+
typedef struct NcpFwUpdateConfig NcpFwUpdateConfig;
29+
#endif
30+
31+
#ifdef __cplusplus
32+
extern "C" {
33+
#endif
34+
35+
#if !defined(PARTICLE_USER_MODULE) || defined(PARTICLE_USE_UNSTABLE_API)
36+
int ncp_fw_udpate_check(const NcpFwUpdateConfig* data, void* reserved);
37+
#endif // !defined(PARTICLE_USER_MODULE) || defined(PARTICLE_USE_UNSTABLE_API)
38+
39+
#ifdef __cplusplus
40+
}
41+
#endif

services/inc/services_dynalib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#ifdef DYNALIB_EXPORT
2929
#include "nanopb_misc.h"
3030
#include <stdint.h>
31+
#include "ncp_fw_update_dynalib.h"
3132
#ifdef PB_WITHOUT_64BIT
3233
#define pb_int64_t int32_t
3334
#define pb_uint64_t uint32_t
@@ -114,6 +115,7 @@ DYNALIB_FN(BASE_IDX + 0, services, set_system_error_message, void(const char*, .
114115
DYNALIB_FN(BASE_IDX + 1, services, clear_system_error_message, void())
115116
DYNALIB_FN(BASE_IDX + 2, services, get_system_error_message, const char*(int))
116117
DYNALIB_FN(BASE_IDX + 3, services, jsmn_parse, int(jsmn_parser*, const char*, size_t, jsmntok_t*, unsigned int, void*))
118+
DYNALIB_FN(BASE_IDX + 4, services, ncp_fw_udpate_check, int(const NcpFwUpdateConfig*, void*))
117119

118120
DYNALIB_END(services)
119121

services/inc/system_cache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ namespace particle { namespace services {
2323

2424
enum class SystemCacheKey : uint16_t {
2525
WIFI_NCP_FIRMWARE_VERSION = 0x0000,
26-
WIFI_NCP_MAC_ADDRESS = 0x0001
26+
WIFI_NCP_MAC_ADDRESS = 0x0001,
27+
NCP_FW_UPDATE_DATA = 0x0002,
2728
};
2829

2930
class SystemCache {

services/inc/system_defs.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,71 @@ typedef enum network_disconnect_reason {
9494
NETWORK_DISCONNECT_REASON_UNKNOWN = 7 ///< Unspecified disconnection reason.
9595
} network_disconnect_reason;
9696

97+
typedef enum system_flag_t {
98+
/**
99+
* When 0, no OTA update is pending.
100+
* When 1, an OTA update is pending, and will start when the SYSTEM_FLAG_OTA_UPDATES_FLAG
101+
* is set.
102+
*/
103+
SYSTEM_FLAG_OTA_UPDATE_PENDING,
104+
105+
/**
106+
* When 0, OTA updates are not started.
107+
* When 1, OTA updates are started. Default.
108+
*/
109+
SYSTEM_FLAG_OTA_UPDATE_ENABLED,
110+
111+
/*
112+
* When 0, no reset is pending.
113+
* When 1, a reset is pending. The system will perform the reset
114+
* when SYSTEM_FLAG_RESET_ENABLED is set to 1.
115+
*/
116+
SYSTEM_FLAG_RESET_PENDING,
117+
118+
/**
119+
* When 0, the system is not able to perform a system reset.
120+
* When 1, thee system will reset the device when a reset is pending.
121+
*/
122+
SYSTEM_FLAG_RESET_ENABLED,
123+
124+
/**
125+
* A persistent flag that when set will cause the system to startup
126+
* in listening mode. The flag is automatically cleared on reboot.
127+
*/
128+
SYSTEM_FLAG_STARTUP_LISTEN_MODE,
129+
130+
/**
131+
* Enable/Disable use of serial1 during setup.
132+
*/
133+
SYSTEM_FLAG_WIFITESTER_OVER_SERIAL1,
134+
135+
/**
136+
* Enable/disable publishing of last reset info to the cloud.
137+
*/
138+
SYSTEM_FLAG_PUBLISH_RESET_INFO,
139+
140+
/**
141+
* When 0, the system doesn't reset network connection on cloud connection errors.
142+
* When 1 (default), the system resets network connection after a number of failed attempts to
143+
* connect to the cloud.
144+
*/
145+
SYSTEM_FLAG_RESET_NETWORK_ON_CLOUD_ERRORS,
146+
147+
/**
148+
* Enable/Disable runtime power management peripheral detection
149+
*/
150+
SYSTEM_FLAG_PM_DETECTION,
151+
152+
/**
153+
* When 0, OTA updates are only applied when SYSTEM_FLAG_OTA_UPDATE_ENABLED is set.
154+
* When 1, OTA updates are applied irrespective of the value of SYSTEM_FLAG_OTA_UPDATE_ENABLED.
155+
*/
156+
SYSTEM_FLAG_OTA_UPDATE_FORCED,
157+
158+
SYSTEM_FLAG_MAX
159+
160+
} system_flag_t;
161+
97162
#ifdef __cplusplus
98163

99164
#include "enumflags.h"

0 commit comments

Comments
 (0)