I'm trying to get location information sent with SMS to my phone. I have made sure my SIM card is SMS capable by using sms sample, which managed to send and receive messages and GNSS location services work and find fixes.
I wanted to use simple example for start when combining the two, so I have just tried to add SMS to devAcademy Cellular fundamentals lesson 6 exercise 1. When running program it crashes when trying to send the SMS after location fix is made and second LED indicator lights up.
I'm using thingy:91 with external antenna, in Windows
/* * Copyright (c) 2022 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ #include <stdio.h> #include <zephyr/kernel.h> #include <zephyr/logging/log.h> #include <modem/lte_lc.h> #include <dk_buttons_and_leds.h> /* STEP 4 - Include the header file for the GNSS interface */ #include <nrf_modem_gnss.h> // Include SMS #include <modem/sms.h> /* STEP 5 - Define the PVT data frame variable */ static struct nrf_modem_gnss_pvt_data_frame pvt_data; /* STEP 12.1 - Declare helper variables to find the TTFF */ static int64_t gnss_start_time; static bool first_fix = false; static K_SEM_DEFINE(lte_connected, 0, 1); LOG_MODULE_REGISTER(Lesson6_Exercise1, LOG_LEVEL_INF); static void lte_handler(const struct lte_lc_evt *const evt) { switch (evt->type) { case LTE_LC_EVT_NW_REG_STATUS: if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) && (evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) { break; } LOG_INF("Network registration status: %s", evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ? "Connected - home network" : "Connected - roaming"); k_sem_give(<e_connected); break; case LTE_LC_EVT_RRC_UPDATE: LOG_INF("RRC mode: %s", evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ? "Connected" : "Idle"); break; default: break; } } static void modem_configure(void) { LOG_INF("Connecting to LTE network"); int err = lte_lc_init_and_connect_async(lte_handler); if (err) { LOG_ERR("Modem could not be configured, error: %d", err); return; } k_sem_take(<e_connected, K_FOREVER); LOG_INF("Connected to LTE network"); dk_set_led_on(DK_LED2); } /* STEP 6 - Define a function to log fix data in a readable format */ static void print_fix_data(struct nrf_modem_gnss_pvt_data_frame *pvt_data) { LOG_INF("Latitude: %.06f", pvt_data->latitude); LOG_INF("Longitude: %.06f", pvt_data->longitude); LOG_INF("Altitude: %.01f m", pvt_data->altitude); LOG_INF("Time (UTC): %02u:%02u:%02u.%03u", pvt_data->datetime.hour, pvt_data->datetime.minute, pvt_data->datetime.seconds, pvt_data->datetime.ms); // Phone number removed for ticket if (sms_send_text("","Fix found")!=0) LOG_INF("Failed to SMS fix"); } static void gnss_event_handler(int event) { int err; switch (event) { /* STEP 7 - On a PVT event, confirm if PVT data is a valid fix */ case NRF_MODEM_GNSS_EVT_PVT: LOG_INF("Searching..."); /* STEP 15 - Print satellite information */ int num_satellites = 0; for (int i = 0; i < 12 ; i++) { if (pvt_data.sv[i].signal != 0) { LOG_INF("sv: %d, cn0: %d", pvt_data.sv[i].sv, pvt_data.sv[i].cn0); num_satellites++; } } LOG_INF("Number of current satellites: %d", num_satellites); err = nrf_modem_gnss_read(&pvt_data, sizeof(pvt_data), NRF_MODEM_GNSS_DATA_PVT); if (err) { LOG_ERR("nrf_modem_gnss_read failed, err %d", err); return; } if (pvt_data.flags & NRF_MODEM_GNSS_PVT_FLAG_FIX_VALID) { dk_set_led_on(DK_LED1); print_fix_data(&pvt_data); /* STEP 12.3 - Print the time to first fix */ if (!first_fix) { LOG_INF("Time to first fix: %2.1lld s", (k_uptime_get() - gnss_start_time)/1000); first_fix = true; } return; } break; /* STEP 7.2 - Log when the GNSS sleeps and wakes up */ case NRF_MODEM_GNSS_EVT_PERIODIC_WAKEUP: LOG_INF("GNSS has woken up"); break; case NRF_MODEM_GNSS_EVT_SLEEP_AFTER_FIX: LOG_INF("GNSS enter sleep after fix"); break; default: break; } } static void sms_callback(struct sms_data *const data, void *context) { if (data == NULL) { printk("%s with NULL data\n", __func__); return; } if (data->type == SMS_TYPE_DELIVER) { /* When SMS message is received, print information */ struct sms_deliver_header *header = &data->header.deliver; printk("\nSMS received:\n"); printk("\tTime: %02d-%02d-%02d %02d:%02d:%02d\n", header->time.year, header->time.month, header->time.day, header->time.hour, header->time.minute, header->time.second); printk("\tText: '%s'\n", data->payload); printk("\tLength: %d\n", data->payload_len); if (header->app_port.present) { printk("\tApplication port addressing scheme: dest_port=%d, src_port=%d\n", header->app_port.dest_port, header->app_port.src_port); } if (header->concatenated.present) { printk("\tConcatenated short message: ref_number=%d, msg %d/%d\n", header->concatenated.ref_number, header->concatenated.seq_number, header->concatenated.total_msgs); } } else if (data->type == SMS_TYPE_STATUS_REPORT) { printk("SMS status report received\n"); } else { printk("SMS protocol message with unknown type received\n"); } } void main(void) { if (dk_leds_init() != 0) { LOG_ERR("Failed to initialize the LEDs Library"); } modem_configure(); /* STEP 8 - Activate modem and deactivate LTE */ if (lte_lc_func_mode_set(LTE_LC_FUNC_MODE_NORMAL) != 0) { LOG_ERR("Failed to activate GNSS functional mode"); return; } LOG_INF("Deactivating LTE"); if (lte_lc_func_mode_set(LTE_LC_FUNC_MODE_DEACTIVATE_LTE) != 0) { LOG_ERR("Failed to activate GNSS functional mode"); return; } /* STEP 9 - Register the GNSS event handler */ if (nrf_modem_gnss_event_handler_set(gnss_event_handler) != 0) { LOG_ERR("Failed to set GNSS event handler"); return; } /* STEP 10 - Set the GNSS fix interval and GNSS fix retry period */ if (nrf_modem_gnss_fix_interval_set(CONFIG_GNSS_PERIODIC_INTERVAL) != 0) { LOG_ERR("Failed to set GNSS fix interval"); return; } if (nrf_modem_gnss_fix_retry_set(CONFIG_GNSS_PERIODIC_TIMEOUT) != 0) { LOG_ERR("Failed to set GNSS fix retry"); return; } /* STEP 11 - Start the GNSS receiver*/ LOG_INF("Starting GNSS"); if (nrf_modem_gnss_start() != 0) { LOG_ERR("Failed to start GNSS"); return; } int handle = sms_register_listener(sms_callback,NULL); /* STEP 12.2 - Log the current system uptime */ gnss_start_time = k_uptime_get(); }