Skip to content

Commit 661f320

Browse files
committed
app: Add CoAP support to nRF Cloud AT commands
Add overlay to enable CoAP connectivity for nRF Cloud AT commands. Use 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 2db2c75 commit 661f320

File tree

9 files changed

+248
-22
lines changed

9 files changed

+248
-22
lines changed

app/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,11 @@ config SM_NRF_CLOUD
258258
bool "nRF Cloud support"
259259
default y
260260

261+
config SM_NRF_CLOUD_LOCATION
262+
bool "nRF Cloud Location support"
263+
depends on SM_NRF_CLOUD
264+
select NRF_CLOUD_LOCATION if NRF_CLOUD_MQTT
265+
261266
config SM_MQTTC
262267
bool "MQTT client support"
263268
default y

app/overlay-nrf_cloud-coap.conf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#
2+
# Copyright (c) 2026 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# NRF Cloud CoAP settings
8+
CONFIG_NRF_CLOUD_MQTT=n
9+
CONFIG_NRF_CLOUD_LOCATION=n
10+
CONFIG_NRF_CLOUD_COAP=y
11+
CONFIG_NRF_CLOUD_COAP_DOWNLOADS=n
12+
13+
# CoAP client settings
14+
CONFIG_COAP_CLIENT_BLOCK_SIZE=1024
15+
CONFIG_COAP_CLIENT_THREAD_PRIORITY=0
16+
CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=96
17+
CONFIG_COAP_CLIENT_STACK_SIZE=2048

app/prj.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,13 @@ CONFIG_SETTINGS_NVS=y
9191
CONFIG_NVS=y
9292

9393
# nRF Cloud
94+
CONFIG_SM_NRF_CLOUD_LOCATION=y
9495
CONFIG_NRF_CLOUD=y
9596
CONFIG_NRF_CLOUD_MQTT=y
9697
CONFIG_NRF_CLOUD_FOTA=n
9798
CONFIG_NRF_CLOUD_AGNSS=y
9899
CONFIG_NRF_CLOUD_AGNSS_FILTERED=n
99100
CONFIG_NRF_CLOUD_PGPS=n
100-
CONFIG_NRF_CLOUD_LOCATION=y
101101
CONFIG_NRF_CLOUD_LOG_LEVEL_INF=y
102102
CONFIG_NRF_CLOUD_GPS_LOG_LEVEL_INF=y
103103
CONFIG_NRF_CLOUD_CLIENT_ID_SRC_INTERNAL_UUID=y

app/src/sm_at_gnss.c

Lines changed: 97 additions & 3 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)
@@ -72,6 +73,10 @@ static struct k_work agnss_req_work;
7273
#endif
7374
#if defined(CONFIG_NRF_CLOUD_PGPS)
7475
static struct k_work pgps_req_work;
76+
#if defined(CONFIG_NRF_CLOUD_COAP)
77+
static struct k_work pgps_coap_req_work;
78+
static struct gps_pgps_request pgps_coap_request;
79+
#endif
7580
#endif
7681

7782
#endif /* CONFIG_SM_NRF_CLOUD */
@@ -341,7 +346,7 @@ static void agnss_requestor(struct k_work *)
341346
LOG_ERR("Failed to read A-GNSS request (%d).", err);
342347
return;
343348
}
344-
349+
#if defined(CONFIG_NRF_CLOUD_MQTT)
345350
err = nrf_cloud_agnss_request(&req);
346351
if (err) {
347352
LOG_ERR("Failed to request A-GNSS data (%d).", err);
@@ -353,6 +358,38 @@ static void agnss_requestor(struct k_work *)
353358
* plays a role as A-GNSS expects P-GPS to process some of the data.
354359
*/
355360
}
361+
#endif
362+
#if defined(CONFIG_NRF_CLOUD_COAP)
363+
static char agnss_rest_data_buf[NRF_CLOUD_AGNSS_MAX_DATA_SIZE];
364+
struct nrf_cloud_rest_agnss_request request = {
365+
NRF_CLOUD_REST_AGNSS_REQ_CUSTOM,
366+
&req,
367+
};
368+
369+
struct nrf_cloud_rest_agnss_result result = {agnss_rest_data_buf,
370+
sizeof(agnss_rest_data_buf), 0};
371+
struct lte_lc_cells_info net_info = {0};
372+
373+
err = get_single_cell_info(&net_info.current_cell);
374+
if (err) {
375+
LOG_ERR("Failed to obtain single-cell cellular network information (%d).", err);
376+
return;
377+
}
378+
request.net_info = &net_info;
379+
380+
err = nrf_cloud_coap_agnss_data_get(&request, &result);
381+
if (err) {
382+
LOG_ERR("Failed to request A-GNSS data via REST (%d).", err);
383+
return;
384+
}
385+
386+
err = nrf_cloud_agnss_process(result.buf, result.agnss_sz);
387+
if (err) {
388+
LOG_ERR("Failed to process A-GNSS data, error: %d", err);
389+
return;
390+
}
391+
LOG_INF("A-GNSS data received via CoAP.");
392+
#endif
356393
}
357394
#endif /* CONFIG_NRF_CLOUD_AGNSS */
358395

