Skip to content

Commit

Permalink
lib: location: Use %NCELLMEAS for GNSS assistance network info
Browse files Browse the repository at this point in the history
Changed GNSS assistance request to use %NCELLMEAS instead of
%XMONITOR, because %XMONITOR may return stale cell information
when modem is in PSM.

Signed-off-by: Tommi Kangas <[email protected]>
  • Loading branch information
tokangas authored and nordicjm committed Sep 7, 2023
1 parent b3e65bd commit 6692196
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 129 deletions.
5 changes: 4 additions & 1 deletion lib/location/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ zephyr_library_sources(location.c)
zephyr_library_sources(location_core.c)
zephyr_library_sources(location_utils.c)
zephyr_library_sources_ifdef(CONFIG_LOCATION_METHOD_GNSS method_gnss.c)
zephyr_library_sources_ifdef(CONFIG_LOCATION_METHOD_CELLULAR scan_cellular.c)
zephyr_library_sources_ifdef(CONFIG_LOCATION_METHOD_WIFI scan_wifi.c)

if(CONFIG_LOCATION_METHOD_CELLULAR OR CONFIG_LOCATION_METHOD_GNSS)
zephyr_library_sources(scan_cellular.c)
endif()

if(CONFIG_LOCATION_METHOD_CELLULAR OR CONFIG_LOCATION_METHOD_WIFI)
zephyr_library_sources(method_cloud_location.c)
add_subdirectory(cloud_service)
Expand Down
62 changes: 1 addition & 61 deletions lib/location/location_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,74 +55,14 @@ bool location_utils_is_lte_available(void)
return is_active;
}

int location_utils_modem_params_read(struct location_utils_modem_params_info *modem_params)
{
/* Parsed strings include double quotes */
char plmn_str[MODEM_PARAM_STR_MAX_LEN + 1] = { 0 };
char tac_str[MODEM_PARAM_STR_MAX_LEN + 1] = { 0 };
char cell_id_str[MODEM_PARAM_STR_MAX_LEN + 1] = { 0 };
int err = 0;

__ASSERT_NO_MSG(modem_params != NULL);

err = nrf_modem_at_scanf(
"AT%XMONITOR",
"%%XMONITOR: "
"%*d" /* <reg_status>: ignored */
",%*[^,]" /* <full_name>: ignored */
",%*[^,]" /* <short_name>: ignored */
",%"L(MODEM_PARAM_STR_MAX_LEN)"[^,]" /* <plmn> */
",%"L(MODEM_PARAM_STR_MAX_LEN)"[^,]" /* <tac> */
",%*d" /* <AcT>: ignored */
",%*d" /* <band>: ignored */
",%"L(MODEM_PARAM_STR_MAX_LEN)"[^,]" /* <cell_id> */
",%d", /* <phys_cell_id> */
plmn_str, tac_str, cell_id_str, &modem_params->phys_cell_id);

if (err <= 2) {
LOG_ERR("Cannot get modem parameters, err %d", err);
} else {
/* Indicate success to the caller with zero return value */
err = 0;

/* Read MNC and store as integer. The MNC starts as the fifth character
* in the string, following double quote and three characters long MCC.
*/
modem_params->mnc = strtol(&plmn_str[4], NULL, 10);

/* Null-terminated MCC, read and store it. */
plmn_str[4] = '\0';

modem_params->mcc = strtol(plmn_str + 1, NULL, 10);

/* <tac> */
modem_params->tac = strtol(tac_str + 1, NULL, 16);

/* <cell_id> */
modem_params->cell_id = strtol(cell_id_str + 1, NULL, 16);

LOG_DBG("parsed modem parameters: "
"mcc %d, mnc %d, tac %d (string: %s), cell_id %d (string: %s) phys_cell_id %d",
modem_params->mcc, modem_params->mnc, modem_params->tac,
tac_str, modem_params->cell_id, cell_id_str,
modem_params->phys_cell_id);
}
return err;
}

#else /* CONFIG_NRF_MODEM_LIB */

bool location_utils_is_lte_available(void)
{
return false;
}

