Skip to content

Commit 7c503f2

Browse files
committed
drivers: modem: hl78xx: Add AirVantage FOTA support
Sierra Wireless AirVantage FOTA updates in the HL78xx modem driver. Signed-off-by: Zafer SEN <[email protected]>
1 parent a306725 commit 7c503f2

File tree

8 files changed

+502
-6
lines changed

8 files changed

+502
-6
lines changed

drivers/modem/hl78xx/Kconfig.hl78xx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,59 @@ config MODEM_MIN_ALLOWED_SIGNAL_STRENGTH
722722
default -140
723723
range - 140 0
724724

725+
config MODEM_HL78XX_AIRVANTAGE
726+
bool "AirVantage"
727+
help
728+
Enable HL78xx modules connect to the AirVantage DM Server over OMA
729+
730+
if MODEM_HL78XX_AIRVANTAGE
731+
732+
choice MODEM_HL78XX_AIRVANTAGE_SESSION_INITIATION
733+
prompt "AirVantage Initialization"
734+
default MODEM_HL78XX_AIRVANTAGE_HOST_INITIATED
735+
help
736+
Choose this setting to enable HL78xx modules to connect to the AirVantage DM Server.
737+
738+
config MODEM_HL78XX_AIRVANTAGE_HOST_INITIATED
739+
bool "Host Initiated"
740+
help
741+
The host application is responsible for initiating the connection to the AirVantage server.
742+
743+
config MODEM_HL78XX_AIRVANTAGE_MODULE_INITIATED
744+
bool "Module Initiated"
745+
help
746+
The HL78xx module is responsible for initiating the connection to the AirVantage server.
747+
748+
endchoice
749+
750+
menuconfig MODEM_HL78XX_AIRVANTAGE_USER_AGREEMENT
751+
bool "User Agreement Activation"
752+
help
753+
Activating User Agreements enables the host processor application to control the FOTA flow. For instance, the host
754+
processor application, busy fulfilling a service (e.g. car is operating, ongoing payment transaction), can decide to
755+
postpone firmware download or install operations, as accepting a firmware installation will lead the embedded
756+
module to reboot upon FOTA completion.
757+
758+
if MODEM_HL78XX_AIRVANTAGE_USER_AGREEMENT
759+
760+
config MODEM_HL78XX_AIRVANTAGE_UA_CONNECT_AIRVANTAGE
761+
bool "Connect to AirVantage"
762+
help
763+
Module requests the user/application to connect to AirVantage
764+
765+
config MODEM_HL78XX_AIRVANTAGE_UA_DOWNLOAD_FIRMWARE
766+
bool "Download Firmware"
767+
help
768+
AirVantage requests the device to download a firmware package
769+
770+
config MODEM_HL78XX_AIRVANTAGE_UA_INSTALL_FIRMWARE
771+
bool "Install Firmware"
772+
help
773+
AirVantage requests the device to install the downloaded firmware package
774+
775+
endif # MODEM_HL78XX_AIRVANTAGE_USER_AGREEMENT
776+
endif # MODEM_HL78XX_AIRVANTAGE
777+
725778
config MODEM_HL78XX_ADVANCED_SOCKET_CONFIG
726779
bool "Advanced socket configuration"
727780
help

drivers/modem/hl78xx/hl78xx.c

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ static const char *hl78xx_state_str(enum hl78xx_state state)
108108
return "await registered";
109109
case MODEM_HL78XX_STATE_CARRIER_ON:
110110
return "carrier on";
111+
case MODEM_HL78XX_STATE_FOTA:
112+
return "fota";
111113
case MODEM_HL78XX_STATE_CARRIER_OFF:
112114
return "carrier off";
113115
case MODEM_HL78XX_STATE_SIM_POWER_OFF:
@@ -152,6 +154,28 @@ static const char *hl78xx_event_str(enum hl78xx_event event)
152154
return "bus closed";
153155
case MODEM_HL78XX_EVENT_SOCKET_READY:
154156
return "socket ready";
157+
#ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE
158+
case MODEM_HL78XX_EVENT_WDSI_UPDATE:
159+
return "wdsi update";
160+
case MODEM_HL78XX_EVENT_WDSI_RESTART:
161+
return "wdsi restart";
162+
case MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_REQUEST:
163+
return "wdsi download request";
164+
case MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_PROGRESS:
165+
return "wdsi download progress";
166+
case MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_COMPLETE:
167+
return "wdsi download complete";
168+
case MODEM_HL78XX_EVENT_WDSI_INSTALL_REQUEST:
169+
return "wdsi install request";
170+
case MODEM_HL78XX_EVENT_WDSI_INSTALLING_FIRMWARE:
171+
return "wdsi installing firmware";
172+
case MODEM_HL78XX_EVENT_WDSI_FIRMWARE_INSTALL_SUCCEEDED:
173+
return "wdsi firmware install succeeded";
174+
case MODEM_HL78XX_EVENT_WDSI_FIRMWARE_INSTALL_FAILED:
175+
return "wdsi firmware install failed";
176+
#endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */
177+
case MODEM_HL78XX_EVENT_MDM_RESTART:
178+
return "modem unexpected restart";
155179
default:
156180
return "unknown event";
157181
}
@@ -451,6 +475,20 @@ void hl78xx_on_cgmr(struct modem_chat *chat, char **argv, uint16_t argc, void *u
451475
k_mutex_unlock(&data->api_lock);
452476
}
453477