@@ -370,6 +407,49 @@ static void pgps_requestor(struct k_work *)
370407
}
371408
}
372409

410+
#if defined(CONFIG_NRF_CLOUD_COAP)
411+
static void pgps_coap_requestor(struct k_work *)
412+
{
413+
int err;
414+
struct nrf_cloud_rest_pgps_request request = {.pgps_req = &pgps_coap_request};
415+
struct nrf_cloud_pgps_result file_location = {0};
416+
static char host[64];
417+
static char path[128];
418+
419+
LOG_INF("Getting P-GPS predictions from nRF Cloud...");
420+
421+
memset(host, 0, sizeof(host));
422+
memset(path, 0, sizeof(path));
423+
424+
file_location.host = host;
425+
file_location.host_sz = sizeof(host);
426+
file_location.path = path;
427+
file_location.path_sz = sizeof(path);
428+
429+
err = nrf_cloud_coap_pgps_url_get(&request, &file_location);
430+
if (err) {
431+
LOG_ERR("Failed to get P-GPS data, error: %d", err);
432+
nrf_cloud_pgps_request_reset();
433+
return;
434+
}
435+
436+
err = nrf_cloud_pgps_update(&file_location);
437+
if (err) {
438+
LOG_ERR("Failed to process P-GPS response, error: %d", err);
439+
nrf_cloud_pgps_request_reset();
440+
return;
441+
}
442+
443+
err = nrf_cloud_pgps_notify_prediction();
444+
if (err) {
445+
LOG_ERR("Failed to request current prediction, error: %d", err);
446+
return;
447+
}
448+
449+
LOG_INF("P-GPS predictions requested");
450+
}
451+
#endif
452+
373453
static void pgps_event_handler(struct nrf_cloud_pgps_event *event)
374454
{
375455
int err;
@@ -421,6 +501,10 @@ static void pgps_event_handler(struct nrf_cloud_pgps_event *event)
421501
break;
422502
case PGPS_EVT_REQUEST:
423503
LOG_INF("PGPS_EVT_REQUEST");
504+
#if defined(CONFIG_NRF_CLOUD_COAP)
505+
memcpy(&pgps_coap_request, event->request, sizeof(pgps_coap_request));
506+
k_work_submit_to_queue(&sm_work_q, &pgps_coap_req_work);
507+
#endif
424508
break;
425509
}
426510
}
@@ -508,6 +592,8 @@ static void on_gnss_evt_pvt(void)
508592
static int do_cloud_send_obj(struct nrf_cloud_obj *const obj)
509593
{
510594
int err;
595+
596+
#if defined(CONFIG_NRF_CLOUD_MQTT)
511597
struct nrf_cloud_tx_data msg = {
512598
.obj = obj,
513599
.topic_type = NRF_CLOUD_TOPIC_MESSAGE,
@@ -518,7 +604,13 @@ static int do_cloud_send_obj(struct nrf_cloud_obj *const obj)
518604
if (err) {
519605
LOG_ERR("nrf_cloud_send failed, error: %d", err);
520606
}
521-
607+
#endif
608+
#if defined(CONFIG_NRF_CLOUD_COAP)
609+
err = nrf_cloud_coap_obj_send(obj, false);
610+
if (err) {
611+
LOG_ERR("nrf_cloud_send failed, error: %d", err);
612+
}
613+
#endif
522614
(void)nrf_cloud_obj_free(obj);
523615

524616
return err;
@@ -534,7 +626,6 @@ static void send_location(struct nrf_modem_gnss_pvt_data_frame * const pvt_data)
534626
.mdm_pvt = pvt_data
535627
};
536628
NRF_CLOUD_OBJ_JSON_DEFINE(msg_obj);
537-
538629
/* On failure, NRF_CLOUD_NO_TIMESTAMP is used and the timestamp is omitted */
539630
(void)date_time_now(&gnss.ts_ms);
540631

@@ -867,7 +958,10 @@ static int sm_at_gnss_init(void)
867958
#endif
868959
#if defined(CONFIG_NRF_CLOUD_PGPS)
869960
k_work_init(&pgps_req_work, pgps_requestor);
961+
#if defined(CONFIG_NRF_CLOUD_COAP)
962+
k_work_init(&pgps_coap_req_work, pgps_coap_requestor);
870963
#endif
964+
#endif /* CONFIG_NRF_CLOUD_PGPS */
871965
#endif /* CONFIG_SM_NRF_CLOUD */
872966
k_work_init(&gnss_fix_send_work, gnss_fix_sender);
873967

0 commit comments

Comments
 (0)