int location_utils_modem_params_read(struct location_utils_modem_params_info *modem_params)
{
return 0;
}

#endif /* CONFIG_NRF_MODEM_LIB*/
#endif /* CONFIG_NRF_MODEM_LIB */

const char *location_utils_nrf_cloud_jwt_generate(void)
{
Expand Down
28 changes: 0 additions & 28 deletions lib/location/location_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,6 @@

#include <modem/location.h>

/** Modem parameters. */
struct location_utils_modem_params_info {
/** Mobile Country Code. */
int mcc;

/** Mobile Network Code. */
int mnc;

/** E-UTRAN cell ID */
uint32_t cell_id;

/** Tracking area code. */
uint32_t tac;

/** Physical cell ID. */
uint16_t phys_cell_id;
};

/**
* @brief Check if LTE networking is available.
*
Expand All @@ -38,16 +20,6 @@ struct location_utils_modem_params_info {
*/
bool location_utils_is_lte_available(void);

/**
* @brief Read modem parameters.
*
* @param[out] modem_params Context where parameters are filled.
*
* @retval true If modem parameters were received successfully.
* @retval false If modem parameters were not received successfully.
*/
int location_utils_modem_params_read(struct location_utils_modem_params_info *modem_params);

/**
* @brief Generate JWT buffer to be used for nRF Cloud REST API use.
*
Expand Down
4 changes: 2 additions & 2 deletions lib/location/method_cloud_location.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ static void method_cloud_location_positioning_work_fn(struct k_work *work)

#if defined(CONFIG_LOCATION_METHOD_WIFI)
if (wifi_config != NULL) {
err = scan_wifi_start(&wifi_scan_ready);
scan_wifi_start(&wifi_scan_ready);
}
#endif

#if defined(CONFIG_LOCATION_METHOD_CELLULAR)
if (cell_config != NULL) {
err = scan_cellular_start(cell_config->cell_count);
scan_cellular_start(cell_config->cell_count, false);
scan_cellular_info = scan_cellular_results_get();
}
#endif
Expand Down
29 changes: 20 additions & 9 deletions lib/location/method_gnss.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "location_core.h"
#include "location_utils.h"
#if defined(CONFIG_NRF_CLOUD_AGPS)
#include "scan_cellular.h"
#include <net/nrf_cloud_rest.h>
#include <net/nrf_cloud_agps.h>
#include <stdlib.h>
Expand Down Expand Up @@ -289,19 +290,20 @@ static void method_gnss_nrf_cloud_agps_request(void)
};

struct lte_lc_cells_info net_info = {0};
struct location_utils_modem_params_info modem_params = { 0 };
struct lte_lc_cells_info *scan_results;

/* Get network info for the A-GPS location request. */
err = location_utils_modem_params_read(&modem_params);

if (err < 0) {
scan_cellular_start(0, true);
scan_results = scan_cellular_results_get();
if (scan_results == NULL) {
LOG_WRN("Requesting A-GPS data without location assistance");
} else {
net_info.current_cell.id = modem_params.cell_id;
net_info.current_cell.tac = modem_params.tac;
net_info.current_cell.mcc = modem_params.mcc;
net_info.current_cell.mnc = modem_params.mnc;
net_info.current_cell.phys_cell_id = modem_params.phys_cell_id;
net_info.current_cell.mcc = scan_results->current_cell.mcc;
net_info.current_cell.mnc = scan_results->current_cell.mnc;
net_info.current_cell.id = scan_results->current_cell.id;
net_info.current_cell.tac = scan_results->current_cell.tac;
net_info.current_cell.phys_cell_id = scan_results->current_cell.phys_cell_id;
net_info.current_cell.rsrp = scan_results->current_cell.rsrp;
request.net_info = &net_info;
}

Expand Down Expand Up @@ -1201,5 +1203,14 @@ int method_gnss_init(void)
method_gnss_modem_sleep_notif_subscribe(MIN_SLEEP_DURATION_FOR_STARTING_GNSS);
#endif
lte_lc_register_handler(method_gnss_lte_ind_handler);

#if !defined(CONFIG_LOCATION_METHOD_CELLULAR)
/* Cellular location method is disabled, but GNSS method uses the cellular scan
* functionality for A-GNSS request. The module needs to be initialized explicitly, because
* init is not called by core.
*/
scan_cellular_init();
#endif

return 0;
}
28 changes: 4 additions & 24 deletions lib/location/scan_cellular.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ void scan_cellular_lte_ind_handler(const struct lte_lc_evt *const evt)
}
}

