Skip to content

Commit a6609d2

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 89894a8 commit a6609d2

File tree

9 files changed

+247
-22
lines changed

9 files changed

+247
-22
lines changed

app/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,11 @@ config SM_NRF_CLOUD
250250
default y
251251
select EXPERIMENTAL
252252

253+
config SM_NRF_CLOUD_LOCATION
254+
bool "nRF Cloud Location support"
255+
depends on SM_NRF_CLOUD
256+
select NRF_CLOUD_LOCATION if NRF_CLOUD_MQTT
257+
253258
config SM_MQTTC
254259
bool "MQTT client support"
255260
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
@@ -90,13 +90,13 @@ CONFIG_SETTINGS_NVS=y
9090
CONFIG_NVS=y
9191

9292
# nRF Cloud
93+
CONFIG_SM_NRF_CLOUD_LOCATION=y
9394
CONFIG_NRF_CLOUD=y
9495
CONFIG_NRF_CLOUD_MQTT=y
9596
CONFIG_NRF_CLOUD_FOTA=n
9697
CONFIG_NRF_CLOUD_AGNSS=y
9798
CONFIG_NRF_CLOUD_AGNSS_FILTERED=n
9899
CONFIG_NRF_CLOUD_PGPS=n
99-
CONFIG_NRF_CLOUD_LOCATION=y
100100
CONFIG_NRF_CLOUD_LOG_LEVEL_INF=y
101101
CONFIG_NRF_CLOUD_GPS_LOG_LEVEL_INF=y
102102
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)
@@ -60,6 +61,10 @@ 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+
#if defined(CONFIG_NRF_CLOUD_COAP)
65+
static struct k_work pgps_coap_req_work;
66+
static struct gps_pgps_request pgps_coap_request;
67+
#endif
6368
#endif
6469

6570
#endif /* CONFIG_SM_NRF_CLOUD */
@@ -321,7 +326,7 @@ static void agnss_requestor(struct k_work *)
321326
LOG_ERR("Failed to read A-GNSS request (%d).", err);
322327
return;
323328
}
324-
329+
#if defined(CONFIG_NRF_CLOUD_MQTT)
325330
err = nrf_cloud_agnss_request(&req);
326331
if (err) {
327332
LOG_ERR("Failed to request A-GNSS data (%d).", err);
@@ -333,6 +338,38 @@ static void agnss_requestor(struct k_work *)
333338
* plays a role as A-GNSS expects P-GPS to process some of the data.
334339
*/
335340
}
341+
#endif
342+
#if defined(CONFIG_NRF_CLOUD_COAP)
343+
static char agnss_rest_data_buf[NRF_CLOUD_AGNSS_MAX_DATA_SIZE];
344+
struct nrf_cloud_rest_agnss_request request = {
345+
NRF_CLOUD_REST_AGNSS_REQ_CUSTOM,
346+
&req,
347+
};
348+
349+
struct nrf_cloud_rest_agnss_result result = {agnss_rest_data_buf,
350+
sizeof(agnss_rest_data_buf), 0};
351+
struct lte_lc_cells_info net_info = {0};
352+
353+
err = get_single_cell_info(&net_info.current_cell);
354+
if (err) {
355+
LOG_ERR("Failed to obtain single-cell cellular network information (%d).", err);
356+
return;
357+
}
358+
request.net_info = &net_info;
359+
360+
err = nrf_cloud_coap_agnss_data_get(&request, &result);
361+
if (err) {
362+
LOG_ERR("Failed to request A-GNSS data via REST (%d).", err);
363+
return;
364+
}
365+
366+
err = nrf_cloud_agnss_process(result.buf, result.agnss_sz);
367+
if (err) {
368+
LOG_ERR("Failed to process A-GNSS data, error: %d", err);
369+
return;
370+
}
371+
LOG_INF("A-GNSS data received via CoAP.");
372+
#endif
336373
}
337374
#endif /* CONFIG_NRF_CLOUD_AGNSS */
338375

@@ -350,6 +387,49 @@ static void pgps_requestor(struct k_work *)
350387
}
351388
}
352389

