Skip to content

Commit 588f19d

Browse files
tokangasrlubos
authored andcommitted
lib: location: skip A-GNSS data request when no ephe/alm requested
GNSS asks for some A-GNSS data, like UTC and iono parameters, once every 24 hours. This may have caused a separate A-GNSS data request for this data alone. The implementation has now been modified to skip such a request. All data is downloaded with the next ephemeris request, which happens approximately every two hours. Signed-off-by: Tommi Kangas <[email protected]>
1 parent 020cc3f commit 588f19d

File tree

2 files changed

+188
-48
lines changed

2 files changed

+188
-48
lines changed

lib/location/method_gnss.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -425,20 +425,28 @@ static void method_gnss_pgps_request_work_fn(struct k_work *item)
425425
static bool method_gnss_agnss_required(void)
426426
{
427427
int32_t time_since_agnss_req;
428-
bool ephe_or_alm_required = false;
428+
bool ephe_requested = false;
429+
bool alm_requested = false;
429430

430431
/* Check if A-GNSS data is needed. */
431432
for (int i = 0; i < agnss_request.system_count; i++) {
432-
if (agnss_request.system[i].sv_mask_ephe != 0 ||
433-
agnss_request.system[i].sv_mask_alm != 0) {
434-
ephe_or_alm_required = true;
435-
break;
433+
if (agnss_request.system[i].sv_mask_ephe != 0) {
434+
ephe_requested = true;
435+
}
436+
if (agnss_request.system[i].sv_mask_alm != 0) {
437+
alm_requested = true;
436438
}
437439
}
438440

439-
if (agnss_request.data_flags == 0 && !ephe_or_alm_required) {
441+
if (!ephe_requested && !alm_requested && agnss_request.data_flags == 0) {
440442
LOG_DBG("No A-GNSS data types requested");
441443
return false;
444+
} else if (!IS_ENABLED(CONFIG_NRF_CLOUD_PGPS) && !ephe_requested) {
445+
/* No ephemerides requested and A-GNSS is used to provide ephemerides.
446+
* Skip this request and download all data with the next ephemeris request.
447+
*/
448+
LOG_DBG("Skipping A-GNSS request, no ephemerides requested");
449+
return false;
442450
}
443451

444452
/* A-GNSS data is needed, check if enough time has passed since the last A-GNSS data
@@ -551,12 +559,8 @@ static void method_gnss_assistance_request(void)
551559
* QZSS satellites always as expired.
552560
*/
553561
if (agnss_request.system_count > 1) {
554-
if (agnss_request.data_flags != 0 ||
555-
agnss_request.system[0].sv_mask_ephe != 0 ||
556-
agnss_request.system[0].sv_mask_alm != 0) {
557-
/* QZSS ephemerides are requested always when other assistance data is
558-
* needed.
559-
*/
562+
if (agnss_request.system[0].sv_mask_ephe != 0) {
563+
/* QZSS ephemerides are requested whenever GPS ephemerides are requested. */
560564
agnss_request.system[1].sv_mask_ephe = 0x3ff;
561565
} else {
562566
/* No other assistance is needed. Request QZSS ephemerides anyway if
@@ -1172,7 +1176,7 @@ static void method_gnss_agnss_expiry_process(const struct nrf_modem_gnss_agnss_e
11721176
*/
11731177

11741178
/* QZSS ephemerides are valid for a maximum of two hours, so no expiry
1175-
* is used here.
1179+
* threshold is used here.
11761180
*/
11771181
if (agnss_expiry->sv[i].ephe_expiry == 0) {
11781182
expired_qzss_ephe_mask |=

tests/lib/location/src/location_test.c

Lines changed: 171 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,150 @@ int nrf_cloud_rest_agnss_data_get_Stub(
576576
return 0;
577577
}
578578

579+
/* Test that no A-GNSS data is requested when less than 3 GPS satellites have expired
580+
* ephemerides, even when all other data is expired.
581+
*/
582+
void test_location_gnss_agnss_no_request(void)
583+
{
584+
int err;
585+
struct location_config config = { 0 };
586+
enum location_method methods[] = {LOCATION_METHOD_GNSS};
587+
588+
#if !defined(CONFIG_LOCATION_TEST_AGNSS)
589+
TEST_IGNORE();
590+
#endif
591+
592+
location_config_defaults_set(&config, 1, methods);
593+
594+
#if defined(CONFIG_LOCATION_DATA_DETAILS)
595+
test_location_event_data[location_cb_expected].id = LOCATION_EVT_STARTED;
596+
test_location_event_data[location_cb_expected].method = LOCATION_METHOD_GNSS;
597+
location_cb_expected++;
598+
#endif
599+
600+
test_pvt_data.flags = NRF_MODEM_GNSS_PVT_FLAG_FIX_VALID;
601+
test_pvt_data.latitude = 61.005;
602+
test_pvt_data.longitude = -45.997;
603+
test_pvt_data.accuracy = 15.83;
604+
test_pvt_data.datetime.year = 2021;
605+
test_pvt_data.datetime.month = 8;
606+
test_pvt_data.datetime.day = 13;
607+
test_pvt_data.datetime.hour = 12;
608+
test_pvt_data.datetime.minute = 34;
609+
test_pvt_data.datetime.seconds = 56;
610+
test_pvt_data.datetime.ms = 789;
611+
test_pvt_data.sv[0].sv = 2;
612+
test_pvt_data.sv[0].flags = NRF_MODEM_GNSS_SV_FLAG_USED_IN_FIX;
613+
test_pvt_data.sv[1].sv = 4;
614+
test_pvt_data.sv[1].flags = NRF_MODEM_GNSS_SV_FLAG_USED_IN_FIX;
615+
test_pvt_data.sv[2].sv = 6;
616+
test_pvt_data.sv[2].flags = NRF_MODEM_GNSS_SV_FLAG_USED_IN_FIX;
617+
test_pvt_data.sv[3].sv = 8;
618+
test_pvt_data.sv[3].flags = NRF_MODEM_GNSS_SV_FLAG_USED_IN_FIX;
619+
test_pvt_data.sv[4].sv = 10;
620+
test_pvt_data.sv[4].flags = NRF_MODEM_GNSS_SV_FLAG_USED_IN_FIX;
621+
622+
test_location_event_data[location_cb_expected].id = LOCATION_EVT_LOCATION;
623+
test_location_event_data[location_cb_expected].method = LOCATION_METHOD_GNSS;
624+
test_location_event_data[location_cb_expected].location.latitude = 61.005;
625+
test_location_event_data[location_cb_expected].location.longitude = -45.997;
626+
test_location_event_data[location_cb_expected].location.accuracy = 15.83;
627+
test_location_event_data[location_cb_expected].location.datetime.valid = true;
628+
test_location_event_data[location_cb_expected].location.datetime.year = 2021;
629+
test_location_event_data[location_cb_expected].location.datetime.month = 8;
630+
test_location_event_data[location_cb_expected].location.datetime.day = 13;
631+
test_location_event_data[location_cb_expected].location.datetime.hour = 12;
632+
test_location_event_data[location_cb_expected].location.datetime.minute = 34;
633+
test_location_event_data[location_cb_expected].location.datetime.second = 56;
634+
test_location_event_data[location_cb_expected].location.datetime.ms = 789;
635+
#if defined(CONFIG_LOCATION_DATA_DETAILS)
636+
test_location_event_data[location_cb_expected].location.details.gnss.satellites_tracked = 5;
637+
test_location_event_data[location_cb_expected].location.details.gnss.satellites_used = 5;
638+
test_location_event_data[location_cb_expected].location.details.gnss.elapsed_time_gnss = 50;
639+
test_location_event_data[location_cb_expected].location.details.gnss.pvt_data =
640+
test_pvt_data;
641+
#endif
642+
location_cb_expected++;
643+
644+
__cmock_nrf_modem_gnss_event_handler_set_ExpectAndReturn(&method_gnss_event_handler, 0);
645+
646+
/* The expiry times are in minutes. Most of the data types are considered expired when
647+
* there's less than 80 minutes left.
648+
*/
649+
struct nrf_modem_gnss_agnss_expiry agnss_expiry = {
650+
/* All generic assistance data is expired. */
651+
.data_flags =
652+
NRF_MODEM_GNSS_AGNSS_GPS_UTC_REQUEST |
653+
NRF_MODEM_GNSS_AGNSS_KLOBUCHAR_REQUEST |
654+
NRF_MODEM_GNSS_AGNSS_NEQUICK_REQUEST |
655+
NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST |
656+
NRF_MODEM_GNSS_AGNSS_INTEGRITY_REQUEST,
657+
.utc_expiry = 50, /* expired */
658+
.klob_expiry = 50, /* expired */
659+
.neq_expiry = 50, /* expired */
660+
.integrity_expiry = 50, /* expired */
661+
.position_expiry = 0, /* expired, no expiry threshold used for position */
662+
.sv_count = 32 + 10 /* expired */
663+
};
664+
665+
/* Two GPS satellites have expired ephemerides, all GPS satellites have expired almanacs. */
666+
for (int i = 0; i < 32; i++) {
667+
agnss_expiry.sv[i].sv_id = i + 1;
668+
agnss_expiry.sv[i].system_id = NRF_MODEM_GNSS_SYSTEM_GPS;
669+
agnss_expiry.sv[i].ephe_expiry = 120; /* valid */
670+
agnss_expiry.sv[i].alm_expiry = 50; /* expired */
671+
}
672+
agnss_expiry.sv[0].ephe_expiry = 50; /* expired */
673+
agnss_expiry.sv[1].ephe_expiry = 50; /* expired */
674+
675+
/* All QZSS satellites have expired ephemerides and almanacs. */
676+
for (int i = 0; i < 10; i++) {
677+
agnss_expiry.sv[i + 32].sv_id = i + 1;
678+
agnss_expiry.sv[i + 32].system_id = NRF_MODEM_GNSS_SYSTEM_QZSS;
679+
/* No expiry threshold used for QZSS. */
680+
agnss_expiry.sv[i + 32].ephe_expiry = 0; /* expired */
681+
agnss_expiry.sv[i + 32].alm_expiry = 0; /* expired */
682+
}
683+
684+
__cmock_nrf_modem_gnss_agnss_expiry_get_ExpectAndReturn(NULL, 0);
685+
__cmock_nrf_modem_gnss_agnss_expiry_get_IgnoreArg_agnss_expiry();
686+
__cmock_nrf_modem_gnss_agnss_expiry_get_ReturnMemThruPtr_agnss_expiry(
687+
&agnss_expiry, sizeof(agnss_expiry));
688+
689+
__cmock_nrf_modem_gnss_fix_interval_set_ExpectAndReturn(1, 0);
690+
__cmock_nrf_modem_gnss_use_case_set_ExpectAndReturn(
691+
NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START, 0);
692+
__cmock_nrf_modem_gnss_start_ExpectAndReturn(0);
693+
694+
__mock_nrf_modem_at_scanf_ExpectAndReturn(
695+
"AT%XSYSTEMMODE?", "%%XSYSTEMMODE: %d,%d,%d,%d", 4);
696+
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* LTE-M support */
697+
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* NB-IoT support */
698+
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* GNSS support */
699+
__mock_nrf_modem_at_scanf_ReturnVarg_int(0); /* LTE preference */
700+
701+
err = location_request(&config);
702+
TEST_ASSERT_EQUAL(0, err);
703+
k_sleep(K_MSEC(1));
704+
705+
#if defined(CONFIG_LOCATION_DATA_DETAILS)
706+
err = k_sem_take(&event_handler_called_sem, K_SECONDS(3));
707+
TEST_ASSERT_EQUAL(0, err);
708+
#endif
709+
710+
/* An event other than NRF_MODEM_GNSS_EVT_PVT to see that no actions are done */
711+
method_gnss_event_handler(NRF_MODEM_GNSS_EVT_FIX);
712+
k_sleep(K_MSEC(1));
713+
714+
__cmock_nrf_modem_gnss_read_ExpectAndReturn(
715+
NULL, sizeof(test_pvt_data), NRF_MODEM_GNSS_DATA_PVT, 0);
716+
__cmock_nrf_modem_gnss_read_IgnoreArg_buf();
717+
__cmock_nrf_modem_gnss_read_ReturnMemThruPtr_buf(&test_pvt_data, sizeof(test_pvt_data));
718+
__cmock_nrf_modem_gnss_stop_ExpectAndReturn(0);
719+
method_gnss_event_handler(NRF_MODEM_GNSS_EVT_PVT);
720+
k_sleep(K_MSEC(1));
721+
}
722+
579723
/* Test successful GNSS location request. */
580724
void test_location_gnss(void)
581725
{
@@ -645,51 +789,49 @@ void test_location_gnss(void)
645789
__cmock_nrf_modem_gnss_event_handler_set_ExpectAndReturn(&method_gnss_event_handler, 0);
646790

647791
#if defined(CONFIG_LOCATION_TEST_AGNSS)
648-
/* Zero triggers new AGNSS data request */
792+
/* The expiry times are in minutes. Most of the data types are considered expired when
793+
* there's less than 80 minutes left.
794+
*/
649795
struct nrf_modem_gnss_agnss_expiry agnss_expiry = {
650-
.data_flags = NRF_MODEM_GNSS_AGNSS_GPS_SYS_TIME_AND_SV_TOW_REQUEST,
651-
.utc_expiry = 1,
652-
.klob_expiry = 2,
653-
.neq_expiry = 3,
654-
.integrity_expiry = 4,
655-
.position_expiry = 5,
656-
.sv_count = 6,
796+
/* Only position is expired, but all generic assistance data should be
797+
* requested at the same time.
798+
*/
799+
.data_flags = NRF_MODEM_GNSS_AGNSS_POSITION_REQUEST,
800+
.utc_expiry = 120, /* valid */
801+
.klob_expiry = 120, /* valid */
802+
.neq_expiry = 120, /* valid */
803+
.integrity_expiry = 120, /* valid */
804+
.position_expiry = 0, /* expired */
805+
.sv_count = 4,
657806
.sv = {
807+
/* Three expired GPS ephes and almanacs are needed to trigger a request. */
658808
{
659809
.sv_id = 1,
660810
.system_id = NRF_MODEM_GNSS_SYSTEM_GPS,
661-
.ephe_expiry = 1,
662-
.alm_expiry = 4
811+
.ephe_expiry = 50, /* expired */
812+
.alm_expiry = 50 /* expired */
663813
},
664814
{
665815
.sv_id = 2,
666816
.system_id = NRF_MODEM_GNSS_SYSTEM_GPS,
667-
.ephe_expiry = 100,
668-
.alm_expiry = 4
817+
.ephe_expiry = 50, /* expired */
818+
.alm_expiry = 50 /* expired */
669819
},
670820
{
671821
.sv_id = 3,
672822
.system_id = NRF_MODEM_GNSS_SYSTEM_GPS,
673-
.ephe_expiry = 0,
674-
.alm_expiry = 101
675-
},
676-
{
677-
.sv_id = 4,
678-
.system_id = NRF_MODEM_GNSS_SYSTEM_GPS,
679-
.ephe_expiry = 6,
680-
.alm_expiry = 1
823+
.ephe_expiry = 50, /* expired */
824+
.alm_expiry = 50 /* expired */
681825
},
826+
/* QZSS ephes and almanacs are requested at the same time with GPS, when
827+
* QZSS is supported. It's enough to have one QZSS SV and data doesn't
828+
* even have to be expired.
829+
*/
682830
{
683831
.sv_id = 193,
684832
.system_id = NRF_MODEM_GNSS_SYSTEM_QZSS,
685-
.ephe_expiry = 0,
686-
.alm_expiry = 100
687-
},
688-
{
689-
.sv_id = 202,
690-
.system_id = NRF_MODEM_GNSS_SYSTEM_QZSS,
691-
.ephe_expiry = 100,
692-
.alm_expiry = 4
833+
.ephe_expiry = 120, /* valid */
834+
.alm_expiry = 120 /* valid */
693835
},
694836
}
695837
};
@@ -740,7 +882,7 @@ void test_location_gnss(void)
740882
test_agnss_data, sizeof(test_agnss_data), 0);
741883
#endif
742884
#endif
743-
/* TODO: Cannot determine the used system mode but it's set as zero by default in lte_lc */
885+
744886
__mock_nrf_modem_at_scanf_ExpectAndReturn(
745887
"AT%XSYSTEMMODE?", "%%XSYSTEMMODE: %d,%d,%d,%d", 4);
746888
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* LTE-M support */
@@ -842,7 +984,6 @@ void test_location_gnss_location_request_timeout(void)
842984
NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START, 0);
843985
__cmock_nrf_modem_gnss_start_ExpectAndReturn(0);
844986

845-
/* TODO: Cannot determine the used system mode but it's set as zero by default in lte_lc */
846987
__mock_nrf_modem_at_scanf_ExpectAndReturn(
847988
"AT%XSYSTEMMODE?", "%%XSYSTEMMODE: %d,%d,%d,%d", 4);
848989
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* LTE-M support */
@@ -1452,7 +1593,6 @@ void test_location_request_default(void)
14521593
NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START, 0);
14531594
__cmock_nrf_modem_gnss_start_ExpectAndReturn(0);
14541595

1455-
/* TODO: Cannot determine the used system mode but it's set as zero by default in lte_lc */
14561596
__mock_nrf_modem_at_scanf_ExpectAndReturn(
14571597
"AT%XSYSTEMMODE?", "%%XSYSTEMMODE: %d,%d,%d,%d", 4);
14581598
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* LTE-M support */
@@ -1684,7 +1824,6 @@ void test_location_request_mode_all_cellular_gnss(void)
16841824
NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START, 0);
16851825
__cmock_nrf_modem_gnss_start_ExpectAndReturn(0);
16861826

1687-
/* TODO: Cannot determine the used system mode but it's set as zero by default in lte_lc */
16881827
__mock_nrf_modem_at_scanf_ExpectAndReturn(
16891828
"AT%XSYSTEMMODE?", "%%XSYSTEMMODE: %d,%d,%d,%d", 4);
16901829
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* LTE-M support */
@@ -1786,7 +1925,6 @@ void test_location_request_mode_all_cellular_error_gnss_timeout(void)
17861925
NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START, 0);
17871926
__cmock_nrf_modem_gnss_start_ExpectAndReturn(0);
17881927

1789-
/* TODO: Cannot determine the used system mode but it's set as zero by default in lte_lc */
17901928
__mock_nrf_modem_at_scanf_ExpectAndReturn(
17911929
"AT%XSYSTEMMODE?", "%%XSYSTEMMODE: %d,%d,%d,%d", 4);
17921930
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* LTE-M support */
@@ -1885,7 +2023,6 @@ void test_location_gnss_periodic(void)
18852023
NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START, 0);
18862024
__cmock_nrf_modem_gnss_start_ExpectAndReturn(0);
18872025

1888-
/* TODO: Cannot determine the used system mode but it's set as zero by default in lte_lc */
18892026
__mock_nrf_modem_at_scanf_ExpectAndReturn(
18902027
"AT%XSYSTEMMODE?", "%%XSYSTEMMODE: %d,%d,%d,%d", 4);
18912028
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* LTE-M support */
@@ -1947,7 +2084,6 @@ void test_location_gnss_periodic(void)
19472084
NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START, 0);
19482085
__cmock_nrf_modem_gnss_start_ExpectAndReturn(0);
19492086

1950-
/* TODO: Cannot determine the used system mode but it's set as zero by default in lte_lc */
19512087
__mock_nrf_modem_at_scanf_ExpectAndReturn(
19522088
"AT%XSYSTEMMODE?", "%%XSYSTEMMODE: %d,%d,%d,%d", 4);
19532089
__mock_nrf_modem_at_scanf_ReturnVarg_int(1); /* LTE-M support */

0 commit comments

Comments
 (0)