Skip to content
This repository was archived by the owner on Jul 9, 2024. It is now read-only.

Commit 6ad48de

Browse files
author
GitHub Actions
committed
1 parent 4a4b5db commit 6ad48de

27 files changed

Lines changed: 674 additions & 78 deletions

README.rst

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,21 @@ Data types
6464
Data from multiple sensor sources are collected to construct information about the location, environment, and the health of the nRF9160-based device.
6565
The application supports the following data types:
6666

67-
+---------------+----------------------------+-----------------------------------------------+
68-
| Data type | Description | Identifiers |
69-
+===============+============================+===============================================+
70-
| Location | GNSS coordinates | APP_DATA_GNSS |
71-
+---------------+----------------------------+-----------------------------------------------+
72-
| Environmental | Temperature, humidity | APP_DATA_ENVIRONMENTAL |
73-
+---------------+----------------------------+-----------------------------------------------+
74-
| Movement | Acceleration | APP_DATA_MOVEMENT |
75-
+---------------+----------------------------+-----------------------------------------------+
76-
| Modem | LTE link data, device data | APP_DATA_MODEM_DYNAMIC, APP_DATA_MODEM_STATIC |
77-
+---------------+----------------------------+-----------------------------------------------+
78-
| Battery | Voltage | APP_DATA_BATTERY |
79-
+---------------+----------------------------+-----------------------------------------------+
67+
+----------------+----------------------------+-----------------------------------------------+
68+
| Data type | Description | Identifiers |
69+
+================+============================+===============================================+
70+
| Location | GNSS coordinates | APP_DATA_GNSS |
71+
+----------------+----------------------------+-----------------------------------------------+
72+
| Environmental | Temperature, humidity | APP_DATA_ENVIRONMENTAL |
73+
+----------------+----------------------------+-----------------------------------------------+
74+
| Movement | Acceleration | APP_DATA_MOVEMENT |
75+
+----------------+----------------------------+-----------------------------------------------+
76+
| Modem | LTE link data, device data | APP_DATA_MODEM_DYNAMIC, APP_DATA_MODEM_STATIC |
77+
+----------------+----------------------------+-----------------------------------------------+
78+
| Battery | Voltage | APP_DATA_BATTERY |
79+
+----------------+----------------------------+-----------------------------------------------+
80+
| Neighbor cells | Neighbor cell measurements | APP_DATA_NEIGHBOR_CELLS |
81+
+----------------+----------------------------+-----------------------------------------------+
8082

8183
The sets of sensor data that are published to the cloud service consist of relative `timestamps <Timestamping_>`_ that originate from the time of sampling.
8284

src/cloud/aws_iot_integration.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ LOG_MODULE_REGISTER(MODULE, CONFIG_CLOUD_INTEGRATION_LOG_LEVEL);
2222
#define BATCH_TOPIC_LEN (AWS_CLOUD_CLIENT_ID_LEN + 6)
2323
#define MESSAGES_TOPIC "%s/messages"
2424
#define MESSAGES_TOPIC_LEN (AWS_CLOUD_CLIENT_ID_LEN + 9)
25+
#define NEIGHBOR_CELLS_TOPIC "%s/ncellmeas"
26+
#define NEIGHBOR_CELLS_TOPIC_LEN (AWS_CLOUD_CLIENT_ID_LEN + 10)
2527

2628
#define APP_SUB_TOPICS_COUNT 1
27-
#define APP_PUB_TOPICS_COUNT 2
29+
#define APP_PUB_TOPICS_COUNT 3
2830

2931
#define REQUEST_SHADOW_DOCUMENT_STRING ""
3032

3133
static char client_id_buf[AWS_CLOUD_CLIENT_ID_LEN + 1];
3234
static char batch_topic[BATCH_TOPIC_LEN + 1];
3335
static char cfg_topic[CFG_TOPIC_LEN + 1];
3436
static char messages_topic[MESSAGES_TOPIC_LEN + 1];
37+
static char neighbor_cells_topic[NEIGHBOR_CELLS_TOPIC_LEN + 1];
3538

3639
static struct aws_iot_topic_data sub_topics[APP_SUB_TOPICS_COUNT];
3740
static struct aws_iot_topic_data pub_topics[APP_PUB_TOPICS_COUNT];
@@ -71,6 +74,15 @@ static int populate_app_endpoint_topics(void)
7174
pub_topics[1].str = messages_topic;
7275
pub_topics[1].len = MESSAGES_TOPIC_LEN;
7376

