Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,15 @@ config SM_NRF_CLOUD
default y
select EXPERIMENTAL

if SM_NRF_CLOUD
config HEAP_MEM_POOL_ADD_SIZE_SM_NRF_CLOUD
int "Additional heap memory pool size for nRF Cloud support"
default 8192
help
Some libraries used by nRF Cloud use System Heap (k_malloc() / k_free()) for
dynamic memory allocation.
endif # SM_NRF_CLOUD

config SM_MQTTC
bool "MQTT client support"
default y
Expand All @@ -269,6 +278,15 @@ config SM_PPP
config SM_CMUX
bool "CMUX support"

config SM_CMUX_CHANNEL_COUNT
int "Number of CMUX channels"
depends on SM_CMUX
default 2
range 1 63
help
Number of channels to be used by the CMUX implementation.
Each channel adds about 4 kB of RAM usage for buffers.

if SM_PPP

config SM_PPP_FALLBACK_MTU
Expand Down Expand Up @@ -333,7 +351,7 @@ choice NRF_MODEM_LIB_TRACE_BACKEND

config SM_MODEM_TRACE_BACKEND_CMUX
bool "CMUX modem trace backend"
depends on SM_CMUX
depends on SM_CMUX_CHANNEL_COUNT > 2
help
When CMUX is enabled, modem traces are transmitted on a dedicated CMUX channel.
The trace channel is the first channel after the AT command channel and the PPP channel.
Expand Down
1 change: 1 addition & 0 deletions app/overlay-trace-backend-cmux.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
# CMUX modem trace backend
CONFIG_NRF_MODEM_LIB_TRACE=y
CONFIG_SM_MODEM_TRACE_BACKEND_CMUX=y
CONFIG_SM_CMUX_CHANNEL_COUNT=3
8 changes: 7 additions & 1 deletion app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ CONFIG_NET_IPV6=y
CONFIG_NRF_MODEM_LIB=y
CONFIG_AT_CMD_CUSTOM=y

# Modem pipe
CONFIG_MODEM_MODULES=y
CONFIG_MODEM_PIPE=y
CONFIG_MODEM_CMUX=y

# Handle modem fault
CONFIG_NRF_MODEM_LIB_ON_FAULT_APPLICATION_SPECIFIC=y

Expand All @@ -55,9 +60,10 @@ CONFIG_UART_INTERRUPT_DRIVEN=n

# Stacks and heaps
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_AT_MONITOR_HEAP_SIZE=4096
CONFIG_COMMON_LIBC_MALLOC=y
CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=-1

# Device power management
CONFIG_PM_DEVICE=y
Expand Down
1 change: 1 addition & 0 deletions app/scripts/sm_start_ppp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ noremoteip
defaultroute
defaultroute-metric -1
lcp-echo-interval 0
asyncmap 0xffffffff
$PPP_DEBUG
"

Expand Down
24 changes: 13 additions & 11 deletions app/src/lwm2m_carrier/sm_at_carrier.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ static void print_err(const lwm2m_carrier_event_t *evt)

LOG_ERR("LWM2M_CARRIER_EVENT_ERROR: %s, reason %d", strerr[err->type], err->value);

rsp_send("\r\n#XCARRIEREVT: %u,%u,%d\r\n",
LWM2M_CARRIER_EVENT_ERROR, err->type, err->value);
urc_send_to(sm_at_host_get_urc_pipe(), "\r\n#XCARRIEREVT: %u,%u,%d\r\n",
LWM2M_CARRIER_EVENT_ERROR, err->type, err->value);
}

static void print_deferred(const lwm2m_carrier_event_t *evt)
Expand Down Expand Up @@ -91,8 +91,8 @@ static void print_deferred(const lwm2m_carrier_event_t *evt)
LOG_INF("LWM2M_CARRIER_EVENT_DEFERRED: reason %s, timeout %d seconds",
strdef[def->reason], def->timeout);

rsp_send("\r\n#XCARRIEREVT: %u,%u,%d\r\n",
LWM2M_CARRIER_EVENT_DEFERRED, def->reason, def->timeout);
urc_send_to(sm_at_host_get_urc_pipe(), "\r\n#XCARRIEREVT: %u,%u,%d\r\n",
LWM2M_CARRIER_EVENT_DEFERRED, def->reason, def->timeout);
}

static void on_event_app_data(const lwm2m_carrier_event_t *event)
Expand Down Expand Up @@ -129,13 +129,15 @@ static void on_event_app_data(const lwm2m_carrier_event_t *event)
return;
}