int scan_cellular_start(uint8_t cell_count)
void scan_cellular_start(uint8_t cell_count, bool light_search)
{
struct location_utils_modem_params_info modem_params = { 0 };
struct lte_lc_ncellmeas_params ncellmeas_params = {
.search_type = LTE_LC_NEIGHBOR_SEARCH_TYPE_EXTENDED_COMPLETE,
.search_type = light_search ? LTE_LC_NEIGHBOR_SEARCH_TYPE_EXTENDED_LIGHT :
LTE_LC_NEIGHBOR_SEARCH_TYPE_EXTENDED_COMPLETE,
.gci_count = 0
};
int err;
Expand All @@ -103,26 +103,7 @@ int scan_cellular_start(uint8_t cell_count)

err = lte_lc_neighbor_cell_measurement(&ncellmeas_params);
if (err) {
LOG_WRN("Failed to initiate neighbor cell measurements: %d, "
"next: fallback to get modem parameters",
err);

/* Doing fallback to get only the mandatory items manually:
* cell id, mcc, mnc and tac
*/
err = location_utils_modem_params_read(&modem_params);
if (err < 0) {
LOG_ERR("Could not obtain modem parameters");
} else {
memset(&scan_cellular_info, 0, sizeof(struct lte_lc_cells_info));

/* Filling only the mandatory parameters */
scan_cellular_info.current_cell.mcc = modem_params.mcc;
scan_cellular_info.current_cell.mnc = modem_params.mnc;
scan_cellular_info.current_cell.tac = modem_params.tac;
scan_cellular_info.current_cell.id = modem_params.cell_id;
scan_cellular_info.current_cell.phys_cell_id = modem_params.phys_cell_id;
}
LOG_ERR("Failed to initiate neighbor cell measurements: %d", err);
goto end;
}
err = k_sem_take(&scan_cellular_sem_ncellmeas_evt, K_FOREVER);
Expand Down Expand Up @@ -160,7 +141,6 @@ int scan_cellular_start(uint8_t cell_count)

end:
running = false;
return err;
}

int scan_cellular_cancel(void)
Expand Down
2 changes: 1 addition & 1 deletion lib/location/scan_cellular.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <modem/lte_lc.h>

int scan_cellular_init(void);
int scan_cellular_start(uint8_t cell_count);
void scan_cellular_start(uint8_t cell_count, bool light_search);
struct lte_lc_cells_info *scan_cellular_results_get(void);
int scan_cellular_cancel(void);

Expand Down
3 changes: 1 addition & 2 deletions lib/location/scan_wifi.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct wifi_scan_info *scan_wifi_results_get(void)
return &scan_wifi_info;
}

int scan_wifi_start(struct k_sem *wifi_scan_ready)
void scan_wifi_start(struct k_sem *wifi_scan_ready)
{
int ret;

Expand All @@ -64,7 +64,6 @@ int scan_wifi_start(struct k_sem *wifi_scan_ready)
k_sem_give(wifi_scan_ready);
wifi_scan_ready = NULL;
}
return ret;
}

static void scan_wifi_result_handle(struct net_mgmt_event_callback *cb)
Expand Down
2 changes: 1 addition & 1 deletion lib/location/scan_wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <net/wifi_location_common.h>

int scan_wifi_init(void);
int scan_wifi_start(struct k_sem *wifi_scan_ready);
void scan_wifi_start(struct k_sem *wifi_scan_ready);
struct wifi_scan_info *scan_wifi_results_get(void);
int scan_wifi_cancel(void);

Expand Down

0 comments on commit 6692196

Please sign in to comment.