Skip to content

Commit 1033b19

Browse files
committed
app: Switch nRF Cloud AT commands from MQTT to CoAP
Replace nRF Cloud MQTT transport with the more lightweight CoAP protocol. Introduced new Kconfig option CONFIG_SM_NRF_CLOUD_LOCATION to enable location support, since CONFIG_NRF_CLOUD_LOCATION depends on NRF_CLOUD_MQTT and cannot be enabled when using NRF_CLOUD_COAP. Jira: SM-235 Signed-off-by: Juha Ylinen <juha.ylinen@nordicsemi.no>
1 parent e78e79a commit 1033b19

9 files changed

Lines changed: 247 additions & 306 deletions

File tree

app/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,13 @@ config HEAP_MEM_POOL_ADD_SIZE_SM_NRF_CLOUD
259259
dynamic memory allocation.
260260
endif # SM_NRF_CLOUD
261261

262+
config SM_NRF_CLOUD_LOCATION
263+
bool "nRF Cloud Location support"
264+
depends on SM_NRF_CLOUD
265+
help
266+
Enable the nRF Cloud Location service for cloud-assisted geolocation.
267+
Supports cellular and Wi-Fi positioning.
268+
262269
config SM_MQTTC
263270
bool "MQTT client support"
264271
default y

app/prj.conf

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,14 @@ CONFIG_SETTINGS_NVS=y
9494
CONFIG_NVS=y
9595

9696
# nRF Cloud
97+
CONFIG_SM_NRF_CLOUD_LOCATION=y
9798
CONFIG_NRF_CLOUD=y
98-
CONFIG_NRF_CLOUD_MQTT=y
99+
CONFIG_NRF_CLOUD_COAP=y
100+
CONFIG_NRF_CLOUD_COAP_DOWNLOADS=n
99101
CONFIG_NRF_CLOUD_FOTA=n
100102
CONFIG_NRF_CLOUD_AGNSS=y
101103
CONFIG_NRF_CLOUD_AGNSS_FILTERED=n
102104
CONFIG_NRF_CLOUD_PGPS=n
103-
CONFIG_NRF_CLOUD_LOCATION=y
104105
CONFIG_NRF_CLOUD_LOG_LEVEL_INF=y
105106
CONFIG_NRF_CLOUD_GPS_LOG_LEVEL_INF=y
106107
CONFIG_NRF_CLOUD_CLIENT_ID_SRC_INTERNAL_UUID=y
@@ -109,6 +110,12 @@ CONFIG_DATE_TIME=y
109110
CONFIG_MODEM_INFO=y
110111
CONFIG_MODEM_INFO_ADD_DATE_TIME=n
111112

113+
# CoAP client settings
114+
CONFIG_COAP_CLIENT_BLOCK_SIZE=1024
115+
CONFIG_COAP_CLIENT_THREAD_PRIORITY=0
116+
CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=96
117+
CONFIG_COAP_CLIENT_STACK_SIZE=2048
118+
112119
# UUID and JWT
113120
CONFIG_MODEM_JWT=y
114121

app/src/sm_at_gnss.c

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#if defined(CONFIG_SM_NRF_CLOUD)
1717
#include <net/nrf_cloud.h>
1818
#include <net/nrf_cloud_codec.h>
19+
#include <net/nrf_cloud_coap.h>
1920
#include "sm_at_nrfcloud.h"
2021

2122
#if defined(CONFIG_NRF_CLOUD_AGNSS)
@@ -60,6 +61,8 @@ static struct k_work agnss_req_work;
6061
#endif
6162
#if defined(CONFIG_NRF_CLOUD_PGPS)
6263
static struct k_work pgps_req_work;
64+
static struct k_work pgps_coap_req_work;
65+
static struct gps_pgps_request pgps_coap_request;
6366
#endif
6467

