Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,13 @@ config HEAP_MEM_POOL_ADD_SIZE_SM_NRF_CLOUD
dynamic memory allocation.
endif # SM_NRF_CLOUD

config SM_NRF_CLOUD_LOCATION
Comment thread
trantanen marked this conversation as resolved.
bool "nRF Cloud Location support"
depends on SM_NRF_CLOUD
help
Enable the nRF Cloud Location service for cloud-assisted geolocation.
Supports cellular and Wi-Fi positioning.

config SM_MQTTC
bool "MQTT client support"
default y
Expand Down
11 changes: 9 additions & 2 deletions app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,14 @@ CONFIG_SETTINGS_NVS=y
CONFIG_NVS=y

# nRF Cloud
CONFIG_SM_NRF_CLOUD_LOCATION=y
CONFIG_NRF_CLOUD=y
CONFIG_NRF_CLOUD_MQTT=y
CONFIG_NRF_CLOUD_COAP=y
CONFIG_NRF_CLOUD_COAP_DOWNLOADS=n
CONFIG_NRF_CLOUD_FOTA=n
CONFIG_NRF_CLOUD_AGNSS=y
CONFIG_NRF_CLOUD_AGNSS_FILTERED=n
CONFIG_NRF_CLOUD_PGPS=n
CONFIG_NRF_CLOUD_LOCATION=y
CONFIG_NRF_CLOUD_LOG_LEVEL_INF=y
CONFIG_NRF_CLOUD_GPS_LOG_LEVEL_INF=y
CONFIG_NRF_CLOUD_CLIENT_ID_SRC_INTERNAL_UUID=y
Expand All @@ -109,6 +110,12 @@ CONFIG_DATE_TIME=y
CONFIG_MODEM_INFO=y
CONFIG_MODEM_INFO_ADD_DATE_TIME=n

# CoAP client settings
CONFIG_COAP_CLIENT_BLOCK_SIZE=1024
CONFIG_COAP_CLIENT_THREAD_PRIORITY=0
CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=96
CONFIG_COAP_CLIENT_STACK_SIZE=2048

# UUID and JWT
CONFIG_MODEM_JWT=y

Expand Down
113 changes: 94 additions & 19 deletions app/src/sm_at_gnss.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#if defined(CONFIG_SM_NRF_CLOUD)
#include <net/nrf_cloud.h>
#include <net/nrf_cloud_codec.h>
#include <net/nrf_cloud_coap.h>
#include "sm_at_nrfcloud.h"

#if defined(CONFIG_NRF_CLOUD_AGNSS)
Expand Down Expand Up @@ -60,6 +61,8 @@ static struct k_work agnss_req_work;
#endif
#if defined(CONFIG_NRF_CLOUD_PGPS)
static struct k_work pgps_req_work;
static struct k_work pgps_coap_req_work;
static struct gps_pgps_request pgps_coap_request;
#endif

#endif /* CONFIG_SM_NRF_CLOUD */
Expand Down Expand Up @@ -317,24 +320,41 @@ static void agnss_requestor(struct k_work *)
{
int err;
struct nrf_modem_gnss_agnss_data_frame req;
static char agnss_rest_data_buf[NRF_CLOUD_AGNSS_MAX_DATA_SIZE];
Comment thread
trantanen marked this conversation as resolved.
struct nrf_cloud_rest_agnss_request request = {
NRF_CLOUD_REST_AGNSS_REQ_CUSTOM,
&req,
};

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

err = nrf_cloud_agnss_request(&req);
struct nrf_cloud_rest_agnss_result result = {agnss_rest_data_buf,
sizeof(agnss_rest_data_buf), 0};
struct lte_lc_cells_info net_info = {0};

err = get_single_cell_info(&net_info.current_cell);
if (err) {
LOG_ERR("Failed to request A-GNSS data (%d).", err);
} else {
LOG_INF("A-GNSS data requested.");
/* When A-GNSS data is received it gets injected in the background by
* nrf_cloud_agnss_process() without notification. In the case where
* CONFIG_NRF_CLOUD_PGPS=y, nrf_cloud_pgps_inject() (called on PGPS_EVT_AVAILABLE)
* plays a role as A-GNSS expects P-GPS to process some of the data.
*/
LOG_ERR("Failed to obtain single-cell cellular network information (%d).", err);
return;
}
request.net_info = &net_info;

err = nrf_cloud_coap_agnss_data_get(&request, &result);
if (err) {
LOG_ERR("Failed to request A-GNSS data via REST (%d).", err);
return;
}

err = nrf_cloud_agnss_process(result.buf, result.agnss_sz);
if (err) {
LOG_ERR("Failed to process A-GNSS data, error: %d", err);
return;
}
LOG_INF("A-GNSS data received via CoAP.");
}
#endif /* CONFIG_NRF_CLOUD_AGNSS */