478+
void hl78xx_on_serial_number(struct modem_chat *chat, char **argv, uint16_t argc, void *user_data)
479+
{
480+
struct hl78xx_data *data = (struct hl78xx_data *)user_data;
481+
482+
if (argc != 2) {
483+
return;
484+
}
485+
HL78XX_LOG_DBG("Serial Number: %s %s", argv[0], argv[1]);
486+
k_mutex_lock(&data->api_lock, K_FOREVER);
487+
safe_strncpy((char *)data->identity.serial_number, argv[1],
488+
sizeof(data->identity.serial_number));
489+
k_mutex_unlock(&data->api_lock);
490+
}
491+
454492
void hl78xx_on_iccid(struct modem_chat *chat, char **argv, uint16_t argc, void *user_data)
455493
{
456494
struct hl78xx_data *data = (struct hl78xx_data *)user_data;
@@ -627,6 +665,60 @@ void hl78xx_on_cops(struct modem_chat *chat, char **argv, uint16_t argc, void *u
627665
data->status.network_operator.format = ATOI(argv[2], 0, "network_operator_format");
628666
}
629667

668+
#ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE
669+
670+
void hl78xx_on_wdsi(struct modem_chat *chat, char **argv, uint16_t argc, void *user_data)
671+
{
672+
struct hl78xx_data *data = (struct hl78xx_data *)user_data;
673+
struct hl78xx_evt event = {.type = HL78XX_LTE_FOTA_UPDATE_STATUS};
674+
int wsi_status = -1;
675+
uint32_t wsi_data = 0;
676+
677+
if (argc < 2) {
678+
return;
679+
}
680+
wsi_status = ATOI(argv[1], -1, "wdsi");
681+
if (wsi_status == -1) {
682+
return;
683+
}
684+
data->status.wdsi.level = wsi_status;
685+
if (argc == 3) {
686+
wsi_data = ATOI(argv[2], 0, "data");
687+
data->status.wdsi.data = wsi_data;
688+
}
689+
if (data->status.wdsi.level == WDSI_FIRMWARE_AVAILABLE) {
690+
data->status.wdsi.fota_size = wsi_data;
691+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_UPDATE);
692+
} else if (data->status.wdsi.level == WDSI_BOOTSTRAP_CREDENTIALS_PRESENT) {
693+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_RESTART);
694+
} else if (data->status.wdsi.level == WDSI_FIRMWARE_DOWNLOAD_REQUEST) {
695+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_REQUEST);
696+
} else if (data->status.wdsi.level == WDSI_DOWNLOAD_IN_PROGRESS) {
697+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_PROGRESS);
698+
data->status.wdsi.progress = wsi_data;
699+
} else if (data->status.wdsi.level == WDSI_FIRMWARE_DOWNLOADED) {
700+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_COMPLETE);
701+
} else if (data->status.wdsi.level == WDSI_FIRMWARE_INSTALL_REQUEST) {
702+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_INSTALL_REQUEST);
703+
} else if (data->status.wdsi.level == WDSI_FIRMWARE_UPDATE_START) {
704+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_INSTALLING_FIRMWARE);
705+
} else if (data->status.wdsi.level == WDSI_FIRMWARE_UPDATE_SUCCESS) {
706+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_FIRMWARE_INSTALL_SUCCEEDED);
707+
} else if (data->status.wdsi.level == WDSI_FIRMWARE_UPDATE_FAILED) {
708+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_FIRMWARE_INSTALL_FAILED);
709+
} else {
710+
/* other WDSI levels during FOTA can be handled here if needed */
711+
}
712+
if ((data->status.wdsi.level == WDSI_DOWNLOAD_IN_PROGRESS &&
713+
(data->status.wdsi.progress == 0 || data->status.wdsi.progress == 100)) ||
714+
data->status.wdsi.level != WDSI_DOWNLOAD_IN_PROGRESS) {
715+
event.content.wdsi_indication = data->status.wdsi.level;
716+
event_dispatcher_dispatch(&event);
717+
}
718+
HL78XX_LOG_DBG("WDSI: %d %d", wsi_status, wsi_data);
719+
}
720+
721+
#endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */
630722
/* -------------------------------------------------------------------------
631723
* Pipe & chat initialization
632724
* - modem backend pipe setup and chat initialisation helpers
@@ -1273,6 +1365,15 @@ static void hl78xx_carrier_on_event_handler(struct hl78xx_data *data, enum hl78x
12731365
LOG_DBG("Modem restart detected %d", __LINE__);
12741366
hl78xx_enter_state(data, MODEM_HL78XX_STATE_RUN_INIT_SCRIPT);
12751367
break;
1368+
#ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE
1369+
case MODEM_HL78XX_EVENT_WDSI_UPDATE:
1370+
case MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_REQUEST:
1371+
case MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_PROGRESS:
1372+
case MODEM_HL78XX_EVENT_WDSI_INSTALL_REQUEST:
1373+
hl78xx_enter_state(data, MODEM_HL78XX_STATE_FOTA);
1374+
data->status.wdsi.in_progress = true;
1375+
break;
1376+
#endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */
12761377
default:
12771378
break;
12781379
}
@@ -1284,6 +1385,120 @@ static int hl78xx_on_carrier_on_state_leave(struct hl78xx_data *data)
12841385
return 0;
12851386
}
12861387