6568
#endif /* CONFIG_SM_NRF_CLOUD */
@@ -317,24 +320,41 @@ static void agnss_requestor(struct k_work *)
317320
{
318321
int err;
319322
struct nrf_modem_gnss_agnss_data_frame req;
323+
static char agnss_rest_data_buf[NRF_CLOUD_AGNSS_MAX_DATA_SIZE];
324+
struct nrf_cloud_rest_agnss_request request = {
325+
NRF_CLOUD_REST_AGNSS_REQ_CUSTOM,
326+
&req,
327+
};
320328

321329
err = read_agnss_req(&req);
322330
if (err) {
323331
LOG_ERR("Failed to read A-GNSS request (%d).", err);
324332
return;
325333
}
326334

327-
err = nrf_cloud_agnss_request(&req);
335+
struct nrf_cloud_rest_agnss_result result = {agnss_rest_data_buf,
336+
sizeof(agnss_rest_data_buf), 0};
337+
struct lte_lc_cells_info net_info = {0};
338+
339+
err = get_single_cell_info(&net_info.current_cell);
328340
if (err) {
329-
LOG_ERR("Failed to request A-GNSS data (%d).", err);
330-
} else {
331-
LOG_INF("A-GNSS data requested.");
332-
/* When A-GNSS data is received it gets injected in the background by
333-
* nrf_cloud_agnss_process() without notification. In the case where
334-
* CONFIG_NRF_CLOUD_PGPS=y, nrf_cloud_pgps_inject() (called on PGPS_EVT_AVAILABLE)
335-
* plays a role as A-GNSS expects P-GPS to process some of the data.
336-
*/
341+
LOG_ERR("Failed to obtain single-cell cellular network information (%d).", err);
342+
return;
337343
}
344+
request.net_info = &net_info;
345+
346+
err = nrf_cloud_coap_agnss_data_get(&request, &result);
347+
if (err) {
348+
LOG_ERR("Failed to request A-GNSS data via REST (%d).", err);
349+
return;
350+
}
351+
352+
err = nrf_cloud_agnss_process(result.buf, result.agnss_sz);
353+
if (err) {
354+
LOG_ERR("Failed to process A-GNSS data, error: %d", err);
355+
return;
356+
}
357+
LOG_INF("A-GNSS data received via CoAP.");
338358
}
339359
#endif /* CONFIG_NRF_CLOUD_AGNSS */
340360

@@ -352,6 +372,47 @@ static void pgps_requestor(struct k_work *)
352372
}
353373
}
354374