rsp_send("\r\n#XCARRIEREVT: %u,%hhu,\"%s\",%zu\r\n\"", event->type, app_data->type,
uri_path, size);
data_send(sm_data_buf, size);
rsp_send("\"");
struct modem_pipe *pipe = sm_at_host_get_urc_pipe();

urc_send_to(pipe, "\r\n#XCARRIEREVT: %u,%hhu,\"%s\",%zu\r\n\"", event->type,
app_data->type, uri_path, size);
data_send(pipe, sm_data_buf, size);
urc_send_to(pipe, "\"");
} else {
rsp_send("\r\n#XCARRIEREVT: %u,%hhu,\"%s\"\r\n", event->type, app_data->type,
uri_path);
urc_send_to(sm_at_host_get_urc_pipe(), "\r\n#XCARRIEREVT: %u,%hhu,\"%s\"\r\n",
event->type, app_data->type, uri_path);
}
}

Expand Down Expand Up @@ -235,7 +237,7 @@ int lwm2m_carrier_event_handler(const lwm2m_carrier_event_t *event)
return 0;
}

rsp_send("\r\n#XCARRIEREVT: %d,%d\r\n", event->type, err);
urc_send_to(sm_at_host_get_urc_pipe(), "\r\n#XCARRIEREVT: %d,%d\r\n", event->type, err);

#if defined(CONFIG_SM_CARRIER_AUTO_CONTROL)
/* Allow time for the URC be flushed before reboot */
Expand Down
35 changes: 8 additions & 27 deletions app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ static struct nrf_modem_fault_info modem_fault_info;
static void on_modem_failure(struct k_work *)
{
int ret;
struct modem_pipe *pipe = sm_at_host_get_urc_pipe();

rsp_send("\r\n#XMODEM: FAULT,0x%x,0x%x\r\n", modem_fault_info.reason,
modem_fault_info.program_counter);
urc_send_to(pipe, "\r\n#XMODEM: FAULT,0x%x,0x%x\r\n", modem_fault_info.reason,
modem_fault_info.program_counter);

ret = nrf_modem_lib_shutdown();
rsp_send("\r\n#XMODEM: SHUTDOWN,%d\r\n", ret);
urc_send_to(pipe, "\r\n#XMODEM: SHUTDOWN,%d\r\n", ret);

ret = nrf_modem_lib_init();
rsp_send("\r\n#XMODEM: INIT,%d\r\n", ret);
urc_send_to(pipe, "\r\n#XMODEM: INIT,%d\r\n", ret);
}
K_WORK_DEFINE(modem_failure_work, on_modem_failure);

Expand Down Expand Up @@ -144,17 +145,7 @@ static int bootloader_mode_init(void)
}
LOG_INF("Bootloader mode initiated successfully");

ret = sm_at_host_bootloader_init();
if (ret) {
LOG_ERR("Failed to init at_host: %d", ret);
return ret;
}

ret = sm_at_send_str("Bootloader mode ready\r\n");
if (ret) {
LOG_ERR("Failed to send bootloader mode ready string: %d", ret);
return ret;
}
urc_send("Bootloader mode ready\r\n");

sm_bootloader_mode_enabled = true;

Expand Down Expand Up @@ -257,12 +248,6 @@ static int sm_main(void)
}
}

ret = sm_uart_handler_enable();
if (ret) {
LOG_ERR("Failed to enable UART handler (%d).", ret);
return ret;
}

