19
19
#include <zephyr/logging/log.h>
20
20
#include <zephyr/sys/byteorder.h>
21
21
22
+ #include <zephyr/sys/base64.h>
23
+
22
24
/* Standard includes */
23
25
#include <errno.h>
24
26
#include <stdbool.h>
27
29
28
30
#define MODEM_SLEEP_DELAY K_SECONDS(10)
29
31
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
+
30
35
LOG_MODULE_REGISTER (ctr_cloud_transfer , CONFIG_CTR_CLOUD_LOG_LEVEL );
31
36
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 );
34
39
35
40
static uint16_t m_sequence ;
36
41
static uint16_t m_last_recv_sequence ;
@@ -44,26 +49,49 @@ static struct ctr_cloud_transfer_metrics m_metrics = {
44
49
};
45
50
static K_MUTEX_DEFINE (m_lock_metrics );
46
51
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 )
48
53
{
49
54
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 ;
50
59
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 );
53
62
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:" );
55
82
56
83
struct ctr_lte_v2_send_recv_param param = {
57
84
.rai = rai ,
85
+ .send_as_string = true,
58
86
.send_buf = ctr_buf_get_mem (send_buf ),
59
87
.send_len = ctr_buf_get_used (send_buf ),
60
88
.recv_buf = NULL ,
61
89
.recv_size = 0 ,
62
- .recv_len = & recv_len ,
63
- .timeout = K_FOREVER ,
90
+ .recv_len = & len ,
91
+ .timeout = K_FOREVER , // todo timeout
64
92
};
65
93
66
- if (recv_buf ) {
94
+ if (pck_recv ) {
67
95
ctr_buf_reset (recv_buf );
68
96
param .recv_buf = ctr_buf_get_mem (recv_buf );
69
97
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
75
103
return ret ;
76
104
}
77
105
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 );
80
108
if (ret ) {
81
109
LOG_ERR ("Call `ctr_buf_seek` failed: %d" , ret );
82
110
return ret ;
83
111
}
84
112
85
- if (!ctr_buf_get_used (& m_recv_buf )) {
113
+ if (!ctr_buf_get_used (recv_buf )) {
86
114
LOG_ERR ("No data received" );
87
115
return - EIO ;
88
116
}
89
117
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 ),
91
119
// "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 );
92
141
}
93
142
94
143
return 0 ;
@@ -155,7 +204,7 @@ int ctr_cloud_transfer_uplink(struct ctr_buf *buf, bool *has_downlink)
155
204
int part = 0 ;
156
205
int fragments = 0 ;
157
206
158
- if (has_downlink != NULL ) {
207
+ if (has_downlink ) {
159
208
* has_downlink = false;
160
209
}
161
210
@@ -166,78 +215,44 @@ int ctr_cloud_transfer_uplink(struct ctr_buf *buf, bool *has_downlink)
166
215
p = ctr_buf_get_mem (buf );
167
216
len = ctr_buf_get_used (buf );
168
217
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 ) {
171
221
fragments ++ ;
172
222
}
173
223
}
174
224
175
225
do {
176
226
LOG_INF ("Processing part: %d (%d left)" , part , fragments - part - 1 );
177
227
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 );
201
230
m_pck_send .sequence = m_sequence ;
202
231
m_sequence = ctr_cloud_packet_sequence_inc (m_sequence );
203
232
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 ;
213
236
}
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 ;
222
239
}
223
240
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 );
225
243
if (ret ) {
226
- LOG_ERR ("Call `ctr_cloud_packet_unpack ` failed: %d" , ret );
244
+ LOG_ERR ("Call `transfer ` failed: %d" , ret );
227
245
res = ret ;
228
246
goto exit ;
229
247
}
230
248
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
-
234
249
if (m_pck_recv .serial_number != m_pck_send .serial_number ) {
235
250
LOG_ERR ("Serial number mismatch" );
236
251
res = - EREMCHG ;
237
252
goto exit ;
238
253
}
239
254
240
- if (has_downlink != NULL ) {
255
+ if (has_downlink ) {
241
256
* has_downlink = m_pck_recv .flags & CTR_CLOUD_PACKET_FLAG_POLL ;
242
257
}
243
258
@@ -256,22 +271,26 @@ int ctr_cloud_transfer_uplink(struct ctr_buf *buf, bool *has_downlink)
256
271
if (m_pck_recv .sequence != m_sequence ) {
257
272
if (m_pck_recv .sequence == m_last_recv_sequence ) {
258
273
LOG_WRN ("Received repeat response" );
259
- goto again ;
274
+ continue ;
260
275
} else {
261
276
LOG_WRN ("Received unexpected sequence expect: %u" , m_sequence );
262
277
m_sequence = 0 ;
263
278
goto restart ;
264
279
}
265
280
}
266
281
282
+ if (m_pck_recv .data_len ) {
283
+ LOG_ERR ("Received unexpected data length" );
284
+ m_sequence = 0 ;
285
+ goto restart ;
286
+ }
287
+
267
288
m_last_recv_sequence = m_pck_recv .sequence ;
268
289
m_sequence = ctr_cloud_packet_sequence_inc (m_sequence );
269
290
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 ++ ;
275
294
276
295
} while (len );
277
296
@@ -307,8 +326,9 @@ int ctr_cloud_transfer_downlink(struct ctr_buf *buf, bool *has_downlink)
307
326
int part = 0 ;
308
327
bool quit ;
309
328
310
- * has_downlink = false;
311
-
329
+ if (has_downlink ) {
330
+ * has_downlink = false;
331
+ }
312
332
size_t buf_used = ctr_buf_get_used (buf );
313
333
314
334
restart :
@@ -327,48 +347,26 @@ int ctr_cloud_transfer_downlink(struct ctr_buf *buf, bool *has_downlink)
327
347
m_sequence = ctr_cloud_packet_sequence_inc (m_sequence );
328
348
329
349
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 );
342
350
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 );
345
354
if (ret ) {
346
- LOG_ERR ("Call `send_recv ` failed: %d" , ret );
355
+ LOG_ERR ("Call `transfer ` failed: %d" , ret );
347
356
res = ret ;
348
357
goto exit ;
349
358
}
350
359
break ;
351
360
}
352
361
353
362
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 );
356
364
if (ret ) {
357
- LOG_ERR ("Call `send_recv ` failed: %d" , ret );
365
+ LOG_ERR ("Call `transfer ` failed: %d" , ret );
358
366
res = ret ;
359
367
goto exit ;
360
368
}
361
369
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
-
372
370
if (m_pck_recv .serial_number != m_pck_send .serial_number ) {
373
371
LOG_ERR ("Serial number mismatch" );
374
372
res = - EREMCHG ;
@@ -413,7 +411,10 @@ int ctr_cloud_transfer_downlink(struct ctr_buf *buf, bool *has_downlink)
413
411
}
414
412
415
413
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
+ }
417
418
418
419
if (quit && m_pck_recv .data_len == 0 && part == 0 ) {
419
420
LOG_INF ("Skip ack response" );
0 commit comments