390+
#if defined(CONFIG_NRF_CLOUD_COAP)
391+
static void pgps_coap_requestor(struct k_work *)
392+
{
393+
int err;
394+
struct nrf_cloud_rest_pgps_request request = {.pgps_req = &pgps_coap_request};
395+
struct nrf_cloud_pgps_result file_location = {0};
396+
static char host[64];
397+
static char path[128];
398+
399+
LOG_INF("Getting P-GPS predictions from nRF Cloud...");
400+
401+
memset(host, 0, sizeof(host));
402+
memset(path, 0, sizeof(path));
403+
404+
file_location.host = host;
405+
file_location.host_sz = sizeof(host);
406+
file_location.path = path;
407+
file_location.path_sz = sizeof(path);
408+
409+
err = nrf_cloud_coap_pgps_url_get(&request, &file_location);
410+
if (err) {
411+
LOG_ERR("Failed to get P-GPS data, error: %d", err);
412+
nrf_cloud_pgps_request_reset();
413+
return;
414+
}
415+
416+
err = nrf_cloud_pgps_update(&file_location);
417+
if (err) {
418+
LOG_ERR("Failed to process P-GPS response, error: %d", err);
419+
nrf_cloud_pgps_request_reset();
420+
return;
421+
}
422+
423+
err = nrf_cloud_pgps_notify_prediction();
424+
if (err) {
425+
LOG_ERR("Failed to request current prediction, error: %d", err);
426+
return;
427+
}
428+
429+
LOG_INF("P-GPS predictions requested");
430+
}
431+
#endif
432+
353433
static void pgps_event_handler(struct nrf_cloud_pgps_event *event)
354434
{
355435
int err;
@@ -401,6 +481,10 @@ static void pgps_event_handler(struct nrf_cloud_pgps_event *event)
401481
break;
402482
case PGPS_EVT_REQUEST:
403483
LOG_INF("PGPS_EVT_REQUEST");
484+
#if defined(CONFIG_NRF_CLOUD_COAP)
485+
memcpy(&pgps_coap_request, event->request, sizeof(pgps_coap_request));
486+
k_work_submit_to_queue(&sm_work_q, &pgps_coap_req_work);
487+
#endif
404488
break;
405489
}
406490
}
@@ -455,6 +539,8 @@ static void on_gnss_evt_pvt(void)
455539
static int do_cloud_send_obj(struct nrf_cloud_obj *const obj)
456540
{
457541
int err;
542+
543+
#if defined(CONFIG_NRF_CLOUD_MQTT)
458544
struct nrf_cloud_tx_data msg = {
459545
.obj = obj,
460546
.topic_type = NRF_CLOUD_TOPIC_MESSAGE,
@@ -465,7 +551,13 @@ static int do_cloud_send_obj(struct nrf_cloud_obj *const obj)
465551
if (err) {
466552
LOG_ERR("nrf_cloud_send failed, error: %d", err);
467553
}
468-
554+
#endif
555+
#if defined(CONFIG_NRF_CLOUD_COAP)
556+
err = nrf_cloud_coap_obj_send(obj, false);
557+
if (err) {
558+
LOG_ERR("nrf_cloud_send failed, error: %d", err);
559+
}
560+
#endif
469561
(void)nrf_cloud_obj_free(obj);
470562

471563
return err;
@@ -481,7 +573,6 @@ static void send_location(struct nrf_modem_gnss_pvt_data_frame * const pvt_data)
481573
.mdm_pvt = pvt_data
482574
};
483575
NRF_CLOUD_OBJ_JSON_DEFINE(msg_obj);
484-
485576
/* On failure, NRF_CLOUD_NO_TIMESTAMP is used and the timestamp is omitted */
486577
(void)date_time_now(&gnss.ts_ms);
487578

@@ -812,7 +903,10 @@ static int sm_at_gnss_init(void)
812903
#endif
813904
#if defined(CONFIG_NRF_CLOUD_PGPS)
814905
k_work_init(&pgps_req_work, pgps_requestor);
906+
#if defined(CONFIG_NRF_CLOUD_COAP)
907+
k_work_init(&pgps_coap_req_work, pgps_coap_requestor);
815908
#endif
909+
#endif /* CONFIG_NRF_CLOUD_PGPS */
816910
#endif /* CONFIG_SM_NRF_CLOUD */
817911
k_work_init(&gnss_fix_send_work, gnss_fix_sender);
818912

0 commit comments

Comments
 (0)