77+
err = snprintf(neighbor_cells_topic, sizeof(neighbor_cells_topic),
78+
NEIGHBOR_CELLS_TOPIC, client_id_buf);
79+
if (err != NEIGHBOR_CELLS_TOPIC_LEN) {
80+
return -ENOMEM;
81+
}
82+
83+
pub_topics[2].str = neighbor_cells_topic;
84+
pub_topics[2].len = NEIGHBOR_CELLS_TOPIC_LEN;
85+
7486
err = snprintf(cfg_topic, sizeof(cfg_topic), CFG_TOPIC, client_id_buf);
7587
if (err != CFG_TOPIC_LEN) {
7688
return -ENOMEM;
@@ -347,3 +359,23 @@ int cloud_wrap_ui_send(char *buf, size_t len)
347359

348360
return 0;
349361
}
362+
363+
int cloud_wrap_neighbor_cells_send(char *buf, size_t len)
364+
{
365+
int err;
366+
struct aws_iot_data msg = {
367+
.ptr = buf,
368+
.len = len,
369+
.qos = MQTT_QOS_0_AT_MOST_ONCE,
370+
/* <imei>/ncellmeas */
371+
.topic = pub_topics[2]
372+
};
373+
374+
err = aws_iot_send(&msg);
375+
if (err) {
376+
LOG_ERR("aws_iot_send, error: %d", err);
377+
return err;
378+
}
379+
380+
return 0;
381+
}

src/cloud/azure_iot_hub_integration.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,9 @@ int cloud_wrap_ui_send(char *buf, size_t len)
319319

320320
return 0;
321321
}
322+
323+
int cloud_wrap_neighbor_cells_send(char *buf, size_t len)
324+
{
325+
/* Not supported */
326+
return -ENOTSUP;
327+
}

src/cloud/cloud_codec/aws_iot_codec.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,48 @@ static bool has_shadow_update_been_handled(cJSON *root_obj)
4949
return retval;
5050
}
5151