Expand All @@ -352,6 +372,47 @@ static void pgps_requestor(struct k_work *)
}
}

static void pgps_coap_requestor(struct k_work *)
{
int err;
struct nrf_cloud_rest_pgps_request request = {.pgps_req = &pgps_coap_request};
struct nrf_cloud_pgps_result file_location = {0};
static char host[64];
static char path[128];

LOG_INF("Getting P-GPS predictions from nRF Cloud...");

memset(host, 0, sizeof(host));
memset(path, 0, sizeof(path));

file_location.host = host;
file_location.host_sz = sizeof(host);
file_location.path = path;
file_location.path_sz = sizeof(path);

err = nrf_cloud_coap_pgps_url_get(&request, &file_location);
if (err) {
LOG_ERR("Failed to get P-GPS data, error: %d", err);
nrf_cloud_pgps_request_reset();
return;
}

err = nrf_cloud_pgps_update(&file_location);
if (err) {
LOG_ERR("Failed to process P-GPS response, error: %d", err);
nrf_cloud_pgps_request_reset();
return;
}

err = nrf_cloud_pgps_notify_prediction();
if (err) {
LOG_ERR("Failed to request current prediction, error: %d", err);
return;
}

LOG_INF("P-GPS predictions requested");
}

static void pgps_event_handler(struct nrf_cloud_pgps_event *event)
{
int err;
Expand Down Expand Up @@ -403,6 +464,8 @@ static void pgps_event_handler(struct nrf_cloud_pgps_event *event)
break;
case PGPS_EVT_REQUEST:
LOG_INF("PGPS_EVT_REQUEST");
memcpy(&pgps_coap_request, event->request, sizeof(pgps_coap_request));
k_work_submit_to_queue(&sm_work_q, &pgps_coap_req_work);
break;
}
}
Expand Down Expand Up @@ -457,13 +520,8 @@ static void on_gnss_evt_pvt(void)
static int do_cloud_send_obj(struct nrf_cloud_obj *const obj)
{
int err;
struct nrf_cloud_tx_data msg = {
.obj = obj,
.topic_type = NRF_CLOUD_TOPIC_MESSAGE,
.qos = MQTT_QOS_0_AT_MOST_ONCE
};

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

static void send_location(struct nrf_modem_gnss_pvt_data_frame * const pvt_data)
{
#define CLOUD_GNSS_HEADING_ACC_LIMIT (float)60.0

static int64_t last_ts_ms = NRF_CLOUD_NO_TIMESTAMP;
int err;

/* Map modem PVT data to nRF Cloud PVT structure */
struct nrf_cloud_gnss_pvt pvt = {
.lat = pvt_data->latitude,
.lon = pvt_data->longitude,
.accuracy = pvt_data->accuracy,
.alt = pvt_data->altitude,
.has_alt = 1,
Comment thread
trantanen marked this conversation as resolved.
.speed = pvt_data->speed,
.has_speed = pvt_data->flags & NRF_MODEM_GNSS_PVT_FLAG_VELOCITY_VALID,
.heading = pvt_data->heading,
.has_heading = pvt_data->heading_accuracy < CLOUD_GNSS_HEADING_ACC_LIMIT ? 1 : 0,
};

struct nrf_cloud_gnss_data gnss = {
.ts_ms = NRF_CLOUD_NO_TIMESTAMP,
.type = NRF_CLOUD_GNSS_TYPE_MODEM_PVT,
.mdm_pvt = pvt_data
.type = NRF_CLOUD_GNSS_TYPE_PVT,
.pvt = pvt,
};
NRF_CLOUD_OBJ_JSON_DEFINE(msg_obj);

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

Expand Down Expand Up @@ -816,7 +890,8 @@ static int sm_at_gnss_init(void)
#endif
#if defined(CONFIG_NRF_CLOUD_PGPS)
k_work_init(&pgps_req_work, pgps_requestor);
#endif
k_work_init(&pgps_coap_req_work, pgps_coap_requestor);
#endif /* CONFIG_NRF_CLOUD_PGPS */
#endif /* CONFIG_SM_NRF_CLOUD */
k_work_init(&gnss_fix_send_work, gnss_fix_sender);

Expand Down
Loading
Loading