Skip to content

Commit e15af1f

Browse files
committed
app: nrfcloud: Add GCI support to cellpos
Implement cell positioning similarly to Location library meaning AT%NCELLMEAS will be done 1-3 times depending on how many cells are requested and found in each attempt. Implementation done by copying GCI parsing from lte_lc. Signed-off-by: Tommi Rantanen <tommi.rantanen@nordicsemi.no>
1 parent 7cc258a commit e15af1f

8 files changed

Lines changed: 1180 additions & 369 deletions

File tree

app/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ config SM_GNSS
248248
config SM_NRF_CLOUD
249249
bool "nRF Cloud support"
250250
default y
251+
depends on NRF_CLOUD
252+
depends on NRF_CLOUD_COAP
253+
depends on DATE_TIME
251254
select EXPERIMENTAL
252255

253256
if SM_NRF_CLOUD
@@ -261,6 +264,7 @@ endif # SM_NRF_CLOUD
261264

262265
config SM_NRF_CLOUD_LOCATION
263266
bool "nRF Cloud Location support"
267+
default y
264268
depends on SM_NRF_CLOUD
265269
help
266270
Enable the nRF Cloud Location service for cloud-assisted geolocation.

app/prj.conf

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ CONFIG_SETTINGS_NVS=y
9595
CONFIG_NVS=y
9696

9797
# nRF Cloud
98-
CONFIG_SM_NRF_CLOUD_LOCATION=y
9998
CONFIG_NRF_CLOUD=y
10099
CONFIG_NRF_CLOUD_COAP=y
101100
CONFIG_NRF_CLOUD_COAP_DOWNLOADS=n

app/src/sm_at_gnss.c

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,13 @@ enum sm_gnss_operation {
5959

6060
#if defined(CONFIG_NRF_CLOUD_AGNSS)
6161
static struct k_work agnss_req_work;
62-
#endif
62+
63+
#if defined(CONFIG_SM_NRF_CLOUD_LOCATION)
64+
static K_SEM_DEFINE(agnss_ncellmeas_sem, 0, 1);
65+
static struct lte_lc_cells_info *agnss_net_info;
66+
#endif /* CONFIG_SM_NRF_CLOUD_LOCATION */
67+
#endif /* CONFIG_SM_NRF_CLOUD */
68+
6369
#if defined(CONFIG_NRF_CLOUD_PGPS)
6470
static struct k_work pgps_req_work;
6571
static struct k_work pgps_coap_req_work;
@@ -317,13 +323,26 @@ static int read_agnss_req(struct nrf_modem_gnss_agnss_data_frame *req)
317323
#endif /* CONFIG_NRF_CLOUD_AGNSS || CONFIG_NRF_CLOUD_PGPS */
318324

319325
#if defined(CONFIG_NRF_CLOUD_AGNSS)
326+
327+
#if defined(CONFIG_SM_NRF_CLOUD_LOCATION)
328+
static void agnss_ncellmeas_done(struct lte_lc_cells_info *cell_data, void *ctx)
329+
{
330+
ARG_UNUSED(ctx);
331+
agnss_net_info = cell_data;
332+
k_sem_give(&agnss_ncellmeas_sem);
333+
}
334+
#endif /* CONFIG_SM_NRF_CLOUD_LOCATION */
335+
320336
static void agnss_requestor(struct k_work *)
321337
{
322338
int err;
323339
struct nrf_modem_gnss_agnss_data_frame req;
324340
struct nrf_cloud_coap_agnss_request request = {
325-
NRF_CLOUD_COAP_AGNSS_REQ_CUSTOM,
326-
&req,
341+
.type = NRF_CLOUD_COAP_AGNSS_REQ_CUSTOM,
342+
.agnss_req = &req,
343+
.net_info = NULL,
344+
.filtered = false,
345+
.mask_angle = 0,
327346
};
328347
char *agnss_rest_data_buf = calloc(1, NRF_CLOUD_AGNSS_MAX_DATA_SIZE);
329348

@@ -339,20 +358,43 @@ static void agnss_requestor(struct k_work *)
339358
}
340359

341360
struct nrf_cloud_coap_agnss_result result = {
342-
agnss_rest_data_buf,
343-
NRF_CLOUD_AGNSS_MAX_DATA_SIZE,
344-
0
361+
.buf = agnss_rest_data_buf,
362+
.buf_sz = NRF_CLOUD_AGNSS_MAX_DATA_SIZE,
363+
.agnss_sz = 0,
345364
};
346-
struct lte_lc_cells_info net_info = {0};
347365

348-
err = get_single_cell_info(&net_info.current_cell);
349-
if (err) {
350-
LOG_ERR("Failed to obtain single-cell cellular network information (%d).", err);
351-
goto cleanup;
366+
#if defined(CONFIG_SM_NRF_CLOUD_LOCATION)
367+
/* Start async ncellmeas and wait for the result via semaphore.
368+
* agnss_ncellmeas_done() is called from the AT monitor thread
369+
* (not sm_work_q) for the single-phase case, so giving the semaphore
370+
* does not deadlock this work item.
371+
*/
372+
struct lte_lc_cells_info *net_info = NULL;
373+
374+
err = sm_at_nrfcloud_ncellmeas_start(1, false, agnss_ncellmeas_done, NULL);
375+
if (err == 0) {
376+
/* We will wait for 5 seconds for NCELLMEAS to complete. */
377+
k_sem_take(&agnss_ncellmeas_sem, K_SECONDS(5));
378+
net_info = agnss_net_info;
379+
agnss_net_info = NULL;
352380
}
353-
request.net_info = &net_info;
354381

382+
if (net_info != NULL && net_info->current_cell.id != LTE_LC_CELL_EUTRAN_ID_INVALID) {
383+
request.net_info = net_info;
384+
} else {
385+
LOG_WRN("Requesting A-GNSS data without location assistance");
386+
sm_at_nrfcloud_ncellmeas_cleanup(net_info);
387+
net_info = NULL;
388+
}
389+
#else
390+
LOG_INF("Requesting A-GNSS data without location assistance "
391+
"since CONFIG_SM_NRF_CLOUD_LOCATION is not defined");
392+
#endif
355393
err = nrf_cloud_coap_agnss_data_get(&request, &result);
394+
#if defined(CONFIG_SM_NRF_CLOUD_LOCATION)
395+
sm_at_nrfcloud_ncellmeas_cleanup(net_info);
396+
net_info = NULL;
397+
#endif
356398
if (err) {
357399
LOG_ERR("Failed to request A-GNSS data via CoAP (%d).", err);
358400
goto cleanup;

0 commit comments

Comments
 (0)