#if defined(CONFIG_SM_FULL_FOTA)
if (sm_modem_full_fota) {
sm_finish_modem_full_fota();
Expand All @@ -287,13 +272,9 @@ static int sm_main(void)
check_app_fota_status();

if (sm_init_failed) {
ret = sm_at_send_str(SM_SYNC_ERR_STR);
urc_send(SM_SYNC_ERR_STR);
} else {
ret = sm_at_send_str(SM_SYNC_STR);
}

if (ret) {
return ret;
urc_send(SM_SYNC_STR);
}

/* This is here and not earlier because in case of firmware
Expand Down
9 changes: 7 additions & 2 deletions app/src/sm_at_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,15 @@ STATIC int handle_at_clac(enum at_parser_cmd_type cmd_type, struct at_parser *,
const char *cmd = _nrf_modem_at_cmd_custom_list_start[i].cmd;
/* Modem AT commands start with 'AT+' or AT%. Other commands are
* Serial Modem specific'. Skip modem AT commands.
* Exception: AT+IPR is implemented in Serial Modem.
* Exceptions that are implemented in Serial Modem:
* * AT+IPR
* * AT+CMUX
* * AT+CGDATA
*/
if ((strncasecmp(cmd, "AT+", strlen("AT+")) == 0 &&
strncasecmp(cmd, "AT+IPR", strlen("AT+IPR")) != 0) ||
strncasecmp(cmd, "AT+IPR", strlen("AT+IPR")) != 0 &&
strncasecmp(cmd, "AT+CMUX", strlen("AT+CMUX")) != 0 &&
strncasecmp(cmd, "AT+CGDATA", strlen("AT+CGDATA")) != 0) ||
strncasecmp(cmd, "AT%%", strlen("AT%%")) == 0) {
continue;
}
Expand Down
21 changes: 13 additions & 8 deletions app/src/sm_at_fota.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ int32_t sm_fota_info;

static char path[FILE_URI_MAX];
static char hostname[URI_HOST_MAX];
static struct modem_pipe *fota_pipe;

