From 3384c22f436ff6d5b30447d8c71d2581c7975c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eivind=20J=C3=B8lsgard?= Date: Mon, 25 Sep 2023 12:45:27 +0200 Subject: [PATCH] manifest: nrf_modem: v2.5.0 release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See CHANGELOG file in nrfxlib for details about library features. Co-authored-by: Emanuele Di Santo Co-authored-by: Tommi Kangas Signed-off-by: Eivind Jølsgard --- applications/asset_tracker_v2/sample.yaml | 1 - .../src/cloud/cloud_codec/cloud_codec.h | 2 +- .../src/cloud/cloud_codec/json_common.c | 22 +- .../src/events/location_module_event.h | 4 +- applications/asset_tracker_v2/src/main.c | 47 +-- .../src/modules/data_module.c | 35 +-- .../tests/json_common/src/main.c | 16 +- .../src/location_module_test.c | 33 +- .../src/lwm2m_codec_helpers_test.c | 4 +- .../serial_lte_modem/src/gnss/slm_at_gnss.c | 27 +- applications/serial_lte_modem/src/main.c | 66 ++-- .../serial_lte_modem/src/slm_at_commands.c | 48 +-- .../serial_lte_modem/src/slm_at_fota.c | 17 +- .../serial_lte_modem/src/slm_at_fota.h | 16 +- .../serial_lte_modem/src/slm_at_icmp.c | 11 +- .../serial_lte_modem/src/slm_at_socket.c | 6 +- .../libraries/networking/nrf_cloud_pgps.rst | 2 +- doc/nrf/libraries/others/supl_os_client.rst | 2 +- .../releases/release-notes-changelog.rst | 9 +- ext/curl/lib/connect.c | 46 +-- ext/curl/lib/setopt.c | 1 + ext/iperf3/iperf_util.c | 60 ++-- include/modem/location.h | 2 +- include/modem/nrf_modem_lib.h | 61 +++- include/net/lwm2m_client_utils_location.h | 2 +- include/net/nrf_cloud_agps.h | 4 +- include/net/nrf_cloud_pgps.h | 4 +- include/net/nrf_cloud_rest.h | 4 +- include/supl_os_client.h | 6 +- lib/bin/lwm2m_carrier/os/lwm2m_carrier.c | 53 +++- lib/location/Kconfig | 7 + lib/location/location_core.c | 6 +- lib/location/location_core.h | 2 +- lib/location/method_gnss.c | 283 ++++++++++++------ lib/lte_link_control/lte_lc_modem_hooks.c | 4 - .../lte_connectivity/lte_connectivity.c | 43 +-- .../lte_connectivity/lte_connectivity.h | 2 - lib/nrf_modem_lib/nrf91_sockets.c | 24 +- lib/nrf_modem_lib/nrf_modem_lib.c | 14 +- lib/nrf_modem_lib/nrf_modem_lib.ld | 3 + lib/supl/os/supl_os_client.c | 14 +- samples/cellular/azure_fota/src/main.c | 36 ++- samples/cellular/gnss/src/assistance.c | 50 +++- samples/cellular/gnss/src/assistance.h | 4 +- .../cellular/gnss/src/assistance_minimal.c | 17 +- samples/cellular/gnss/src/assistance_supl.c | 10 +- samples/cellular/gnss/src/main.c | 123 ++++++-- .../http_update/modem_delta_update/src/main.c | 41 +-- samples/cellular/lte_ble_gateway/src/main.c | 6 +- .../src/events/include/location_events.h | 2 +- .../lwm2m_client/src/sensors/gnss_module.c | 6 +- samples/cellular/modem_shell/src/fota/fota.c | 49 ++- samples/cellular/modem_shell/src/gnss/gnss.c | 243 +++++++++------ .../modem_shell/src/gnss/gnss_shell.c | 6 +- .../modem_shell/src/location/location_shell.c | 4 +- .../src/location/location_srv_ext.h | 2 +- .../src/location/location_srv_ext_lwm2m.c | 2 +- .../src/location/location_srv_ext_nrf_cloud.c | 2 +- .../modem_shell/src/utils/net_utils.c | 7 +- samples/cellular/nidd/src/main.c | 4 +- subsys/mgmt/fmfu/src/fmfu_mgmt.c | 10 +- .../lib/download_client/src/download_client.c | 9 +- .../src/util/fota_download_delta_modem.c | 13 +- .../location/location_assistance.c | 24 +- .../lwm2m_client_utils/lwm2m/lwm2m_firmware.c | 13 - .../net/lib/nrf_cloud/coap/src/coap_codec.c | 2 +- .../include/nrf_cloud_agps_schema_v1.h | 31 +- .../include/nrf_cloud_codec_internal.h | 6 +- .../include/nrf_cloud_pgps_schema_v1.h | 2 +- subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c | 263 +++++++++------- .../lib/nrf_cloud/src/nrf_cloud_agps_utils.c | 63 ++-- .../nrf_cloud/src/nrf_cloud_codec_internal.c | 74 +++-- .../lib/nrf_cloud/src/nrf_cloud_fota_common.c | 29 +- subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c | 48 +-- subsys/net/lib/nrf_cloud/src/nrf_cloud_rest.c | 67 ++--- .../src/lte_connectivity_test.c | 7 +- .../nrf91_sockets/src/nrf91_sockets_test.c | 28 ++ .../src/location_assistance.c | 8 +- .../net/lib/lwm2m_fota_utils/src/firmware.c | 15 +- west.yml | 4 +- 80 files changed, 1408 insertions(+), 935 deletions(-) diff --git a/applications/asset_tracker_v2/sample.yaml b/applications/asset_tracker_v2/sample.yaml index ea4f54baca27..4ba4f0aeadca 100644 --- a/applications/asset_tracker_v2/sample.yaml +++ b/applications/asset_tracker_v2/sample.yaml @@ -124,7 +124,6 @@ tests: platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns integration_platforms: - nrf9160dk_nrf9160_ns - - thingy91_nrf9160_ns extra_args: EXTRA_CONF_FILE=overlay-carrier.conf tags: ci_build applications.asset_tracker_v2.carrier.nrf9161dk: diff --git a/applications/asset_tracker_v2/src/cloud/cloud_codec/cloud_codec.h b/applications/asset_tracker_v2/src/cloud/cloud_codec/cloud_codec.h index 89d98daf08bc..a453441131f8 100644 --- a/applications/asset_tracker_v2/src/cloud/cloud_codec/cloud_codec.h +++ b/applications/asset_tracker_v2/src/cloud/cloud_codec/cloud_codec.h @@ -254,7 +254,7 @@ struct cloud_data_agps_request { /** Area Code. */ uint32_t area; /** AGPS request types */ - struct nrf_modem_gnss_agps_data_frame request; + struct nrf_modem_gnss_agnss_data_frame request; /** Flag signifying that the data entry is to be encoded. */ bool queued : 1; }; diff --git a/applications/asset_tracker_v2/src/cloud/cloud_codec/json_common.c b/applications/asset_tracker_v2/src/cloud/cloud_codec/json_common.c index 767a1378d43b..ef5a9a80707e 100644 --- a/applications/asset_tracker_v2/src/cloud/cloud_codec/json_common.c +++ b/applications/asset_tracker_v2/src/cloud/cloud_codec/json_common.c @@ -820,7 +820,7 @@ int json_common_agps_request_data_add(cJSON *parent, return -ENOMEM; } - if (data->request.data_flags & NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST) { + if (data->request.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST) { err = json_add_number_to_array(agps_types, DATA_AGPS_REQUEST_TYPE_UTC_PARAMETERS); if (err) { @@ -829,7 +829,13 @@ int json_common_agps_request_data_add(cJSON *parent, } } - if (data->request.sv_mask_ephe) { + /* GPS data need is always expected to be present and first in list. */ + __ASSERT(data->request.system_count > 0, + "GNSS system data need not found"); + __ASSERT(data->request.system[0].system_id == NRF_MODEM_GNSS_SYSTEM_GPS, + "GPS data need not found"); + + if (data->request.system[0].sv_mask_ephe) { err = json_add_number_to_array(agps_types, DATA_AGPS_REQUEST_TYPE_EPHEMERIDES); if (err) { @@ -838,7 +844,7 @@ int json_common_agps_request_data_add(cJSON *parent, } } - if (data->request.sv_mask_alm) { + if (data->request.system[0].sv_mask_alm) { err = json_add_number_to_array(agps_types, DATA_AGPS_REQUEST_TYPE_ALMANAC); if (err) { @@ -847,7 +853,7 @@ int json_common_agps_request_data_add(cJSON *parent, } } - if (data->request.data_flags & NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST) { + if (data->request.data_flags & NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST) { err = json_add_number_to_array(agps_types, DATA_AGPS_REQUEST_TYPE_KLOBUCHAR_CORRECTION); if (err) { @@ -856,7 +862,7 @@ int json_common_agps_request_data_add(cJSON *parent, } } - if (data->request.data_flags & NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST) { + if (data->request.data_flags & NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST) { err = json_add_number_to_array(agps_types, DATA_AGPS_REQUEST_TYPE_NEQUICK_CORRECTION); if (err) { @@ -865,7 +871,7 @@ int json_common_agps_request_data_add(cJSON *parent, } } - if (data->request.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) { + if (data->request.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST) { err = json_add_number_to_array(agps_types, DATA_AGPS_REQUEST_TYPE_GPS_TOWS); if (err) { @@ -881,7 +887,7 @@ int json_common_agps_request_data_add(cJSON *parent, } } - if (data->request.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST) { + if (data->request.data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST) { err = json_add_number_to_array(agps_types, DATA_AGPS_REQUEST_TYPE_LOCATION); if (err) { @@ -890,7 +896,7 @@ int json_common_agps_request_data_add(cJSON *parent, } } - if (data->request.data_flags & NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST) { + if (data->request.data_flags & NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST) { err = json_add_number_to_array(agps_types, DATA_AGPS_REQUEST_TYPE_INTEGRITY); if (err) { diff --git a/applications/asset_tracker_v2/src/events/location_module_event.h b/applications/asset_tracker_v2/src/events/location_module_event.h index c557f85dd9af..54e578903bc3 100644 --- a/applications/asset_tracker_v2/src/events/location_module_event.h +++ b/applications/asset_tracker_v2/src/events/location_module_event.h @@ -72,7 +72,7 @@ enum location_module_event_type { LOCATION_MODULE_EVT_SHUTDOWN_READY, /** The location library has reported that it needs GPS assistance data. - * The event has associated payload of the type ``struct nrf_modem_gnss_agps_data_frame`` + * The event has associated payload of the type ``struct nrf_modem_gnss_agnss_data_frame`` * in the event struct member ``data.agps_request``, which contains the types * of A-GPS data that the modem needs. */ @@ -184,7 +184,7 @@ struct location_module_event { /** Data for event LOCATION_MODULE_EVT_CLOUD_LOCATION_DATA_READY. */ struct location_module_cloud_location cloud_location; /** Data for event LOCATION_MODULE_EVT_AGPS_NEEDED. */ - struct nrf_modem_gnss_agps_data_frame agps_request; + struct nrf_modem_gnss_agnss_data_frame agps_request; #if defined(CONFIG_NRF_CLOUD_PGPS) /** Data for event LOCATION_MODULE_EVT_PGPS_NEEDED. */ struct gps_pgps_request pgps_request; diff --git a/applications/asset_tracker_v2/src/main.c b/applications/asset_tracker_v2/src/main.c index 86264ac3ed41..232b18917eff 100644 --- a/applications/asset_tracker_v2/src/main.c +++ b/applications/asset_tracker_v2/src/main.c @@ -174,41 +174,48 @@ static void sub_state_set(enum sub_state_type new_state) } #if defined(CONFIG_NRF_MODEM_LIB) -/* Check the return code from nRF modem library initialization to ensure that - * the modem is rebooted if a modem firmware update is ready to be applied or - * an error condition occurred during firmware update or library initialization. - */ -static void modem_init(void) -{ - int ret = nrf_modem_lib_init(); - /* Handle return values relating to modem firmware update */ - switch (ret) { - case 0: - /* Initialization successful, no action required. */ - return; +static void on_modem_lib_dfu(int dfu_res, void *ctx) +{ + switch (dfu_res) { case NRF_MODEM_DFU_RESULT_OK: - LOG_DBG("MODEM UPDATE OK. Will run new modem firmware after reboot"); + LOG_DBG("MODEM UPDATE OK. Running new firmware"); break; case NRF_MODEM_DFU_RESULT_UUID_ERROR: case NRF_MODEM_DFU_RESULT_AUTH_ERROR: - LOG_ERR("MODEM UPDATE ERROR %d. Will run old firmware", ret); + LOG_ERR("MODEM UPDATE ERROR 0x%x. Running old firmware", dfu_res); break; case NRF_MODEM_DFU_RESULT_HARDWARE_ERROR: case NRF_MODEM_DFU_RESULT_INTERNAL_ERROR: - LOG_ERR("MODEM UPDATE FATAL ERROR %d. Modem failure", ret); + LOG_ERR("MODEM UPDATE FATAL ERROR 0x%x. Modem failure", dfu_res); break; case NRF_MODEM_DFU_RESULT_VOLTAGE_LOW: - LOG_ERR("MODEM UPDATE CANCELLED %d.", ret); + LOG_ERR("MODEM UPDATE CANCELLED 0x%x.", dfu_res); LOG_ERR("Please reboot once you have sufficient power for the DFU"); break; default: - /* All non-zero return codes other than DFU result codes are - * considered irrecoverable and a reboot is needed. - */ - LOG_ERR("nRF modem lib initialization failed, error: %d", ret); + /* Unknown DFU result code */ + LOG_ERR("nRF modem DFU failed, error: 0x%x", dfu_res); break; } +} + +NRF_MODEM_LIB_ON_DFU_RES(main_dfu_hook, on_modem_lib_dfu, NULL); + +/* Check the return code from nRF modem library initialization to ensure that + * the modem is rebooted or an error condition occurred during library initialization. + */ +static void modem_init(void) +{ + int ret; + + ret = nrf_modem_lib_init(); + if (ret == 0) { + LOG_DBG("nRF Modem Library initialized successfully"); + return; + } + + LOG_ERR("nRF modem lib initialization failed, error: %d", ret); #if defined(CONFIG_NRF_CLOUD_FOTA) /* Ignore return value, rebooting below */ diff --git a/applications/asset_tracker_v2/src/modules/data_module.c b/applications/asset_tracker_v2/src/modules/data_module.c index 5878ad1ac47e..6fa655c85db4 100644 --- a/applications/asset_tracker_v2/src/modules/data_module.c +++ b/applications/asset_tracker_v2/src/modules/data_module.c @@ -138,7 +138,7 @@ enum coneval_supported_data_type { bool agps_request_buffered; /* Buffered A-GPS request. */ -struct nrf_modem_gnss_agps_data_frame agps_request_buffer; +struct nrf_modem_gnss_agnss_data_frame agps_request_buffer; /* Data module message queue. */ #define DATA_QUEUE_ENTRY_COUNT 10 @@ -704,7 +704,7 @@ static int get_modem_info(struct modem_param_info *const modem_info) * * @return 0 on success, otherwise a negative error code indicating reason of failure. */ -static int agps_request_encode(struct nrf_modem_gnss_agps_data_frame *incoming_request) +static int agps_request_encode(struct nrf_modem_gnss_agnss_data_frame *incoming_request) { int err; struct cloud_codec_data codec = {0}; @@ -720,15 +720,16 @@ static int agps_request_encode(struct nrf_modem_gnss_agps_data_frame *incoming_r const uint32_t mask = IS_ENABLED(CONFIG_NRF_CLOUD_PGPS) ? 0u : 0xFFFFFFFFu; LOG_DBG("Requesting all A-GPS elements"); - cloud_agps_request.request.sv_mask_ephe = mask, - cloud_agps_request.request.sv_mask_alm = mask, cloud_agps_request.request.data_flags = - NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST | - NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST | - NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST | - NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST | - NRF_MODEM_GNSS_AGPS_POSITION_REQUEST | - NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST; + NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST | + NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST | + NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST | + NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST | + NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST; + cloud_agps_request.request.system_count = 1; + cloud_agps_request.request.system[0].sv_mask_ephe = mask; + cloud_agps_request.request.system[0].sv_mask_alm = mask; } else { cloud_agps_request.request = *incoming_request; } @@ -1060,25 +1061,17 @@ static void new_config_handle(struct cloud_data_cfg *new_config) * requested by the modem. If incoming_request is NULL, all A-GPS data * types are requested. */ -static void agps_request_handle(struct nrf_modem_gnss_agps_data_frame *incoming_request) +static void agps_request_handle(struct nrf_modem_gnss_agnss_data_frame *incoming_request) { int err; #if defined(CONFIG_NRF_CLOUD_AGPS) - struct nrf_modem_gnss_agps_data_frame request; - - if (incoming_request != NULL) { - request.sv_mask_ephe = incoming_request->sv_mask_ephe; - request.sv_mask_alm = incoming_request->sv_mask_alm; - request.data_flags = incoming_request->data_flags; - } - #if defined(CONFIG_NRF_CLOUD_MQTT) /* If CONFIG_NRF_CLOUD_MQTT is enabled, the nRF Cloud MQTT transport library will be used * to send the request. */ err = (incoming_request == NULL) ? nrf_cloud_agps_request_all() : - nrf_cloud_agps_request(&request); + nrf_cloud_agps_request(incoming_request); if (err) { LOG_WRN("Failed to request A-GPS data, error: %d", err); LOG_DBG("This is expected to fail if we are not in a connected state"); @@ -1096,7 +1089,7 @@ static void agps_request_handle(struct nrf_modem_gnss_agps_data_frame *incoming_ * up and send to the cloud that is currently used. */ err = (incoming_request == NULL) ? agps_request_encode(NULL) : - agps_request_encode(&request); + agps_request_encode(incoming_request); if (err) { LOG_WRN("Failed to request A-GPS data, error: %d", err); } else { diff --git a/applications/asset_tracker_v2/tests/json_common/src/main.c b/applications/asset_tracker_v2/tests/json_common/src/main.c index c14cf683ee2a..553da5b169ef 100644 --- a/applications/asset_tracker_v2/tests/json_common/src/main.c +++ b/applications/asset_tracker_v2/tests/json_common/src/main.c @@ -701,15 +701,15 @@ void test_encode_agps_request_data_object(void) .mnc = 1, .cell = 21679716, .area = 40401, - .request.sv_mask_ephe = UINT32_MAX, - .request.sv_mask_alm = UINT32_MAX, + .request.system[0].sv_mask_ephe = UINT32_MAX, + .request.system[0].sv_mask_alm = UINT32_MAX, .request.data_flags = - NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST | - NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST | - NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST | - NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST | - NRF_MODEM_GNSS_AGPS_POSITION_REQUEST | - NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST, + NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST | + NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST | + NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST | + NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST | + NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST, .queued = true }; diff --git a/applications/asset_tracker_v2/tests/location_module/src/location_module_test.c b/applications/asset_tracker_v2/tests/location_module/src/location_module_test.c index 38a219bf379c..208af8d1f579 100644 --- a/applications/asset_tracker_v2/tests/location_module/src/location_module_test.c +++ b/applications/asset_tracker_v2/tests/location_module/src/location_module_test.c @@ -111,6 +111,9 @@ static void validate_location_module_evt(struct app_event_header *aeh, int no_of uint32_t index = location_module_event_count; struct location_module_event *event = cast_location_module_event(aeh); + struct nrf_modem_gnss_agnss_data_frame *agps_req_exp = + &expected_location_module_events[index].data.agps_request; + /* Make sure we don't get more events than expected. */ TEST_ASSERT_LESS_THAN(expected_location_module_event_count, location_module_event_count); @@ -212,13 +215,13 @@ static void validate_location_module_evt(struct app_event_header *aeh, int no_of break; case LOCATION_MODULE_EVT_AGPS_NEEDED: TEST_ASSERT_EQUAL( - expected_location_module_events[index].data.agps_request.sv_mask_ephe, - event->data.agps_request.sv_mask_ephe); + agps_req_exp->system[0].sv_mask_ephe, + event->data.agps_request.system[0].sv_mask_ephe); TEST_ASSERT_EQUAL( - expected_location_module_events[index].data.agps_request.sv_mask_alm, - event->data.agps_request.sv_mask_alm); + agps_req_exp->system[0].sv_mask_alm, + event->data.agps_request.system[0].sv_mask_alm); TEST_ASSERT_EQUAL( - expected_location_module_events[index].data.agps_request.data_flags, + agps_req_exp->data_flags, event->data.agps_request.data_flags); break; case LOCATION_MODULE_EVT_PGPS_NEEDED: @@ -358,12 +361,12 @@ void test_location_gnss_with_agps(void) expected_location_module_events[0].type = LOCATION_MODULE_EVT_ACTIVE; expected_location_module_events[1].type = LOCATION_MODULE_EVT_AGPS_NEEDED; - expected_location_module_events[1].data.agps_request.sv_mask_ephe = 0xabbaabba, - expected_location_module_events[1].data.agps_request.sv_mask_alm = 0xdeaddead, + expected_location_module_events[1].data.agps_request.system[0].sv_mask_ephe = 0xabbaabba, + expected_location_module_events[1].data.agps_request.system[0].sv_mask_alm = 0xdeaddead, expected_location_module_events[1].data.agps_request.data_flags = - NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST | - NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST | - NRF_MODEM_GNSS_AGPS_POSITION_REQUEST; + NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST | + NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST; expected_location_module_events[2].type = LOCATION_MODULE_EVT_GNSS_DATA_READY; expected_location_module_events[2].data.location.pvt.latitude = 34.087; @@ -382,11 +385,11 @@ void test_location_gnss_with_agps(void) /* Location request is responded with location library events. */ struct location_event_data event_data_agps = { .id = LOCATION_EVT_GNSS_ASSISTANCE_REQUEST, - .agps_request.sv_mask_ephe = 0xabbaabba, - .agps_request.sv_mask_alm = 0xdeaddead, - .agps_request.data_flags = NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST | - NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST | - NRF_MODEM_GNSS_AGPS_POSITION_REQUEST + .agps_request.system[0].sv_mask_ephe = 0xabbaabba, + .agps_request.system[0].sv_mask_alm = 0xdeaddead, + .agps_request.data_flags = NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST | + NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST }; location_event_handler(&event_data_agps); diff --git a/applications/asset_tracker_v2/tests/lwm2m_codec_helpers/src/lwm2m_codec_helpers_test.c b/applications/asset_tracker_v2/tests/lwm2m_codec_helpers/src/lwm2m_codec_helpers_test.c index c15465de581a..fe69846121fd 100644 --- a/applications/asset_tracker_v2/tests/lwm2m_codec_helpers/src/lwm2m_codec_helpers_test.c +++ b/applications/asset_tracker_v2/tests/lwm2m_codec_helpers/src/lwm2m_codec_helpers_test.c @@ -208,8 +208,8 @@ void test_codec_helpers_set_agps_data(void) .mcc = 242, .area = 30601, .cell = 52118273, - .request.sv_mask_ephe = 0xFFFFFFFFu, - .request.sv_mask_alm = 0xFFFFFFFFu, + .request.system[0].sv_mask_ephe = 0xFFFFFFFFu, + .request.system[0].sv_mask_alm = 0xFFFFFFFFu, .request.data_flags = 0xFFFFFFFFu, .queued = true, }; diff --git a/applications/serial_lte_modem/src/gnss/slm_at_gnss.c b/applications/serial_lte_modem/src/gnss/slm_at_gnss.c index 18aa44ad3b4a..ce7d31bc30ed 100644 --- a/applications/serial_lte_modem/src/gnss/slm_at_gnss.c +++ b/applications/serial_lte_modem/src/gnss/slm_at_gnss.c @@ -214,11 +214,11 @@ static int gnss_startup(void) * the modem will not request new almanacs/ephemerides from the cloud. */ const int64_t gps_sec = utc_to_gps_sec(utc_now_ms / 1000); - struct nrf_modem_gnss_agps_data_system_time_and_sv_tow gps_time = { 0 }; + struct nrf_modem_gnss_agnss_gps_data_system_time_and_sv_tow gps_time = {0}; gps_sec_to_day_time(gps_sec, &gps_time.date_day, &gps_time.time_full_s); - ret = nrf_modem_gnss_agps_write(&gps_time, sizeof(gps_time), - NRF_MODEM_GNSS_AGPS_GPS_SYSTEM_CLOCK_AND_TOWS); + ret = nrf_modem_gnss_agnss_write(&gps_time, sizeof(gps_time), + NRF_MODEM_GNSS_AGNSS_GPS_SYSTEM_CLOCK_AND_TOWS); if (ret) { LOG_WRN("Failed to inject GNSS time (%d).", ret); } else { @@ -298,18 +298,18 @@ static int gnss_shutdown(void) #if defined(CONFIG_SLM_NRF_CLOUD) #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) -static int read_agnss_req(struct nrf_modem_gnss_agps_data_frame *req) +static int read_agnss_req(struct nrf_modem_gnss_agnss_data_frame *req) { int err; err = nrf_modem_gnss_read((void *)req, sizeof(*req), - NRF_MODEM_GNSS_DATA_AGPS_REQ); + NRF_MODEM_GNSS_DATA_AGNSS_REQ); if (err) { return err; } - LOG_DBG("AGPS_REQ.sv_mask_ephe = 0x%08x", req->sv_mask_ephe); - LOG_DBG("AGPS_REQ.sv_mask_alm = 0x%08x", req->sv_mask_alm); + LOG_DBG("AGPS_REQ.sv_mask_ephe = 0x%08x", (uint32_t)req->system[0].sv_mask_ephe); + LOG_DBG("AGPS_REQ.sv_mask_alm = 0x%08x", (uint32_t)req->system[0].sv_mask_alm); LOG_DBG("AGPS_REQ.data_flags = 0x%08x", req->data_flags); return 0; @@ -320,7 +320,7 @@ static int read_agnss_req(struct nrf_modem_gnss_agps_data_frame *req) static void agnss_req_wk(struct k_work *work) { int err; - struct nrf_modem_gnss_agps_data_frame req; + struct nrf_modem_gnss_agnss_data_frame req; ARG_UNUSED(work); @@ -379,10 +379,10 @@ static void pgps_event_handler(struct nrf_cloud_pgps_event *event) break; /* A P-GPS prediction is available now for the current date and time. */ case PGPS_EVT_AVAILABLE: { - LOG_INF("PGPS_EVT_AVAILABLE"); - struct nrf_modem_gnss_agps_data_frame req; + struct nrf_modem_gnss_agnss_data_frame req; - /* read out previous NRF_MODEM_GNSS_EVT_AGPS_REQ */ + LOG_INF("PGPS_EVT_AVAILABLE"); + /* read out previous NRF_MODEM_GNSS_EVT_AGNSS_REQ */ err = read_agnss_req(&req); if (err) { LOG_INF("Failed to read back A-GNSS request (%d)." @@ -588,9 +588,8 @@ static void gnss_event_handler(int event) LOG_INF("GNSS_EVT_FIX"); on_gnss_evt_fix(); break; - case NRF_MODEM_GNSS_EVT_AGPS_REQ: - LOG_INF("GNSS_EVT_AGPS_REQ"); - /* This will send A-GNSS/P-GPS requests only if cloud assistance is enabled. */ + case NRF_MODEM_GNSS_EVT_AGNSS_REQ: + LOG_INF("GNSS_EVT_AGNSS_REQ"); on_gnss_evt_agnss_req(); break; case NRF_MODEM_GNSS_EVT_BLOCKED: diff --git a/applications/serial_lte_modem/src/main.c b/applications/serial_lte_modem/src/main.c index 6e2d5725cc1c..338685bbd611 100644 --- a/applications/serial_lte_modem/src/main.c +++ b/applications/serial_lte_modem/src/main.c @@ -49,6 +49,7 @@ static void indicate_wk(struct k_work *work); BUILD_ASSERT(CONFIG_SLM_WAKEUP_PIN >= 0, "Wake up pin not configured"); NRF_MODEM_LIB_ON_INIT(lwm2m_init_hook, on_modem_lib_init, NULL); +NRF_MODEM_LIB_ON_DFU_RES(main_dfu_hook, on_modem_dfu_res, NULL); static void on_modem_lib_init(int ret, void *ctx) { @@ -265,54 +266,46 @@ void enter_shutdown(void) nrf_regulators_system_off(NRF_REGULATORS_NS); } -bool handle_nrf_modem_lib_init_ret(int ret) +static void on_modem_dfu_res(int dfu_res, void *ctx) { - switch (ret) { - case 0: - return false; /* Initialization successful, no action required. */ + switch (dfu_res) { case NRF_MODEM_DFU_RESULT_OK: - LOG_INF("MODEM UPDATE OK. Will run new firmware"); + LOG_INF("MODEM UPDATE OK. Running new firmware"); slm_fota_stage = FOTA_STAGE_COMPLETE; slm_fota_status = FOTA_STATUS_OK; slm_fota_info = 0; break; case NRF_MODEM_DFU_RESULT_UUID_ERROR: case NRF_MODEM_DFU_RESULT_AUTH_ERROR: - LOG_ERR("MODEM UPDATE ERROR %d. Will run old firmware", ret); + LOG_ERR("MODEM UPDATE ERROR %d. Running old firmware", dfu_res); slm_fota_status = FOTA_STATUS_ERROR; - slm_fota_info = ret; + slm_fota_info = dfu_res; break; case NRF_MODEM_DFU_RESULT_HARDWARE_ERROR: case NRF_MODEM_DFU_RESULT_INTERNAL_ERROR: - LOG_ERR("MODEM UPDATE FATAL ERROR %d. Modem failure", ret); + LOG_ERR("MODEM UPDATE FATAL ERROR %d. Modem failure", dfu_res); slm_fota_status = FOTA_STATUS_ERROR; - slm_fota_info = ret; + slm_fota_info = dfu_res; break; case NRF_MODEM_DFU_RESULT_VOLTAGE_LOW: - LOG_ERR("MODEM UPDATE CANCELLED %d.", ret); + LOG_ERR("MODEM UPDATE CANCELLED %d.", dfu_res); LOG_ERR("Please reboot once you have sufficient power for the DFU"); slm_fota_stage = FOTA_STAGE_ACTIVATE; slm_fota_status = FOTA_STATUS_ERROR; - slm_fota_info = ret; + slm_fota_info = dfu_res; break; default: - if (ret >= 0) { - LOG_WRN("Unhandled nrf_modem_lib_init() return code %d.", ret); - break; - } - /* All non-zero return codes other than DFU result codes are - * considered irrecoverable and a reboot is needed. + LOG_WRN("Unhandled nrf_modem DFU result code %d.", dfu_res); + + /* All unknown return codes are considered irrecoverable and reprogramming + * the modem is needed. */ - LOG_ERR("nRF modem lib initialization failed, error: %d", ret); + LOG_ERR("nRF modem lib initialization failed, error: %d", dfu_res); slm_fota_status = FOTA_STATUS_ERROR; - slm_fota_info = ret; + slm_fota_info = dfu_res; slm_settings_fota_save(); - LOG_WRN("Rebooting..."); - LOG_PANIC(); - sys_reboot(SYS_REBOOT_COLD); break; } - return true; } static void handle_mcuboot_swap_ret(void) @@ -420,6 +413,7 @@ static void indicate_wk(struct k_work *work) int main(void) { uint32_t rr = nrf_power_resetreas_get(NRF_POWER_NS); + enum fota_stage fota_stage; nrf_power_resetreas_clear(NRF_POWER_NS, 0x70017); LOG_DBG("RR: 0x%08x", rr); @@ -434,21 +428,33 @@ int main(void) LOG_WRN("Failed to init slm settings"); } + /* The fota stage is updated in the dfu_callback during modem initialization. + * We store it here to see if a fota was performed during this modem init. + */ + fota_stage = slm_fota_stage; + const int ret = nrf_modem_lib_init(); - if (ret < 0) { + if (ret) { LOG_ERR("Modem library init failed, err: %d", ret); - return ret; + if (ret != -EAGAIN && ret != -EIO) { + return ret; + } else if (ret == -EIO) { + LOG_ERR("Please program full modem firmware with the bootloader or " + "external tools"); + } } + /* Post-FOTA handling */ - if (slm_fota_stage == FOTA_STAGE_ACTIVATE) { - if (slm_fota_type == DFU_TARGET_IMAGE_TYPE_MODEM_DELTA || - slm_fota_type == DFU_TARGET_IMAGE_TYPE_FULL_MODEM) { - slm_finish_modem_fota(ret); + if (fota_stage == FOTA_STAGE_ACTIVATE) { + if (slm_fota_type == DFU_TARGET_IMAGE_TYPE_FULL_MODEM) { +#if defined(CONFIG_SLM_FULL_FOTA) + slm_finish_modem_full_dfu(); +#endif } else if (slm_fota_type == DFU_TARGET_IMAGE_TYPE_MCUBOOT) { handle_mcuboot_swap_ret(); - } else { + } else if (slm_fota_type != DFU_TARGET_IMAGE_TYPE_MODEM_DELTA) { LOG_ERR("Unknown DFU type: %d", slm_fota_type); slm_fota_status = FOTA_STATUS_ERROR; slm_fota_info = -EAGAIN; diff --git a/applications/serial_lte_modem/src/slm_at_commands.c b/applications/serial_lte_modem/src/slm_at_commands.c index dd01f1201387..39e933212089 100644 --- a/applications/serial_lte_modem/src/slm_at_commands.c +++ b/applications/serial_lte_modem/src/slm_at_commands.c @@ -216,33 +216,37 @@ static int handle_at_modemreset(enum at_cmd_type type) unsigned int step = 1; int ret; - do { - ret = nrf_modem_lib_shutdown(); - if (ret != 0) { - break; - } - ++step; + /* The fota stage is updated in the dfu_callback during modem initialization. + * We store it here to see if a fota was performed during this modem init. + */ + enum fota_stage fota_stage = slm_fota_stage; - ret = nrf_modem_lib_init(); - if (ret < 0) { - break; - } - ++step; - if (ret > 0 || (slm_fota_stage == FOTA_STAGE_ACTIVATE - && (slm_fota_type == DFU_TARGET_IMAGE_TYPE_MODEM_DELTA || - slm_fota_type == DFU_TARGET_IMAGE_TYPE_FULL_MODEM))) { - slm_finish_modem_fota(ret); - slm_fota_post_process(); - } + ret = nrf_modem_lib_shutdown(); + if (ret != 0) { + goto out; + } + ++step; - /* Success. */ - rsp_send("\r\n#XMODEMRESET: 0\r\n"); + ret = nrf_modem_lib_init(); + + if ((fota_stage == FOTA_STAGE_ACTIVATE && + (slm_fota_type == DFU_TARGET_IMAGE_TYPE_MODEM_DELTA || + slm_fota_type == DFU_TARGET_IMAGE_TYPE_FULL_MODEM))) { +#if defined(CONFIG_SLM_FULL_FOTA) + slm_finish_modem_full_dfu(); +#endif + slm_fota_post_process(); + } + +out: + if (ret) { + /* Error; print the step that failed and its error code. */ + rsp_send("\r\n#XMODEMRESET: %u,%d\r\n", step, ret); return 0; - } while (0); + } - /* Error; print the step that failed and its error code. */ - rsp_send("\r\n#XMODEMRESET: %u,%d\r\n", step, ret); + rsp_send("\r\n#XMODEMRESET: 0\r\n"); return 0; } diff --git a/applications/serial_lte_modem/src/slm_at_fota.c b/applications/serial_lte_modem/src/slm_at_fota.c index 5cc2717dea7f..385957fbc947 100644 --- a/applications/serial_lte_modem/src/slm_at_fota.c +++ b/applications/serial_lte_modem/src/slm_at_fota.c @@ -456,9 +456,9 @@ static void handle_full_fota_activation_fail(int ret) } #endif -void slm_finish_modem_fota(int modem_lib_init_ret) -{ #if defined(CONFIG_SLM_FULL_FOTA) +void slm_finish_modem_full_dfu(void) +{ int err; if (slm_fota_type == DFU_TARGET_IMAGE_TYPE_FULL_MODEM) { @@ -518,17 +518,6 @@ void slm_finish_modem_fota(int modem_lib_init_ret) else LOG_INF("External flash erase succeeded"); } -#endif - if (slm_fota_type == DFU_TARGET_IMAGE_TYPE_MODEM_DELTA && - handle_nrf_modem_lib_init_ret(modem_lib_init_ret)) { - - LOG_INF("Re-initializing the modem due to ongoing delta modem firmware update."); - /* The second init needs to be done regardless of the return value. - * Refer to the below link for more information on the procedure. - * https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrfxlib/nrf_modem/doc/delta_dfu.html#reinitializing-the-modem-to-run-the-new-firmware - */ - modem_lib_init_ret = nrf_modem_lib_init(); - handle_nrf_modem_lib_init_ret(modem_lib_init_ret); - } } +#endif diff --git a/applications/serial_lte_modem/src/slm_at_fota.h b/applications/serial_lte_modem/src/slm_at_fota.h index 6fd5c3943cda..950a24f7e0b6 100644 --- a/applications/serial_lte_modem/src/slm_at_fota.h +++ b/applications/serial_lte_modem/src/slm_at_fota.h @@ -58,20 +58,14 @@ int slm_at_fota_uninit(void); void slm_fota_post_process(void); /** - * @brief Finishes the modem firmware update. + * @brief Finishes the full modem firmware update. * * This is to be called after the application or modem - * has been rebooted and a modem firmware update is ongoing. + * has been rebooted and a full modem firmware update is ongoing. */ -void slm_finish_modem_fota(int modem_lib_init_ret); - -/** - * @brief Handles @ref nrf_modem_lib_init() return values - * relating to modem firmware update. - * - * @return Whether the modem must be re-initialized. - */ -bool handle_nrf_modem_lib_init_ret(int modem_lib_init_ret); +#if defined(CONFIG_SLM_FULL_FOTA) +void slm_finish_modem_full_dfu(void); +#endif /** @} */ #endif /* SLM_AT_FOTA_ */ diff --git a/applications/serial_lte_modem/src/slm_at_icmp.c b/applications/serial_lte_modem/src/slm_at_icmp.c index b28e1364fcc4..f8b049bf1c38 100644 --- a/applications/serial_lte_modem/src/slm_at_icmp.c +++ b/applications/serial_lte_modem/src/slm_at_icmp.c @@ -247,16 +247,13 @@ static uint32_t send_ping_wait_reply(void) /* Use non-primary PDN if specified, fail if cannot proceed */ if (ping_argv.pdn != 0) { - size_t len; - struct ifreq ifr = { 0 }; + int pdn = ping_argv.pdn; - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "pdn%d", ping_argv.pdn); - len = strlen(ifr.ifr_name); - if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, len) < 0) { - LOG_WRN("Unable to set socket SO_BINDTODEVICE, abort"); + if (setsockopt(fd, SOL_SOCKET, SO_BINDTOPDN, &pdn, sizeof(int))) { + LOG_WRN("Unable to set socket SO_BINDTOPDN, abort"); goto close_end; } - LOG_DBG("Use PDN: %d", ping_argv.pdn); + LOG_DBG("Use PDN: %d", pdn); } else { LOG_DBG("Use PDN: 0"); } diff --git a/applications/serial_lte_modem/src/slm_at_socket.c b/applications/serial_lte_modem/src/slm_at_socket.c index 8f56b02e72af..48f3ccf17c09 100644 --- a/applications/serial_lte_modem/src/slm_at_socket.c +++ b/applications/serial_lte_modem/src/slm_at_socket.c @@ -108,9 +108,9 @@ static int bind_to_device(uint16_t cid) if (cid > 0) { int cid_int = cid; - ret = setsockopt(sock.fd, SOL_SOCKET, SO_BINDTODEVICE, &cid_int, sizeof(int)); + ret = setsockopt(sock.fd, SOL_SOCKET, SO_BINDTOPDN, &cid_int, sizeof(int)); if (ret < 0) { - LOG_ERR("SO_BINDTODEVICE error: %d", -errno); + LOG_ERR("SO_BINDTOPDN error: %d", -errno); } } @@ -306,7 +306,7 @@ static int do_socketopt_set(int option, int value) int ret = 0; switch (option) { - case SO_BINDTODEVICE: + case SO_BINDTOPDN: case SO_REUSEADDR: ret = setsockopt(sock.fd, SOL_SOCKET, option, &value, sizeof(int)); break; diff --git a/doc/nrf/libraries/networking/nrf_cloud_pgps.rst b/doc/nrf/libraries/networking/nrf_cloud_pgps.rst index 8e8d65d24a07..f6504fc79c04 100644 --- a/doc/nrf/libraries/networking/nrf_cloud_pgps.rst +++ b/doc/nrf/libraries/networking/nrf_cloud_pgps.rst @@ -281,7 +281,7 @@ When the application receives the :c:enumerator:`NRF_MODEM_GNSS_EVT_AGPS_REQ` ev This event results in the callback of the application's :c:func:`pgps_event_handler_t` function when a valid P-GPS prediction set is available. It passes the :c:enum:`PGPS_EVT_AVAILABLE` event and a pointer to the :c:struct:`nrf_cloud_pgps_prediction` structure to the handler. -The application must pass this prediction to the :c:func:`nrf_cloud_pgps_inject` function, along with either the :c:struct:`nrf_modem_gnss_agps_data_frame` structure read from the GNSS interface after the :c:enumerator:`NRF_MODEM_GNSS_EVT_AGPS_REQ` event or NULL. +The application must pass this prediction to the :c:func:`nrf_cloud_pgps_inject` function, along with either the :c:struct:`nrf_modem_gnss_agnss_data_frame` structure read from the GNSS interface after the :c:enumerator:`NRF_MODEM_GNSS_EVT_AGPS_REQ` event or NULL. If the device does not move distances longer than a few dozen kilometers before it gets a new GNSS fix, it can pass the latitude and longitude read after the :c:enumerator:`NRF_MODEM_GNSS_EVT_FIX` event to the :c:func:`nrf_cloud_pgps_set_location` function. The P-GPS subsystem uses this stored location for the next GNSS request for position assistance when A-GPS assistance is not enabled or is unavailable. diff --git a/doc/nrf/libraries/others/supl_os_client.rst b/doc/nrf/libraries/others/supl_os_client.rst index cb6951b3762b..cdbd2816aab0 100644 --- a/doc/nrf/libraries/others/supl_os_client.rst +++ b/doc/nrf/libraries/others/supl_os_client.rst @@ -175,7 +175,7 @@ The various steps in the communication session are described below: #. In order to start a SUPL session, the application must first initialize the SUPL client library. This is done by calling the :c:func:`supl_init` function of the SUPL client OS integration library. The function sets up the API and the buffers required for initializing the SUPL client library and invokes the :c:func:`supl_client_init` function with these parameters. -#. The application can then begin the SUPL session by calling the :c:func:`supl_session` function with a copy of the :c:type:`nrf_modem_gnss_agps_data_frame` data that was received through the A-GPS data request event from the GNSS module. +#. The application can then begin the SUPL session by calling the :c:func:`supl_session` function with a copy of the :c:type:`nrf_modem_gnss_agnss_data_frame` data that was received through the A-GPS data request event from the GNSS module. The SUPL client OS integration library generates the following parameters that are necessary for the session: * ``supl_session_ctx_t`` structure from the A-GPS request event data diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index decc624454c7..a2d951dd4809 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -688,7 +688,14 @@ Modem libraries * :ref:`nrf_modem_lib_readme`: - * Added CEREG event tracking to ``lte_connectivity``. + * Added: + + * CEREG event tracking to ``lte_connectivity``. + * The :c:macro:`NRF_MODEM_LIB_ON_DFU_RES` macro to add callbacks for modem DFU results. + + * Replaced the use of :c:macro:`SO_BINDTODEVICE` socket option with :c:macro:`SO_BINDTOPDN` to bind the socket to a PDN. + The new option takes an integer for the PDN ID instead of a string. + * Updated: * The :c:func:`nrf_modem_lib_shutdown` function to allow the modem to be in flight mode (``CFUN=4``) when shutting down the modem. diff --git a/ext/curl/lib/connect.c b/ext/curl/lib/connect.c index a8ee2f2a7e5b..5da3664615c9 100644 --- a/ext/curl/lib/connect.c +++ b/ext/curl/lib/connect.c @@ -242,20 +242,18 @@ timediff_t Curl_timeleft(struct Curl_easy *data, #if defined(CONFIG_NRF_CURL_INTEGRATION) static int bind_with_pdn_id(int fd, const char *pdn_id_str) { - int ret; - size_t len; - struct ifreq ifr = {0}; - - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "pdn%s", pdn_id_str); - len = strlen(ifr.ifr_name); - - ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, len); - if (ret < 0) { - printk("Failed to bind socket with PDN ID %s, error: %d, %s\n", + int ret; + int pdn_int; + + pdn_int = atoi(pdn_id_str); + + ret = setsockopt(fd, SOL_SOCKET, SO_BINDTOPDN, &pdn_int, sizeof(int)); + if (ret < 0) { + printk("Failed to bind socket with PDN ID %s, error: %d, %s\n", pdn_id_str, ret, strerror(ret)); - return -EINVAL; - } - return 0; + return -EINVAL; + } + return 0; } #endif @@ -280,6 +278,7 @@ static CURLcode bindlocal(struct connectdata *conn, const char *dev = data->set.str[STRING_DEVICE]; #if defined(CONFIG_NRF_CURL_INTEGRATION) const char *pdn_id = data->set.str[STRING_DEVICE_PDN_ID]; + int opt_retvalue = -1; #endif int error; @@ -321,12 +320,9 @@ static CURLcode bindlocal(struct connectdata *conn, } /* interface */ if(!is_host) { -#ifdef SO_BINDTODEVICE -#if defined(CONFIG_NRF_CURL_INTEGRATION) - struct ifreq ifr = {0}; - int opt_retvalue = -1; - int len; +#ifdef SO_BINDTOPDN +#if defined(CONFIG_NRF_CURL_INTEGRATION) /* Set PDN based on PDN ID or APN if requested */ if (pdn_id != NULL) { /* Nordic specific --pdn_id option: */ @@ -334,14 +330,22 @@ static CURLcode bindlocal(struct connectdata *conn, if (opt_retvalue != 0) { printk("cannot bind socket with PDN ID %s\n", pdn_id); return CURLE_INTERFACE_FAILED; - } + } + + printf("bindpdn: \"%s\", opt_retvalue : %d\n", pdn_id, opt_retvalue); } - else { +#endif /* defined(CONFIG_NRF_CURL_INTEGRATION) */ +#endif /* SO_BINDTOPDN */ + +#ifdef SO_BINDTODEVICE +#if defined(CONFIG_NRF_CURL_INTEGRATION) + struct ifreq ifr = {0}; + int len; + /* Normal --interface option: */ len = strlen(dev); memcpy(ifr.ifr_name, dev, len); opt_retvalue = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, len); - } printf("bindlocal: dev if \"%s\", opt_retvalue : %d\n", ((pdn_id != NULL) ? pdn_id : dev), opt_retvalue); if(opt_retvalue == 0) { diff --git a/ext/curl/lib/setopt.c b/ext/curl/lib/setopt.c index e19e982574cd..4034c0292e43 100644 --- a/ext/curl/lib/setopt.c +++ b/ext/curl/lib/setopt.c @@ -1791,6 +1791,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #if defined(CONFIG_NRF_CURL_INTEGRATION) case CURLOPT_INTERFACE_PDN_ID: + /* Set what PDN to bind the socket to. */ result = Curl_setstropt(&data->set.str[STRING_DEVICE_PDN_ID], va_arg(param, char *)); break; diff --git a/ext/iperf3/iperf_util.c b/ext/iperf3/iperf_util.c index 2f53eb6e2941..fe5763ab5842 100644 --- a/ext/iperf3/iperf_util.c +++ b/ext/iperf3/iperf_util.c @@ -107,21 +107,19 @@ int getrusage(int who, struct rusage *usage) #if defined (CONFIG_NRF_IPERF3_MULTICONTEXT_SUPPORT) int iperf_util_socket_pdn_id_set(int fd, const char *pdn_id_str) { - int ret; - size_t len; - struct ifreq ifr = {0}; - - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "pdn%s", pdn_id_str); - len = strlen(ifr.ifr_name); - - ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, len); - if (ret < 0) { - printk("Failed to bind socket with PDN ID %s, error: %d, %s\n", + int ret; + int pdn_int; + + pdn_int = atoi(pdn_id_str); + + ret = setsockopt(fd, SOL_SOCKET, SO_BINDTOPDN, &pdn_int, sizeof(int)); + if (ret < 0) { + printk("Failed to bind socket with PDN ID %s, error: %d, %s\n", pdn_id_str, ret, strerror(ret)); - return -EINVAL; - } + return -EINVAL; + } - return 0; + return 0; } #endif /* @@ -223,7 +221,7 @@ void make_cookie(const char *cookie) /* is_closed * * Test if the file descriptor fd is closed. - * + * * Iperf uses this function to test whether a TCP stream socket * is closed, because accepting and denying an invalid connection * in iperf_tcp_accept is not considered an error. @@ -271,7 +269,7 @@ double timeval_diff(struct timeval * tv0, struct timeval * tv1) { double time1, time2; - + time1 = tv0->tv_sec + (tv0->tv_usec / 1000000.0); time2 = tv1->tv_sec + (tv1->tv_usec / 1000000.0); @@ -331,7 +329,7 @@ get_system_info(void) struct utsname uts; memset(buf, 0, 1024); uname(&uts); - snprintf(buf, sizeof(buf), "%s %s %s %s %s", uts.sysname, uts.nodename, + snprintf(buf, sizeof(buf), "%s %s %s %s %s", uts.sysname, uts.nodename, uts.release, uts.version, uts.machine); #endif return buf; @@ -353,44 +351,44 @@ get_optional_features(void) #if !defined(CONFIG_NRF_IPERF3_INTEGRATION) /* not supported */ #if defined(HAVE_CPU_AFFINITY) if (numfeatures > 0) { - strncat(features, ", ", + strncat(features, ", ", sizeof(features) - strlen(features) - 1); } - strncat(features, "CPU affinity setting", + strncat(features, "CPU affinity setting", sizeof(features) - strlen(features) - 1); numfeatures++; #endif /* HAVE_CPU_AFFINITY */ - + #if defined(HAVE_FLOWLABEL) if (numfeatures > 0) { - strncat(features, ", ", + strncat(features, ", ", sizeof(features) - strlen(features) - 1); } - strncat(features, "IPv6 flow label", + strncat(features, "IPv6 flow label", sizeof(features) - strlen(features) - 1); numfeatures++; #endif /* HAVE_FLOWLABEL */ - + #if defined(HAVE_SCTP_H) if (numfeatures > 0) { - strncat(features, ", ", + strncat(features, ", ", sizeof(features) - strlen(features) - 1); } - strncat(features, "SCTP", + strncat(features, "SCTP", sizeof(features) - strlen(features) - 1); numfeatures++; #endif /* HAVE_SCTP_H */ - + #if defined(HAVE_TCP_CONGESTION) if (numfeatures > 0) { - strncat(features, ", ", + strncat(features, ", ", sizeof(features) - strlen(features) - 1); } - strncat(features, "TCP congestion algorithm setting", + strncat(features, "TCP congestion algorithm setting", sizeof(features) - strlen(features) - 1); numfeatures++; #endif /* HAVE_TCP_CONGESTION */ - + #if defined(HAVE_SENDFILE) if (numfeatures > 0) { strncat(features, ", ", @@ -422,7 +420,7 @@ get_optional_features(void) #endif /* HAVE_SSL */ #endif if (numfeatures == 0) { - strncat(features, "None", + strncat(features, "None", sizeof(features) - strlen(features) - 1); } @@ -561,8 +559,8 @@ int daemon(int nochdir, int noclose) /* * Fork again to avoid becoming a session leader. - * This might only matter on old SVr4-derived OSs. - * Note in particular that glibc and FreeBSD libc + * This might only matter on old SVr4-derived OSs. + * Note in particular that glibc and FreeBSD libc * only fork once. */ pid = fork(); diff --git a/include/modem/location.h b/include/modem/location.h index 9f466474044f..3a2d6d5807a2 100644 --- a/include/modem/location.h +++ b/include/modem/location.h @@ -222,7 +222,7 @@ struct location_event_data { * A-GPS notification data frame used by GNSS to let the application know it * needs new assistance data, used with event LOCATION_EVT_GNSS_ASSISTANCE_REQUEST. */ - struct nrf_modem_gnss_agps_data_frame agps_request; + struct nrf_modem_gnss_agnss_data_frame agps_request; #endif #if defined(CONFIG_LOCATION_SERVICE_EXTERNAL) && defined(CONFIG_NRF_CLOUD_PGPS) /** diff --git a/include/modem/nrf_modem_lib.h b/include/modem/nrf_modem_lib.h index be3b350207dc..c1785cdd2135 100644 --- a/include/modem/nrf_modem_lib.h +++ b/include/modem/nrf_modem_lib.h @@ -38,8 +38,20 @@ extern "C" { * Use @ref nrf_modem_lib_init() to initialize in normal mode and * @ref nrf_modem_lib_bootloader_init() to initialize the Modem library in bootloader mode. * - * @return int Zero on success, a positive value @em nrf_modem_dfu when executing - * Modem firmware updates, and negative errno on other failures. + * @retval Zero on success. + * + * @retval -NRF_EPERM The Modem library is already initialized. + * @retval -NRF_EFAULT @c init_params is @c NULL. + * @retval -NRF_ENOLCK Not enough semaphores. + * @retval -NRF_ENOMEM Not enough shared memory. + * @retval -NRF_EINVAL Control region size is incorrect or missing handlers in @c init_params. + * @retval -NRF_ENOTSUPP RPC version mismatch. + * @retval -NRF_ETIMEDOUT Operation timed out. + * @retval -NRF_ACCESS Modem firmware authentication failure. + * @retval -NRF_EAGAIN Modem device firmware upgrade failure. + * DFU is scheduled at next initialization. + * @retval -NRF_EIO Modem device firmware upgrade failure. + * Reprogramming the modem firmware is necessary to recover. */ int nrf_modem_lib_init(void); @@ -54,7 +66,17 @@ int nrf_modem_lib_init(void); * Use @ref nrf_modem_lib_init() to initialize in normal mode and * @ref nrf_modem_lib_bootloader_init() to initialize the Modem library in bootloader mode. * - * @return int Zero on success, non-zero otherwise. + * @retval Zero on success. + * + * @retval -NRF_EPERM The Modem library is already initialized. + * @retval -NRF_EFAULT @c init_params is @c NULL. + * @retval -NRF_ENOLCK Not enough semaphores. + * @retval -NRF_ENOMEM Not enough shared memory. + * @retval -NRF_EINVAL Missing handler in @c init_params. + * @retval -NRF_EACCES Bad root digest. + * @retval -NRF_ETIMEDOUT Operation timed out. + * @retval -NRF_EIO Bootloader fault. + * @retval -NRF_ENOSYS Operation not available. */ int nrf_modem_lib_bootloader_init(void); @@ -67,6 +89,20 @@ int nrf_modem_lib_bootloader_init(void); */ int nrf_modem_lib_shutdown(void); +/** + * @brief Modem library dfu callback struct. + */ +struct nrf_modem_lib_dfu_cb { + /** + * @brief Callback function. + * @param dfu_res The return value of nrf_modem_init() + * @param ctx User-defined context + */ + void (*callback)(int dfu_res, void *ctx); + /** User defined context */ + void *context; +}; + /** * @brief Modem library initialization callback struct. */ @@ -94,6 +130,25 @@ struct nrf_modem_lib_shutdown_cb { void *context; }; +/** + * @brief Define a callback for DFU result @ref nrf_modem_lib_init calls. + * + * The callback function @p _callback is invoked after the library has been initialized. + * + * @note The @c NRF_MODEM_LIB_ON_DFU_RES callback can be used to subscribe to the result of a modem + * DFU operation. + * + * @param name Callback name + * @param _callback Callback function name + * @param _context User-defined context for the callback + */ +#define NRF_MODEM_LIB_ON_DFU_RES(name, _callback, _context) \ + static void _callback(int dfu_res, void *ctx); \ + STRUCT_SECTION_ITERABLE(nrf_modem_lib_dfu_cb, nrf_modem_dfu_hook_##name) = { \ + .callback = _callback, \ + .context = _context, \ + }; + /** * @brief Define a callback for @ref nrf_modem_lib_init calls. * diff --git a/include/net/lwm2m_client_utils_location.h b/include/net/lwm2m_client_utils_location.h index f37b8ff25195..95b4a5ca07cb 100644 --- a/include/net/lwm2m_client_utils_location.h +++ b/include/net/lwm2m_client_utils_location.h @@ -66,7 +66,7 @@ void location_assistance_set_result_code_cb(location_assistance_result_code_cb_t * @return Returns a negative error code (errno.h) indicating * reason of failure or 0 for success. */ -int location_assistance_agps_set_mask(const struct nrf_modem_gnss_agps_data_frame *agps_req); +int location_assistance_agps_set_mask(const struct nrf_modem_gnss_agnss_data_frame *agps_req); /** * @brief Send the A-GPS assistance request to LwM2M server diff --git a/include/net/nrf_cloud_agps.h b/include/net/nrf_cloud_agps.h index d85bd9bbc06e..11b55383db70 100644 --- a/include/net/nrf_cloud_agps.h +++ b/include/net/nrf_cloud_agps.h @@ -35,7 +35,7 @@ extern "C" { * @retval -EACCES Cloud connection is not established; wait for @ref NRF_CLOUD_EVT_READY. * @return A negative value indicates an error. */ -int nrf_cloud_agps_request(const struct nrf_modem_gnss_agps_data_frame *request); +int nrf_cloud_agps_request(const struct nrf_modem_gnss_agnss_data_frame *request); /** @brief Requests all available A-GPS data from nRF Cloud via MQTT. * @@ -63,7 +63,7 @@ int nrf_cloud_agps_process(const char *buf, size_t buf_len); * @param received_elements return copy of requested elements received * since A-GPS request was made */ -void nrf_cloud_agps_processed(struct nrf_modem_gnss_agps_data_frame *received_elements); +void nrf_cloud_agps_processed(struct nrf_modem_gnss_agnss_data_frame *received_elements); /** @brief Query whether A-GPS data has been requested from cloud * diff --git a/include/net/nrf_cloud_pgps.h b/include/net/nrf_cloud_pgps.h index dea956d7ac06..e5619daab7cb 100644 --- a/include/net/nrf_cloud_pgps.h +++ b/include/net/nrf_cloud_pgps.h @@ -15,7 +15,7 @@ #if defined(CONFIG_NRF_MODEM) #include #else -struct nrf_modem_gnss_agps_data_frame; +struct nrf_modem_gnss_agnss_data_frame; #endif #include "nrf_cloud_agps_schema_v1.h" @@ -340,7 +340,7 @@ int nrf_cloud_pgps_update(struct nrf_cloud_pgps_result *file_location); * @return 0 if successful, otherwise a (negative) error code. */ int nrf_cloud_pgps_inject(struct nrf_cloud_pgps_prediction *p, - const struct nrf_modem_gnss_agps_data_frame *request); + const struct nrf_modem_gnss_agnss_data_frame *request); /** @brief Find out if P-GPS update is in progress * diff --git a/include/net/nrf_cloud_rest.h b/include/net/nrf_cloud_rest.h index d035798e19e3..0b8d674c374b 100644 --- a/include/net/nrf_cloud_rest.h +++ b/include/net/nrf_cloud_rest.h @@ -48,7 +48,7 @@ enum nrf_cloud_rest_agps_req_type { NRF_CLOUD_REST_AGPS_REQ_ASSISTANCE, /** Request only location (NRF_CLOUD_AGPS_LOCATION) */ NRF_CLOUD_REST_AGPS_REQ_LOCATION, - /** Request the data specified by nrf_modem_gnss_agps_data_frame */ + /** Request the data specified by nrf_modem_gnss_agnss_data_frame */ NRF_CLOUD_REST_AGPS_REQ_CUSTOM }; @@ -135,7 +135,7 @@ struct nrf_cloud_rest_location_request { struct nrf_cloud_rest_agps_request { enum nrf_cloud_rest_agps_req_type type; /** Required for custom request type (NRF_CLOUD_REST_AGPS_REQ_CUSTOM) */ - struct nrf_modem_gnss_agps_data_frame *agps_req; + struct nrf_modem_gnss_agnss_data_frame *agnss_req; /** Optional; provide network info or set to NULL. The cloud cannot * provide location assistance data if network info is NULL. */ diff --git a/include/supl_os_client.h b/include/supl_os_client.h index 04f89babff47..9f5e3173e3ab 100644 --- a/include/supl_os_client.h +++ b/include/supl_os_client.h @@ -22,13 +22,13 @@ * * @brief Start a SUPL session * - * @param[in] agps_request This contain the information about the AGPS data - * that the GNSS module is requesting from the server. + * @param[in] agnss_request This contain the information about the A-GNSS data + * that the GNSS module is requesting from the server. * * @return 0 SUPL session was successful. * <0 SUPL session failed. */ -int supl_session(const struct nrf_modem_gnss_agps_data_frame *const agps_request); +int supl_session(const struct nrf_modem_gnss_agnss_data_frame *const agnss_request); /** * @brief Setup the API and the buffers required by diff --git a/lib/bin/lwm2m_carrier/os/lwm2m_carrier.c b/lib/bin/lwm2m_carrier/os/lwm2m_carrier.c index b8e15df17578..90e70cc79a48 100644 --- a/lib/bin/lwm2m_carrier/os/lwm2m_carrier.c +++ b/lib/bin/lwm2m_carrier/os/lwm2m_carrier.c @@ -14,6 +14,9 @@ #define LWM2M_CARRIER_THREAD_STACK_SIZE 4096 #define LWM2M_CARRIER_THREAD_PRIORITY K_LOWEST_APPLICATION_THREAD_PRIO +static int nrf_modem_dfu_result; + +NRF_MODEM_LIB_ON_DFU_RES(lwm2m_carrier_dfu_hook, on_modem_lib_dfu, NULL); NRF_MODEM_LIB_ON_INIT(lwm2m_carrier_init_hook, on_modem_lib_init, NULL); NRF_MODEM_LIB_ON_SHUTDOWN(lwm2m_carrier_shutdown_hook, on_modem_lib_shutdown, NULL); @@ -92,42 +95,60 @@ __weak int lwm2m_carrier_event_handler(const lwm2m_carrier_event_t *event) } #endif -static void on_modem_lib_init(int ret, void *ctx) +static void on_modem_lib_dfu(int32_t dfu_res, void *ctx) { - ARG_UNUSED(ctx); - - int result; - - switch (ret) { - case 0: - result = LWM2M_CARRIER_MODEM_INIT_SUCCESS; - break; + switch (dfu_res) { case NRF_MODEM_DFU_RESULT_OK: printk("Modem firmware update successful.\n"); - printk("Modem will run the new firmware after next initialization.\n"); - result = LWM2M_CARRIER_MODEM_INIT_UPDATED; + printk("Modem is running the new firmware.\n"); + nrf_modem_dfu_result = LWM2M_CARRIER_MODEM_INIT_UPDATED; break; case NRF_MODEM_DFU_RESULT_UUID_ERROR: case NRF_MODEM_DFU_RESULT_AUTH_ERROR: printk("Modem firmware update failed.\n"); - printk("Modem will run non-updated firmware on next initialization.\n"); - result = LWM2M_CARRIER_MODEM_INIT_UPDATE_FAILED; + printk("Modem is running non-updated firmware.\n"); + nrf_modem_dfu_result = LWM2M_CARRIER_MODEM_INIT_UPDATE_FAILED; break; case NRF_MODEM_DFU_RESULT_HARDWARE_ERROR: case NRF_MODEM_DFU_RESULT_INTERNAL_ERROR: printk("Modem firmware update failed.\n"); printk("Fatal error.\n"); - result = LWM2M_CARRIER_MODEM_INIT_UPDATE_FAILED; + nrf_modem_dfu_result = LWM2M_CARRIER_MODEM_INIT_UPDATE_FAILED; + break; + case NRF_MODEM_DFU_RESULT_VOLTAGE_LOW: + printk("Modem firmware update failed.\n"); + printk("Low voltage.\n"); + nrf_modem_dfu_result = LWM2M_CARRIER_MODEM_INIT_UPDATE_FAILED; break; - case -NRF_EPERM: + default: + printk("Modem update result %d. Assuming failure\n", dfu_res); + nrf_modem_dfu_result = LWM2M_CARRIER_MODEM_INIT_UPDATE_FAILED; + break; + } +} + +static void on_modem_lib_init(int ret, void *ctx) +{ + ARG_UNUSED(ctx); + + int result; + + if (nrf_modem_dfu_result) { + result = nrf_modem_dfu_result; + } else if (ret == -NRF_EPERM) { printk("Modem already initialized\n"); return; - default: + } else if (ret == 0) { + result = LWM2M_CARRIER_MODEM_INIT_SUCCESS; + } else { printk("Could not initialize modem library.\n"); printk("Fatal error.\n"); result = -EIO; } + /* Reset for a normal init without DFU. */ + nrf_modem_dfu_result = 0; + lwm2m_carrier_on_modem_init(result); } diff --git a/lib/location/Kconfig b/lib/location/Kconfig index ca18cc30c0a3..cf24e1d29d0a 100644 --- a/lib/location/Kconfig +++ b/lib/location/Kconfig @@ -65,6 +65,13 @@ config LOCATION_METHOD_GNSS_VISIBILITY_DETECTION_SAT_LIMIT when A-GPS is used. Without assistance, the value should probably be adjusted, because GNSS acquires satellites more slowly. +config LOCATION_METHOD_GNSS_PRIORITIZE_QZSS_ASSISTANCE + bool "Allow A-GNSS data request when only QZSS assistance is needed" + help + By default, QZSS assistance data is only requested when some other assistance data is + needed at the same time. Enabling this option allows A-GNSS data request to be sent also + when only QZSS assistance data (usually ephemerides) is needed. + endif # LOCATION_METHOD_GNSS if LOCATION_METHOD_WIFI diff --git a/lib/location/location_core.c b/lib/location/location_core.c index d2f698d42798..223ae491a499 100644 --- a/lib/location/location_core.c +++ b/lib/location/location_core.c @@ -505,13 +505,13 @@ void location_core_event_cb_timeout(void) } #if defined(CONFIG_LOCATION_SERVICE_EXTERNAL) && defined(CONFIG_NRF_CLOUD_AGPS) -void location_core_event_cb_agps_request(const struct nrf_modem_gnss_agps_data_frame *request) +void location_core_event_cb_agps_request(const struct nrf_modem_gnss_agnss_data_frame *request) { struct location_event_data agps_request_event_data; LOG_DBG("Request A-GPS data from application: ephe 0x%08x, alm 0x%08x, data_flags 0x%02x", - request->sv_mask_ephe, - request->sv_mask_alm, + (uint32_t)request->system[0].sv_mask_ephe, + (uint32_t)request->system[0].sv_mask_alm, request->data_flags); agps_request_event_data.id = LOCATION_EVT_GNSS_ASSISTANCE_REQUEST; diff --git a/lib/location/location_core.h b/lib/location/location_core.h index ae7467a42a25..62db557d5ee8 100644 --- a/lib/location/location_core.h +++ b/lib/location/location_core.h @@ -67,7 +67,7 @@ void location_core_event_cb(const struct location_data *location); void location_core_event_cb_error(void); void location_core_event_cb_timeout(void); #if defined(CONFIG_LOCATION_SERVICE_EXTERNAL) && defined(CONFIG_NRF_CLOUD_AGPS) -void location_core_event_cb_agps_request(const struct nrf_modem_gnss_agps_data_frame *request); +void location_core_event_cb_agps_request(const struct nrf_modem_gnss_agnss_data_frame *request); #endif #if defined(CONFIG_LOCATION_SERVICE_EXTERNAL) && defined(CONFIG_NRF_CLOUD_PGPS) void location_core_event_cb_pgps_request(const struct gps_pgps_request *request); diff --git a/lib/location/method_gnss.c b/lib/location/method_gnss.c index a63ffaaf7d2b..4e87158bf07c 100644 --- a/lib/location/method_gnss.c +++ b/lib/location/method_gnss.c @@ -56,13 +56,13 @@ BUILD_ASSERT( #define AGPS_REQUEST_HTTPS_RESP_HEADER_SIZE 400 /* Minimum time between two A-GPS data requests in seconds. */ #define AGPS_REQUEST_MIN_INTERVAL (60 * 60) -/* A-GPS data expiration threshold in seconds before requesting fresh data. An 80 minute threshold +/* A-GPS data expiration threshold in minutes before requesting fresh data. An 80 minute threshold * is used because it leaves enough time to try again after an hour if fetching of A-GPS data fails * once. Also, because of overlapping ephemeris validity times, fresh ephemerides are * needed on average every two hours with both 80 minute and shorter expiration thresholds. */ -#define AGPS_EXPIRY_THRESHOLD (80 * 60) -/* P-GPS data expiration threshold is zero seconds, because there is no overlap between +#define AGPS_EXPIRY_THRESHOLD (80) +/* P-GPS data expiration threshold is zero minutes, because there is no overlap between * predictions. */ #define PGPS_EXPIRY_THRESHOLD 0 @@ -76,6 +76,8 @@ BUILD_ASSERT( #define PGPS_EPHE_MIN_COUNT 12 /* A-GPS minimum number of expired almanacs to request all almanacs. */ #define AGPS_ALM_MIN_COUNT 3 +/* PRN of the first QZSS satellite. The range for QZSS PRNs is 193...202. */ +#define FIRST_QZSS_PRN 193 #endif #define VISIBILITY_DETECTION_EXEC_TIME CONFIG_LOCATION_METHOD_GNSS_VISIBILITY_DETECTION_EXEC_TIME @@ -84,8 +86,8 @@ BUILD_ASSERT( static struct k_work method_gnss_start_work; static struct k_work method_gnss_pvt_work; #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) -/* Flag indicating whether nrf_modem_gnss_agps_expiry_get() is supported. If the API is - * supported, NRF_MODEM_GNSS_EVT_AGPS_REQ events are ignored. +/* Flag indicating whether nrf_modem_gnss_agnss_expiry_get() is supported. If the API is + * supported, NRF_MODEM_GNSS_EVT_AGNSS_REQ events are ignored. */ static bool agps_expiry_get_supported; static struct k_work method_gnss_agps_req_event_handle_work; @@ -117,19 +119,21 @@ static K_SEM_DEFINE(entered_psm_mode, 0, 1); static K_SEM_DEFINE(entered_rrc_idle, 1, 1); #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) -static struct nrf_modem_gnss_agps_data_frame agps_request; +static struct nrf_modem_gnss_agnss_data_frame agps_request; #endif #if defined(CONFIG_NRF_CLOUD_PGPS) -static struct nrf_modem_gnss_agps_data_frame pgps_agps_request = { - /* Ephe mask is initially all set, because event PGPS_EVT_AVAILABLE may be received before - * the assistance request from GNSS. If ephe mask would be zero, no predictions would be - * injected. +static struct nrf_modem_gnss_agnss_data_frame pgps_agps_request = { + /* Inject current time by default. */ + .data_flags = NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST, + .system_count = 1, + /* Ephe mask for GPS is initially all set, because event PGPS_EVT_AVAILABLE may be received + * before the assistance request from GNSS. If ephe mask would be zero, no predictions + * would be injected. */ - .sv_mask_ephe = 0xffffffff, - .sv_mask_alm = 0x00000000, - /* Also inject current time by default. */ - .data_flags = NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST + .system[0].system_id = NRF_MODEM_GNSS_SYSTEM_GPS, + .system[0].sv_mask_ephe = 0xffffffff, + .system[0].sv_mask_alm = 0x00000000, }; #endif @@ -162,7 +166,8 @@ static void method_gnss_inject_pgps_work_fn(struct k_work *work) ARG_UNUSED(work); int err; - LOG_DBG("Sending prediction to modem (ephe: 0x%08x)...", pgps_agps_request.sv_mask_ephe); + LOG_DBG("Sending prediction to modem (ephe: 0x%08x)...", + (uint32_t)pgps_agps_request.system[0].sv_mask_ephe); err = nrf_cloud_pgps_inject(prediction, &pgps_agps_request); if (err) { @@ -417,23 +422,32 @@ static void method_gnss_pgps_request_work_fn(struct k_work *item) #endif #if defined(CONFIG_NRF_CLOUD_AGPS) -bool method_gnss_agps_required(struct nrf_modem_gnss_agps_data_frame *request) +static bool method_gnss_agps_required(void) { int32_t time_since_agps_req; + bool ephe_or_alm_required = false; - /* Check if A-GPS data is needed. */ - if (request->sv_mask_ephe == 0 && request->sv_mask_alm == 0 && request->data_flags == 0) { - LOG_DBG("No A-GPS data types requested"); + /* Check if A-GNSS data is needed. */ + for (int i = 0; i < agps_request.system_count; i++) { + if (agps_request.system[i].sv_mask_ephe != 0 || + agps_request.system[i].sv_mask_alm != 0) { + ephe_or_alm_required = true; + break; + } + } + + if (agps_request.data_flags == 0 && !ephe_or_alm_required) { + LOG_DBG("No A-GNSS data types requested"); return false; } - /* A-GPS data is needed, check if enough time has passed since the last A-GPS data + /* A-GNSS data is needed, check if enough time has passed since the last A-GNSS data * request. */ if (agps_req_timestamp != 0) { time_since_agps_req = k_uptime_get() - agps_req_timestamp; if (time_since_agps_req < (AGPS_REQUEST_MIN_INTERVAL * MSEC_PER_SEC)) { - LOG_DBG("Skipping A-GPS request, time since last request: %d s", + LOG_DBG("Skipping A-GNSS request, time since last request: %d s", time_since_agps_req / 1000); return false; } @@ -441,9 +455,26 @@ bool method_gnss_agps_required(struct nrf_modem_gnss_agps_data_frame *request) return true; } -#endif +#endif /* CONFIG_NRF_CLOUD_AGPS */ #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) +static const char *get_system_string(uint8_t system_id) +{ + switch (system_id) { + case NRF_MODEM_GNSS_SYSTEM_INVALID: + return "invalid"; + + case NRF_MODEM_GNSS_SYSTEM_GPS: + return "GPS"; + + case NRF_MODEM_GNSS_SYSTEM_QZSS: + return "QZSS"; + + default: + return "unknown"; + } +} + /* Triggers A-GPS data request and/or injection of P-GPS predictions. * * Before this function is called, the assistance data need from GNSS must be stored into @@ -457,8 +488,8 @@ bool method_gnss_agps_required(struct nrf_modem_gnss_agps_data_frame *request) * all additional assistance is requested at the same time. * * A-GPS and P-GPS: - * Ephemerides are handled by P-GPS. - * Almanacs are handled by A-GPS, but only if the downloaded P-GPS prediction set is longer than + * GPS ephemerides are handled by P-GPS. + * GPS almanacs are handled by A-GPS, but only if the downloaded P-GPS prediction set is longer than * one week. * Additional assistance data is handled by A-GPS. * If any additional assistance data (UTC, Klobuchar, GPS time, integrity or position) is needed, @@ -480,13 +511,13 @@ bool method_gnss_agps_required(struct nrf_modem_gnss_agps_data_frame *request) static void method_gnss_assistance_request(void) { #if defined(CONFIG_NRF_CLOUD_PGPS) - /* Ephemerides come from P-GPS. */ - pgps_agps_request.sv_mask_ephe = agps_request.sv_mask_ephe; + /* GPS ephemerides come from P-GPS. */ + pgps_agps_request.system[0].sv_mask_ephe = agps_request.system[0].sv_mask_ephe; pgps_agps_request.data_flags = agps_request.data_flags; - agps_request.sv_mask_ephe = 0; + agps_request.system[0].sv_mask_ephe = 0; if (CONFIG_NRF_CLOUD_PGPS_NUM_PREDICTIONS <= 42) { - /* Almanacs not needed in this configuration. */ - agps_request.sv_mask_alm = 0; + /* GPS almanacs not needed in this configuration. */ + agps_request.system[0].sv_mask_alm = 0; } if (IS_ENABLED(CONFIG_NRF_CLOUD_AGPS)) { @@ -495,7 +526,7 @@ static void method_gnss_assistance_request(void) } LOG_DBG("P-GPS request sv_mask_ephe: 0x%08x, data_flags 0x%02x", - pgps_agps_request.sv_mask_ephe, pgps_agps_request.data_flags); + (uint32_t)pgps_agps_request.system[0].sv_mask_ephe, pgps_agps_request.data_flags); #endif /* CONFIG_NRF_CLOUD_PGPS */ #if defined(CONFIG_NRF_CLOUD_AGPS) @@ -505,21 +536,56 @@ static void method_gnss_assistance_request(void) * of data. */ agps_request.data_flags = - NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST | - NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST | - NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST | - NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST | - NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST | - NRF_MODEM_GNSS_AGPS_POSITION_REQUEST; + NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST | + NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST | + NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST | + NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST | + NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST; + } + + /* QZSS needs special handling because QZSS ephemerides are valid for a shorter time + * than GPS ephemerides, there are only a few QZSS satellites and GNSS reports unused + * QZSS satellites always as expired. + */ + if (agps_request.system_count > 1) { + if (agps_request.data_flags != 0 || + agps_request.system[0].sv_mask_ephe != 0 || + agps_request.system[0].sv_mask_alm != 0) { + /* QZSS ephemerides are requested always when other assistance data is + * needed. + */ + agps_request.system[1].sv_mask_ephe = 0x3ff; + } else { + /* No other assistance is needed. Request QZSS ephemerides anyway if + * all QZSS ephemerides are expired and QZSS assistance is prioritized. + */ + if (!(agps_request.system[1].sv_mask_ephe == 0x3ff && + IS_ENABLED(CONFIG_LOCATION_METHOD_GNSS_PRIORITIZE_QZSS_ASSISTANCE))) { + agps_request.system[1].sv_mask_ephe = 0x0; + } + } + + /* QZSS almanacs are requested whenever GPS almanacs are requested. */ + if (agps_request.system[0].sv_mask_alm != 0) { + agps_request.system[1].sv_mask_alm = 0x3ff; + } else { + agps_request.system[1].sv_mask_alm = 0x0; + } } - LOG_DBG("A-GPS request sv_mask_ephe: 0x%08x, sv_mask_alm: 0x%08x, data_flags: 0x%02x", - agps_request.sv_mask_ephe, agps_request.sv_mask_alm, agps_request.data_flags); + LOG_DBG("A-GNSS request: data_flags: 0x%02x", agps_request.data_flags); + for (int i = 0; i < agps_request.system_count; i++) { + LOG_DBG("A-GNSS request: %s sv_mask_ephe: 0x%llx, sv_mask_alm: 0x%llx", + get_system_string(agps_request.system[i].system_id), + agps_request.system[i].sv_mask_ephe, + agps_request.system[i].sv_mask_alm); + } - /* Check the request. If no A-GPS data types except ephemeris or almanac are requested, - * jump to P-GPS (if enabled). + /* Check if A-GPS data should be requested. If A-GPS request is not needed, jump to + * P-GPS (if enabled). */ - if (method_gnss_agps_required(&agps_request)) { + if (method_gnss_agps_required()) { enum lte_lc_nw_reg_status reg_status = LTE_LC_NW_REG_NOT_REGISTERED; lte_lc_nw_reg_status_get(®_status); @@ -539,7 +605,7 @@ static void method_gnss_assistance_request(void) #endif /* CONFIG_NRF_CLOUD_AGPS */ #if defined(CONFIG_NRF_CLOUD_PGPS) - if (pgps_agps_request.sv_mask_ephe != 0) { + if (pgps_agps_request.system[0].sv_mask_ephe != 0) { /* When A-GPS is used, the nRF Cloud library also calls this function after * A-GPS data has been processed. However, the call happens too late to trigger * the initial P-GPS data download at the correct stage. @@ -558,13 +624,19 @@ static void method_gnss_agps_req_event_handle_work_fn(struct k_work *item) { int err = nrf_modem_gnss_read(&agps_request, sizeof(agps_request), - NRF_MODEM_GNSS_DATA_AGPS_REQ); + NRF_MODEM_GNSS_DATA_AGNSS_REQ); if (err) { LOG_WRN("Reading A-GPS req data from GNSS failed, error: %d", err); return; } + /* GPS data need is always expected to be present and first in list. */ + __ASSERT(agps_request.system_count > 0, + "GNSS system data need not found"); + __ASSERT(agps_request.system[0].system_id == NRF_MODEM_GNSS_SYSTEM_GPS, + "GPS data need not found"); + method_gnss_assistance_request(); } #endif /* defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) */ @@ -576,7 +648,7 @@ void method_gnss_event_handler(int event) k_work_submit_to_queue(location_core_work_queue_get(), &method_gnss_pvt_work); break; - case NRF_MODEM_GNSS_EVT_AGPS_REQ: + case NRF_MODEM_GNSS_EVT_AGNSS_REQ: #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) if (!agps_expiry_get_supported) { k_work_submit_to_queue( @@ -960,7 +1032,7 @@ static void method_gnss_positioning_work_fn(struct k_work *work) } #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) -/* Processes A-GPS expiry data from nrf_modem_gnss_agps_expiry_get() function. +/* Processes A-GPS expiry data from nrf_modem_gnss_agnss_expiry_get() function. * * This function is only used with modem firmware v1.3.2 or later. With older modem firmware * versions, the logic in this function is handled by GNSS. @@ -985,12 +1057,15 @@ static void method_gnss_positioning_work_fn(struct k_work *work) * provided by GNSS. For some data, there is only a flag indicating whether the data is needed or * not. */ -static bool method_gnss_agps_expiry_process(const struct nrf_modem_gnss_agps_expiry *agps_expiry) +static void method_gnss_agps_expiry_process(const struct nrf_modem_gnss_agnss_expiry *agps_expiry) { uint16_t ephe_expiry_threshold; uint8_t expired_ephes_min_count; - uint8_t expired_ephes = 0; - uint8_t expired_alms = 0; + uint8_t expired_gps_ephes = 0; + uint8_t expired_gps_alms = 0; + bool qzss_supported = false; + uint32_t expired_qzss_ephe_mask = 0; + uint32_t expired_qzss_alm_mask = 0; memset(&agps_request, 0, sizeof(agps_request)); @@ -1000,13 +1075,37 @@ static bool method_gnss_agps_expiry_process(const struct nrf_modem_gnss_agps_exp ephe_expiry_threshold = AGPS_EXPIRY_THRESHOLD; } - for (int i = 0; i < NRF_MODEM_GNSS_NUM_GPS_SATELLITES; i++) { - if (agps_expiry->ephe_expiry[i] <= ephe_expiry_threshold) { - expired_ephes++; + for (int i = 0; i < agps_expiry->sv_count; i++) { + if (agps_expiry->sv[i].system_id == NRF_MODEM_GNSS_SYSTEM_GPS) { + if (agps_expiry->sv[i].ephe_expiry <= ephe_expiry_threshold) { + expired_gps_ephes++; + } + + if (agps_expiry->sv[i].alm_expiry <= AGPS_EXPIRY_THRESHOLD) { + expired_gps_alms++; + } } - if (agps_expiry->alm_expiry[i] <= AGPS_EXPIRY_THRESHOLD) { - expired_alms++; + if (agps_expiry->sv[i].system_id == NRF_MODEM_GNSS_SYSTEM_QZSS) { + qzss_supported = true; + + /* GNSS supports QZSS PRNs 193...202. Only part of these are currently + * deployed, so even after all available QZSS ephemerides and almanancs + * have been injected, GNSS reports the unused ones as expired. + */ + + /* QZSS ephemerides are valid for a maximum of two hours, so no expiry + * is used here. + */ + if (agps_expiry->sv[i].ephe_expiry == 0) { + expired_qzss_ephe_mask |= + 1 << (agps_expiry->sv[i].sv_id - FIRST_QZSS_PRN); + } + + if (agps_expiry->sv[i].alm_expiry < AGPS_EXPIRY_THRESHOLD) { + expired_qzss_alm_mask |= + 1 << (agps_expiry->sv[i].sv_id - FIRST_QZSS_PRN); + } } } @@ -1016,32 +1115,33 @@ static bool method_gnss_agps_expiry_process(const struct nrf_modem_gnss_agps_exp expired_ephes_min_count = AGPS_EPHE_MIN_COUNT; } - if (expired_ephes >= expired_ephes_min_count) { - agps_request.sv_mask_ephe = 0xffffffff; + agps_request.system_count = 1; + agps_request.system[0].system_id = NRF_MODEM_GNSS_SYSTEM_GPS; + if (expired_gps_ephes >= expired_ephes_min_count) { + agps_request.system[0].sv_mask_ephe = 0xffffffff; } - - if (expired_alms >= AGPS_ALM_MIN_COUNT) { - agps_request.sv_mask_alm = 0xffffffff; + if (expired_gps_alms >= AGPS_ALM_MIN_COUNT) { + agps_request.system[0].sv_mask_alm = 0xffffffff; } if (agps_expiry->utc_expiry <= AGPS_EXPIRY_THRESHOLD) { - agps_request.data_flags |= NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST; + agps_request.data_flags |= NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST; } if (agps_expiry->klob_expiry <= AGPS_EXPIRY_THRESHOLD) { - agps_request.data_flags |= NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST; + agps_request.data_flags |= NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST; } if (agps_expiry->neq_expiry <= AGPS_EXPIRY_THRESHOLD) { - agps_request.data_flags |= NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST; + agps_request.data_flags |= NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST; } - if (agps_expiry->data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) { - agps_request.data_flags |= NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST; + if (agps_expiry->data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST) { + agps_request.data_flags |= NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST; } if (agps_expiry->integrity_expiry <= AGPS_EXPIRY_THRESHOLD) { - agps_request.data_flags |= NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST; + agps_request.data_flags |= NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST; } /* Position is reported as being valid for 2h. The uncertainty increases with time, @@ -1051,47 +1151,55 @@ static bool method_gnss_agps_expiry_process(const struct nrf_modem_gnss_agps_exp * Position is only requested when also some other assistance data is needed. */ if (agps_expiry->position_expiry == 0 && - (agps_request.sv_mask_ephe != 0 || - agps_request.sv_mask_alm != 0 || + (agps_request.system[0].sv_mask_ephe != 0 || + agps_request.system[0].sv_mask_alm != 0 || agps_request.data_flags != 0)) { - agps_request.data_flags |= NRF_MODEM_GNSS_AGPS_POSITION_REQUEST; + agps_request.data_flags |= NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST; } - LOG_DBG("Expired ephemerides: %d, almanacs: %d", expired_ephes, expired_alms); + if (qzss_supported) { + agps_request.system_count = 2; + agps_request.system[1].system_id = NRF_MODEM_GNSS_SYSTEM_QZSS; + agps_request.system[1].sv_mask_ephe = expired_qzss_ephe_mask; + agps_request.system[1].sv_mask_alm = expired_qzss_alm_mask; + } - LOG_DBG("Assistance request sv_mask_ephe: 0x%08x, sv_mask_alm: 0x%08x, data_flags: 0x%02x", - agps_request.sv_mask_ephe, agps_request.sv_mask_alm, agps_request.data_flags); + LOG_DBG("GPS: Expired ephemerides: %d, almanacs: %d", expired_gps_ephes, expired_gps_alms); - return agps_request.sv_mask_ephe != 0x0 || - agps_request.sv_mask_alm != 0x0 || - agps_request.data_flags != 0x0; + LOG_DBG("A-GNSS data need: data_flags: 0x%02x", agps_request.data_flags); + for (int i = 0; i < agps_request.system_count; i++) { + LOG_DBG("A-GNSS data need: %s sv_mask_ephe: 0x%llx, sv_mask_alm: 0x%llx", + get_system_string(agps_request.system[i].system_id), + agps_request.system[i].sv_mask_ephe, + agps_request.system[i].sv_mask_alm); + } } /* Queries assistance data need from GNSS. * * To maintain backward compatibility with older modem firmware versions, two different methods are - * supported. If the nrf_modem_gnss_agps_expiry_get() API is not supported (pre-v1.3.2 modem - * firmware), GNSS is briefly started to trigger the NRF_MODEM_GNSS_EVT_AGPS_REQ event from GNSS + * supported. If the nrf_modem_gnss_agnss_expiry_get() API is not supported (pre-v1.3.2 modem + * firmware), GNSS is briefly started to trigger the NRF_MODEM_GNSS_EVT_AGNSS_REQ event from GNSS * in case assistance data is currently needed. */ static void method_gnss_agps_req_work_fn(struct k_work *work) { int err; - struct nrf_modem_gnss_agps_expiry agps_expiry; + struct nrf_modem_gnss_agnss_expiry agps_expiry; - err = nrf_modem_gnss_agps_expiry_get(&agps_expiry); + err = nrf_modem_gnss_agnss_expiry_get(&agps_expiry); if (err) { if (err == -NRF_EOPNOTSUPP) { - LOG_DBG("nrf_modem_gnss_agps_expiry_get() not supported by the modem " + LOG_DBG("nrf_modem_gnss_agnss_expiry_get() not supported by the modem " "firmware"); - /* Start and stop GNSS to trigger NRF_MODEM_GNSS_EVT_AGPS_REQ event if + /* Start and stop GNSS to trigger NRF_MODEM_GNSS_EVT_AGNSS_REQ event if * assistance data is needed. */ nrf_modem_gnss_start(); nrf_modem_gnss_stop(); } else { - LOG_WRN("nrf_modem_gnss_agps_expiry_get() failed, err %d", err); + LOG_WRN("nrf_modem_gnss_agnss_expiry_get() failed, err %d", err); } return; @@ -1099,9 +1207,9 @@ static void method_gnss_agps_req_work_fn(struct k_work *work) agps_expiry_get_supported = true; - if (method_gnss_agps_expiry_process(&agps_expiry)) { - method_gnss_assistance_request(); - } + method_gnss_agps_expiry_process(&agps_expiry); + + method_gnss_assistance_request(); } #endif @@ -1147,10 +1255,11 @@ int method_gnss_location_get(const struct location_request_info *request) #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) k_work_submit_to_queue(location_core_work_queue_get(), &method_gnss_agps_req_work); /* Sleep for a while before submitting the next work, otherwise A-GPS data may not be - * downloaded before GNSS is started. If the nrf_modem_gnss_agps_expiry_get() API is not - * supported, GNSS is briefly started and stopped to trigger the NRF_MODEM_GNSS_EVT_AGPS_REQ - * event, which in turn causes the A-GPS data download work item to be submitted into the - * work queue. This all needs to happen before the work item below is submitted. + * downloaded before GNSS is started. If the nrf_modem_gnss_agnss_expiry_get() API is not + * supported, GNSS is briefly started and stopped to trigger the + * NRF_MODEM_GNSS_EVT_AGNSS_REQ event, which in turn causes the A-GPS data download work + * item to be submitted into the work queue. This all needs to happen before the work item + * below is submitted. */ k_sleep(K_MSEC(100)); #endif diff --git a/lib/lte_link_control/lte_lc_modem_hooks.c b/lib/lte_link_control/lte_lc_modem_hooks.c index 225571a6e651..6be10cd8a2d5 100644 --- a/lib/lte_link_control/lte_lc_modem_hooks.c +++ b/lib/lte_link_control/lte_lc_modem_hooks.c @@ -17,10 +17,6 @@ NRF_MODEM_LIB_ON_SHUTDOWN(lte_lc_shutdown_hook, on_modem_shutdown, NULL); static void on_modem_init(int err, void *ctx) { if (err) { - if (err == NRF_MODEM_DFU_RESULT_OK) { - LOG_DBG("Modem DFU, lte_lc not initialized"); - return; - } LOG_ERR("Modem library init error: %d, lte_lc not initialized", err); return; } diff --git a/lib/nrf_modem_lib/lte_connectivity/lte_connectivity.c b/lib/nrf_modem_lib/lte_connectivity/lte_connectivity.c index 18ff971d00cc..8179032961ca 100644 --- a/lib/nrf_modem_lib/lte_connectivity/lte_connectivity.c +++ b/lib/nrf_modem_lib/lte_connectivity/lte_connectivity.c @@ -212,48 +212,7 @@ static int modem_init(void) { LOG_DBG("Initializing nRF Modem Library"); - int ret = nrf_modem_lib_init(); - - /* Handle return values related to modem DFU. */ - switch (ret) { - case 0: - /* Initialization successful, no action required. */ - LOG_DBG("nRF Modem Library initialized successfully"); - return 0; - case NRF_MODEM_DFU_RESULT_OK: - LOG_DBG("Modem DFU successful. The modem will run the updated " - "firmware after reinitialization."); - break; - case NRF_MODEM_DFU_RESULT_UUID_ERROR: - case NRF_MODEM_DFU_RESULT_AUTH_ERROR: - LOG_ERR("Modem DFU error: %d. The modem will automatically run the previous " - "(non-updated) firmware after reinitialization.", - ret); - break; - case NRF_MODEM_DFU_RESULT_VOLTAGE_LOW: - LOG_ERR("Modem DFU not executed due to low voltage, error: %d. " - "The modem will retry the update on reinitialization.", - ret); - break; - case NRF_MODEM_DFU_RESULT_HARDWARE_ERROR: - case NRF_MODEM_DFU_RESULT_INTERNAL_ERROR: - /* Fall through */ - default: - LOG_ERR("The modem encountered a fatal error during DFU: %d", ret); - return ret; - } - - LOG_DBG("Reinitializing nRF Modem Library"); - - ret = nrf_modem_lib_init(); - if (ret) { - LOG_ERR("Reinitialization of nRF Modem library failed, retval: %d", ret); - return ret; - } - - LOG_DBG("nRF Modem Library reinitialized"); - - return 0; + return nrf_modem_lib_init(); } static void on_pdn_activated(void) diff --git a/lib/nrf_modem_lib/lte_connectivity/lte_connectivity.h b/lib/nrf_modem_lib/lte_connectivity/lte_connectivity.h index b45df7fc20cc..c3f9eb2e7252 100644 --- a/lib/nrf_modem_lib/lte_connectivity/lte_connectivity.h +++ b/lib/nrf_modem_lib/lte_connectivity/lte_connectivity.h @@ -66,8 +66,6 @@ void lte_connectivity_init(struct conn_mgr_conn_binding * const if_conn); * for more information. * * @returns 0 on success, nonzero value on failure. - * If a positive value is returned, modem reinitialization failed. (DFU related) - * DFU related error codes are listed in nrf_modem.h prefixed NRF_MODEM_DFU_RESULT. */ int lte_connectivity_enable(void); diff --git a/lib/nrf_modem_lib/nrf91_sockets.c b/lib/nrf_modem_lib/nrf91_sockets.c index 3b3c8c0e2b21..4ab896064a76 100644 --- a/lib/nrf_modem_lib/nrf91_sockets.c +++ b/lib/nrf_modem_lib/nrf91_sockets.c @@ -27,6 +27,7 @@ #include #include #include +#include #if defined(CONFIG_POSIX_API) #include @@ -93,7 +94,6 @@ static void z_to_nrf_ipv4(const struct sockaddr *z_in, { const struct sockaddr_in *ptr = (const struct sockaddr_in *)z_in; - nrf_out->sin_len = sizeof(struct nrf_sockaddr_in); nrf_out->sin_port = ptr->sin_port; nrf_out->sin_family = NRF_AF_INET; nrf_out->sin_addr.s_addr = ptr->sin_addr.s_addr; @@ -115,7 +115,6 @@ static void z_to_nrf_ipv6(const struct sockaddr *z_in, const struct sockaddr_in6 *ptr = (const struct sockaddr_in6 *)z_in; /* nrf_out->sin6_flowinfo field not used */ - nrf_out->sin6_len = sizeof(struct nrf_sockaddr_in6); nrf_out->sin6_port = ptr->sin6_port; nrf_out->sin6_family = NRF_AF_INET6; memcpy(nrf_out->sin6_addr.s6_addr, ptr->sin6_addr.s6_addr, @@ -128,7 +127,7 @@ static void nrf_to_z_ipv6(struct sockaddr *z_out, { struct sockaddr_in6 *ptr = (struct sockaddr_in6 *)z_out; - /* nrf_sockaddr_in6 fields .sin6_flowinfo and .sin6_len not used */ + /* nrf_sockaddr_in6 field .sin6_flowinfo not used */ ptr->sin6_port = nrf_in->sin6_port; ptr->sin6_family = AF_INET6; memcpy(ptr->sin6_addr.s6_addr, nrf_in->sin6_addr.s6_addr, @@ -197,14 +196,17 @@ static int z_to_nrf_optname(int z_in_level, int z_in_optname, case SO_ERROR: *nrf_out_optname = NRF_SO_ERROR; break; + case SO_EXCEPTIONAL_DATA: + *nrf_out_optname = NRF_SO_EXCEPTIONAL_DATA; + break; case SO_RCVTIMEO: *nrf_out_optname = NRF_SO_RCVTIMEO; break; case SO_SNDTIMEO: *nrf_out_optname = NRF_SO_SNDTIMEO; break; - case SO_BINDTODEVICE: - *nrf_out_optname = NRF_SO_BINDTODEVICE; + case SO_BINDTOPDN: + *nrf_out_optname = NRF_SO_BINDTOPDN; break; case SO_REUSEADDR: *nrf_out_optname = NRF_SO_REUSEADDR; @@ -488,6 +490,18 @@ static int nrf91_socket_offload_setsockopt(void *obj, int level, int optname, void *nrf_optval = (void *)optval; nrf_socklen_t nrf_optlen = optlen; + if ((level == SOL_SOCKET) && (optname == SO_BINDTODEVICE)) { + if (IS_ENABLED(CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER)) { + /* This is used by socket dispatcher in zephyr and is forwarded to the + * offloading layer afterwards. We don't have to do anything in this case. + */ + return 0; + } + + errno = EOPNOTSUPP; + return -1; + } + if (z_to_nrf_optname(level, optname, &nrf_optname) < 0) { errno = ENOPROTOOPT; return -1; diff --git a/lib/nrf_modem_lib/nrf_modem_lib.c b/lib/nrf_modem_lib/nrf_modem_lib.c index 859a7133a6bf..b141311f4c26 100644 --- a/lib/nrf_modem_lib/nrf_modem_lib.c +++ b/lib/nrf_modem_lib/nrf_modem_lib.c @@ -36,6 +36,8 @@ BUILD_ASSERT(IPC_IRQn == NRF_MODEM_IPC_IRQ, "NRF_MODEM_IPC_IRQ mismatch"); */ #define NRF_MODEM_LIB_SHMEM_TX_HEAP_OVERHEAD_SIZE 128 +static void nrf_modem_lib_dfu_handler(uint32_t dfu_res); + static const struct nrf_modem_init_params init_params = { .ipc_irq_prio = CONFIG_NRF_MODEM_LIB_IPC_IRQ_PRIO, .shmem.ctrl = { @@ -57,7 +59,8 @@ static const struct nrf_modem_init_params init_params = { .size = CONFIG_NRF_MODEM_LIB_SHMEM_TRACE_SIZE, }, #endif - .fault_handler = nrf_modem_fault_handler + .fault_handler = nrf_modem_fault_handler, + .dfu_handler = nrf_modem_lib_dfu_handler, }; static const struct nrf_modem_bootloader_init_params bootloader_init_params = { @@ -113,6 +116,15 @@ static void log_fw_version_uuid(void) } } +static void nrf_modem_lib_dfu_handler(uint32_t dfu_res) +{ + LOG_DBG("Modem library update result %d", dfu_res); + STRUCT_SECTION_FOREACH(nrf_modem_lib_dfu_cb, e) { + LOG_DBG("Modem dfu callback: %p", e->callback); + e->callback(dfu_res, e->context); + } +} + static int _nrf_modem_lib_init(void) { int rc; diff --git a/lib/nrf_modem_lib/nrf_modem_lib.ld b/lib/nrf_modem_lib/nrf_modem_lib.ld index c5fa78d93e59..d9d1a60d8d1b 100644 --- a/lib/nrf_modem_lib/nrf_modem_lib.ld +++ b/lib/nrf_modem_lib/nrf_modem_lib.ld @@ -1,4 +1,7 @@ . = ALIGN(4); +_nrf_modem_lib_dfu_cb_list_start = .; +KEEP(*(SORT_BY_NAME("._nrf_modem_lib_dfu_cb.*"))); +_nrf_modem_lib_dfu_cb_list_end = .; _nrf_modem_lib_init_cb_list_start = .; KEEP(*(SORT_BY_NAME("._nrf_modem_lib_init_cb.*"))); _nrf_modem_lib_init_cb_list_end = .; diff --git a/lib/supl/os/supl_os_client.c b/lib/supl/os/supl_os_client.c index 5610d833b5ad..7086cd4ee2b4 100644 --- a/lib/supl/os/supl_os_client.c +++ b/lib/supl/os/supl_os_client.c @@ -124,14 +124,20 @@ static int set_lte_params(void) return 0; } -int supl_session(const struct nrf_modem_gnss_agps_data_frame *const agps_request) +int supl_session(const struct nrf_modem_gnss_agnss_data_frame *const agnss_request) { set_device_id(); set_lte_params(); - supl_client_ctx.agps_types.data_flags = agps_request->data_flags; - supl_client_ctx.agps_types.sv_mask_alm = agps_request->sv_mask_alm; - supl_client_ctx.agps_types.sv_mask_ephe = agps_request->sv_mask_ephe; + /* GPS data need is always expected to be present and first in list. */ + __ASSERT(agnss_request->system_count > 0, + "GNSS system data need not found"); + __ASSERT(agnss_request->system[0].system_id == NRF_MODEM_GNSS_SYSTEM_GPS, + "GPS data need not found"); + + supl_client_ctx.agps_types.data_flags = agnss_request->data_flags; + supl_client_ctx.agps_types.sv_mask_alm = agnss_request->system[0].sv_mask_alm; + supl_client_ctx.agps_types.sv_mask_ephe = agnss_request->system[0].sv_mask_ephe; return supl_client_session(&supl_client_ctx); } diff --git a/samples/cellular/azure_fota/src/main.c b/samples/cellular/azure_fota/src/main.c index e4eaaf3d6aff..1e1888a78728 100644 --- a/samples/cellular/azure_fota/src/main.c +++ b/samples/cellular/azure_fota/src/main.c @@ -190,25 +190,16 @@ static void modem_configure(void) } } -int main(void) +static void on_modem_lib_dfu(int32_t dfu_res, void *ctx) { - int err; - - LOG_INF("Azure FOTA sample started"); - LOG_INF("This may take a while if a modem firmware update is pending"); - - err = nrf_modem_lib_init(); - - switch (err) { + switch (dfu_res) { case NRF_MODEM_DFU_RESULT_OK: - LOG_INF("Modem firmware update successful!"); - LOG_INF("Modem will run the new firmware after reboot"); - k_thread_suspend(k_current_get()); + LOG_DBG("Modem firmware updated"); break; case NRF_MODEM_DFU_RESULT_UUID_ERROR: case NRF_MODEM_DFU_RESULT_AUTH_ERROR: LOG_INF("Modem firmware update failed"); - LOG_INF("Modem will run non-updated firmware on reboot."); + LOG_INF("Modem is running old firmware."); break; case NRF_MODEM_DFU_RESULT_HARDWARE_ERROR: case NRF_MODEM_DFU_RESULT_INTERNAL_ERROR: @@ -219,12 +210,25 @@ int main(void) LOG_INF("Modem firmware update failed"); LOG_INF("Please reboot once you have sufficient power for the DFU."); break; - case -1: + default: + break; + } +} + +NRF_MODEM_LIB_ON_DFU_RES(main_dfu_hook, on_modem_lib_dfu, NULL); + +int main(void) +{ + int err; + + LOG_INF("Azure FOTA sample started"); + LOG_INF("This may take a while if a modem firmware update is pending"); + + err = nrf_modem_lib_init(); + if (err) { LOG_INF("Could not initialize modem library"); LOG_INF("Fatal error."); return 0; - default: - break; } k_work_init_delayable(&reboot_work, reboot_work_fn); diff --git a/samples/cellular/gnss/src/assistance.c b/samples/cellular/gnss/src/assistance.c index 0089cd1e649f..a06a673dfb3e 100644 --- a/samples/cellular/gnss/src/assistance.c +++ b/samples/cellular/gnss/src/assistance.c @@ -29,7 +29,7 @@ static char agps_data_buf[3500]; #endif /* CONFIG_NRF_CLOUD_AGPS */ #if defined(CONFIG_NRF_CLOUD_PGPS) -static struct nrf_modem_gnss_agps_data_frame agps_need; +static struct nrf_modem_gnss_agnss_data_frame agnss_need; static struct gps_pgps_request pgps_request; static struct nrf_cloud_pgps_prediction *prediction; static struct k_work get_pgps_data_work; @@ -158,7 +158,7 @@ static void inject_pgps_data_work_fn(struct k_work *work) LOG_INF("Injecting P-GPS ephemerides"); - err = nrf_cloud_pgps_inject(prediction, &agps_need); + err = nrf_cloud_pgps_inject(prediction, &agnss_need); if (err) { LOG_ERR("Failed to inject P-GPS ephemerides"); } @@ -203,6 +203,25 @@ static void pgps_event_handler(struct nrf_cloud_pgps_event *event) } #endif /* CONFIG_NRF_CLOUD_PGPS */ +#if defined(CONFIG_NRF_CLOUD_AGPS) +static const char *get_system_string(uint8_t system_id) +{ + switch (system_id) { + case NRF_MODEM_GNSS_SYSTEM_INVALID: + return "invalid"; + + case NRF_MODEM_GNSS_SYSTEM_GPS: + return "GPS"; + + case NRF_MODEM_GNSS_SYSTEM_QZSS: + return "QZSS"; + + default: + return "unknown"; + } +} +#endif /* CONFIG_NRF_CLOUD_AGPS */ + int assistance_init(struct k_work_q *assistance_work_q) { work_q = assistance_work_q; @@ -227,25 +246,25 @@ int assistance_init(struct k_work_q *assistance_work_q) return 0; } -int assistance_request(struct nrf_modem_gnss_agps_data_frame *agps_request) +int assistance_request(struct nrf_modem_gnss_agnss_data_frame *agnss_request) { int err = 0; #if defined(CONFIG_NRF_CLOUD_PGPS) /* Store the A-GPS data request for P-GPS use. */ - memcpy(&agps_need, agps_request, sizeof(agps_need)); + memcpy(&agnss_need, agnss_request, sizeof(agnss_need)); #if defined(CONFIG_NRF_CLOUD_AGPS) - if (!agps_request->data_flags) { + if (!agnss_request->data_flags) { /* No assistance needed from A-GPS, skip directly to P-GPS. */ nrf_cloud_pgps_notify_prediction(); return 0; } - /* P-GPS will handle ephemerides, so skip those. */ - agps_request->sv_mask_ephe = 0; - /* Almanacs are not needed with P-GPS, so skip those. */ - agps_request->sv_mask_alm = 0; + /* P-GPS will handle GPS ephemerides, so skip those. */ + agnss_request->system[0].sv_mask_ephe = 0; + /* GPS almanacs are not needed with P-GPS, so skip those. */ + agnss_request->system[0].sv_mask_alm = 0; #endif /* CONFIG_NRF_CLOUD_AGPS */ #endif /* CONFIG_NRF_CLOUD_PGPS */ #if defined(CONFIG_NRF_CLOUD_AGPS) @@ -273,7 +292,7 @@ int assistance_request(struct nrf_modem_gnss_agps_data_frame *agps_request) struct nrf_cloud_rest_agps_request request = { .type = NRF_CLOUD_REST_AGPS_REQ_CUSTOM, - .agps_req = agps_request, + .agnss_req = agnss_request, .net_info = NULL, #if defined(CONFIG_NRF_CLOUD_AGPS_FILTERED_RUNTIME) .filtered = true, @@ -307,10 +326,13 @@ int assistance_request(struct nrf_modem_gnss_agps_data_frame *agps_request) request.net_info = &net_info; } - LOG_INF("Requesting A-GPS data, ephe 0x%08x, alm 0x%08x, flags 0x%02x", - agps_request->sv_mask_ephe, - agps_request->sv_mask_alm, - agps_request->data_flags); + LOG_INF("Requesting A-GNSS data: data_flags: 0x%02x", agnss_request->data_flags); + for (int i = 0; i < agnss_request->system_count; i++) { + LOG_INF("Requesting A-GNSS data: %s ephe: 0x%llx, alm: 0x%llx", + get_system_string(agnss_request->system[i].system_id), + agnss_request->system[i].sv_mask_ephe, + agnss_request->system[i].sv_mask_alm); + } err = nrf_cloud_rest_agps_data_get(&rest_ctx, &request, &result); if (err) { diff --git a/samples/cellular/gnss/src/assistance.h b/samples/cellular/gnss/src/assistance.h index 600da9f1410f..240de4693cd0 100644 --- a/samples/cellular/gnss/src/assistance.h +++ b/samples/cellular/gnss/src/assistance.h @@ -26,12 +26,12 @@ int assistance_init(struct k_work_q *assistance_work_q); * * @details Fetches and injects assistance data to the GNSS. * - * @param[in] agps_request A-GPS data requested by GNSS. + * @param[in] agnss_request A-GNSS data requested by GNSS. * * @retval 0 on success. * @retval <0 in case of an error. */ -int assistance_request(struct nrf_modem_gnss_agps_data_frame *agps_request); +int assistance_request(struct nrf_modem_gnss_agnss_data_frame *agnss_request); /** * @brief Returns assistance module state. diff --git a/samples/cellular/gnss/src/assistance_minimal.c b/samples/cellular/gnss/src/assistance_minimal.c index d74b83ad3534..3baa3c519329 100644 --- a/samples/cellular/gnss/src/assistance_minimal.c +++ b/samples/cellular/gnss/src/assistance_minimal.c @@ -147,7 +147,7 @@ static void time_inject(void) struct tm date_time; int64_t utc_sec; int64_t gps_sec; - struct nrf_modem_gnss_agps_data_system_time_and_sv_tow gps_time = { 0 }; + struct nrf_modem_gnss_agnss_gps_data_system_time_and_sv_tow gps_time = { 0 }; /* Read current UTC time from the modem. */ ret = nrf_modem_at_scanf("AT+CCLK?", @@ -175,8 +175,8 @@ static void time_inject(void) gps_sec_to_day_time(gps_sec, &gps_time.date_day, &gps_time.time_full_s); - ret = nrf_modem_gnss_agps_write(&gps_time, sizeof(gps_time), - NRF_MODEM_GNSS_AGPS_GPS_SYSTEM_CLOCK_AND_TOWS); + ret = nrf_modem_gnss_agnss_write(&gps_time, sizeof(gps_time), + NRF_MODEM_GNSS_AGNSS_GPS_SYSTEM_CLOCK_AND_TOWS); if (ret != 0) { LOG_ERR("Failed to inject time, error %d", ret); return; @@ -192,7 +192,7 @@ static void location_inject(void) char plmn_str[PLMN_STR_MAX_LEN + 1]; uint16_t mcc; const struct mcc_table *mcc_info; - struct nrf_modem_gnss_agps_data_location location = { 0 }; + struct nrf_modem_gnss_agnss_data_location location = { 0 }; /* Read PLMN string from modem to get the MCC. */ err = nrf_modem_at_scanf( @@ -244,7 +244,8 @@ static void location_inject(void) location.unc_altitude = 255; /* altitude not used */ } - err = nrf_modem_gnss_agps_write(&location, sizeof(location), NRF_MODEM_GNSS_AGPS_LOCATION); + err = nrf_modem_gnss_agnss_write( + &location, sizeof(location), NRF_MODEM_GNSS_AGNSS_LOCATION); if (err) { LOG_ERR("Failed to inject location for MCC %u, error %d", mcc, err); return; @@ -282,13 +283,13 @@ int assistance_init(struct k_work_q *assistance_work_q) return 0; } -int assistance_request(struct nrf_modem_gnss_agps_data_frame *agps_request) +int assistance_request(struct nrf_modem_gnss_agnss_data_frame *agnss_request) { - if (agps_request->data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) { + if (agnss_request->data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST) { time_inject(); } - if (agps_request->data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST) { + if (agnss_request->data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST) { location_inject(); } diff --git a/samples/cellular/gnss/src/assistance_supl.c b/samples/cellular/gnss/src/assistance_supl.c index a974e8492557..f35896771445 100644 --- a/samples/cellular/gnss/src/assistance_supl.c +++ b/samples/cellular/gnss/src/assistance_supl.c @@ -51,14 +51,14 @@ static int inject_agps_type(void *agps, size_t agps_size, uint16_t type, void *u { ARG_UNUSED(user_data); - int retval = nrf_modem_gnss_agps_write(agps, agps_size, type); + int retval = nrf_modem_gnss_agnss_write(agps, agps_size, type); if (retval != 0) { - LOG_ERR("Failed to write A-GPS data, type: %d (errno: %d)", type, errno); + LOG_ERR("Failed to write A-GNSS data, type: %d (errno: %d)", type, errno); return -1; } - LOG_INF("Injected A-GPS data, type: %d, size: %d", type, agps_size); + LOG_INF("Injected A-GNSS data, type: %d, size: %d", type, agps_size); return 0; } @@ -194,7 +194,7 @@ int assistance_init(struct k_work_q *assistance_work_q) return 0; } -int assistance_request(struct nrf_modem_gnss_agps_data_frame *agps_request) +int assistance_request(struct nrf_modem_gnss_agnss_data_frame *agnss_request) { int err; @@ -206,7 +206,7 @@ int assistance_request(struct nrf_modem_gnss_agps_data_frame *agps_request) } LOG_INF("Starting SUPL session"); - err = supl_session(agps_request); + err = supl_session(agnss_request); LOG_INF("Done"); close_supl_socket(); diff --git a/samples/cellular/gnss/src/main.c b/samples/cellular/gnss/src/main.c index 4c5bfa3b27c9..2777776ca136 100644 --- a/samples/cellular/gnss/src/main.c +++ b/samples/cellular/gnss/src/main.c @@ -33,8 +33,8 @@ K_THREAD_STACK_DEFINE(gnss_workq_stack_area, GNSS_WORKQ_THREAD_STACK_SIZE); #if !defined(CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE) #include "assistance.h" -static struct nrf_modem_gnss_agps_data_frame last_agps; -static struct k_work agps_data_get_work; +static struct nrf_modem_gnss_agnss_data_frame last_agnss; +static struct k_work agnss_data_get_work; static volatile bool requesting_assistance; #endif /* !CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE */ @@ -164,13 +164,13 @@ static void gnss_event_handler(int event) } break; - case NRF_MODEM_GNSS_EVT_AGPS_REQ: + case NRF_MODEM_GNSS_EVT_AGNSS_REQ: #if !defined(CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE) - retval = nrf_modem_gnss_read(&last_agps, - sizeof(last_agps), - NRF_MODEM_GNSS_DATA_AGPS_REQ); + retval = nrf_modem_gnss_read(&last_agnss, + sizeof(last_agnss), + NRF_MODEM_GNSS_DATA_AGNSS_REQ); if (retval == 0) { - k_work_submit_to_queue(&gnss_work_q, &agps_data_get_work); + k_work_submit_to_queue(&gnss_work_q, &agnss_data_get_work); } #endif /* !CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE */ break; @@ -232,20 +232,43 @@ void lte_disconnect(void) } #endif /* CONFIG_GNSS_SAMPLE_LTE_ON_DEMAND */ -static void agps_data_get_work_fn(struct k_work *item) +static const char *get_system_string(uint8_t system_id) +{ + switch (system_id) { + case NRF_MODEM_GNSS_SYSTEM_INVALID: + return "invalid"; + + case NRF_MODEM_GNSS_SYSTEM_GPS: + return "GPS"; + + case NRF_MODEM_GNSS_SYSTEM_QZSS: + return "QZSS"; + + default: + return "unknown"; + } +} + +static void agnss_data_get_work_fn(struct k_work *item) { ARG_UNUSED(item); int err; + /* GPS data need is always expected to be present and first in list. */ + __ASSERT(last_agnss.system_count > 0, + "GNSS system data need not found"); + __ASSERT(last_agnss.system[0].system_id == NRF_MODEM_GNSS_SYSTEM_GPS, + "GPS data need not found"); + #if defined(CONFIG_GNSS_SAMPLE_ASSISTANCE_SUPL) /* SUPL doesn't usually provide NeQuick ionospheric corrections and satellite real time * integrity information. If GNSS asks only for those, the request should be ignored. */ - if (last_agps.sv_mask_ephe == 0 && - last_agps.sv_mask_alm == 0 && - (last_agps.data_flags & ~(NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST | - NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST)) == 0) { + if (last_agnss.system[0].sv_mask_ephe == 0 && + last_agnss.system[0].sv_mask_alm == 0 && + (last_agnss.data_flags & ~(NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST)) == 0) { LOG_INF("Ignoring assistance request for only NeQuick and/or integrity"); return; } @@ -255,25 +278,35 @@ static void agps_data_get_work_fn(struct k_work *item) /* With minimal assistance, the request should be ignored if no GPS time or position * is requested. */ - if (!(last_agps.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) && - !(last_agps.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST)) { + if (!(last_agnss.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST) && + !(last_agnss.data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST)) { LOG_INF("Ignoring assistance request because no GPS time or position is requested"); return; } #endif /* CONFIG_GNSS_SAMPLE_ASSISTANCE_MINIMAL */ + if (last_agnss.data_flags == 0 && + last_agnss.system[0].sv_mask_ephe == 0 && + last_agnss.system[0].sv_mask_alm == 0) { + LOG_INF("Ignoring assistance request because only QZSS data is requested"); + return; + } + requesting_assistance = true; - LOG_INF("Assistance data needed, ephe 0x%08x, alm 0x%08x, flags 0x%02x", - last_agps.sv_mask_ephe, - last_agps.sv_mask_alm, - last_agps.data_flags); + LOG_INF("Assistance data needed: data_flags: 0x%02x", last_agnss.data_flags); + for (int i = 0; i < last_agnss.system_count; i++) { + LOG_INF("Assistance data needed: %s ephe: 0x%llx, alm: 0x%llx", + get_system_string(last_agnss.system[i].system_id), + last_agnss.system[i].sv_mask_ephe, + last_agnss.system[i].sv_mask_alm); + } #if defined(CONFIG_GNSS_SAMPLE_LTE_ON_DEMAND) lte_connect(); #endif /* CONFIG_GNSS_SAMPLE_LTE_ON_DEMAND */ - err = assistance_request(&last_agps); + err = assistance_request(&last_agnss); if (err) { LOG_ERR("Failed to request assistance data"); } @@ -328,6 +361,22 @@ static int ttff_test_force_cold_start(void) return 0; } +#if defined(CONFIG_GNSS_SAMPLE_ASSISTANCE_NRF_CLOUD) +static bool qzss_assistance_is_supported(void) +{ + char resp[32]; + + if (nrf_modem_at_cmd(resp, sizeof(resp), "AT+CGMM") == 0) { + /* nRF9160 does not support QZSS assistance, while nRF91x1 do. */ + if (strstr(resp, "nRF9160") != NULL) { + return false; + } + } + + return true; +} +#endif /* CONFIG_GNSS_SAMPLE_ASSISTANCE_NRF_CLOUD */ + static void ttff_test_prepare_work_fn(struct k_work *item) { /* Make sure GNSS is stopped before next start. */ @@ -341,20 +390,28 @@ static void ttff_test_prepare_work_fn(struct k_work *item) #if !defined(CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE) if (IS_ENABLED(CONFIG_GNSS_SAMPLE_MODE_TTFF_TEST_COLD_START)) { - /* All A-GPS data is always requested before GNSS is started. */ - last_agps.sv_mask_ephe = 0xffffffff; - last_agps.sv_mask_alm = 0xffffffff; - last_agps.data_flags = - NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST | - NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST | - NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST | - NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST | - NRF_MODEM_GNSS_AGPS_POSITION_REQUEST | - NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST; - - k_work_submit_to_queue(&gnss_work_q, &agps_data_get_work); + /* All A-GNSS data is always requested before GNSS is started. */ + last_agnss.data_flags = + NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST | + NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST | + NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST | + NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST | + NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST; + last_agnss.system_count = 1; + last_agnss.system[0].sv_mask_ephe = 0xffffffff; + last_agnss.system[0].sv_mask_alm = 0xffffffff; +#if defined(CONFIG_GNSS_SAMPLE_ASSISTANCE_NRF_CLOUD) + if (qzss_assistance_is_supported()) { + last_agnss.system_count = 2; + last_agnss.system[1].sv_mask_ephe = 0x3ff; + last_agnss.system[1].sv_mask_alm = 0x3ff; + } +#endif /* CONFIG_GNSS_SAMPLE_ASSISTANCE_NRF_CLOUD */ + + k_work_submit_to_queue(&gnss_work_q, &agnss_data_get_work); } else { - /* Start and stop GNSS to trigger possible A-GPS data request. If new A-GPS + /* Start and stop GNSS to trigger possible A-GNSS data request. If new A-GNSS * data is needed it is fetched before GNSS is started. */ nrf_modem_gnss_start(); @@ -442,7 +499,7 @@ static int sample_init(void) #endif /* !CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE || CONFIG_GNSS_SAMPLE_MODE_TTFF_TEST */ #if !defined(CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE) - k_work_init(&agps_data_get_work, agps_data_get_work_fn); + k_work_init(&agnss_data_get_work, agnss_data_get_work_fn); err = assistance_init(&gnss_work_q); #endif /* !CONFIG_GNSS_SAMPLE_ASSISTANCE_NONE */ diff --git a/samples/cellular/http_update/modem_delta_update/src/main.c b/samples/cellular/http_update/modem_delta_update/src/main.c index 6f24467a9e0e..d808d4886844 100644 --- a/samples/cellular/http_update/modem_delta_update/src/main.c +++ b/samples/cellular/http_update/modem_delta_update/src/main.c @@ -77,27 +77,16 @@ static int num_leds(void) } } -int main(void) +static void on_modem_lib_dfu(int32_t dfu_res, void *ctx) { - int err; - - printk("HTTP delta modem update sample started\n"); - - printk("Initializing modem library\n"); - - err = nrf_modem_lib_init(); - switch (err) { + switch (dfu_res) { case NRF_MODEM_DFU_RESULT_OK: - printk("Modem firmware update successful!\n"); - printk("Modem will run the new firmware after reboot\n"); - printk("Press 'Reset' button or enter 'reset' to apply new firmware\n"); - k_thread_suspend(k_current_get()); + printk("Modem firmware updated\n"); break; case NRF_MODEM_DFU_RESULT_UUID_ERROR: case NRF_MODEM_DFU_RESULT_AUTH_ERROR: printk("Modem firmware update failed\n"); - printk("Modem will run non-updated firmware on reboot.\n"); - printk("Press 'Reset' button or enter 'reset'\n"); + printk("Modem is running the old firmware.\n"); break; case NRF_MODEM_DFU_RESULT_HARDWARE_ERROR: case NRF_MODEM_DFU_RESULT_INTERNAL_ERROR: @@ -108,13 +97,27 @@ int main(void) printk("Modem firmware update failed\n"); printk("Please reboot once you have sufficient power for the DFU.\n"); break; - case -1: - printk("Could not initialize momdem library.\n"); - printk("Fatal error.\n"); - return 0; default: break; } +} + +NRF_MODEM_LIB_ON_DFU_RES(main_dfu_hook, on_modem_lib_dfu, NULL); + +int main(void) +{ + int err; + + printk("HTTP delta modem update sample started\n"); + + printk("Initializing modem library\n"); + + err = nrf_modem_lib_init(); + if (err) { + printk("Could not initialize momdem library, err %d\n", err); + return 0; + } + printk("Initialized modem library\n"); err = fota_download_init(fota_dl_handler); diff --git a/samples/cellular/lte_ble_gateway/src/main.c b/samples/cellular/lte_ble_gateway/src/main.c index e6b6a1303087..a9bff9914444 100644 --- a/samples/cellular/lte_ble_gateway/src/main.c +++ b/samples/cellular/lte_ble_gateway/src/main.c @@ -165,11 +165,11 @@ void nrf_modem_fault_handler(struct nrf_modem_fault_info *fault_info) static void agps_request(struct k_work *work) { int retval; - struct nrf_modem_gnss_agps_data_frame agps_data; + struct nrf_modem_gnss_agnss_data_frame agps_data; if (!nrf_cloud_agps_request_in_progress()) { retval = nrf_modem_gnss_read(&agps_data, sizeof(agps_data), - NRF_MODEM_GNSS_DATA_AGPS_REQ); + NRF_MODEM_GNSS_DATA_AGNSS_REQ); if (retval) { LOG_ERR("Failed to read AGPS data, err %d", retval); return; @@ -223,7 +223,7 @@ static void gnss_event_handler(int event) } return; - case NRF_MODEM_GNSS_EVT_AGPS_REQ: + case NRF_MODEM_GNSS_EVT_AGNSS_REQ: LOG_INF("Requesting AGPS Data"); k_work_submit(&agps_request_work); return; diff --git a/samples/cellular/lwm2m_client/src/events/include/location_events.h b/samples/cellular/lwm2m_client/src/events/include/location_events.h index d42c73924481..cf834319e1c1 100644 --- a/samples/cellular/lwm2m_client/src/events/include/location_events.h +++ b/samples/cellular/lwm2m_client/src/events/include/location_events.h @@ -15,7 +15,7 @@ struct gnss_agps_request_event { struct app_event_header header; - struct nrf_modem_gnss_agps_data_frame agps_req; + struct nrf_modem_gnss_agnss_data_frame agps_req; }; APP_EVENT_TYPE_DECLARE(gnss_agps_request_event); diff --git a/samples/cellular/lwm2m_client/src/sensors/gnss_module.c b/samples/cellular/lwm2m_client/src/sensors/gnss_module.c index 8edd212822a0..75e042042922 100644 --- a/samples/cellular/lwm2m_client/src/sensors/gnss_module.c +++ b/samples/cellular/lwm2m_client/src/sensors/gnss_module.c @@ -26,7 +26,7 @@ LOG_MODULE_REGISTER(gnss_module, CONFIG_APP_LOG_LEVEL); static struct nrf_modem_gnss_pvt_data_frame pvt_data; #if defined(CONFIG_LWM2M_CLIENT_UTILS_LOCATION_ASSIST_AGPS) || \ defined(CONFIG_LWM2M_CLIENT_UTILS_LOCATION_ASSIST_PGPS) -static struct nrf_modem_gnss_agps_data_frame agps_req; +static struct nrf_modem_gnss_agnss_data_frame agps_req; #endif static bool running; @@ -94,12 +94,12 @@ static void gnss_event_handler(int event_id) APP_EVENT_SUBMIT(event); break; } - case NRF_MODEM_GNSS_EVT_AGPS_REQ: { + case NRF_MODEM_GNSS_EVT_AGNSS_REQ: { #if defined(CONFIG_LWM2M_CLIENT_UTILS_LOCATION_ASSIST_AGPS) || \ defined(CONFIG_LWM2M_CLIENT_UTILS_LOCATION_ASSIST_PGPS) LOG_INF("GPS requests AGPS Data. Sending request to LwM2M server"); err = nrf_modem_gnss_read(&agps_req, sizeof(agps_req), - NRF_MODEM_GNSS_DATA_AGPS_REQ); + NRF_MODEM_GNSS_DATA_AGNSS_REQ); if (err) { LOG_ERR("Error reading AGPS request (%d)", err); } diff --git a/samples/cellular/modem_shell/src/fota/fota.c b/samples/cellular/modem_shell/src/fota/fota.c index 6e458e914cf9..3ef2e1f59005 100644 --- a/samples/cellular/modem_shell/src/fota/fota.c +++ b/samples/cellular/modem_shell/src/fota/fota.c @@ -16,35 +16,20 @@ #include "link.h" #include "mosh_print.h" -static void modem_update_apply(void) +static void on_modem_lib_dfu(int dfu_res, void *ctx) { - int err; - - link_func_mode_set(LTE_LC_FUNC_MODE_OFFLINE, true); - - mosh_print("FOTA: Shutting down modem to trigger DFU update..."); - - err = nrf_modem_lib_shutdown(); - if (err) { - mosh_warn("FOTA: Failed to shut down modem, err: %d", err); - } - - err = nrf_modem_lib_init(); - switch (err) { - case 0: - mosh_error("FOTA: Expected DFU result from modem library, " - "but no DFU was triggered"); - goto exit; + switch (dfu_res) { case NRF_MODEM_DFU_RESULT_OK: mosh_print("FOTA: Modem firmware update successful!"); - goto restart_modem; + break; case NRF_MODEM_DFU_RESULT_UUID_ERROR: case NRF_MODEM_DFU_RESULT_AUTH_ERROR: - mosh_error("FOTA: Modem firmware update failed, err: 0x%08x", err); - goto restart_modem; + mosh_error("FOTA: Modem firmware update failed, err: 0x%08x", dfu_res); + mosh_error("FOTA: Modem is running previous firmware"); + break; case NRF_MODEM_DFU_RESULT_HARDWARE_ERROR: case NRF_MODEM_DFU_RESULT_INTERNAL_ERROR: - mosh_error("FOTA: Fatal error, modem firmware update failed, err: 0x%08x", err); + mosh_error("FOTA: Fatal error, modem firmware update failed, err: 0x%08x", dfu_res); __ASSERT(false, "Modem firmware update failed on fatal error"); case NRF_MODEM_DFU_RESULT_VOLTAGE_LOW: mosh_error("FOTA: Modem firmware update cancelled due to low voltage"); @@ -52,12 +37,21 @@ static void modem_update_apply(void) __ASSERT(false, "Modem firmware update cancelled due to low voltage"); default: /* Modem library initialization failed. */ - mosh_error("FOTA: Fatal error, could not initialize nrf_modem_lib, err: %d", err); + mosh_error("FOTA: Fatal error, could not initialize nrf_modem_lib, err: %d", + dfu_res); __ASSERT(false, "Could not initialize nrf_modem_lib"); } +} + +NRF_MODEM_LIB_ON_DFU_RES(fota_dfu_hook, on_modem_lib_dfu, NULL); -restart_modem: - mosh_print("FOTA: Restarting modem..."); +static void modem_update_apply(void) +{ + int err; + + link_func_mode_set(LTE_LC_FUNC_MODE_OFFLINE, true); + + mosh_print("FOTA: Shutting down modem to trigger DFU update..."); err = nrf_modem_lib_shutdown(); if (err) { @@ -65,9 +59,10 @@ static void modem_update_apply(void) } err = nrf_modem_lib_init(); - __ASSERT(!err, "FOTA: Failed to initialize modem, err: %d", err); + if (err) { + __ASSERT(false, "Modem initialization failed, err: %d", err); + } -exit: link_func_mode_set(LTE_LC_FUNC_MODE_NORMAL, true); } diff --git a/samples/cellular/modem_shell/src/gnss/gnss.c b/samples/cellular/modem_shell/src/gnss/gnss.c index 8a0d6a75ec91..d48453ffcf0b 100644 --- a/samples/cellular/modem_shell/src/gnss/gnss.c +++ b/samples/cellular/modem_shell/src/gnss/gnss.c @@ -83,7 +83,7 @@ static enum gnss_operation_mode operation_mode = GNSS_OP_MODE_CONTINUOUS; static uint32_t periodic_fix_interval; static uint32_t periodic_fix_retry; static bool nmea_mask_set; -static struct nrf_modem_gnss_agps_data_frame agps_need; +static struct nrf_modem_gnss_agnss_data_frame agnss_need; static uint8_t gnss_elevation = 5; /* init to modem default threshold angle */ #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_SUPL_CLIENT_LIB) @@ -232,10 +232,10 @@ static void gnss_event_handler(int event_id) sizeof(struct nrf_modem_gnss_nmea_data_frame)); break; - case NRF_MODEM_GNSS_EVT_AGPS_REQ: + case NRF_MODEM_GNSS_EVT_AGNSS_REQ: err = get_event_data(&event.data, - NRF_MODEM_GNSS_DATA_AGPS_REQ, - sizeof(struct nrf_modem_gnss_agps_data_frame)); + NRF_MODEM_GNSS_DATA_AGNSS_REQ, + sizeof(struct nrf_modem_gnss_agnss_data_frame)); break; default: @@ -395,22 +395,22 @@ static void get_agps_data_flags_string(char *flags_string, uint32_t data_flags) *flags_string = '\0'; - if (data_flags & NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST) { + if (data_flags & NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST) { (void)strcat(flags_string, "utc | "); } - if (data_flags & NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST) { + if (data_flags & NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST) { (void)strcat(flags_string, "klob | "); } - if (data_flags & NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST) { + if (data_flags & NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST) { (void)strcat(flags_string, "neq | "); } - if (data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) { + if (data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST) { (void)strcat(flags_string, "time | "); } - if (data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST) { + if (data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST) { (void)strcat(flags_string, "pos | "); } - if (data_flags & NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST) { + if (data_flags & NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST) { (void)strcat(flags_string, "int | "); } @@ -422,9 +422,27 @@ static void get_agps_data_flags_string(char *flags_string, uint32_t data_flags) } } +static const char *get_system_string(uint8_t system_id) +{ + switch (system_id) { + case NRF_MODEM_GNSS_SYSTEM_INVALID: + return "invalid"; + + case NRF_MODEM_GNSS_SYSTEM_GPS: + return "GPS"; + + case NRF_MODEM_GNSS_SYSTEM_QZSS: + return "QZSS"; + + default: + return "unknown"; + } +} + static void data_handler_thread_fn(void) { struct event_item event; + struct nrf_modem_gnss_agnss_data_frame *agnss_data_frame; while (true) { k_msgq_get(&gnss_event_msgq, &event, K_FOREVER); @@ -447,26 +465,35 @@ static void data_handler_thread_fn(void) print_nmea((struct nrf_modem_gnss_nmea_data_frame *)event.data); break; - case NRF_MODEM_GNSS_EVT_AGPS_REQ: + case NRF_MODEM_GNSS_EVT_AGNSS_REQ: + agnss_data_frame = (struct nrf_modem_gnss_agnss_data_frame *)event.data; + + /* GPS data need is always expected to be present and first in list. */ + __ASSERT(agnss_data_frame->system_count > 0, + "GNSS system data need not found"); + __ASSERT(agnss_data_frame->system[0].system_id == NRF_MODEM_GNSS_SYSTEM_GPS, + "GPS data need not found"); + if (event_output_level > 0) { char flags_string[48]; get_agps_data_flags_string( flags_string, - ((struct nrf_modem_gnss_agps_data_frame *) - event.data)->data_flags); - - mosh_print( - "GNSS: A-GPS data needed (ephe: 0x%08x, alm: 0x%08x, " - "flags: %s)", - ((struct nrf_modem_gnss_agps_data_frame *) - event.data)->sv_mask_ephe, - ((struct nrf_modem_gnss_agps_data_frame *) - event.data)->sv_mask_alm, - flags_string); + agnss_data_frame->data_flags); + + mosh_print("GNSS: A-GNSS data needed: Flags: %s", flags_string); + for (int i = 0; i < agnss_data_frame->system_count; i++) { + mosh_print( + "GNSS: A-GNSS data needed: " + "%s ephe: 0x%llx, alm: 0x%llx", + get_system_string( + agnss_data_frame->system[i].system_id), + agnss_data_frame->system[i].sv_mask_ephe, + agnss_data_frame->system[i].sv_mask_alm); + } } - memcpy(&agps_need, event.data, sizeof(agps_need)); + memcpy(&agnss_need, event.data, sizeof(agnss_need)); #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_SUPL_CLIENT_LIB) if (agps_automatic) { @@ -475,7 +502,7 @@ static void data_handler_thread_fn(void) #endif #if defined(CONFIG_NRF_CLOUD_PGPS) - if (pgps_enabled && agps_need.sv_mask_ephe != 0x0) { + if (pgps_enabled && agnss_data_frame->system[0].sv_mask_ephe != 0x0) { k_work_submit_to_queue(&mosh_common_work_q, ¬ify_pgps_prediction_work); } @@ -599,39 +626,50 @@ static int serving_cell_info_get(struct lte_lc_cell *serving_cell) #endif #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_SUPL_CLIENT_LIB) -static void get_filtered_agps_request(struct nrf_modem_gnss_agps_data_frame *agps_request) +static void get_filtered_agps_request(struct nrf_modem_gnss_agnss_data_frame *agnss_request) { - memset(agps_request, 0, sizeof(*agps_request)); + memset(agnss_request, 0, sizeof(*agnss_request)); - if (agps_inject_ephe) { - agps_request->sv_mask_ephe = agps_need.sv_mask_ephe; - } - if (agps_inject_alm) { - agps_request->sv_mask_alm = agps_need.sv_mask_alm; + agnss_request->system_count = agnss_need.system_count; + + for (int i = 0; i < agnss_need.system_count; i++) { + const struct nrf_modem_gnss_agnss_system_data_need *src = &agnss_need.system[i]; + struct nrf_modem_gnss_agnss_system_data_need *dst = &agnss_request->system[i]; + + dst->system_id = src->system_id; + + if (agps_inject_ephe) { + dst->sv_mask_ephe = src->sv_mask_ephe; + } + if (agps_inject_alm) { + dst->sv_mask_alm = src->sv_mask_alm; + } } + if (agps_inject_utc) { - agps_request->data_flags |= - agps_need.data_flags & NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST; + agnss_request->data_flags |= + agnss_need.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST; } if (agps_inject_klob) { - agps_request->data_flags |= - agps_need.data_flags & NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST; + agnss_request->data_flags |= + agnss_need.data_flags & NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST; } if (agps_inject_neq) { - agps_request->data_flags |= - agps_need.data_flags & NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST; + agnss_request->data_flags |= + agnss_need.data_flags & NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST; } if (agps_inject_time) { - agps_request->data_flags |= - agps_need.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST; + agnss_request->data_flags |= + agnss_need.data_flags & + NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST; } if (agps_inject_pos) { - agps_request->data_flags |= - agps_need.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST; + agnss_request->data_flags |= + agnss_need.data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST; } if (agps_inject_int) { - agps_request->data_flags |= - agps_need.data_flags & NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST; + agnss_request->data_flags |= + agnss_need.data_flags & NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST; } } @@ -641,38 +679,43 @@ static void get_agps_data(struct k_work *item) int err; char flags_string[48]; - struct nrf_modem_gnss_agps_data_frame agps_request; + struct nrf_modem_gnss_agnss_data_frame agnss_request; - get_filtered_agps_request(&agps_request); + get_filtered_agps_request(&agnss_request); - get_agps_data_flags_string(flags_string, agps_request.data_flags); + get_agps_data_flags_string(flags_string, agnss_request.data_flags); mosh_print( - "GNSS: Getting A-GPS data from %s (ephe: 0x%08x, alm: 0x%08x, flags: %s)...", + "GNSS: Getting A-GNSS data from %s...", #if defined(CONFIG_LWM2M_CLIENT_UTILS_LOCATION_ASSIST_AGPS) - "LwM2M", + "LwM2M" #elif defined(CONFIG_NRF_CLOUD_AGPS) - "nRF Cloud", + "nRF Cloud" #else - "SUPL", + "SUPL" #endif - agps_request.sv_mask_ephe, - agps_request.sv_mask_alm, - flags_string); + ); + mosh_print("GNSS: A-GNSS request: flags: %s", flags_string); + for (int i = 0; i < agnss_request.system_count; i++) { + mosh_print("GNSS: A-GNSS request: %s sv_mask_ephe: 0x%llx, sv_mask_alm: 0x%llx", + get_system_string(agnss_request.system[i].system_id), + agnss_request.system[i].sv_mask_ephe, + agnss_request.system[i].sv_mask_alm); + } #if defined(CONFIG_LWM2M_CLIENT_UTILS_LOCATION_ASSIST_AGPS) if (!cloud_lwm2m_is_connected()) { mosh_error("GNSS: LwM2M not connected, can't request A-GPS data"); return; } - location_assistance_agps_set_mask(&agps_request); + location_assistance_agps_set_mask(&agnss_request); err = location_assistance_agps_request_send(cloud_lwm2m_client_ctx_get()); if (err) { mosh_error("GNSS: Failed to request A-GPS data, error: %d", err); } #elif defined(CONFIG_NRF_CLOUD_AGPS) #if defined(CONFIG_NRF_CLOUD_MQTT) - err = nrf_cloud_agps_request(&agps_request); + err = nrf_cloud_agps_request(&agnss_request); if (err == -EACCES) { mosh_error("GNSS: Not connected to nRF Cloud"); } else if (err) { @@ -698,7 +741,7 @@ static void get_agps_data(struct k_work *item) struct nrf_cloud_rest_agps_request request = { .type = NRF_CLOUD_REST_AGPS_REQ_CUSTOM, - .agps_req = &agps_request, + .agnss_req = &agnss_request, }; struct nrf_cloud_rest_agps_result result = { @@ -746,7 +789,7 @@ static void get_agps_data(struct k_work *item) #endif #else /* CONFIG_SUPL_CLIENT_LIB */ if (open_supl_socket() == 0) { - err = supl_session((void *)&agps_request); + err = supl_session((void *)&agnss_request); if (err) { mosh_error("GNSS: Failed to get A-GPS data, error: %d", err); } @@ -760,25 +803,25 @@ static void get_agps_data(struct k_work *item) static void get_agps_data_type_string(char *type_string, uint16_t type) { switch (type) { - case NRF_MODEM_GNSS_AGPS_UTC_PARAMETERS: + case NRF_MODEM_GNSS_AGNSS_GPS_UTC_PARAMETERS: (void)strcpy(type_string, "utc"); break; - case NRF_MODEM_GNSS_AGPS_EPHEMERIDES: + case NRF_MODEM_GNSS_AGNSS_GPS_EPHEMERIDES: (void)strcpy(type_string, "ephe"); break; - case NRF_MODEM_GNSS_AGPS_ALMANAC: + case NRF_MODEM_GNSS_AGNSS_GPS_ALMANAC: (void)strcpy(type_string, "alm"); break; - case NRF_MODEM_GNSS_AGPS_KLOBUCHAR_IONOSPHERIC_CORRECTION: + case NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_IONOSPHERIC_CORRECTION: (void)strcpy(type_string, "klob"); break; - case NRF_MODEM_GNSS_AGPS_NEQUICK_IONOSPHERIC_CORRECTION: + case NRF_MODEM_GNSS_AGNSS_NEQUICK_IONOSPHERIC_CORRECTION: (void)strcpy(type_string, "neq"); break; - case NRF_MODEM_GNSS_AGPS_GPS_SYSTEM_CLOCK_AND_TOWS: + case NRF_MODEM_GNSS_AGNSS_GPS_SYSTEM_CLOCK_AND_TOWS: (void)strcpy(type_string, "time"); break; - case NRF_MODEM_GNSS_AGPS_LOCATION: + case NRF_MODEM_GNSS_AGNSS_LOCATION: (void)strcpy(type_string, "pos"); break; case NRF_MODEM_GNSS_AGPS_INTEGRITY: @@ -800,7 +843,7 @@ static int inject_agps_data(void *agps, int err; char type_string[16]; - err = nrf_modem_gnss_agps_write(agps, agps_size, type); + err = nrf_modem_gnss_agnss_write(agps, agps_size, type); get_agps_data_type_string(type_string, type); @@ -976,7 +1019,7 @@ static void inject_pgps_data_work_fn(struct k_work *work) mosh_print("GNSS: Injecting ephemerides to modem..."); - err = nrf_cloud_pgps_inject(prediction, &agps_need); + err = nrf_cloud_pgps_inject(prediction, &agnss_need); if (err) { mosh_error("GNSS: Failed to inject ephemerides to modem"); } @@ -1262,7 +1305,7 @@ int gnss_set_system_mask(uint8_t system_mask) { int err; - err = nrf_modem_gnss_system_mask_set(system_mask); + err = nrf_modem_gnss_signal_mask_set(system_mask); if (err) { mosh_error("GNSS: Failed to set system mask, error: %d (%s)", err, gnss_err_to_str(err)); @@ -1568,20 +1611,47 @@ int gnss_set_agps_automatic(bool value) #endif } +#if defined(CONFIG_NRF_CLOUD_AGPS) +static bool qzss_assistance_is_supported(void) +{ + char resp[32]; + + if (nrf_modem_at_cmd(resp, sizeof(resp), "AT+CGMM") == 0) { + /* nRF9160 does not support QZSS assistance, while nRF91x1 do. */ + if (strstr(resp, "nRF9160") != NULL) { + return false; + } + } + + return true; +} +#endif /* CONFIG_NRF_CLOUD_AGPS */ + int gnss_inject_agps_data(void) { #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_SUPL_CLIENT_LIB) gnss_api_init(); /* Pretend modem requested all A-GPS data */ - agps_need.sv_mask_ephe = 0xffffffff; - agps_need.sv_mask_alm = 0xffffffff; - agps_need.data_flags = NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST | - NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST | - NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST | - NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST | - NRF_MODEM_GNSS_AGPS_POSITION_REQUEST | - NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST; + agnss_need.data_flags = + NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST | + NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST | + NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST | + NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST | + NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST; + agnss_need.system_count = 1; + agnss_need.system[0].system_id = NRF_MODEM_GNSS_SYSTEM_GPS; + agnss_need.system[0].sv_mask_ephe = 0xffffffff; + agnss_need.system[0].sv_mask_alm = 0xffffffff; +#if defined(CONFIG_NRF_CLOUD_AGPS) + if (qzss_assistance_is_supported()) { + agnss_need.system_count = 2; + agnss_need.system[1].system_id = NRF_MODEM_GNSS_SYSTEM_QZSS; + agnss_need.system[1].sv_mask_ephe = 0x3ff; + agnss_need.system[1].sv_mask_alm = 0x3ff; + } +#endif k_work_submit_to_queue(&mosh_common_work_q, &get_agps_data_work); @@ -1636,9 +1706,9 @@ int gnss_enable_pgps(void) #endif } -static void get_expiry_string(char *string, uint32_t string_len, uint32_t expiry) +static void get_expiry_string(char *string, uint32_t string_len, uint16_t expiry) { - if (expiry == UINT32_MAX) { + if (expiry == UINT16_MAX) { strncpy(string, "not used", string_len); } else if (expiry == 0) { strncpy(string, "expired", string_len); @@ -1650,11 +1720,12 @@ static void get_expiry_string(char *string, uint32_t string_len, uint32_t expiry int gnss_get_agps_expiry(void) { int err; - struct nrf_modem_gnss_agps_expiry agps_expiry; + struct nrf_modem_gnss_agnss_expiry agps_expiry; + const char *system_string; char expiry_string[16]; char expiry_string2[16]; - err = nrf_modem_gnss_agps_expiry_get(&agps_expiry); + err = nrf_modem_gnss_agnss_expiry_get(&agps_expiry); if (err) { mosh_error("GNSS: Failed to query A-GPS data expiry, error: %d (%s)", err, gnss_err_to_str(err)); @@ -1663,7 +1734,7 @@ int gnss_get_agps_expiry(void) mosh_print("Data flags: 0x%x", agps_expiry.data_flags); mosh_print("Time valid: %s", - agps_expiry.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST ? + agps_expiry.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST ? "false" : "true"); get_expiry_string(expiry_string, sizeof(expiry_string), agps_expiry.utc_expiry); mosh_print("UTC: %s", expiry_string); @@ -1676,14 +1747,16 @@ int gnss_get_agps_expiry(void) get_expiry_string(expiry_string, sizeof(expiry_string), agps_expiry.position_expiry); mosh_print("Position: %s", expiry_string); - for (int i = 0; i < NRF_MODEM_GNSS_NUM_GPS_SATELLITES; i++) { + for (int i = 0; i < agps_expiry.sv_count; i++) { + system_string = get_system_string(agps_expiry.sv[i].system_id); get_expiry_string(expiry_string, sizeof(expiry_string), - agps_expiry.ephe_expiry[i]); + agps_expiry.sv[i].ephe_expiry); get_expiry_string(expiry_string2, sizeof(expiry_string2), - agps_expiry.alm_expiry[i]); + agps_expiry.sv[i].alm_expiry); - mosh_print("PRN %02u: ephe: %-10s alm: %-10s", - i + 1, expiry_string, expiry_string2); + mosh_print("ID %3u (%s): ephe: %-10s alm: %-10s", + agps_expiry.sv[i].sv_id, system_string, + expiry_string, expiry_string2); } return 0; diff --git a/samples/cellular/modem_shell/src/gnss/gnss_shell.c b/samples/cellular/modem_shell/src/gnss/gnss_shell.c index 4718e88abcf6..fa2d9087d3ac 100644 --- a/samples/cellular/modem_shell/src/gnss/gnss_shell.c +++ b/samples/cellular/modem_shell/src/gnss/gnss_shell.c @@ -427,7 +427,7 @@ static int cmd_gnss_agps_expiry(const struct shell *shell, size_t argc, char **a static int cmd_gnss_agps_ref_altitude(const struct shell *shell, size_t argc, char **argv) { int altitude = 0; - struct nrf_modem_gnss_agps_data_location location = { 0 }; + struct nrf_modem_gnss_agnss_data_location location = { 0 }; if (argc != 2) { mosh_error("ref_altitude: wrong parameter count"); @@ -461,10 +461,10 @@ static int cmd_gnss_agps_ref_altitude(const struct shell *shell, size_t argc, ch */ location.unc_altitude = 0; - return nrf_modem_gnss_agps_write( + return nrf_modem_gnss_agnss_write( &location, sizeof(location), - NRF_MODEM_GNSS_AGPS_LOCATION) == 0 ? 0 : -ENOEXEC; + NRF_MODEM_GNSS_AGNSS_LOCATION) == 0 ? 0 : -ENOEXEC; } static int cmd_gnss_pgps(const struct shell *shell, size_t argc, char **argv) diff --git a/samples/cellular/modem_shell/src/location/location_shell.c b/samples/cellular/modem_shell/src/location/location_shell.c index c3100da4c246..c6a847e4e257 100644 --- a/samples/cellular/modem_shell/src/location/location_shell.c +++ b/samples/cellular/modem_shell/src/location/location_shell.c @@ -308,8 +308,8 @@ void location_ctrl_event_handler(const struct location_event_data *event_data) mosh_print( "A-GPS request from Location library " "(ephe: 0x%08x alm: 0x%08x flags: 0x%02x)", - event_data->agps_request.sv_mask_ephe, - event_data->agps_request.sv_mask_alm, + (uint32_t)event_data->agps_request.system[0].sv_mask_ephe, + (uint32_t)event_data->agps_request.system[0].sv_mask_alm, event_data->agps_request.data_flags); location_srv_ext_agps_handle(&event_data->agps_request); break; diff --git a/samples/cellular/modem_shell/src/location/location_srv_ext.h b/samples/cellular/modem_shell/src/location/location_srv_ext.h index d1c8b82b8961..3c34b857e61e 100644 --- a/samples/cellular/modem_shell/src/location/location_srv_ext.h +++ b/samples/cellular/modem_shell/src/location/location_srv_ext.h @@ -21,7 +21,7 @@ #endif #if defined(CONFIG_NRF_CLOUD_AGPS) -void location_srv_ext_agps_handle(const struct nrf_modem_gnss_agps_data_frame *agps_req); +void location_srv_ext_agps_handle(const struct nrf_modem_gnss_agnss_data_frame *agps_req); #endif #if defined(CONFIG_NRF_CLOUD_PGPS) void location_srv_ext_pgps_handle(const struct gps_pgps_request *pgps_req); diff --git a/samples/cellular/modem_shell/src/location/location_srv_ext_lwm2m.c b/samples/cellular/modem_shell/src/location/location_srv_ext_lwm2m.c index fd2b4a5d802e..12b1021d2155 100644 --- a/samples/cellular/modem_shell/src/location/location_srv_ext_lwm2m.c +++ b/samples/cellular/modem_shell/src/location/location_srv_ext_lwm2m.c @@ -20,7 +20,7 @@ #define GROUND_FIX_ACCURACY 4 #if defined(CONFIG_NRF_CLOUD_AGPS) -void location_srv_ext_agps_handle(const struct nrf_modem_gnss_agps_data_frame *agps_req) +void location_srv_ext_agps_handle(const struct nrf_modem_gnss_agnss_data_frame *agps_req) { int err; diff --git a/samples/cellular/modem_shell/src/location/location_srv_ext_nrf_cloud.c b/samples/cellular/modem_shell/src/location/location_srv_ext_nrf_cloud.c index 012bf46db167..ae67efb8a9ac 100644 --- a/samples/cellular/modem_shell/src/location/location_srv_ext_nrf_cloud.c +++ b/samples/cellular/modem_shell/src/location/location_srv_ext_nrf_cloud.c @@ -20,7 +20,7 @@ static struct location_data nrf_cloud_location; static K_SEM_DEFINE(location_ready, 0, 1); #if defined(CONFIG_NRF_CLOUD_AGPS) -void location_srv_ext_agps_handle(const struct nrf_modem_gnss_agps_data_frame *agps_req) +void location_srv_ext_agps_handle(const struct nrf_modem_gnss_agnss_data_frame *agps_req) { int err; diff --git a/samples/cellular/modem_shell/src/utils/net_utils.c b/samples/cellular/modem_shell/src/utils/net_utils.c index 58ff20929eb0..345c6c7c010a 100644 --- a/samples/cellular/modem_shell/src/utils/net_utils.c +++ b/samples/cellular/modem_shell/src/utils/net_utils.c @@ -18,13 +18,8 @@ int net_utils_socket_pdn_id_set(int fd, uint32_t pdn_id) { int ret; - size_t len; - struct ifreq ifr = { 0 }; - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "pdn%d", pdn_id); - len = strlen(ifr.ifr_name); - - ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, len); + ret = setsockopt(fd, SOL_SOCKET, SO_BINDTOPDN, &pdn_id, sizeof(pdn_id)); if (ret < 0) { mosh_error( "Failed to bind socket with PDN ID %d, error: %d, %s", diff --git a/samples/cellular/nidd/src/main.c b/samples/cellular/nidd/src/main.c index d017a8150740..466c7844ef88 100644 --- a/samples/cellular/nidd/src/main.c +++ b/samples/cellular/nidd/src/main.c @@ -149,7 +149,6 @@ static void nidd_socket_close(int fd) static int nidd_socket_setup(int pdn_id) { - char pdn[8]; int fd, err; fd = socket(AF_PACKET, SOCK_RAW, 0); @@ -161,8 +160,7 @@ static int nidd_socket_setup(int pdn_id) } if (IS_ENABLED(CONFIG_NIDD_ALLOC_NEW_CID)) { - (void)snprintf(pdn, sizeof(pdn), "pdn%d", pdn_id); - err = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, pdn, strlen(pdn)); + err = setsockopt(fd, SOL_SOCKET, SO_BINDTOPDN, &pdn_id, sizeof(pdn_id)); if (err == 0) { printk("Bound to PDN ID %d\n", pdn_id); } else { diff --git a/subsys/mgmt/fmfu/src/fmfu_mgmt.c b/subsys/mgmt/fmfu/src/fmfu_mgmt.c index 5677cd36f7a7..c22fe44d9b16 100644 --- a/subsys/mgmt/fmfu/src/fmfu_mgmt.c +++ b/subsys/mgmt/fmfu/src/fmfu_mgmt.c @@ -154,6 +154,7 @@ static int fmfu_get_memory_hash(struct smp_streamer *ctxt) uint64_t start; uint64_t end; struct nrf_modem_bootloader_digest digest; + struct nrf_modem_bootloader_fw_segment segment; struct zcbor_string zdigest; bool ok; size_t decoded = 0; @@ -174,13 +175,14 @@ static int fmfu_get_memory_hash(struct smp_streamer *ctxt) ok = zcbor_map_decode_bulk(zsd, mem_hash_decode, ARRAY_SIZE(mem_hash_decode), &decoded) == 0; - if (!ok || start == 0 || end == 0) { return MGMT_ERR_EINVAL; } - rc = nrf_modem_bootloader_digest(start, end - start, &digest); + segment.start_addr = start; + segment.end_addr = end; + rc = nrf_modem_bootloader_digest(&segment, 1, &digest); if (rc != 0) { LOG_ERR("nrf_fmfu_hash_get failed, err: %d.", rc); LOG_ERR("start:%d end: %d\n.", (uint32_t)start, (uint32_t)end); @@ -188,8 +190,8 @@ static int fmfu_get_memory_hash(struct smp_streamer *ctxt) } /* Put the digest response in the response */ - zdigest.value = digest.data; - zdigest.len = NRF_MODEM_BOOTLOADER_DIGEST_LEN; + zdigest.value = (uint8_t *)digest.data; + zdigest.len = NRF_MODEM_BOOTLOADER_DIGEST_LEN * sizeof(uint32_t); ok = zcbor_tstr_put_lit(zse, "digest") && zcbor_bstr_encode(zse, &zdigest) && diff --git a/subsys/net/lib/download_client/src/download_client.c b/subsys/net/lib/download_client/src/download_client.c index e863f28ef72e..c38ceca740db 100644 --- a/subsys/net/lib/download_client/src/download_client.c +++ b/subsys/net/lib/download_client/src/download_client.c @@ -220,15 +220,12 @@ static int socket_tls_hostname_set(int fd, const char * const hostname) return 0; } -static int socket_pdn_id_set(int fd, uint8_t pdn_id) +static int socket_pdn_id_set(int fd, int pdn_id) { int err; - char buf[8] = {0}; - (void) snprintf(buf, sizeof(buf), "pdn%d", pdn_id); - - LOG_INF("Binding to PDN ID: %s", buf); - err = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &buf, strlen(buf)); + LOG_INF("Binding to PDN ID: %d", pdn_id); + err = setsockopt(fd, SOL_SOCKET, SO_BINDTOPDN, &pdn_id, sizeof(pdn_id)); if (err) { LOG_ERR("Failed to bind socket to PDN ID %d, err %d", pdn_id, errno); diff --git a/subsys/net/lib/fota_download/src/util/fota_download_delta_modem.c b/subsys/net/lib/fota_download/src/util/fota_download_delta_modem.c index 989355eb844a..20a8cad82122 100644 --- a/subsys/net/lib/fota_download/src/util/fota_download_delta_modem.c +++ b/subsys/net/lib/fota_download/src/util/fota_download_delta_modem.c @@ -11,14 +11,14 @@ LOG_MODULE_REGISTER(fota_download_delta_modem, CONFIG_LOG_DEFAULT_LEVEL); /* Initialized to value different than success (0) */ -static int modem_lib_init_result = -1; +static int dfu_result = -1; -NRF_MODEM_LIB_ON_INIT(fota_delta_modem_init_hook, - on_modem_lib_init, NULL); +NRF_MODEM_LIB_ON_DFU_RES(fota_delta_modem_dfu_res_hook, + on_modem_dfu_res, NULL); -static void on_modem_lib_init(int ret, void *ctx) +static void on_modem_dfu_res(int dfu_res, void *ctx) { - modem_lib_init_result = ret; + dfu_result = dfu_res; } int fota_download_apply_delta_modem_update(void) @@ -30,8 +30,7 @@ int fota_download_apply_delta_modem_update(void) nrf_modem_lib_shutdown(); ret = nrf_modem_lib_init(); - ret = modem_lib_init_result; - switch (ret) { + switch (dfu_result) { case NRF_MODEM_DFU_RESULT_OK: LOG_INF("MODEM UPDATE OK. Will run new firmware"); result = 0; diff --git a/subsys/net/lib/lwm2m_client_utils/location/location_assistance.c b/subsys/net/lib/lwm2m_client_utils/location/location_assistance.c index 1e2a12bd48fd..86404c39994b 100644 --- a/subsys/net/lib/lwm2m_client_utils/location/location_assistance.c +++ b/subsys/net/lib/lwm2m_client_utils/location/location_assistance.c @@ -149,34 +149,40 @@ static void location_assist_ground_fix_result_cb(int32_t data) } #if defined(CONFIG_LWM2M_CLIENT_UTILS_LOCATION_ASSIST_AGPS) -int location_assistance_agps_set_mask(const struct nrf_modem_gnss_agps_data_frame *agps_req) +int location_assistance_agps_set_mask(const struct nrf_modem_gnss_agnss_data_frame *agps_req) { uint32_t mask = 0; - if (agps_req->data_flags & NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST) { + /* GPS data need is always expected to be present and first in list. */ + __ASSERT(agps_req->system_count > 0, + "GNSS system data need not found"); + __ASSERT(agps_req->system[0].system_id == NRF_MODEM_GNSS_SYSTEM_GPS, + "GPS data need not found"); + + if (agps_req->data_flags & NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST) { mask |= LOCATION_ASSIST_NEEDS_UTC; } - if (agps_req->sv_mask_ephe) { + if (agps_req->system[0].sv_mask_ephe) { mask |= LOCATION_ASSIST_NEEDS_EPHEMERIES; } - if (agps_req->sv_mask_alm) { + if (agps_req->system[0].sv_mask_alm) { mask |= LOCATION_ASSIST_NEEDS_ALMANAC; } - if (agps_req->data_flags & NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST) { + if (agps_req->data_flags & NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST) { mask |= LOCATION_ASSIST_NEEDS_KLOBUCHAR; } - if (agps_req->data_flags & NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST) { + if (agps_req->data_flags & NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST) { mask |= LOCATION_ASSIST_NEEDS_NEQUICK; } - if (agps_req->data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) { + if (agps_req->data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST) { mask |= LOCATION_ASSIST_NEEDS_TOW; mask |= LOCATION_ASSIST_NEEDS_CLOCK; } - if (agps_req->data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST) { + if (agps_req->data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST) { mask |= LOCATION_ASSIST_NEEDS_LOCATION; } - if (agps_req->data_flags & NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST) { + if (agps_req->data_flags & NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST) { mask |= LOCATION_ASSIST_NEEDS_INTEGRITY; } diff --git a/subsys/net/lib/lwm2m_client_utils/lwm2m/lwm2m_firmware.c b/subsys/net/lib/lwm2m_client_utils/lwm2m/lwm2m_firmware.c index 15b52867e2c4..c99eec225498 100644 --- a/subsys/net/lib/lwm2m_client_utils/lwm2m/lwm2m_firmware.c +++ b/subsys/net/lib/lwm2m_client_utils/lwm2m/lwm2m_firmware.c @@ -97,19 +97,6 @@ static struct update_data { void client_acknowledge(void); - - -#ifdef CONFIG_ZTEST -/* Initialized to value different than success (0) */ -static int modem_lib_init_result = -1; - -/* Only for unit test for emulate modem lib init hook */ -void lwm2m_firmware_emulate_modem_lib_init(int modem_init_ret_val) -{ - modem_lib_init_result = modem_init_ret_val; -} -#endif - static void apply_firmware_update(enum dfu_target_image_type type, uint16_t instance_id) { uint8_t result; diff --git a/subsys/net/lib/nrf_cloud/coap/src/coap_codec.c b/subsys/net/lib/nrf_cloud/coap/src/coap_codec.c index 3f43e17c4ab2..82d2ec6c1ebe 100644 --- a/subsys/net/lib/nrf_cloud/coap/src/coap_codec.c +++ b/subsys/net/lib/nrf_cloud/coap/src/coap_codec.c @@ -417,7 +417,7 @@ int coap_codec_agps_encode(struct nrf_cloud_rest_agps_request const *const reque input._agps_req_mnc = request->net_info->current_cell.mnc; input._agps_req_tac = request->net_info->current_cell.tac; if (request->type == NRF_CLOUD_REST_AGPS_REQ_CUSTOM) { - cnt = nrf_cloud_agps_type_array_get(request->agps_req, types, ARRAY_SIZE(types)); + cnt = nrf_cloud_agps_type_array_get(request->agnss_req, types, ARRAY_SIZE(types)); t->_agps_req_types_int_count = cnt; input._agps_req_types_present = true; LOG_DBG("num elements: %d", cnt); diff --git a/subsys/net/lib/nrf_cloud/include/nrf_cloud_agps_schema_v1.h b/subsys/net/lib/nrf_cloud/include/nrf_cloud_agps_schema_v1.h index 849f50f0a1da..ae01b8b8b9da 100644 --- a/subsys/net/lib/nrf_cloud/include/nrf_cloud_agps_schema_v1.h +++ b/subsys/net/lib/nrf_cloud/include/nrf_cloud_agps_schema_v1.h @@ -27,17 +27,26 @@ extern "C" { #define NRF_CLOUD_AGPS_MAX_SV_TOW (32U) enum nrf_cloud_agps_type { - NRF_CLOUD_AGPS__TYPE_INVALID = 0, - NRF_CLOUD_AGPS_UTC_PARAMETERS = 1, - NRF_CLOUD_AGPS_EPHEMERIDES = 2, - NRF_CLOUD_AGPS_ALMANAC = 3, - NRF_CLOUD_AGPS_KLOBUCHAR_CORRECTION = 4, - NRF_CLOUD_AGPS_NEQUICK_CORRECTION = 5, - NRF_CLOUD_AGPS_GPS_TOWS = 6, - NRF_CLOUD_AGPS_GPS_SYSTEM_CLOCK = 7, - NRF_CLOUD_AGPS_LOCATION = 8, - NRF_CLOUD_AGPS_INTEGRITY = 9, - NRF_CLOUD_AGPS__LAST = NRF_CLOUD_AGPS_INTEGRITY + NRF_CLOUD_AGPS__TYPE_INVALID = 0, + NRF_CLOUD_AGPS__FIRST = 1, + NRF_CLOUD_AGPS_UTC_PARAMETERS = NRF_CLOUD_AGPS__FIRST, + NRF_CLOUD_AGPS_EPHEMERIDES = 2, + NRF_CLOUD_AGPS_ALMANAC = 3, + NRF_CLOUD_AGPS_KLOBUCHAR_CORRECTION = 4, + NRF_CLOUD_AGPS_NEQUICK_CORRECTION = 5, + NRF_CLOUD_AGPS_GPS_TOWS = 6, + NRF_CLOUD_AGPS_GPS_SYSTEM_CLOCK = 7, + NRF_CLOUD_AGPS_LOCATION = 8, + NRF_CLOUD_AGPS_INTEGRITY = 9, + /* This value signifies prediction data */ + NRF_CLOUD_AGPS__RSVD_PREDICTION_DATA = 10, + /* A-GNSS types for modem firmware version v2.0.0 or later */ + NRF_CLOUD_AGNSS_QZSS_ALMANAC = 11, + NRF_CLOUD_AGNSS_QZSS_EPHEMERIDES = 12, + NRF_CLOUD_AGNSS_QZSS_INTEGRITY = 13, + NRF_CLOUD_AGPS__LAST = NRF_CLOUD_AGNSS_QZSS_INTEGRITY, + /* Ignore the reserved prediction data enum for the count calculation */ + NRF_CLOUD_AGPS__TYPES_COUNT = NRF_CLOUD_AGPS__LAST - NRF_CLOUD_AGPS__FIRST }; struct nrf_cloud_agps_utc { diff --git a/subsys/net/lib/nrf_cloud/include/nrf_cloud_codec_internal.h b/subsys/net/lib/nrf_cloud/include/nrf_cloud_codec_internal.h index ecf5751f47eb..3929a548e441 100644 --- a/subsys/net/lib/nrf_cloud/include/nrf_cloud_codec_internal.h +++ b/subsys/net/lib/nrf_cloud/include/nrf_cloud_codec_internal.h @@ -321,13 +321,13 @@ int nrf_cloud_modem_pvt_data_encode(const struct nrf_modem_gnss_pvt_data_frame * #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) /** @brief Build A-GPS type array based on request. */ -int nrf_cloud_agps_type_array_get(const struct nrf_modem_gnss_agps_data_frame *const request, +int nrf_cloud_agps_type_array_get(const struct nrf_modem_gnss_agnss_data_frame *const request, enum nrf_cloud_agps_type *array, const size_t array_size); /** @brief Encode an A-GPS request device message to be sent to nRF Cloud */ -int nrf_cloud_agps_req_json_encode(const struct nrf_modem_gnss_agps_data_frame *const request, +int nrf_cloud_agps_req_json_encode(const struct nrf_modem_gnss_agnss_data_frame *const request, cJSON * const agps_req_obj_out); -#endif /* CONFIG_NRF_CLOUD_AGPS */ +#endif /* CONFIG_NRF_CLOUD_AGPS || CONFIG_NRF_CLOUD_PGPS */ #if defined(CONFIG_NRF_CLOUD_PGPS) /** @brief Parse the PGPS response (REST and MQTT) from nRF Cloud */ diff --git a/subsys/net/lib/nrf_cloud/include/nrf_cloud_pgps_schema_v1.h b/subsys/net/lib/nrf_cloud/include/nrf_cloud_pgps_schema_v1.h index 6927ba12f40e..6740455cf5da 100644 --- a/subsys/net/lib/nrf_cloud/include/nrf_cloud_pgps_schema_v1.h +++ b/subsys/net/lib/nrf_cloud/include/nrf_cloud_pgps_schema_v1.h @@ -15,7 +15,7 @@ extern "C" { #endif #define NRF_CLOUD_PGPS_BIN_SCHEMA_VERSION (1) -#define NRF_CLOUD_PGPS_PREDICTION_HEADER ((int)NRF_CLOUD_AGPS__LAST + 1) +#define NRF_CLOUD_PGPS_PREDICTION_HEADER (NRF_CLOUD_AGPS__RSVD_PREDICTION_DATA) #define NRF_CLOUD_PGPS_BIN_SCHEMA_VERSION_INDEX (0) #define NRF_CLOUD_PGPS_BIN_SCHEMA_VERSION_SIZE (1) diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c index 83d8a920dadf..551fc684c143 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,7 @@ extern void agps_print(enum nrf_cloud_agps_type type, void *data); static K_SEM_DEFINE(agps_injection_active, 1, 1); static bool agps_print_enabled; -static struct nrf_modem_gnss_agps_data_frame processed; +static struct nrf_modem_gnss_agnss_data_frame processed; static K_MUTEX_DEFINE(processed_lock); static atomic_t request_in_progress; @@ -54,8 +55,15 @@ bool nrf_cloud_agps_request_in_progress(void) return atomic_get(&request_in_progress) != 0; } -int nrf_cloud_agps_request(const struct nrf_modem_gnss_agps_data_frame *request) +#if IS_ENABLED(CONFIG_NRF_CLOUD_AGPS) +int nrf_cloud_agps_request(const struct nrf_modem_gnss_agnss_data_frame *request) { + /* GPS data need is always expected to be present and first in list. */ + __ASSERT(request->system_count > 0, + "GNSS system data need not found"); + __ASSERT(request->system[0].system_id == NRF_MODEM_GNSS_SYSTEM_GPS, + "GPS data need not found"); + #if IS_ENABLED(CONFIG_NRF_CLOUD_MQTT) if (nfsm_get_current_state() != STATE_DC_CONNECTED) { return -EACCES; @@ -67,12 +75,14 @@ int nrf_cloud_agps_request(const struct nrf_modem_gnss_agps_data_frame *request) int err; cJSON *agps_req_obj; /* Copy the request so that the ephemeris mask can be modified if necessary */ - struct nrf_modem_gnss_agps_data_frame req = *request; + struct nrf_modem_gnss_agnss_data_frame req = *request; atomic_set(&request_in_progress, 0); k_mutex_lock(&processed_lock, K_FOREVER); memset(&processed, 0, sizeof(processed)); + processed.system_count = 1; + processed.system[0].system_id = NRF_MODEM_GNSS_SYSTEM_GPS; k_mutex_unlock(&processed_lock); #if defined(CONFIG_NRF_CLOUD_AGPS_FILTERED) @@ -80,11 +90,11 @@ int nrf_cloud_agps_request(const struct nrf_modem_gnss_agps_data_frame *request) * Determine if we processed ephemerides assistance less than 2 hours ago; if so, * we can skip this. */ - if (req.sv_mask_ephe && + if (req.system[0].sv_mask_ephe && (last_request_timestamp != 0) && ((k_uptime_get() - last_request_timestamp) < AGPS_UPDATE_PERIOD)) { LOG_WRN("A-GPS request was sent less than 2 hours ago"); - req.sv_mask_ephe = 0; + req.system[0].sv_mask_ephe = 0; } #endif @@ -107,23 +117,47 @@ int nrf_cloud_agps_request(const struct nrf_modem_gnss_agps_data_frame *request) #endif } +static bool qzss_assistance_is_supported(void) +{ + char resp[32]; + + if (nrf_modem_at_cmd(resp, sizeof(resp), "AT+CGMM") == 0) { + /* nRF9160 does not support QZSS assistance, while nRF91x1 do. */ + if (strstr(resp, "nRF9160") != NULL) { + return false; + } + } + + return true; +} + int nrf_cloud_agps_request_all(void) { const uint32_t mask = IS_ENABLED(CONFIG_NRF_CLOUD_PGPS) ? 0u : 0xFFFFFFFFu; - struct nrf_modem_gnss_agps_data_frame request = { - .sv_mask_ephe = mask, - .sv_mask_alm = mask, + struct nrf_modem_gnss_agnss_data_frame request = { .data_flags = - NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST | - NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST | - NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST | - NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST | - NRF_MODEM_GNSS_AGPS_POSITION_REQUEST | - NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST + NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST | + NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST | + NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST | + NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST | + NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST, + .system_count = 1, + .system[0].system_id = NRF_MODEM_GNSS_SYSTEM_GPS, + .system[0].sv_mask_ephe = mask, + .system[0].sv_mask_alm = mask }; + if (qzss_assistance_is_supported()) { + request.system_count = 2; + request.system[1].system_id = NRF_MODEM_GNSS_SYSTEM_QZSS; + request.system[1].sv_mask_ephe = 0x3ff; + request.system[1].sv_mask_alm = 0x3ff; + } + return nrf_cloud_agps_request(&request); } +#endif /* CONFIG_NRF_CLOUD_AGPS */ static int send_to_modem(void *data, size_t data_len, uint16_t type) { @@ -131,15 +165,14 @@ static int send_to_modem(void *data, size_t data_len, uint16_t type) agps_print(type, data); } - return nrf_modem_gnss_agps_write(data, data_len, type); + return nrf_modem_gnss_agnss_write(data, data_len, type); } -static int copy_utc(struct nrf_modem_gnss_agps_data_utc *dst, - struct nrf_cloud_apgs_element *src) +static void copy_utc(struct nrf_modem_gnss_agnss_gps_data_utc *dst, + struct nrf_cloud_apgs_element *src) { - if ((src == NULL) || (dst == NULL)) { - return -EINVAL; - } + __ASSERT_NO_MSG(dst != NULL); + __ASSERT_NO_MSG(src != NULL); dst->a1 = src->utc->a1; dst->a0 = src->utc->a0; @@ -149,16 +182,13 @@ static int copy_utc(struct nrf_modem_gnss_agps_data_utc *dst, dst->wn_lsf = src->utc->wn_lsf; dst->dn = src->utc->dn; dst->delta_tlsf = src->utc->delta_tlsf; - - return 0; } -static int copy_almanac(struct nrf_modem_gnss_agps_data_almanac *dst, - struct nrf_cloud_apgs_element *src) +static void copy_almanac(struct nrf_modem_gnss_agnss_gps_data_almanac *dst, + struct nrf_cloud_apgs_element *src) { - if ((src == NULL) || (dst == NULL)) { - return -EINVAL; - } + __ASSERT_NO_MSG(dst != NULL); + __ASSERT_NO_MSG(src != NULL); dst->sv_id = src->almanac->sv_id; dst->wn = src->almanac->wn; @@ -174,16 +204,13 @@ static int copy_almanac(struct nrf_modem_gnss_agps_data_almanac *dst, dst->m0 = src->almanac->m0; dst->af0 = src->almanac->af0; dst->af1 = src->almanac->af1; - - return 0; } -static int copy_ephemeris(struct nrf_modem_gnss_agps_data_ephemeris *dst, - struct nrf_cloud_apgs_element *src) +static void copy_ephemeris(struct nrf_modem_gnss_agnss_gps_data_ephemeris *dst, + struct nrf_cloud_apgs_element *src) { - if ((src == NULL) || (dst == NULL)) { - return -EINVAL; - } + __ASSERT_NO_MSG(dst != NULL); + __ASSERT_NO_MSG(src != NULL); dst->sv_id = src->ephemeris->sv_id; dst->health = src->ephemeris->health; @@ -211,16 +238,13 @@ static int copy_ephemeris(struct nrf_modem_gnss_agps_data_ephemeris *dst, dst->crc = src->ephemeris->crc; dst->cic = src->ephemeris->cic; dst->cuc = src->ephemeris->cuc; - - return 0; } -static int copy_klobuchar(struct nrf_modem_gnss_agps_data_klobuchar *dst, - struct nrf_cloud_apgs_element *src) +static void copy_klobuchar(struct nrf_modem_gnss_agnss_data_klobuchar *dst, + struct nrf_cloud_apgs_element *src) { - if ((src == NULL) || (dst == NULL)) { - return -EINVAL; - } + __ASSERT_NO_MSG(dst != NULL); + __ASSERT_NO_MSG(src != NULL); dst->alpha0 = src->ion_correction.klobuchar->alpha0; dst->alpha1 = src->ion_correction.klobuchar->alpha1; @@ -230,32 +254,26 @@ static int copy_klobuchar(struct nrf_modem_gnss_agps_data_klobuchar *dst, dst->beta1 = src->ion_correction.klobuchar->beta1; dst->beta2 = src->ion_correction.klobuchar->beta2; dst->beta3 = src->ion_correction.klobuchar->beta3; - - return 0; } -static int copy_nequick(struct nrf_modem_gnss_agps_data_nequick *dst, - struct nrf_cloud_apgs_element *src) +static void copy_nequick(struct nrf_modem_gnss_agnss_data_nequick *dst, + struct nrf_cloud_apgs_element *src) { - if ((src == NULL) || (dst == NULL)) { - return -EINVAL; - } + __ASSERT_NO_MSG(dst != NULL); + __ASSERT_NO_MSG(src != NULL); dst->ai0 = src->ion_correction.nequick->ai0; dst->ai1 = src->ion_correction.nequick->ai1; dst->ai2 = src->ion_correction.nequick->ai2; dst->storm_cond = src->ion_correction.nequick->storm_cond; dst->storm_valid = src->ion_correction.nequick->storm_valid; - - return 0; } -static int copy_location(struct nrf_modem_gnss_agps_data_location *dst, - struct nrf_cloud_apgs_element *src) +static void copy_location(struct nrf_modem_gnss_agnss_data_location *dst, + struct nrf_cloud_apgs_element *src) { - if ((src == NULL) || (dst == NULL)) { - return -EINVAL; - } + __ASSERT_NO_MSG(dst != NULL); + __ASSERT_NO_MSG(src != NULL); dst->latitude = src->location->latitude; dst->longitude = src->location->longitude; @@ -265,16 +283,13 @@ static int copy_location(struct nrf_modem_gnss_agps_data_location *dst, dst->orientation_major = src->location->orientation_major; dst->unc_altitude = src->location->unc_altitude; dst->confidence = src->location->confidence; - - return 0; } -static int copy_time_and_tow(struct nrf_modem_gnss_agps_data_system_time_and_sv_tow *dst, - struct nrf_cloud_apgs_element *src) +static void copy_time_and_tow(struct nrf_modem_gnss_agnss_gps_data_system_time_and_sv_tow *dst, + struct nrf_cloud_apgs_element *src) { - if ((src == NULL) || (dst == NULL)) { - return -EINVAL; - } + __ASSERT_NO_MSG(dst != NULL); + __ASSERT_NO_MSG(src != NULL); dst->date_day = src->time_and_tow->date_day; dst->time_full_s = src->time_and_tow->time_full_s; @@ -285,15 +300,33 @@ static int copy_time_and_tow(struct nrf_modem_gnss_agps_data_system_time_and_sv_ LOG_DBG("SW TOW mask is zero, not copying TOW array"); memset(dst->sv_tow, 0, sizeof(dst->sv_tow)); - return 0; + return; } for (size_t i = 0; i < NRF_CLOUD_AGPS_MAX_SV_TOW; i++) { dst->sv_tow[i].flags = src->time_and_tow->sv_tow[i].flags; dst->sv_tow[i].tlm = src->time_and_tow->sv_tow[i].tlm; } +} - return 0; +static void copy_integrity_gps(struct nrf_modem_gnss_agps_data_integrity *dst, + struct nrf_cloud_apgs_element *src) +{ + __ASSERT_NO_MSG(dst != NULL); + __ASSERT_NO_MSG(src != NULL); + + dst->integrity_mask = src->integrity->integrity_mask; +} + +static void copy_integrity_qzss(struct nrf_modem_gnss_agnss_data_integrity *dst, + struct nrf_cloud_apgs_element *src) +{ + __ASSERT_NO_MSG(dst != NULL); + __ASSERT_NO_MSG(src != NULL); + + dst->signal_count = 1; + dst->signal[0].signal_id = NRF_MODEM_GNSS_SIGNAL_QZSS_L1_CA; + dst->signal[0].integrity_mask = src->integrity->integrity_mask; } static int agps_send_to_modem(struct nrf_cloud_apgs_element *agps_data) @@ -302,9 +335,9 @@ static int agps_send_to_modem(struct nrf_cloud_apgs_element *agps_data) switch (agps_data->type) { case NRF_CLOUD_AGPS_UTC_PARAMETERS: { - struct nrf_modem_gnss_agps_data_utc utc; + struct nrf_modem_gnss_agnss_gps_data_utc utc; - processed.data_flags |= NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST; + processed.data_flags |= NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST; copy_utc(&utc, agps_data); #if defined(CONFIG_NRF_CLOUD_PGPS) nrf_cloud_pgps_set_leap_seconds(utc.delta_tls); @@ -312,72 +345,83 @@ static int agps_send_to_modem(struct nrf_cloud_apgs_element *agps_data) LOG_DBG("A-GPS type: NRF_CLOUD_AGPS_UTC_PARAMETERS"); return send_to_modem(&utc, sizeof(utc), - NRF_MODEM_GNSS_AGPS_UTC_PARAMETERS); + NRF_MODEM_GNSS_AGNSS_GPS_UTC_PARAMETERS); } - case NRF_CLOUD_AGPS_EPHEMERIDES: { - struct nrf_modem_gnss_agps_data_ephemeris ephemeris; + case NRF_CLOUD_AGPS_EPHEMERIDES: + case NRF_CLOUD_AGNSS_QZSS_EPHEMERIDES: { + struct nrf_modem_gnss_agnss_gps_data_ephemeris ephemeris; - processed.sv_mask_ephe |= (1 << (agps_data->ephemeris->sv_id - 1)); + if (agps_data->type == NRF_CLOUD_AGPS_EPHEMERIDES) { + processed.system[0].sv_mask_ephe |= + (1 << (agps_data->ephemeris->sv_id - 1)); #if defined(CONFIG_NRF_CLOUD_PGPS) - if (agps_data->ephemeris->health == - NRF_CLOUD_PGPS_EMPTY_EPHEM_HEALTH) { - LOG_DBG("Skipping empty ephemeris for sv %u", - agps_data->ephemeris->sv_id); - return 0; - } + if (agps_data->ephemeris->health == + NRF_CLOUD_PGPS_EMPTY_EPHEM_HEALTH) { + LOG_DBG("Skipping empty ephemeris for sv %u", + agps_data->ephemeris->sv_id); + return 0; + } #endif + } + copy_ephemeris(&ephemeris, agps_data); - LOG_DBG("A-GPS type: NRF_CLOUD_AGPS_EPHEMERIDES %d", + LOG_DBG("A-GNSS type: %s EPHEMERIDES %d", + (agps_data->type == NRF_CLOUD_AGPS_EPHEMERIDES) ? "GPS" : "QZSS", agps_data->ephemeris->sv_id); return send_to_modem(&ephemeris, sizeof(ephemeris), - NRF_MODEM_GNSS_AGPS_EPHEMERIDES); + NRF_MODEM_GNSS_AGNSS_GPS_EPHEMERIDES); } - case NRF_CLOUD_AGPS_ALMANAC: { - struct nrf_modem_gnss_agps_data_almanac almanac; + case NRF_CLOUD_AGPS_ALMANAC: + case NRF_CLOUD_AGNSS_QZSS_ALMANAC: { + struct nrf_modem_gnss_agnss_gps_data_almanac almanac; + + if (agps_data->type == NRF_CLOUD_AGPS_ALMANAC) { + processed.system[0].sv_mask_alm |= (1 << (agps_data->almanac->sv_id - 1)); + } - processed.sv_mask_alm |= (1 << (agps_data->almanac->sv_id - 1)); copy_almanac(&almanac, agps_data); - LOG_DBG("A-GPS type: NRF_CLOUD_AGPS_ALMANAC %d", + LOG_DBG("A-GNSS type: %s ALMANAC %d", + (agps_data->type == NRF_CLOUD_AGPS_ALMANAC) ? "GPS" : "QZSS", agps_data->almanac->sv_id); return send_to_modem(&almanac, sizeof(almanac), - NRF_MODEM_GNSS_AGPS_ALMANAC); + NRF_MODEM_GNSS_AGNSS_GPS_ALMANAC); } case NRF_CLOUD_AGPS_KLOBUCHAR_CORRECTION: { - struct nrf_modem_gnss_agps_data_klobuchar klobuchar; + struct nrf_modem_gnss_agnss_data_klobuchar klobuchar; - processed.data_flags |= NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST; + processed.data_flags |= NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST; copy_klobuchar(&klobuchar, agps_data); LOG_DBG("A-GPS type: NRF_CLOUD_AGPS_KLOBUCHAR_CORRECTION"); return send_to_modem(&klobuchar, sizeof(klobuchar), - NRF_MODEM_GNSS_AGPS_KLOBUCHAR_IONOSPHERIC_CORRECTION); + NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_IONOSPHERIC_CORRECTION); } case NRF_CLOUD_AGPS_NEQUICK_CORRECTION: { - struct nrf_modem_gnss_agps_data_nequick nequick; + struct nrf_modem_gnss_agnss_data_nequick nequick; - processed.data_flags |= NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST; + processed.data_flags |= NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST; copy_nequick(&nequick, agps_data); LOG_DBG("A-GPS type: NRF_CLOUD_AGPS_NEQUICK_CORRECTION"); return send_to_modem(&nequick, sizeof(nequick), - NRF_MODEM_GNSS_AGPS_NEQUICK_IONOSPHERIC_CORRECTION); + NRF_MODEM_GNSS_AGNSS_NEQUICK_IONOSPHERIC_CORRECTION); } case NRF_CLOUD_AGPS_GPS_SYSTEM_CLOCK: { - struct nrf_modem_gnss_agps_data_system_time_and_sv_tow time_and_tow; + struct nrf_modem_gnss_agnss_gps_data_system_time_and_sv_tow time_and_tow; - processed.data_flags |= NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST; + processed.data_flags |= NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST; copy_time_and_tow(&time_and_tow, agps_data); LOG_DBG("A-GPS type: NRF_CLOUD_AGPS_GPS_SYSTEM_CLOCK"); return send_to_modem(&time_and_tow, sizeof(time_and_tow), - NRF_MODEM_GNSS_AGPS_GPS_SYSTEM_CLOCK_AND_TOWS); + NRF_MODEM_GNSS_AGNSS_GPS_SYSTEM_CLOCK_AND_TOWS); } case NRF_CLOUD_AGPS_LOCATION: { - struct nrf_modem_gnss_agps_data_location location = {0}; + struct nrf_modem_gnss_agnss_data_location location = {0}; - processed.data_flags |= NRF_MODEM_GNSS_AGPS_POSITION_REQUEST; + processed.data_flags |= NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST; copy_location(&location, agps_data); #if defined(CONFIG_NRF_CLOUD_PGPS) nrf_cloud_pgps_set_location_normalized(location.latitude, @@ -386,15 +430,28 @@ static int agps_send_to_modem(struct nrf_cloud_apgs_element *agps_data) LOG_DBG("A-GPS type: NRF_CLOUD_AGPS_LOCATION"); return send_to_modem(&location, sizeof(location), - NRF_MODEM_GNSS_AGPS_LOCATION); + NRF_MODEM_GNSS_AGNSS_LOCATION); } - case NRF_CLOUD_AGPS_INTEGRITY: + case NRF_CLOUD_AGPS_INTEGRITY: { + struct nrf_modem_gnss_agps_data_integrity integrity = {0}; + + processed.data_flags |= NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST; + copy_integrity_gps(&integrity, agps_data); LOG_DBG("A-GPS type: NRF_CLOUD_AGPS_INTEGRITY"); - processed.data_flags |= NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST; - return send_to_modem(agps_data->integrity, - sizeof(*(agps_data->integrity)), + return send_to_modem(&integrity, sizeof(integrity), NRF_MODEM_GNSS_AGPS_INTEGRITY); + } + case NRF_CLOUD_AGNSS_QZSS_INTEGRITY: { + struct nrf_modem_gnss_agnss_data_integrity integrity = {0}; + + processed.data_flags |= NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST; + copy_integrity_qzss(&integrity, agps_data); + LOG_DBG("A-GNSS type: NRF_CLOUD_AGNSS_QZSS_INTEGRITY"); + + return send_to_modem(&integrity, sizeof(integrity), + NRF_MODEM_GNSS_AGNSS_INTEGRITY); + } default: LOG_WRN("Unknown AGPS data type: %d", agps_data->type); break; @@ -440,10 +497,12 @@ static size_t get_next_agps_element(struct nrf_cloud_apgs_element *element, len += sizeof(struct nrf_cloud_agps_utc); break; case NRF_CLOUD_AGPS_EPHEMERIDES: + case NRF_CLOUD_AGNSS_QZSS_EPHEMERIDES: element->ephemeris = (struct nrf_cloud_agps_ephemeris *)(buf + len); len += sizeof(struct nrf_cloud_agps_ephemeris); break; case NRF_CLOUD_AGPS_ALMANAC: + case NRF_CLOUD_AGNSS_QZSS_ALMANAC: element->almanac = (struct nrf_cloud_agps_almanac *)(buf + len); len += sizeof(struct nrf_cloud_agps_almanac); break; @@ -473,6 +532,7 @@ static size_t get_next_agps_element(struct nrf_cloud_apgs_element *element, len += sizeof(struct nrf_cloud_agps_location); break; case NRF_CLOUD_AGPS_INTEGRITY: + case NRF_CLOUD_AGNSS_QZSS_INTEGRITY: element->integrity = (struct nrf_cloud_agps_integrity *)(buf + len); len += sizeof(struct nrf_cloud_agps_integrity); @@ -586,8 +646,7 @@ int nrf_cloud_agps_process(const char *buf, size_t buf_len) err = agps_send_to_modem(&element); k_mutex_unlock(&processed_lock); if (err) { - LOG_ERR("Failed to send data to modem, error: %d", err); - break; + LOG_WRN("Failed to send data to modem, error: %d", err); } } @@ -608,7 +667,7 @@ int nrf_cloud_agps_process(const char *buf, size_t buf_len) return err; } -void nrf_cloud_agps_processed(struct nrf_modem_gnss_agps_data_frame *received_elements) +void nrf_cloud_agps_processed(struct nrf_modem_gnss_agnss_data_frame *received_elements) { if (received_elements) { k_mutex_lock(&processed_lock, K_FOREVER); diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps_utils.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps_utils.c index 43c46f97130b..ce2810eeaad0 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps_utils.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps_utils.c @@ -9,7 +9,7 @@ #include #include -static void print_utc(struct nrf_modem_gnss_agps_data_utc *data) +static void print_utc(struct nrf_modem_gnss_agnss_gps_data_utc *data) { printk("utc:\n"); printk("\ta1: %d\n", data->a1); @@ -22,7 +22,7 @@ static void print_utc(struct nrf_modem_gnss_agps_data_utc *data) printk("\tdelta_tlsf: %d\n", data->delta_tlsf); } -static void print_ephemeris(struct nrf_modem_gnss_agps_data_ephemeris *data) +static void print_ephemeris(struct nrf_modem_gnss_agnss_gps_data_ephemeris *data) { printk("ephemeris:\n"); printk("\tsv_id: %d\n", data->sv_id); @@ -53,7 +53,7 @@ static void print_ephemeris(struct nrf_modem_gnss_agps_data_ephemeris *data) printk("\tcuc: %d\n", data->cuc); } -static void print_almanac(struct nrf_modem_gnss_agps_data_almanac *data) +static void print_almanac(struct nrf_modem_gnss_agnss_gps_data_almanac *data) { printk("almanac\n"); printk("\tsv_id: %d\n", data->sv_id); @@ -72,7 +72,7 @@ static void print_almanac(struct nrf_modem_gnss_agps_data_almanac *data) printk("\taf1: %d\n", data->af1); } -static void print_klobuchar(struct nrf_modem_gnss_agps_data_klobuchar *data) +static void print_klobuchar(struct nrf_modem_gnss_agnss_data_klobuchar *data) { printk("klobuchar\n"); printk("\talpha0: %d\n", data->alpha0); @@ -85,7 +85,7 @@ static void print_klobuchar(struct nrf_modem_gnss_agps_data_klobuchar *data) printk("\tbeta3: %d\n", data->beta3); } -static void print_nequick(struct nrf_modem_gnss_agps_data_nequick *data) +static void print_nequick(struct nrf_modem_gnss_agnss_data_nequick *data) { printk("nequick\n"); printk("\tai0: %d\n", data->ai0); @@ -95,7 +95,7 @@ static void print_nequick(struct nrf_modem_gnss_agps_data_nequick *data) printk("\tstorm_valid: %d\n", data->storm_valid); } -static void print_clock_and_tows(struct nrf_modem_gnss_agps_data_system_time_and_sv_tow *data) +static void print_clock_and_tows(struct nrf_modem_gnss_agnss_gps_data_system_time_and_sv_tow *data) { printk("clock_and_tows\n"); printk("\tdate_day: %d\n", data->date_day); @@ -104,14 +104,14 @@ static void print_clock_and_tows(struct nrf_modem_gnss_agps_data_system_time_and printk("\tsv_mask: 0x%08x\n", data->sv_mask); printk("\tsv_tow\n"); - for (size_t i = 0; i < NRF_MODEM_GNSS_AGPS_MAX_SV_TOW; i++) { + for (size_t i = 0; i < NRF_MODEM_GNSS_AGNSS_GPS_MAX_SV_TOW; i++) { printk("\t\tsv_tow[%d]\n", i); printk("\t\t\ttlm: %d\n", data->sv_tow[i].tlm); printk("\t\t\tflags: 0x%02x\n", data->sv_tow[i].flags); } } -static void print_location(struct nrf_modem_gnss_agps_data_location *data) +static void print_location(struct nrf_modem_gnss_agnss_data_location *data) { printk("location\n"); printk("\tlatitude: %d\n", data->latitude); @@ -124,47 +124,60 @@ static void print_location(struct nrf_modem_gnss_agps_data_location *data) printk("\tconfidence: %d\n", data->confidence); } -static void print_integrity(struct nrf_modem_gnss_agps_data_integrity *data) +static void print_gps_integrity(struct nrf_modem_gnss_agps_data_integrity *data) { printk("integrity\n"); - printk("\tintegrity_mask: %d\n", data->integrity_mask); + printk("\tintegrity_mask: 0x%08x\n", data->integrity_mask); +} + +static void print_gnss_integrity(struct nrf_modem_gnss_agnss_data_integrity *data) +{ + printk("integrity\n"); + for (int i = 0; i < data->signal_count; i++) { + printk("\tsignal_id: %d, integrity_mask: 0x%llx\n", + data->signal[i].signal_id, data->signal[i].integrity_mask); + } } void agps_print(uint16_t type, void *data) { switch (type) { - case NRF_MODEM_GNSS_AGPS_UTC_PARAMETERS: { - print_utc((struct nrf_modem_gnss_agps_data_utc *)data); + case NRF_MODEM_GNSS_AGNSS_GPS_UTC_PARAMETERS: { + print_utc((struct nrf_modem_gnss_agnss_gps_data_utc *)data); break; } - case NRF_MODEM_GNSS_AGPS_EPHEMERIDES: { - print_ephemeris((struct nrf_modem_gnss_agps_data_ephemeris *)data); + case NRF_MODEM_GNSS_AGNSS_GPS_EPHEMERIDES: { + print_ephemeris((struct nrf_modem_gnss_agnss_gps_data_ephemeris *)data); break; } - case NRF_MODEM_GNSS_AGPS_ALMANAC: { - print_almanac((struct nrf_modem_gnss_agps_data_almanac *)data); + case NRF_MODEM_GNSS_AGNSS_GPS_ALMANAC: { + print_almanac((struct nrf_modem_gnss_agnss_gps_data_almanac *)data); break; } - case NRF_MODEM_GNSS_AGPS_KLOBUCHAR_IONOSPHERIC_CORRECTION: { - print_klobuchar((struct nrf_modem_gnss_agps_data_klobuchar *)data); + case NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_IONOSPHERIC_CORRECTION: { + print_klobuchar((struct nrf_modem_gnss_agnss_data_klobuchar *)data); break; } - case NRF_MODEM_GNSS_AGPS_NEQUICK_IONOSPHERIC_CORRECTION: { - print_nequick((struct nrf_modem_gnss_agps_data_nequick *)data); + case NRF_MODEM_GNSS_AGNSS_NEQUICK_IONOSPHERIC_CORRECTION: { + print_nequick((struct nrf_modem_gnss_agnss_data_nequick *)data); break; } - case NRF_MODEM_GNSS_AGPS_GPS_SYSTEM_CLOCK_AND_TOWS: { + case NRF_MODEM_GNSS_AGNSS_GPS_SYSTEM_CLOCK_AND_TOWS: { print_clock_and_tows( - (struct nrf_modem_gnss_agps_data_system_time_and_sv_tow *)data); + (struct nrf_modem_gnss_agnss_gps_data_system_time_and_sv_tow *)data); break; } - case NRF_MODEM_GNSS_AGPS_LOCATION: { - print_location((struct nrf_modem_gnss_agps_data_location *)data); + case NRF_MODEM_GNSS_AGNSS_LOCATION: { + print_location((struct nrf_modem_gnss_agnss_data_location *)data); break; } case NRF_MODEM_GNSS_AGPS_INTEGRITY: { - print_integrity((struct nrf_modem_gnss_agps_data_integrity *)data); + print_gps_integrity((struct nrf_modem_gnss_agps_data_integrity *)data); + break; + } + case NRF_MODEM_GNSS_AGNSS_INTEGRITY: { + print_gnss_integrity((struct nrf_modem_gnss_agnss_data_integrity *)data); break; } default: diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_codec_internal.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_codec_internal.c index aa41388117eb..12e620f524b3 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_codec_internal.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_codec_internal.c @@ -3209,6 +3209,8 @@ static int agps_types_array_json_encode(cJSON * const obj, (types[i] > NRF_CLOUD_AGPS__LAST)) { LOG_INF("Ignoring unknown A-GPS type: %d", types[i]); continue; + } else if (types[i] == NRF_CLOUD_AGPS__RSVD_PREDICTION_DATA) { + continue; } cJSON *num = cJSON_CreateNumber(types[i]); @@ -3305,7 +3307,7 @@ int nrf_cloud_modem_pvt_data_encode(const struct nrf_modem_gnss_pvt_data_frame * #endif /* CONFIG_NRF_MODEM */ #if defined(CONFIG_NRF_CLOUD_AGPS) || defined(CONFIG_NRF_CLOUD_PGPS) -int nrf_cloud_agps_req_json_encode(const struct nrf_modem_gnss_agps_data_frame * const request, +int nrf_cloud_agps_req_json_encode(const struct nrf_modem_gnss_agnss_data_frame * const request, cJSON * const agps_req_obj_out) { if (!agps_req_obj_out || !request) { @@ -3363,15 +3365,33 @@ int nrf_cloud_agps_req_json_encode(const struct nrf_modem_gnss_agps_data_frame * return err; } -int nrf_cloud_agps_type_array_get(const struct nrf_modem_gnss_agps_data_frame * const request, +static const struct nrf_modem_gnss_agnss_system_data_need *system_data_need_get( + const struct nrf_modem_gnss_agnss_data_frame *request, + uint8_t system_id) +{ + const struct nrf_modem_gnss_agnss_system_data_need *system_data_need = NULL; + + for (int i = 0; i < request->system_count; i++) { + if (request->system[i].system_id == system_id) { + system_data_need = &request->system[i]; + break; + } + } + + return system_data_need; +} + +int nrf_cloud_agps_type_array_get(const struct nrf_modem_gnss_agnss_data_frame * const request, enum nrf_cloud_agps_type *array, const size_t array_size) { + const struct nrf_modem_gnss_agnss_system_data_need *system_data_need; + if (!request || !array || !array_size) { return -EINVAL; } - if (array_size < NRF_CLOUD_AGPS__LAST) { + if (array_size < NRF_CLOUD_AGPS__TYPES_COUNT) { LOG_ERR("Array size (%d) too small, must be >= %d", - array_size, NRF_CLOUD_AGPS__LAST); + array_size, NRF_CLOUD_AGPS__TYPES_COUNT); return -ERANGE; } @@ -3379,46 +3399,64 @@ int nrf_cloud_agps_type_array_get(const struct nrf_modem_gnss_agps_data_frame * memset((void *)array, NRF_CLOUD_AGPS__TYPE_INVALID, array_size * sizeof(*array)); - if (request->data_flags & NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST) { + if (request->data_flags & NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST) { array[cnt++] = NRF_CLOUD_AGPS_UTC_PARAMETERS; } - if (request->sv_mask_ephe) { - array[cnt++] = NRF_CLOUD_AGPS_EPHEMERIDES; + system_data_need = system_data_need_get(request, NRF_MODEM_GNSS_SYSTEM_GPS); + if (system_data_need) { + if (system_data_need->sv_mask_ephe) { + array[cnt++] = NRF_CLOUD_AGPS_EPHEMERIDES; + } + + if (system_data_need->sv_mask_alm) { + array[cnt++] = NRF_CLOUD_AGPS_ALMANAC; + } + + if (request->data_flags & NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST) { + array[cnt++] = NRF_CLOUD_AGPS_INTEGRITY; + } } - if (request->sv_mask_alm) { - array[cnt++] = NRF_CLOUD_AGPS_ALMANAC; + system_data_need = system_data_need_get(request, NRF_MODEM_GNSS_SYSTEM_QZSS); + if (system_data_need) { + if (system_data_need->sv_mask_ephe) { + array[cnt++] = NRF_CLOUD_AGNSS_QZSS_EPHEMERIDES; + } + + if (system_data_need->sv_mask_alm) { + array[cnt++] = NRF_CLOUD_AGNSS_QZSS_ALMANAC; + } + + if (request->data_flags & NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST) { + array[cnt++] = NRF_CLOUD_AGNSS_QZSS_INTEGRITY; + } } - if (request->data_flags & NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST) { + if (request->data_flags & NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST) { array[cnt++] = NRF_CLOUD_AGPS_KLOBUCHAR_CORRECTION; } - if (request->data_flags & NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST) { + if (request->data_flags & NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST) { array[cnt++] = NRF_CLOUD_AGPS_NEQUICK_CORRECTION; } - if (request->data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) { + if (request->data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST) { array[cnt++] = NRF_CLOUD_AGPS_GPS_TOWS; array[cnt++] = NRF_CLOUD_AGPS_GPS_SYSTEM_CLOCK; } - if (request->data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST) { + if (request->data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST) { array[cnt++] = NRF_CLOUD_AGPS_LOCATION; } - if (request->data_flags & NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST) { - array[cnt++] = NRF_CLOUD_AGPS_INTEGRITY; - } - if (cnt == 0) { return -ENODATA; } return cnt; } -#endif /* CONFIG_NRF_CLOUD_AGPS */ +#endif /* CONFIG_NRF_CLOUD_AGPS || CONFIG_NRF_CLOUD_PGPS */ #if defined(CONFIG_NRF_CLOUD_PGPS) int nrf_cloud_pgps_response_decode(const char *const response, diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_common.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_common.c index 6d331c348cd6..4dd8e98fbf7d 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_common.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_common.c @@ -22,17 +22,15 @@ #include #if defined(CONFIG_NRF_MODEM_LIB) -NRF_MODEM_LIB_ON_INIT(nrf_cloud_fota_common_init_hook, - on_modem_lib_init, NULL); +static int dfu_result; -/* Initialized to value different than success (0) */ -static int modem_lib_init_result = -1; - -static void on_modem_lib_init(int ret, void *ctx) +static void on_modem_lib_dfu(int dfu_res, void *ctx) { - modem_lib_init_result = ret; + dfu_result = dfu_res; } -#endif + +NRF_MODEM_LIB_ON_DFU_RES(nrf_cloud_fota_dfu_hook, on_modem_lib_dfu, NULL); +#endif /* CONFIG_NRF_MODEM_LIB*/ LOG_MODULE_REGISTER(nrf_cloud_fota_common, CONFIG_NRF_CLOUD_LOG_LEVEL); @@ -191,25 +189,28 @@ static enum nrf_cloud_fota_validate_status app_fota_validate_get(void) static enum nrf_cloud_fota_validate_status modem_delta_fota_validate_get(void) { #if defined(CONFIG_NRF_MODEM_LIB) - switch (modem_lib_init_result) { + switch (dfu_result) { case NRF_MODEM_DFU_RESULT_OK: LOG_INF("Modem FOTA update confirmed"); return NRF_CLOUD_FOTA_VALIDATE_PASS; - case NRF_MODEM_DFU_RESULT_INTERNAL_ERROR: case NRF_MODEM_DFU_RESULT_UUID_ERROR: case NRF_MODEM_DFU_RESULT_AUTH_ERROR: + LOG_ERR("Modem FOTA error: 0x%x. Running old firmware", dfu_result); + return NRF_CLOUD_FOTA_VALIDATE_FAIL; case NRF_MODEM_DFU_RESULT_HARDWARE_ERROR: - LOG_ERR("Modem FOTA error: %d", modem_lib_init_result); + case NRF_MODEM_DFU_RESULT_INTERNAL_ERROR: + LOG_ERR("Modem FOTA fatal error: 0x%x. Modem failure", dfu_result); return NRF_CLOUD_FOTA_VALIDATE_FAIL; case NRF_MODEM_DFU_RESULT_VOLTAGE_LOW: - LOG_ERR("Modem FOTA cancelled: %d", modem_lib_init_result); + LOG_ERR("Modem FOTA cancelled: 0x%x.", dfu_result); LOG_ERR("Please reboot once you have sufficient power for the DFU"); return NRF_CLOUD_FOTA_VALIDATE_FAIL; default: - LOG_INF("Modem FOTA result unknown: %d", modem_lib_init_result); + /* Unknown DFU result code */ + LOG_WRN("Modem FOTA result unknown: 0x%x", dfu_result); break; } -#endif +#endif /* CONFIG_NRF_MODEM_LIB*/ return NRF_CLOUD_FOTA_VALIDATE_UNKNOWN; } diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c index fc9ce7c08fcd..f77a211dc921 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c @@ -968,12 +968,12 @@ int nrf_cloud_pgps_preemptive_updates(void) } int nrf_cloud_pgps_inject(struct nrf_cloud_pgps_prediction *p, - const struct nrf_modem_gnss_agps_data_frame *request) + const struct nrf_modem_gnss_agnss_data_frame *request) { int err; int ret = 0; - struct nrf_modem_gnss_agps_data_frame remainder; - struct nrf_modem_gnss_agps_data_frame processed; + struct nrf_modem_gnss_agnss_data_frame remainder; + struct nrf_modem_gnss_agnss_data_frame processed; if (state == PGPS_NONE) { LOG_ERR("P-GPS subsystem is not initialized."); @@ -985,33 +985,37 @@ int nrf_cloud_pgps_inject(struct nrf_cloud_pgps_prediction *p, } else { /* no assistance request provided from modem; assume just ephemerides */ memset(&remainder, 0, sizeof(remainder)); - remainder.sv_mask_ephe = 0xFFFFFFFFU; + remainder.system_count = 1; + remainder.system[0].system_id = NRF_MODEM_GNSS_SYSTEM_GPS; + remainder.system[0].sv_mask_ephe = 0xFFFFFFFFU; } + nrf_cloud_agps_processed(&processed); + LOG_DBG("A-GPS has processed emask:0x%08X amask:0x%08X utc:%u " "klo:%u neq:%u tow:%u pos:%u int:%u", - processed.sv_mask_ephe, - processed.sv_mask_alm, - processed.data_flags & NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST ? 1 : 0, - processed.data_flags & NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST ? 1 : 0, - processed.data_flags & NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST ? 1 : 0, - processed.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST ? 1 : 0, - processed.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST ? 1 : 0, - processed.data_flags & NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST ? 1 : 0); + (uint32_t)processed.system[0].sv_mask_ephe, + (uint32_t)processed.system[0].sv_mask_alm, + processed.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST ? 1 : 0, + processed.data_flags & NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST ? 1 : 0, + processed.data_flags & NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST ? 1 : 0, + processed.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST ? 1 : 0, + processed.data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST ? 1 : 0, + processed.data_flags & NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST ? 1 : 0); /* we will get more accurate data from AGPS for these */ - if (processed.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST && - remainder.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST) { + if (processed.data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST && + remainder.data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST) { LOG_DBG("A-GPS already received position; skipping"); - remainder.data_flags &= ~NRF_MODEM_GNSS_AGPS_POSITION_REQUEST; + remainder.data_flags &= ~NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST; } - if (processed.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST && - remainder.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) { + if (processed.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST && + remainder.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST) { LOG_DBG("A-GPS already received time; skipping"); - remainder.data_flags &= ~NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST; + remainder.data_flags &= ~NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST; } - if (remainder.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) { + if (remainder.data_flags & NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST) { struct pgps_sys_time sys_time; uint16_t day; uint32_t sec; @@ -1049,7 +1053,7 @@ int nrf_cloud_pgps_inject(struct nrf_cloud_pgps_prediction *p, const struct gps_location *saved_location = npgps_get_saved_location(); - if (remainder.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST && + if (remainder.data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST && saved_location->gps_sec) { struct pgps_location location; @@ -1077,13 +1081,13 @@ int nrf_cloud_pgps_inject(struct nrf_cloud_pgps_prediction *p, err); ret = err; } - } else if (remainder.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST) { + } else if (remainder.data_flags & NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST) { LOG_WRN("GPS unit needs location, but it is unknown!"); } else { LOG_DBG("GPS unit does not need location assistance."); } - if (remainder.sv_mask_ephe) { + if (remainder.system[0].sv_mask_ephe) { LOG_INF("GPS unit needs ephemerides. Injecting %u.", p->ephemeris_count); /* send ephemerii */ diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_rest.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_rest.c index b3dc3f32e492..040b8483398d 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_rest.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_rest.c @@ -70,7 +70,7 @@ LOG_MODULE_REGISTER(nrf_cloud_rest, CONFIG_NRF_CLOUD_REST_LOG_LEVEL); #define API_LOCATION "/location" #define API_GET_LOCATION API_VER API_LOCATION "/ground-fix" #define API_GET_LOCATION_NO_REPLY API_VER API_LOCATION "/ground-fix?doReply=0" -#define API_GET_AGPS_BASE API_VER API_LOCATION "/agps" +#define API_GET_AGNSS_BASE API_VER API_LOCATION "/agnss" #define API_GET_PGPS_BASE API_VER API_LOCATION "/pgps" #define API_DEVICES_BASE "/devices" @@ -647,16 +647,14 @@ int nrf_cloud_rest_agps_data_get(struct nrf_cloud_rest_context *const rest_ctx, int ret; int type_count = 0; - size_t url_sz; size_t total_bytes = 0; size_t rcvd_bytes = 0; size_t remain = 0; size_t pos = 0; size_t frag_size = (rest_ctx->fragment_size ? rest_ctx->fragment_size : RANGE_MAX_BYTES); char *auth_hdr = NULL; - char *url = NULL; cJSON *agps_obj; - enum nrf_cloud_agps_type types[NRF_CLOUD_AGPS__LAST]; + enum nrf_cloud_agps_type types[NRF_CLOUD_AGPS__TYPES_COUNT]; char range_hdr[HDR_RANGE_BYTES_SZ]; struct rest_client_req_context req; struct rest_client_resp_context resp; @@ -665,7 +663,7 @@ int nrf_cloud_rest_agps_data_get(struct nrf_cloud_rest_context *const rest_ctx, uint8_t mask_angle = NRF_CLOUD_AGPS_MASK_ANGLE_NONE; memset(&resp, 0, sizeof(resp)); - init_rest_client_request(rest_ctx, &req, HTTP_GET); + init_rest_client_request(rest_ctx, &req, HTTP_POST); #if defined(CONFIG_NRF_CLOUD_AGPS_FILTERED_RUNTIME) filtered = request->filtered; @@ -682,7 +680,7 @@ int nrf_cloud_rest_agps_data_get(struct nrf_cloud_rest_context *const rest_ctx, } if ((request->type == NRF_CLOUD_REST_AGPS_REQ_CUSTOM) && - (request->agps_req == NULL)) { + (request->agnss_req == NULL)) { LOG_ERR("Custom request type requires A-GPS request data"); ret = -EINVAL; goto clean_up; @@ -710,7 +708,7 @@ int nrf_cloud_rest_agps_data_get(struct nrf_cloud_rest_context *const rest_ctx, /* Get the A-GPS type array */ switch (request->type) { case NRF_CLOUD_REST_AGPS_REQ_CUSTOM: - type_count = nrf_cloud_agps_type_array_get(request->agps_req, + type_count = nrf_cloud_agps_type_array_get(request->agnss_req, types, ARRAY_SIZE(types)); break; case NRF_CLOUD_REST_AGPS_REQ_LOCATION: @@ -718,9 +716,19 @@ int nrf_cloud_rest_agps_data_get(struct nrf_cloud_rest_context *const rest_ctx, types[0] = NRF_CLOUD_AGPS_LOCATION; break; case NRF_CLOUD_REST_AGPS_REQ_ASSISTANCE: { - struct nrf_modem_gnss_agps_data_frame assist; - /* Set all request flags */ - memset(&assist, 0xFF, sizeof(assist)); + struct nrf_modem_gnss_agnss_data_frame assist = { 0 }; + /* Set all request flags for GPS */ + assist.data_flags = + NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST | + NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST | + NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST | + NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST | + NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST | + NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST; + assist.system_count = 1; + assist.system[0].system_id = NRF_MODEM_GNSS_SYSTEM_GPS; + assist.system[0].sv_mask_ephe = 0xFFFFFFFF; + assist.system[0].sv_mask_alm = 0xFFFFFFFF; type_count = nrf_cloud_agps_type_array_get(&assist, types, ARRAY_SIZE(types)); break; } @@ -740,40 +748,18 @@ int nrf_cloud_rest_agps_data_get(struct nrf_cloud_rest_context *const rest_ctx, filtered, mask_angle, agps_obj); - /* Create a parameterized URL from the JSON data to use for the GET request. - * The HTTP request body is not used in GET requests. - * Use the rx_buf temporarily. - */ - ret = nrf_cloud_json_to_url_params_convert(rest_ctx->rx_buf, rest_ctx->rx_buf_len, - agps_obj); - - /* Cleanup JSON obj */ + /* Set payload */ + req.body = cJSON_PrintUnformatted(agps_obj); cJSON_Delete(agps_obj); agps_obj = NULL; - if (ret) { - LOG_ERR("Could not create A-GPS request URL"); - goto clean_up; - } - - url_sz = sizeof(API_GET_AGPS_BASE) + strlen(rest_ctx->rx_buf); - url = nrf_cloud_malloc(url_sz); - if (!url) { + if (!req.body) { ret = -ENOMEM; goto clean_up; } - ret = snprintk(url, url_sz, "%s%s", API_GET_AGPS_BASE, rest_ctx->rx_buf); - if (ret < 0 || ret >= url_sz) { - LOG_ERR("Could not format URL"); - ret = -ETXTBSY; - goto clean_up; - } - /* Set the URL */ - req.url = url; - - LOG_DBG("URL: %s", url); + req.url = API_GET_AGNSS_BASE; /* Format auth header */ ret = generate_auth_header(rest_ctx->auth, &auth_hdr); @@ -786,12 +772,15 @@ int nrf_cloud_rest_agps_data_get(struct nrf_cloud_rest_context *const rest_ctx, HDR_ACCEPT_ALL, (char *const)auth_hdr, (char *const)range_hdr, - CONTENT_TYPE_APP_OCT_STR, + CONTENT_TYPE_APP_JSON, NULL }; req.header_fields = (const char **)headers; + LOG_DBG("URL: %s%s", req.host, req.url); + LOG_DBG("Body: %s", req.body); + /* Do as many REST calls as needed to receive entire payload */ do { /* Format range header */ @@ -865,8 +854,10 @@ int nrf_cloud_rest_agps_data_get(struct nrf_cloud_rest_context *const rest_ctx, last_request_timestamp = k_uptime_get(); clean_up: - nrf_cloud_free(url); nrf_cloud_free(auth_hdr); + if (req.body) { + cJSON_free((void *)req.body); + } close_connection(rest_ctx); diff --git a/tests/lib/nrf_modem_lib/lte_connectivity/src/lte_connectivity_test.c b/tests/lib/nrf_modem_lib/lte_connectivity/src/lte_connectivity_test.c index 2946629c0efe..e47454c1e9d3 100644 --- a/tests/lib/nrf_modem_lib/lte_connectivity/src/lte_connectivity_test.c +++ b/tests/lib/nrf_modem_lib/lte_connectivity/src/lte_connectivity_test.c @@ -215,12 +215,11 @@ void test_enable_should_init_modem_and_link_controller(void) TEST_ASSERT_EQUAL(0, net_if_up(net_if)); } -void test_enable_should_init_modem_twice_upon_successful_dfu_result(void) +void test_enable_should_init_modem_upon_successful_dfu_result(void) { struct net_if *net_if = net_if_get_default(); __cmock_nrf_modem_is_initialized_ExpectAndReturn(0); - __cmock_nrf_modem_lib_init_ExpectAndReturn(NRF_MODEM_DFU_RESULT_OK); __cmock_nrf_modem_lib_init_ExpectAndReturn(0); __cmock_lte_lc_init_ExpectAndReturn(0); @@ -232,9 +231,9 @@ void test_enable_should_return_error_upon_dfu_error(void) struct net_if *net_if = net_if_get_default(); __cmock_nrf_modem_is_initialized_ExpectAndReturn(0); - __cmock_nrf_modem_lib_init_ExpectAndReturn(NRF_MODEM_DFU_RESULT_HARDWARE_ERROR); + __cmock_nrf_modem_lib_init_ExpectAndReturn(-EIO); - TEST_ASSERT_EQUAL(NRF_MODEM_DFU_RESULT_HARDWARE_ERROR, net_if_up(net_if)); + TEST_ASSERT_EQUAL(-EIO, net_if_up(net_if)); } /* Verify lte_connectivity_disable() */ diff --git a/tests/lib/nrf_modem_lib/nrf91_sockets/src/nrf91_sockets_test.c b/tests/lib/nrf_modem_lib/nrf91_sockets/src/nrf91_sockets_test.c index 392cfbbe8ceb..48fdd831ca4d 100644 --- a/tests/lib/nrf_modem_lib/nrf91_sockets/src/nrf91_sockets_test.c +++ b/tests/lib/nrf_modem_lib/nrf91_sockets/src/nrf91_sockets_test.c @@ -789,6 +789,34 @@ void test_nrf91_socket_offload_setsockopt_ebadf(void) TEST_ASSERT_EQUAL(errno, EBADF); } +void test_nrf91_socket_offload_setsockopt_bindtodevice_eopnotsup(void) +{ + int ret; + int fd; + int nrf_fd = 2; + int family = AF_INET; + int type = SOCK_STREAM; + int proto = IPPROTO_TCP; + struct timeval data = { 0 }; + + __cmock_nrf_socket_ExpectAndReturn(NRF_AF_INET, NRF_SOCK_STREAM, + NRF_IPPROTO_TCP, nrf_fd); + + fd = socket(family, type, proto); + + TEST_ASSERT_EQUAL(fd, 0); + + ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &data, sizeof(data)); + + TEST_ASSERT_EQUAL(ret, -1); + TEST_ASSERT_EQUAL(errno, EOPNOTSUPP); + + __cmock_nrf_close_ExpectAndReturn(nrf_fd, 0); + ret = close(fd); + + TEST_ASSERT_EQUAL(ret, 0); +} + void test_nrf91_socket_offload_setsockopt_rcvtimeo_success(void) { int ret; diff --git a/tests/subsys/net/lib/lwm2m_client_utils/src/location_assistance.c b/tests/subsys/net/lib/lwm2m_client_utils/src/location_assistance.c index e6ee13eb2d8d..7a84e403ef7b 100644 --- a/tests/subsys/net/lib/lwm2m_client_utils/src/location_assistance.c +++ b/tests/subsys/net/lib/lwm2m_client_utils/src/location_assistance.c @@ -45,10 +45,12 @@ void fake_lwm2m_register_obj(struct lwm2m_engine_obj *obj) } } -static struct nrf_modem_gnss_agps_data_frame agps_req = { - .sv_mask_ephe = 0xffffffff, - .sv_mask_alm = 0xffffffff, +static struct nrf_modem_gnss_agnss_data_frame agps_req = { .data_flags = 0xffffffff, + .system_count = 1, + .system[0].system_id = NRF_MODEM_GNSS_SYSTEM_GPS, + .system[0].sv_mask_ephe = 0xffffffff, + .system[0].sv_mask_alm = 0xffffffff, }; static struct lwm2m_ctx client_ctx; diff --git a/tests/subsys/net/lib/lwm2m_fota_utils/src/firmware.c b/tests/subsys/net/lib/lwm2m_fota_utils/src/firmware.c index 791ed71fe874..64629d15c595 100644 --- a/tests/subsys/net/lib/lwm2m_fota_utils/src/firmware.c +++ b/tests/subsys/net/lib/lwm2m_fota_utils/src/firmware.c @@ -17,7 +17,6 @@ #include "stubs.h" -extern void lwm2m_firmware_emulate_modem_lib_init(int modem_init_ret_val); static int write_fota_dynamic_url(uint8_t instance_id, const char *url, uint16_t len); static void tear_down_test(void *fixie); static void setup_tear_up(void *fixie); @@ -59,6 +58,7 @@ static fota_download_callback_t firmware_fota_download_cb; static struct settings_handler *handler; static int fota_download_ret_val; +static int fota_apply_ret_val; static bool boot_scheduled; static bool target_reset_done; static size_t target_offset; @@ -216,6 +216,11 @@ static int fota_download_init_stub(fota_download_callback_t client_callback) return fota_download_ret_val; } +static int fota_download_util_apply_update_stub(enum dfu_target_image_type dfu_target_type) +{ + return fota_apply_ret_val; +} + static void fota_cb_simulate_event(enum fota_download_evt_id id) { struct fota_download_evt evt; @@ -270,6 +275,7 @@ static void setup_tear_up(void *fixie) fota_download_start_with_image_type_fake.return_val = 0; fota_download_target_fake.return_val = DFU_TARGET_IMAGE_TYPE_MCUBOOT; fota_download_init_fake.custom_fake = fota_download_init_stub; + fota_download_util_apply_update_fake.custom_fake = fota_download_util_apply_update_stub; fota_download_util_download_start_fake.custom_fake = fota_download_util_download_start_stub; settings_subsys_init_fake.return_val = 0; @@ -641,8 +647,7 @@ ZTEST(lwm2m_client_utils_firmware, test_firmware_update) printf("State %d\r\n", state); zassert_equal(state, STATE_DOWNLOADED, "wrong result value"); - lwm2m_firmware_emulate_modem_lib_init(NRF_MODEM_DFU_RESULT_AUTH_ERROR); - fota_download_util_apply_update_fake.return_val = -1; + fota_apply_ret_val = -1; do_firmware_update(modem_instance); result = get_modem_result(); state = get_app_state(); @@ -663,8 +668,7 @@ ZTEST(lwm2m_client_utils_firmware, test_firmware_update) printf("State %d\r\n", state); zassert_equal(state, STATE_DOWNLOADED, "wrong result value"); - lwm2m_firmware_emulate_modem_lib_init(NRF_MODEM_DFU_RESULT_OK); - fota_download_util_apply_update_fake.return_val = 0; + fota_apply_ret_val = 0; do_firmware_update(modem_instance); result = get_modem_result(); zassert_equal(boot_scheduled, true, "Not scheduled"); @@ -785,7 +789,6 @@ ZTEST(lwm2m_client_utils_firmware, test_firmware_multinstace_download) printf("Update %d\r\n", rc); zassert_equal(rc, 0, "wrong result value"); /* Stub Linked write for update */ - lwm2m_firmware_emulate_modem_lib_init(NRF_MODEM_DFU_RESULT_OK); k_sleep(K_SECONDS(6)); state = get_modem_state(); zassert_equal(state, STATE_IDLE, "wrong result value"); diff --git a/west.yml b/west.yml index 20996cd76820..3aab92b488f1 100644 --- a/west.yml +++ b/west.yml @@ -61,7 +61,7 @@ manifest: # https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/modules.html - name: zephyr repo-path: sdk-zephyr - revision: cbe3d5fb40a7a737e4d17d81864335c7e1623508 + revision: c7f3aaa87cf8ab6ca6961ec57f06d65d7c893e5b import: # In addition to the zephyr repository itself, NCS also # imports the contents of zephyr/west.yml at the above @@ -141,7 +141,7 @@ manifest: - name: nrfxlib repo-path: sdk-nrfxlib path: nrfxlib - revision: 410ca110e209c1c1050d613d1f61c6eab6d171df + revision: 50e726589dd622aff6a255335becf6ac92dd32c2 - name: trusted-firmware-m repo-path: sdk-trusted-firmware-m path: modules/tee/tf-m/trusted-firmware-m