52+
int cloud_codec_encode_neighbor_cells(struct cloud_codec_data *output,
53+
struct cloud_data_neighbor_cells *neighbor_cells)
54+
{
55+
int err;
56+
char *buffer;
57+
58+
__ASSERT_NO_MSG(output != NULL);
59+
__ASSERT_NO_MSG(neighbor_cells != NULL);
60+
61+
cJSON *root_obj = cJSON_CreateObject();
62+
63+
if (root_obj == NULL) {
64+
cJSON_Delete(root_obj);
65+
return -ENOMEM;
66+
}
67+
68+
err = json_common_neighbor_cells_data_add(root_obj, neighbor_cells,
69+
JSON_COMMON_ADD_DATA_TO_OBJECT);
70+
if (err) {
71+
goto exit;
72+
}
73+
74+
buffer = cJSON_PrintUnformatted(root_obj);
75+
if (buffer == NULL) {
76+
LOG_ERR("Failed to allocate memory for JSON string");
77+
78+
err = -ENOMEM;
79+
goto exit;
80+
}
81+
82+
if (IS_ENABLED(CONFIG_CLOUD_CODEC_LOG_LEVEL_DBG)) {
83+
json_print_obj("Encoded message:\n", root_obj);
84+
}
85+
86+
output->buf = buffer;
87+
output->len = strlen(buffer);
88+
89+
exit:
90+
cJSON_Delete(root_obj);
91+
return err;
92+
}
93+
5294
int cloud_codec_decode_config(char *input, struct cloud_data_cfg *data)
5395
{
5496
int err = 0;

src/cloud/cloud_codec/azure_iot_hub_codec.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@
2020
#include <logging/log.h>
2121
LOG_MODULE_REGISTER(cloud_codec, CONFIG_CLOUD_CODEC_LOG_LEVEL);
2222

23+
int cloud_codec_encode_neighbor_cells(struct cloud_codec_data *output,
24+
struct cloud_data_neighbor_cells *neighbor_cells)
25+
{
26+
__ASSERT_NO_MSG(output != NULL);
27+
__ASSERT_NO_MSG(neighbor_cells != NULL);
28+
29+
neighbor_cells->queued = false;
30+
return -ENOTSUP;
31+
}
32+
2333
int cloud_codec_decode_config(char *input, struct cloud_data_cfg *data)
2434
{
2535
int err = 0;

src/cloud/cloud_codec/cloud_codec.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <stdlib.h>
1515
#include "cJSON_os.h"
1616
#include <net/net_ip.h>
17+
#include <modem/lte_lc.h>
1718

1819
/**@file
1920
*
@@ -187,11 +188,21 @@ struct cloud_codec_data {
187188
size_t len;
188189
};
189190

191+
struct cloud_data_neighbor_cells {
192+
struct lte_lc_cells_info cell_data;
193+
struct lte_lc_ncell neighbor_cells[17];
194+
int64_t ts;
195+
bool queued : 1;
196+
};
197+
190198
static inline void cloud_codec_init(void)
191199
{
192200
cJSON_Init();
193201
}
194202

203+
int cloud_codec_encode_neighbor_cells(struct cloud_codec_data *output,
204+
struct cloud_data_neighbor_cells *neighbor_cells);
205+
195206
int cloud_codec_decode_config(char *input, struct cloud_data_cfg *cfg);
196207

197208
int cloud_codec_encode_config(struct cloud_codec_data *output,

src/cloud/cloud_codec/json_common.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,158 @@ int json_common_ui_data_add(cJSON *parent,
560560
return err;
561561
}
562562

563+
int json_common_neighbor_cells_data_add(cJSON *parent,
564+
struct cloud_data_neighbor_cells *data,
565+
enum json_common_op_code op)
566+
{
567+
int err;
568+
569+
if (!data->queued) {
570+
return -ENODATA;
571+
}
572+
573+
err = date_time_uptime_to_unix_time_ms(&data->ts);
574+
if (err) {
575+
LOG_ERR("date_time_uptime_to_unix_time_ms, error: %d", err);
576+
return err;
577+
}
578+
579+
err = json_add_number(parent, DATA_NEIGHBOR_CELLS_MCC, data->cell_data.current_cell.mcc);
580+
if (err) {
581+
LOG_ERR("Encoding error: %d returned at %s:%d", err, __FILE__, __LINE__);
582+
return err;
583+
}
584+
585+
err = json_add_number(parent, DATA_NEIGHBOR_CELLS_MNC, data->cell_data.current_cell.mnc);
586+
if (err) {
587+
LOG_ERR("Encoding error: %d returned at %s:%d", err, __FILE__, __LINE__);
588+
return err;
589+
}
590+
591+
err = json_add_number(parent, DATA_NEIGHBOR_CELLS_CID, data->cell_data.current_cell.id);
592+
if (err) {
593+
LOG_ERR("Encoding error: %d returned at %s:%d", err, __FILE__, __LINE__);
594+
return err;
595+
}
596+
597+
err = json_add_number(parent, DATA_NEIGHBOR_CELLS_TAC, data->cell_data.current_cell.tac);
598+
if (err) {
599+
LOG_ERR("Encoding error: %d returned at %s:%d", err, __FILE__, __LINE__);
600+
return err;
601+
}
602+
603+
err = json_add_number(parent, DATA_NEIGHBOR_CELLS_EARFCN,
604+
data->cell_data.current_cell.earfcn);
605+
if (err) {
606+
LOG_ERR("Encoding error: %d returned at %s:%d", err, __FILE__, __LINE__);
607+
return err;
608+
}
609+
610+
err = json_add_number(parent, DATA_NEIGHBOR_CELLS_TIMING,
611+
data->cell_data.current_cell.timing_advance);
612+
if (err) {
613+
LOG_ERR("Encoding error: %d returned at %s:%d", err, __FILE__, __LINE__);
614+
return err;
615+
}
616+
617+
err = json_add_number(parent, DATA_NEIGHBOR_CELLS_RSRP,
618+
data->cell_data.current_cell.rsrp);
619+
if (err) {
620+
LOG_ERR("Encoding error: %d returned at %s:%d", err, __FILE__, __LINE__);
621+
return err;
622+
}
623+
624+
err = json_add_number(parent, DATA_NEIGHBOR_CELLS_RSRQ,
625+
data->cell_data.current_cell.rsrq);
626+
if (err) {
627+
LOG_ERR("Encoding error: %d returned at %s:%d", err, __FILE__, __LINE__);
628+
return err;
629+
}
630+
631+
err = json_add_number(parent, DATA_TIMESTAMP, data->ts);
632+
if (err) {
633+
LOG_ERR("Encoding error: %d returned at %s:%d", err, __FILE__, __LINE__);
634+
return err;
635+
}
636+
637+
if (data->cell_data.ncells_count > 0) {
638+
cJSON *neighbor_cells = cJSON_CreateArray();
639+
640+
if (neighbor_cells == NULL) {
641+
return err;
642+
}
643+
644+
for (int i = 0; i < data->cell_data.ncells_count; i++) {
645+
646+
cJSON *cell = cJSON_CreateObject();
647+
648+
if (cell == NULL) {
649+
err = -ENOMEM;
650+
cJSON_Delete(neighbor_cells);
651+
return err;
652+
}
653+
654+
err = json_add_number(cell, DATA_NEIGHBOR_CELLS_EARFCN,
655+
data->neighbor_cells[i].earfcn);
656+
if (err) {
657+
LOG_ERR("Encoding error: %d returned at %s:%d", err,
658+
__FILE__, __LINE__);
659+
cJSON_Delete(neighbor_cells);
660+
cJSON_Delete(cell);
661+
return err;
662+
}
663+
664+
err = json_add_number(cell, DATA_NEIGHBOR_CELLS_PCI,
665+
data->neighbor_cells[i].phys_cell_id);
666+
if (err) {
667+
LOG_ERR("Encoding error: %d returned at %s:%d", err,
668+
__FILE__, __LINE__);
669+
cJSON_Delete(neighbor_cells);
670+
cJSON_Delete(cell);
671+
return err;
672+
}
673+
674+
err = json_add_number(cell, DATA_NEIGHBOR_CELLS_RSRP,
675+
data->neighbor_cells[i].rsrp);
676+
if (err) {
677+
LOG_ERR("Encoding error: %d returned at %s:%d", err,
678+
__FILE__, __LINE__);
679+
cJSON_Delete(neighbor_cells);
680+
cJSON_Delete(cell);
681+
return err;
682+
}
683+
684+
err = json_add_number(cell, DATA_NEIGHBOR_CELLS_RSRQ,
685+
data->neighbor_cells[i].rsrq);
686+
if (err) {
687+
LOG_ERR("Encoding error: %d returned at %s:%d", err,
688+
__FILE__, __LINE__);
689+
cJSON_Delete(neighbor_cells);
690+
cJSON_Delete(cell);
691+
return err;
692+
}
693+
694+
err = op_code_handle(neighbor_cells, JSON_COMMON_ADD_DATA_TO_ARRAY, NULL,
695+
cell, NULL);
696+
if (err) {
697+
cJSON_Delete(neighbor_cells);
698+
cJSON_Delete(cell);
699+
return err;
700+
}
701+
}
702+
703+
err = op_code_handle(parent, JSON_COMMON_ADD_DATA_TO_OBJECT,
704+
DATA_NEIGHBOR_CELLS_NEIGHBOR_MEAS, neighbor_cells, NULL);
705+
if (err) {
706+
cJSON_Delete(neighbor_cells);
707+
return err;
708+
}
709+
}
710+
711+
data->queued = false;
712+
return err;
713+
}
714+
563715
int json_common_battery_data_add(cJSON *parent,
564716
struct cloud_data_battery *data,
565717
enum json_common_op_code op,

src/cloud/cloud_codec/json_common.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,22 @@ int json_common_ui_data_add(cJSON *parent,
182182
const char *object_label,
183183
cJSON **parent_ref);
184184

185+
/**
186+
* @brief Encode and add neighbor cell data to the parent object.
187+
*
188+
* @param[out] parent Pointer to object that the encoded data is added to.
189+
* @param[in] data Pointer to data that is to be encoded.
190+
* @param[in] op Operation that is to be carried out.
191+
*
192+
* @retval 0 on success.
193+
* @retval -ENODATA if the passed in data is not queued or has an invalid timestamp value.
194+
* @retval -EINVAL if the passed in input arguments does not match whats required by the OP code.
195+
* @retval -ENOMEM if the function fails to allocate memory.
196+
*/
197+
int json_common_neighbor_cells_data_add(cJSON *parent,
198+
struct cloud_data_neighbor_cells *data,
199+
enum json_common_op_code op);
200+
185201
/**
186202
* @brief Encode and add battery data to the parent object.
187203
*

0 commit comments

Comments
 (0)