@@ -59,7 +59,13 @@ enum sm_gnss_operation {
5959
6060#if defined(CONFIG_NRF_CLOUD_AGNSS )
6161static 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 )
6470static struct k_work pgps_req_work ;
6571static 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+
320336static 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