1388+
#ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE
1389+
1390+
static int hl78xx_on_fota_state_enter(struct hl78xx_data *data)
1391+
{
1392+
HL78XX_LOG_DBG("Entering FOTA state");
1393+
hl78xx_start_timer(data, K_MSEC(100));
1394+
/* Decide best time to start FOTA */
1395+
return 0;
1396+
}
1397+
1398+
static void hl78xx_fota_event_handler(struct hl78xx_data *data, enum hl78xx_event evt)
1399+
{
1400+
switch (evt) {
1401+
case MODEM_HL78XX_EVENT_TIMEOUT:
1402+
/* Start FOTA process */
1403+
if (data->status.wdsi.in_progress == true) {
1404+
if (data->status.wdsi.level == WDSI_FIRMWARE_DOWNLOAD_REQUEST &&
1405+
data->status.wdsi.fota_state != HL78XX_WDSI_FOTA_DOWNLOADING) {
1406+
LOG_INF("FOTA available, notifying modem...");
1407+
hl78xx_delegate_event(data,
1408+
MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_REQUEST);
1409+
} else if (data->status.wdsi.level == WDSI_FIRMWARE_INSTALL_REQUEST &&
1410+
data->status.wdsi.fota_state != HL78XX_WDSI_FOTA_INSTALLING) {
1411+
LOG_INF("FOTA downloaded, notifying modem...");
1412+
hl78xx_delegate_event(data,
1413+
MODEM_HL78XX_EVENT_WDSI_INSTALL_REQUEST);
1414+
} else {
1415+
HL78XX_LOG_DBG("FOTA in progress, notifying modem...");
1416+
hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_WDSI_UPDATE);
1417+
}
1418+
}
1419+
break;
1420+
case MODEM_HL78XX_EVENT_SCRIPT_SUCCESS:
1421+
HL78XX_LOG_DBG("FOTA script completed successfully.");
1422+
break;
1423+
case MODEM_HL78XX_EVENT_WDSI_UPDATE:
1424+
if (data->status.wdsi.level == WDSI_DM_SESSION_CLOSED) {
1425+
LOG_INF("FOTA DM session closed.");
1426+
if (data->status.wdsi.in_progress == true) {
1427+
LOG_INF("FOTA update process completed, rebooting modem...");
1428+
} else {
1429+
LOG_INF("FOTA update process not started, returning to "
1430+
"carrier on state...");
1431+
}
1432+
break;
1433+
}
1434+
break;
1435+
case MODEM_HL78XX_EVENT_WDSI_RESTART:
1436+
LOG_INF("FOTA modem restart occurred...%d", data->status.boot.is_booted_previously);
1437+
break;
1438+
case MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_REQUEST:
1439+
if (data->status.wdsi.fota_state == HL78XX_WDSI_FOTA_DOWNLOADING) {
1440+
return;
1441+
}
1442+
LOG_INF("FOTA download requested File size %d bytes, starting download...",
1443+
data->status.wdsi.fota_size);
1444+
data->status.wdsi.fota_state = HL78XX_WDSI_FOTA_DOWNLOADING;
1445+
hl78xx_run_fota_script_download_accept_async(data);
1446+
break;
1447+
case MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_PROGRESS:
1448+
LOG_INF("FOTA update in progress, completion... %d%%", data->status.wdsi.progress);
1449+
break;
1450+
case MODEM_HL78XX_EVENT_WDSI_DOWNLOAD_COMPLETE:
1451+
LOG_INF("FOTA download completed...");
1452+
data->status.wdsi.fota_state = HL78XX_WDSI_FOTA_DOWNLOAD_COMPLETED;
1453+
break;
1454+
case MODEM_HL78XX_EVENT_WDSI_INSTALL_REQUEST:
1455+
LOG_INF("FOTA install request received...");
1456+
data->status.wdsi.fota_state = HL78XX_WDSI_FOTA_INSTALLING;
1457+
hl78xx_run_fota_script_install_accept_async(data);
1458+
break;
1459+
case MODEM_HL78XX_EVENT_WDSI_INSTALLING_FIRMWARE:
1460+
LOG_INF("Install accepted, FOTA update installing...");
1461+
LOG_INF("This may take several minutes, please wait...");
1462+
LOG_INF("Do not power off the modem!!!");
1463+
break;
1464+
case MODEM_HL78XX_EVENT_WDSI_FIRMWARE_INSTALL_SUCCEEDED:
1465+
LOG_INF("FOTA firmware install succeeded...Waiting for modem +KSUP");
1466+
data->status.wdsi.fota_state = HL78XX_WDSI_FOTA_INSTALL_COMPLETED;
1467+
data->status.wdsi.in_progress = false;
1468+
data->status.wdsi.progress = 0;
1469+
break;
1470+
case MODEM_HL78XX_EVENT_WDSI_FIRMWARE_INSTALL_FAILED:
1471+
LOG_INF("FOTA firmware install failed...");
1472+
data->status.wdsi.in_progress = false;
1473+
data->status.wdsi.progress = 0;
1474+
/* TODO: fail, do something */
1475+
break;
1476+
case MODEM_HL78XX_EVENT_MDM_RESTART:
1477+
if (data->status.wdsi.in_progress == true) {
1478+
/* FOTA update in progress, waiting for it to complete */
1479+
data->status.wdsi.fota_state = HL78XX_WDSI_FOTA_IDLE;
1480+
} else {
1481+
LOG_INF("Exiting FOTA state, re-initializing modem...");
1482+
hl78xx_enter_state(data, MODEM_HL78XX_STATE_RUN_INIT_SCRIPT);
1483+
}
1484+
break;
1485+
case MODEM_HL78XX_EVENT_REGISTERED:
1486+
/* stay in FOTA state */
1487+
hl78xx_start_timer(data, K_MSEC(100));
1488+
break;
1489+
default:
1490+
break;
1491+
}
1492+
}
1493+
1494+
static int hl78xx_on_fota_state_leave(struct hl78xx_data *data)
1495+
{
1496+
HL78XX_LOG_DBG("Exiting FOTA state");
1497+
hl78xx_stop_timer(data);
1498+
return 0;
1499+
}
1500+
1501+
#endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */
12871502
static int hl78xx_on_carrier_off_state_enter(struct hl78xx_data *data)
12881503
{
12891504
notif_carrier_off(data->dev);
@@ -1823,6 +2038,13 @@ const static struct hl78xx_state_handlers hl78xx_state_table[] = {
18232038
hl78xx_on_carrier_on_state_leave,
18242039
hl78xx_carrier_on_event_handler
18252040
},
2041+
#ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE
2042+
[MODEM_HL78XX_STATE_FOTA] = {
2043+
hl78xx_on_fota_state_enter,
2044+
hl78xx_on_fota_state_leave,
2045+
hl78xx_fota_event_handler
2046+
},
2047+
#endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */
18262048
[MODEM_HL78XX_STATE_CARRIER_OFF] = {
18272049
hl78xx_on_carrier_off_state_enter,
18282050
hl78xx_on_carrier_off_state_leave,

0 commit comments

Comments
 (0)