#if defined(CONFIG_SM_FULL_FOTA)
/* Buffer used as temporary storage when downloading the modem firmware.
Expand Down Expand Up @@ -287,7 +288,7 @@ static void fota_dl_handler(const struct fota_download_evt *evt)
sm_fota_stage = FOTA_STAGE_DOWNLOAD;
sm_fota_status = FOTA_STATUS_OK;
sm_fota_info = evt->progress;
rsp_send("\r\n#XFOTA: %d,%d,%d\r\n",
urc_send_to(fota_pipe, "\r\n#XFOTA: %d,%d,%d\r\n",
sm_fota_stage, sm_fota_status, sm_fota_info);
break;
case FOTA_DOWNLOAD_EVT_FINISHED:
Expand All @@ -296,17 +297,18 @@ static void fota_dl_handler(const struct fota_download_evt *evt)
sm_modem_full_fota = (sm_fota_type == DFU_TARGET_IMAGE_TYPE_FULL_MODEM);
/* Save, in case reboot by reset */
sm_settings_fota_save();
rsp_send("\r\n#XFOTA: %d,%d\r\n", sm_fota_stage, sm_fota_status);
urc_send_to(fota_pipe, "\r\n#XFOTA: %d,%d\r\n", sm_fota_stage, sm_fota_status);
break;
case FOTA_DOWNLOAD_EVT_ERASE_TIMEOUT:
LOG_INF("Erasure timeout reached. Erasure continues.");
break;
case FOTA_DOWNLOAD_EVT_ERASE_PENDING:
sm_fota_stage = FOTA_STAGE_DOWNLOAD_ERASE_PENDING;
rsp_send("\r\n#XFOTA: %d,%d\r\n", sm_fota_stage, sm_fota_status);
urc_send_to(fota_pipe, "\r\n#XFOTA: %d,%d\r\n", sm_fota_stage, sm_fota_status);
break;
case FOTA_DOWNLOAD_EVT_ERASE_DONE:
rsp_send("\r\n#XFOTA: %d,%d\r\n", FOTA_STAGE_DOWNLOAD_ERASED, sm_fota_status);
urc_send_to(fota_pipe, "\r\n#XFOTA: %d,%d\r\n", FOTA_STAGE_DOWNLOAD_ERASED,
sm_fota_status);
/* Back to init now that the erasure is complete so that potential pre-start
* error codes are printed with the same stage than if there had been no erasure.
*/
Expand All @@ -315,15 +317,15 @@ static void fota_dl_handler(const struct fota_download_evt *evt)
case FOTA_DOWNLOAD_EVT_ERROR:
sm_fota_status = FOTA_STATUS_ERROR;
sm_fota_info = evt->cause;
rsp_send("\r\n#XFOTA: %d,%d,%d\r\n",
urc_send_to(fota_pipe, "\r\n#XFOTA: %d,%d,%d\r\n",
sm_fota_stage, sm_fota_status, sm_fota_info);
/* FOTA session terminated */
sm_fota_init_state();
break;
case FOTA_DOWNLOAD_EVT_CANCELLED:
sm_fota_status = FOTA_STATUS_CANCELLED;
sm_fota_info = 0;
rsp_send("\r\n#XFOTA: %d,%d\r\n", sm_fota_stage, sm_fota_status);
urc_send_to(fota_pipe, "\r\n#XFOTA: %d,%d\r\n", sm_fota_stage, sm_fota_status);
/* FOTA session terminated */
sm_fota_init_state();
break;
Expand All @@ -345,6 +347,7 @@ static int handle_at_fota(enum at_parser_cmd_type cmd_type, struct at_parser *pa

switch (cmd_type) {
case AT_PARSER_CMD_TYPE_SET:
fota_pipe = sm_at_host_get_current_pipe();
err = at_parser_num_get(parser, 1, &op);
if (err < 0) {
return err;
Expand Down Expand Up @@ -492,10 +495,12 @@ void sm_fota_post_process(void)
}
LOG_INF("FOTA result %d,%d,%d", sm_fota_stage, sm_fota_status, sm_fota_info);

struct modem_pipe *pipe = fota_pipe ? fota_pipe : sm_at_host_get_urc_pipe();

if (sm_fota_status == FOTA_STATUS_OK) {
rsp_send("\r\n#XFOTA: %d,%d\r\n", sm_fota_stage, sm_fota_status);
urc_send_to(pipe, "\r\n#XFOTA: %d,%d\r\n", sm_fota_stage, sm_fota_status);
} else {
rsp_send("\r\n#XFOTA: %d,%d,%d\r\n", sm_fota_stage, sm_fota_status,
urc_send_to(pipe, "\r\n#XFOTA: %d,%d,%d\r\n", sm_fota_stage, sm_fota_status,
sm_fota_info);
}

Expand Down
16 changes: 10 additions & 6 deletions app/src/sm_at_gnss.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ static struct k_work gnss_status_notify_work;
/* FIFO to pass the GNSS statuses to the notifier worker. */
K_FIFO_DEFINE(gnss_status_fifo);

static struct modem_pipe *gnss_pipe;

/* Whether to use the nRF Cloud assistive services that were compiled in (A-GNSS/P-GPS).
* If enabled, the connection to nRF Cloud is required during GNSS startup
* and assistance data will be downloaded.
Expand Down Expand Up @@ -123,7 +125,7 @@ static void gnss_status_notifier(struct k_work *)
{
while (!k_fifo_is_empty(&gnss_status_fifo)) {
gnss_status = (enum gnss_status)k_fifo_get(&gnss_status_fifo, K_NO_WAIT);
rsp_send("\r\n#XGNSS: 1,%d\r\n", gnss_status);
urc_send_to(gnss_pipe, "\r\n#XGNSS: 1,%d\r\n", gnss_status);
}
}

Expand Down Expand Up @@ -517,11 +519,11 @@ static void gnss_fix_sender(struct k_work *)
}

/* GIS accuracy: http://wiki.gis.com/wiki/index.php/Decimal_degrees, use default .6lf */
rsp_send("\r\n#XGNSS: %lf,%lf,%f,%f,%f,%f,\"%04u-%02u-%02u %02u:%02u:%02u\"\r\n",
pvt.latitude, pvt.longitude, (double)pvt.altitude,
(double)pvt.accuracy, (double)pvt.speed, (double)pvt.heading,
pvt.datetime.year, pvt.datetime.month, pvt.datetime.day,
pvt.datetime.hour, pvt.datetime.minute, pvt.datetime.seconds);
urc_send_to(gnss_pipe,
"\r\n#XGNSS: %lf,%lf,%f,%f,%f,%f,\"%04u-%02u-%02u %02u:%02u:%02u\"\r\n",
pvt.latitude, pvt.longitude, (double)pvt.altitude, (double)pvt.accuracy,
(double)pvt.speed, (double)pvt.heading, pvt.datetime.year, pvt.datetime.month,
pvt.datetime.day, pvt.datetime.hour, pvt.datetime.minute, pvt.datetime.seconds);

for (int i = 0; i < NRF_MODEM_GNSS_MAX_SATELLITES; ++i) {
if (pvt.sv[i].sv) { /* SV number 0 indicates no satellite */
Expand Down Expand Up @@ -660,6 +662,8 @@ static int handle_at_gnss(enum at_parser_cmd_type cmd_type, struct at_parser *pa
return -EBUSY;
}

gnss_pipe = sm_at_host_get_current_pipe();

err = at_parser_num_get(
parser, CLOUD_ASSISTANCE_IDX, &gnss_cloud_assistance);
if (err || gnss_cloud_assistance > 1) {
Expand Down
Loading