Skip to content

Commit 3dee02d

Browse files
committed
subsys: update ctr_lte_v2 and ctr_cloud configuration, add text mode with Base64
- Unified `nb-iot-mode` and `lte-m-mode` options into a single `mode` option. - Merged `autoconn` and `plmnid` into `network`. - Removed `port` option. - Legacy options are still supported for backward compatibility. - Added support for sending data in text mode using Base64 encoding. - Improved GNSS behavior when PSM is disabled. Signed-off-by: Karel Blavka <[email protected]>
1 parent 8411c7e commit 3dee02d

18 files changed

+876
-341
lines changed

include/chester/ctr_lte_v2.h

+20-3
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,18 @@ enum ctr_lte_v2_cereg_param_act {
4646
struct ctr_lte_v2_cereg_param {
4747
bool valid;
4848
enum ctr_lte_v2_cereg_param_stat stat;
49-
char tac[5]; // Tracking Area Code (TAC). (hexadecimal format.)
50-
int cid; // Cell Identity (CI) (E-UTRAN cell ID.)
51-
enum ctr_lte_v2_cereg_param_act act; // Access Technology (AcT).
49+
char tac[5]; /* Tracking Area Code (TAC). (hexadecimal format.) */
50+
int cid; /* Cell Identity (CI) (E-UTRAN cell ID.) */
51+
enum ctr_lte_v2_cereg_param_act act; /* Access Technology (AcT). */
52+
uint8_t cause_type;
53+
uint8_t reject_cause;
54+
int active_time; /* -1: disabled */
55+
int periodic_tau_ext; /* -1: disabled */
5256
};
5357

5458
struct ctr_lte_v2_send_recv_param {
5559
bool rai;
60+
bool send_as_string;
5661
const void *send_buf;
5762
size_t send_len;
5863
void *recv_buf;
@@ -62,6 +67,11 @@ struct ctr_lte_v2_send_recv_param {
6267
};
6368

6469
struct ctr_lte_v2_metrics {
70+
uint32_t attach_count;
71+
uint32_t attach_fail_count;
72+
uint32_t attach_duration_ms;
73+
int64_t attach_last_ts;
74+
uint32_t attach_last_duration_ms;
6575
uint32_t uplink_count;
6676
uint32_t uplink_bytes;
6777
uint32_t uplink_errors;
@@ -70,8 +80,15 @@ struct ctr_lte_v2_metrics {
7080
uint32_t downlink_bytes;
7181
uint32_t downlink_errors;
7282
int64_t downlink_last_ts;
83+
84+
uint32_t cscon_1_duration_ms;
85+
uint32_t cscon_1_last_duration_ms;
7386
};
7487

88+
// struct ctr_lte_v2_state {
89+
// // not sim card
90+
// bool sim_inserted;
91+
// };
7592
struct ctr_lte_v2_gnss_update {
7693
float latitude;
7794
float longitude;

subsys/ctr_cloud/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ config CTR_CLOUD
1717
select ZCBOR_STOP_ON_ERROR
1818
select SHELL
1919
select SHELL_BACKEND_DUMMY
20+
select BASE64
2021

2122
if CTR_CLOUD
2223

subsys/ctr_cloud/ctr_cloud_transfer.c

+100-99
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include <zephyr/logging/log.h>
2020
#include <zephyr/sys/byteorder.h>
2121

22+
#include <zephyr/sys/base64.h>
23+
2224
/* Standard includes */
2325
#include <errno.h>
2426
#include <stdbool.h>
@@ -27,10 +29,13 @@
2729

2830
#define MODEM_SLEEP_DELAY K_SECONDS(10)
2931

32+
#define MAX_DATA_SIZE (CTR_CLOUD_PACKET_MAX_SIZE - CTR_CLOUD_PACKET_MIN_SIZE)
33+
#define MAX_BASE64_DATA_SIZE ((CTR_CLOUD_PACKET_MAX_SIZE / 4 * 3) - 7 - CTR_CLOUD_PACKET_MIN_SIZE)
34+
3035
LOG_MODULE_REGISTER(ctr_cloud_transfer, CONFIG_CTR_CLOUD_LOG_LEVEL);
3136

32-
CTR_BUF_DEFINE_STATIC(m_send_buf, CTR_CLOUD_PACKET_MAX_SIZE);
33-
CTR_BUF_DEFINE_STATIC(m_recv_buf, CTR_CLOUD_PACKET_MAX_SIZE);
37+
CTR_BUF_DEFINE_STATIC(m_buf_0, CTR_CLOUD_PACKET_MAX_SIZE);
38+
CTR_BUF_DEFINE_STATIC(m_buf_1, CTR_CLOUD_PACKET_MAX_SIZE);
3439

3540
static uint16_t m_sequence;
3641
static uint16_t m_last_recv_sequence;
@@ -44,26 +49,49 @@ static struct ctr_cloud_transfer_metrics m_metrics = {
4449
};
4550
static K_MUTEX_DEFINE(m_lock_metrics);
4651

47-
static int send_recv(struct ctr_buf *send_buf, struct ctr_buf *recv_buf, bool rai)
52+
static int transfer(struct ctr_cloud_packet *pck_send, struct ctr_cloud_packet *pck_recv, bool rai)
4853
{
4954
int ret;
55+
struct ctr_buf *pck_buf = &m_buf_0;
56+
struct ctr_buf *send_buf = &m_buf_1;
57+
struct ctr_buf *recv_buf = &m_buf_0;
58+
size_t len;
5059

51-
LOG_HEXDUMP_INF(ctr_buf_get_mem(&m_send_buf), ctr_buf_get_used(&m_send_buf),
52-
rai ? "Sending packet RAI:" : "Sending packet:");
60+
LOG_INF("Sending packet Sequence: %u %s len: %u", pck_send->sequence,
61+
ctr_cloud_packet_flags_to_str(pck_send->flags), pck_send->data_len);
5362

54-
size_t recv_len;
63+
ctr_buf_reset(pck_buf);
64+
ret = ctr_cloud_packet_pack(pck_send, m_token, pck_buf);
65+
if (ret) {
66+
LOG_ERR("Call `ctr_cloud_packet_pack` failed: %d", ret);
67+
return ret;
68+
}
69+
70+
ctr_buf_reset(send_buf);
71+
ret = base64_encode(ctr_buf_get_mem(send_buf), ctr_buf_get_free(send_buf), &len,
72+
ctr_buf_get_mem(pck_buf), ctr_buf_get_used(pck_buf));
73+
if (ret) {
74+
LOG_ERR("Call `base64_encode` failed: %d", ret);
75+
return ret;
76+
}
77+
ctr_buf_seek(send_buf, len);
78+
len = 0;
79+
80+
LOG_HEXDUMP_INF(ctr_buf_get_mem(send_buf), ctr_buf_get_used(send_buf),
81+
rai ? "Sending packet RAI:" : "Sending packet:");
5582

5683
struct ctr_lte_v2_send_recv_param param = {
5784
.rai = rai,
85+
.send_as_string = true,
5886
.send_buf = ctr_buf_get_mem(send_buf),
5987
.send_len = ctr_buf_get_used(send_buf),
6088
.recv_buf = NULL,
6189
.recv_size = 0,
62-
.recv_len = &recv_len,
63-
.timeout = K_FOREVER,
90+
.recv_len = &len,
91+
.timeout = K_FOREVER, // todo timeout
6492
};
6593

66-
if (recv_buf) {
94+
if (pck_recv) {
6795
ctr_buf_reset(recv_buf);
6896
param.recv_buf = ctr_buf_get_mem(recv_buf);
6997
param.recv_size = ctr_buf_get_free(recv_buf);
@@ -75,20 +103,41 @@ static int send_recv(struct ctr_buf *send_buf, struct ctr_buf *recv_buf, bool ra
75103
return ret;
76104
}
77105

78-
if (recv_buf) {
79-
ret = ctr_buf_seek(&m_recv_buf, recv_len);
106+
if (pck_recv) {
107+
ret = ctr_buf_seek(recv_buf, len);
80108
if (ret) {
81109
LOG_ERR("Call `ctr_buf_seek` failed: %d", ret);
82110
return ret;
83111
}
84112

85-
if (!ctr_buf_get_used(&m_recv_buf)) {
113+
if (!ctr_buf_get_used(recv_buf)) {
86114
LOG_ERR("No data received");
87115
return -EIO;
88116
}
89117

90-
// LOG_HEXDUMP_INF(ctr_buf_get_mem(&m_recv_buf), ctr_buf_get_used(&m_recv_buf),
118+
// LOG_HEXDUMP_INF(ctr_buf_get_mem(recv_buf), ctr_buf_get_used(recv_buf),
91119
// "Received packet:");
120+
121+
pck_buf = &m_buf_1;
122+
len = 0;
123+
124+
ctr_buf_reset(pck_buf);
125+
ret = base64_decode(ctr_buf_get_mem(pck_buf), ctr_buf_get_free(pck_buf), &len,
126+
ctr_buf_get_mem(recv_buf), ctr_buf_get_used(recv_buf));
127+
if (ret) {
128+
LOG_ERR("Call `base64_decode` failed: %d", ret);
129+
return ret;
130+
}
131+
ctr_buf_seek(pck_buf, len);
132+
133+
ret = ctr_cloud_packet_unpack(pck_recv, m_token, pck_buf);
134+
if (ret) {
135+
LOG_ERR("Call `ctr_cloud_packet_unpack` failed: %d", ret);
136+
return ret;
137+
}
138+
139+
LOG_INF("Received packet Sequence: %u %s len: %u", pck_recv->sequence,
140+
ctr_cloud_packet_flags_to_str(pck_recv->flags), pck_recv->data_len);
92141
}
93142

94143
return 0;
@@ -155,7 +204,7 @@ int ctr_cloud_transfer_uplink(struct ctr_buf *buf, bool *has_downlink)
155204
int part = 0;
156205
int fragments = 0;
157206

158-
if (has_downlink != NULL) {
207+
if (has_downlink) {
159208
*has_downlink = false;
160209
}
161210

@@ -166,78 +215,44 @@ int ctr_cloud_transfer_uplink(struct ctr_buf *buf, bool *has_downlink)
166215
p = ctr_buf_get_mem(buf);
167216
len = ctr_buf_get_used(buf);
168217

169-
fragments = len / CTR_CLOUD_DATA_MAX_SIZE;
170-
if (len % CTR_CLOUD_DATA_MAX_SIZE) {
218+
/* calculate number of fragments */
219+
fragments = len / MAX_BASE64_DATA_SIZE;
220+
if (len % MAX_BASE64_DATA_SIZE) {
171221
fragments++;
172222
}
173223
}
174224

175225
do {
176226
LOG_INF("Processing part: %d (%d left)", part, fragments - part - 1);
177227

178-
ctr_buf_reset(&m_recv_buf);
179-
180-
m_pck_send.data_len = 0;
181-
m_pck_send.flags = 0;
182-
m_pck_send.data = NULL;
183-
184-
if (buf) {
185-
m_pck_send.data = p;
186-
m_pck_send.data_len = MIN(len, CTR_CLOUD_DATA_MAX_SIZE);
187-
188-
p += m_pck_send.data_len;
189-
len -= m_pck_send.data_len;
190-
191-
if (part == 0) {
192-
m_pck_send.flags |= CTR_CLOUD_PACKET_FLAG_FIRST;
193-
}
194-
if (len == 0) {
195-
m_pck_send.flags |= CTR_CLOUD_PACKET_FLAG_LAST;
196-
}
197-
198-
part++;
199-
}
200-
228+
m_pck_send.data = p;
229+
m_pck_send.data_len = MIN(len, MAX_BASE64_DATA_SIZE);
201230
m_pck_send.sequence = m_sequence;
202231
m_sequence = ctr_cloud_packet_sequence_inc(m_sequence);
203232

204-
again:
205-
LOG_INF("Sending packet Sequence: %u %s len: %u", m_pck_send.sequence,
206-
ctr_cloud_packet_flags_to_str(m_pck_send.flags), m_pck_send.data_len);
207-
208-
ret = ctr_cloud_packet_pack(&m_pck_send, m_token, &m_send_buf);
209-
if (ret) {
210-
LOG_ERR("Call `ctr_cloud_packet_pack` failed: %d", ret);
211-
res = ret;
212-
goto exit;
233+
m_pck_send.flags = 0;
234+
if (part == 0) {
235+
m_pck_send.flags |= CTR_CLOUD_PACKET_FLAG_FIRST;
213236
}
214-
215-
ctr_buf_reset(&m_recv_buf);
216-
bool rai = m_pck_send.flags & CTR_CLOUD_PACKET_FLAG_LAST;
217-
ret = send_recv(&m_send_buf, &m_recv_buf, rai);
218-
if (ret) {
219-
LOG_ERR("Call `send_recv` failed: %d", ret);
220-
res = ret;
221-
goto exit;
237+
if (len == m_pck_send.data_len) {
238+
m_pck_send.flags |= CTR_CLOUD_PACKET_FLAG_LAST;
222239
}
223240

224-
ret = ctr_cloud_packet_unpack(&m_pck_recv, m_token, &m_recv_buf);
241+
bool rai = m_pck_send.flags & CTR_CLOUD_PACKET_FLAG_LAST;
242+
ret = transfer(&m_pck_send, &m_pck_recv, rai);
225243
if (ret) {
226-
LOG_ERR("Call `ctr_cloud_packet_unpack` failed: %d", ret);
244+
LOG_ERR("Call `transfer` failed: %d", ret);
227245
res = ret;
228246
goto exit;
229247
}
230248

231-
LOG_INF("Received packet Sequence: %u %s len: %u", m_pck_recv.sequence,
232-
ctr_cloud_packet_flags_to_str(m_pck_recv.flags), m_pck_recv.data_len);
233-
234249
if (m_pck_recv.serial_number != m_pck_send.serial_number) {
235250
LOG_ERR("Serial number mismatch");
236251
res = -EREMCHG;
237252
goto exit;
238253
}
239254

240-
if (has_downlink != NULL) {
255+
if (has_downlink) {
241256
*has_downlink = m_pck_recv.flags & CTR_CLOUD_PACKET_FLAG_POLL;
242257
}
243258

@@ -256,22 +271,26 @@ int ctr_cloud_transfer_uplink(struct ctr_buf *buf, bool *has_downlink)
256271
if (m_pck_recv.sequence != m_sequence) {
257272
if (m_pck_recv.sequence == m_last_recv_sequence) {
258273
LOG_WRN("Received repeat response");
259-
goto again;
274+
continue;
260275
} else {
261276
LOG_WRN("Received unexpected sequence expect: %u", m_sequence);
262277
m_sequence = 0;
263278
goto restart;
264279
}
265280
}
266281

282+
if (m_pck_recv.data_len) {
283+
LOG_ERR("Received unexpected data length");
284+
m_sequence = 0;
285+
goto restart;
286+
}
287+
267288
m_last_recv_sequence = m_pck_recv.sequence;
268289
m_sequence = ctr_cloud_packet_sequence_inc(m_sequence);
269290

270-
if (m_pck_recv.data_len != 0) {
271-
LOG_ERR("Received unexpected data length");
272-
res = -EIO;
273-
goto exit;
274-
}
291+
p += m_pck_send.data_len;
292+
len -= m_pck_send.data_len;
293+
part++;
275294

276295
} while (len);
277296

@@ -307,8 +326,9 @@ int ctr_cloud_transfer_downlink(struct ctr_buf *buf, bool *has_downlink)
307326
int part = 0;
308327
bool quit;
309328

310-
*has_downlink = false;
311-
329+
if (has_downlink) {
330+
*has_downlink = false;
331+
}
312332
size_t buf_used = ctr_buf_get_used(buf);
313333

314334
restart:
@@ -327,48 +347,26 @@ int ctr_cloud_transfer_downlink(struct ctr_buf *buf, bool *has_downlink)
327347
m_sequence = ctr_cloud_packet_sequence_inc(m_sequence);
328348

329349
again:
330-
LOG_INF("Sending packet Sequence: %u %s len: %u", m_pck_send.sequence,
331-
ctr_cloud_packet_flags_to_str(m_pck_send.flags), m_pck_send.data_len);
332-
333-
ret = ctr_cloud_packet_pack(&m_pck_send, m_token, &m_send_buf);
334-
335-
if (ret) {
336-
LOG_ERR("Call `ctr_cloud_packet_pack` failed: %d", ret);
337-
res = ret;
338-
goto exit;
339-
}
340-
341-
ctr_buf_reset(&m_recv_buf);
342350
if (quit) {
343-
bool rai = !*has_downlink; // use RAI if no downlink is expected
344-
ret = send_recv(&m_send_buf, NULL, rai);
351+
bool rai = has_downlink ? !*has_downlink
352+
: true; /* use RAI if no downlink is expected */
353+
ret = transfer(&m_pck_send, NULL, rai);
345354
if (ret) {
346-
LOG_ERR("Call `send_recv` failed: %d", ret);
355+
LOG_ERR("Call `transfer` failed: %d", ret);
347356
res = ret;
348357
goto exit;
349358
}
350359
break;
351360
}
352361

353362
bool rai = part == 0;
354-
355-
ret = send_recv(&m_send_buf, &m_recv_buf, rai);
363+
ret = transfer(&m_pck_send, &m_pck_recv, rai);
356364
if (ret) {
357-
LOG_ERR("Call `send_recv` failed: %d", ret);
365+
LOG_ERR("Call `transfer` failed: %d", ret);
358366
res = ret;
359367
goto exit;
360368
}
361369

362-
ret = ctr_cloud_packet_unpack(&m_pck_recv, m_token, &m_recv_buf);
363-
if (ret) {
364-
LOG_ERR("Call `ctr_cloud_packet_unpack` failed: %d", ret);
365-
res = ret;
366-
goto exit;
367-
}
368-
369-
LOG_INF("Received packet Sequence: %u %s len: %u", m_pck_recv.sequence,
370-
ctr_cloud_packet_flags_to_str(m_pck_recv.flags), m_pck_recv.data_len);
371-
372370
if (m_pck_recv.serial_number != m_pck_send.serial_number) {
373371
LOG_ERR("Serial number mismatch");
374372
res = -EREMCHG;
@@ -413,7 +411,10 @@ int ctr_cloud_transfer_downlink(struct ctr_buf *buf, bool *has_downlink)
413411
}
414412

415413
quit = m_pck_recv.flags & CTR_CLOUD_PACKET_FLAG_LAST;
416-
*has_downlink = m_pck_recv.flags & CTR_CLOUD_PACKET_FLAG_POLL;
414+
415+
if (has_downlink) {
416+
*has_downlink = m_pck_recv.flags & CTR_CLOUD_PACKET_FLAG_POLL;
417+
}
417418

418419
if (quit && m_pck_recv.data_len == 0 && part == 0) {
419420
LOG_INF("Skip ack response");

0 commit comments

Comments
 (0)