375+
static void pgps_coap_requestor(struct k_work *)
376+
{
377+
int err;
378+
struct nrf_cloud_rest_pgps_request request = {.pgps_req = &pgps_coap_request};
379+
struct nrf_cloud_pgps_result file_location = {0};
380+
static char host[64];
381+
static char path[128];
382+
383+
LOG_INF("Getting P-GPS predictions from nRF Cloud...");
384+
385+
memset(host, 0, sizeof(host));
386+
memset(path, 0, sizeof(path));
387+
388+
file_location.host = host;
389+
file_location.host_sz = sizeof(host);
390+
file_location.path = path;
391+
file_location.path_sz = sizeof(path);
392+
393+
err = nrf_cloud_coap_pgps_url_get(&request, &file_location);
394+
if (err) {
395+
LOG_ERR("Failed to get P-GPS data, error: %d", err);
396+
nrf_cloud_pgps_request_reset();
397+
return;
398+
}
399+
400+
err = nrf_cloud_pgps_update(&file_location);
401+
if (err) {
402+
LOG_ERR("Failed to process P-GPS response, error: %d", err);
403+
nrf_cloud_pgps_request_reset();
404+
return;
405+
}
406+
407+
err = nrf_cloud_pgps_notify_prediction();
408+
if (err) {
409+
LOG_ERR("Failed to request current prediction, error: %d", err);
410+
return;
411+
}
412+
413+
LOG_INF("P-GPS predictions requested");
414+
}
415+
355416
static void pgps_event_handler(struct nrf_cloud_pgps_event *event)
356417
{
357418
int err;
@@ -403,6 +464,8 @@ static void pgps_event_handler(struct nrf_cloud_pgps_event *event)
403464
break;
404465
case PGPS_EVT_REQUEST:
405466
LOG_INF("PGPS_EVT_REQUEST");
467+
memcpy(&pgps_coap_request, event->request, sizeof(pgps_coap_request));
468+
k_work_submit_to_queue(&sm_work_q, &pgps_coap_req_work);
406469
break;
407470
}
408471
}
@@ -457,13 +520,8 @@ static void on_gnss_evt_pvt(void)
457520
static int do_cloud_send_obj(struct nrf_cloud_obj *const obj)
458521
{
459522
int err;
460-
struct nrf_cloud_tx_data msg = {
461-
.obj = obj,
462-
.topic_type = NRF_CLOUD_TOPIC_MESSAGE,
463-
.qos = MQTT_QOS_0_AT_MOST_ONCE
464-
};
465523

466-
err = nrf_cloud_send(&msg);
524+
err = nrf_cloud_coap_obj_send(obj, true);
467525
if (err) {
468526
LOG_ERR("nrf_cloud_send failed, error: %d", err);
469527
}
@@ -475,15 +533,31 @@ static int do_cloud_send_obj(struct nrf_cloud_obj *const obj)
475533

476534
static void send_location(struct nrf_modem_gnss_pvt_data_frame * const pvt_data)
477535
{
536+
#define CLOUD_GNSS_HEADING_ACC_LIMIT (float)60.0
537+
478538
static int64_t last_ts_ms = NRF_CLOUD_NO_TIMESTAMP;
479539
int err;
540+
541+
/* Map modem PVT data to nRF Cloud PVT structure */
542+
struct nrf_cloud_gnss_pvt pvt = {
543+
.lat = pvt_data->latitude,
544+
.lon = pvt_data->longitude,
545+
.accuracy = pvt_data->accuracy,
546+
.alt = pvt_data->altitude,
547+
.has_alt = 1,
548+
.speed = pvt_data->speed,
549+
.has_speed = pvt_data->flags & NRF_MODEM_GNSS_PVT_FLAG_VELOCITY_VALID,
550+
.heading = pvt_data->heading,
551+
.has_heading = pvt_data->heading_accuracy < CLOUD_GNSS_HEADING_ACC_LIMIT ? 1 : 0,
552+
};
553+
480554
struct nrf_cloud_gnss_data gnss = {
481555
.ts_ms = NRF_CLOUD_NO_TIMESTAMP,
482-
.type = NRF_CLOUD_GNSS_TYPE_MODEM_PVT,
483-
.mdm_pvt = pvt_data
556+
.type = NRF_CLOUD_GNSS_TYPE_PVT,
557+
.pvt = pvt,
484558
};
485-
NRF_CLOUD_OBJ_JSON_DEFINE(msg_obj);
486559

560+
NRF_CLOUD_OBJ_COAP_CBOR_DEFINE(msg_obj);
487561
/* On failure, NRF_CLOUD_NO_TIMESTAMP is used and the timestamp is omitted */
488562
(void)date_time_now(&gnss.ts_ms);
489563

@@ -816,7 +890,8 @@ static int sm_at_gnss_init(void)
816890
#endif
817891
#if defined(CONFIG_NRF_CLOUD_PGPS)
818892
k_work_init(&pgps_req_work, pgps_requestor);
819-
#endif
893+
k_work_init(&pgps_coap_req_work, pgps_coap_requestor);
894+
#endif /* CONFIG_NRF_CLOUD_PGPS */
820895
#endif /* CONFIG_SM_NRF_CLOUD */
821896
k_work_init(&gnss_fix_send_work, gnss_fix_sender);
822897

0 commit comments

Comments
 (0)