1 /*
2 * Copyright (c) 2022 Trackunit Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /*************************************************************************************************/
8 /* Dependencies */
9 /*************************************************************************************************/
10 #include <zephyr/ztest.h>
11 #include <zephyr/kernel.h>
12 #include <string.h>
13
14 #include <zephyr/modem/cmux.h>
15 #include <modem_backend_mock.h>
16
17 /*************************************************************************************************/
18 /* Definitions */
19 /*************************************************************************************************/
20 #define EVENT_CMUX_CONNECTED BIT(0)
21 #define EVENT_CMUX_DLCI1_OPEN BIT(1)
22 #define EVENT_CMUX_DLCI2_OPEN BIT(2)
23 #define EVENT_CMUX_DLCI1_RECEIVE_READY BIT(3)
24 #define EVENT_CMUX_DLCI1_TRANSMIT_IDLE BIT(4)
25 #define EVENT_CMUX_DLCI2_RECEIVE_READY BIT(5)
26 #define EVENT_CMUX_DLCI2_TRANSMIT_IDLE BIT(6)
27 #define EVENT_CMUX_DLCI1_CLOSED BIT(7)
28 #define EVENT_CMUX_DLCI2_CLOSED BIT(8)
29 #define EVENT_CMUX_DISCONNECTED BIT(9)
30 #define CMUX_BASIC_HRD_SMALL_SIZE 6
31 #define CMUX_BASIC_HRD_LARGE_SIZE 7
32 #define TRANSMISSION_DELAY_MS 10
33
34 /*************************************************************************************************/
35 /* Instances */
36 /*************************************************************************************************/
37 static struct modem_cmux cmux;
38 static uint8_t cmux_receive_buf[127];
39 static uint8_t cmux_transmit_buf[149];
40 static struct modem_cmux_dlci dlci1;
41 static struct modem_cmux_dlci dlci2;
42 static struct modem_pipe *dlci1_pipe;
43 static struct modem_pipe *dlci2_pipe;
44
45 static struct k_event cmux_event;
46
47 static struct modem_backend_mock bus_mock;
48 static uint8_t bus_mock_rx_buf[4096];
49 static uint8_t bus_mock_tx_buf[4096];
50 static struct modem_pipe *bus_mock_pipe;
51
52 static uint8_t dlci1_receive_buf[127];
53 static uint8_t dlci2_receive_buf[127];
54
55 static uint8_t buffer1[4096];
56 static uint8_t buffer2[4096];
57
58 /*************************************************************************************************/
59 /* Callbacks */
60 /*************************************************************************************************/
test_modem_dlci1_pipe_callback(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)61 static void test_modem_dlci1_pipe_callback(struct modem_pipe *pipe, enum modem_pipe_event event,
62 void *user_data)
63 {
64 switch (event) {
65 case MODEM_PIPE_EVENT_OPENED:
66 k_event_post(&cmux_event, EVENT_CMUX_DLCI1_OPEN);
67 break;
68
69 case MODEM_PIPE_EVENT_RECEIVE_READY:
70 k_event_post(&cmux_event, EVENT_CMUX_DLCI1_RECEIVE_READY);
71 break;
72
73 case MODEM_PIPE_EVENT_TRANSMIT_IDLE:
74 k_event_post(&cmux_event, EVENT_CMUX_DLCI1_TRANSMIT_IDLE);
75 break;
76
77 case MODEM_PIPE_EVENT_CLOSED:
78 k_event_post(&cmux_event, EVENT_CMUX_DLCI1_CLOSED);
79 break;
80
81 default:
82 break;
83 }
84 }
85
test_modem_dlci2_pipe_callback(struct modem_pipe * pipe,enum modem_pipe_event event,void * user_data)86 static void test_modem_dlci2_pipe_callback(struct modem_pipe *pipe, enum modem_pipe_event event,
87 void *user_data)
88 {
89 switch (event) {
90 case MODEM_PIPE_EVENT_OPENED:
91 k_event_post(&cmux_event, EVENT_CMUX_DLCI2_OPEN);
92 break;
93
94 case MODEM_PIPE_EVENT_RECEIVE_READY:
95 k_event_post(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY);
96 break;
97
98 case MODEM_PIPE_EVENT_TRANSMIT_IDLE:
99 k_event_post(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE);
100 break;
101
102 case MODEM_PIPE_EVENT_CLOSED:
103 k_event_post(&cmux_event, EVENT_CMUX_DLCI2_CLOSED);
104 break;
105
106 default:
107 break;
108 }
109 }
110
111 /*************************************************************************************************/
112 /* CMUX frames */
113 /*************************************************************************************************/
114 static uint8_t cmux_frame_control_sabm_cmd[] = {0xF9, 0x03, 0x3F, 0x01, 0x1C, 0xF9};
115 static uint8_t cmux_frame_control_sabm_ack[] = {0xF9, 0x03, 0x73, 0x01, 0xD7, 0xF9};
116 static uint8_t cmux_frame_control_cld_cmd[] = {0xF9, 0x03, 0xEF, 0x05, 0xC3, 0x01, 0xF2, 0xF9};
117 static uint8_t cmux_frame_control_cld_ack[] = {0xF9, 0x03, 0xEF, 0x05, 0xC1, 0x01, 0xF2, 0xF9};
118 static uint8_t cmux_frame_dlci1_sabm_cmd[] = {0xF9, 0x07, 0x3F, 0x01, 0xDE, 0xF9};
119 static uint8_t cmux_frame_dlci1_sabm_ack[] = {0xF9, 0x07, 0x73, 0x01, 0x15, 0xF9};
120 static uint8_t cmux_frame_dlci1_disc_cmd[] = {0xF9, 0x07, 0x53, 0x01, 0x3F, 0xF9};
121 static uint8_t cmux_frame_dlci1_msc_cmd[] = {0xF9, 0x03, 0xEF, 0x09, 0xE3,
122 0x05, 0x07, 0x8D, 0xFB, 0xF9};
123 static uint8_t cmux_frame_dlci1_ua_ack[] = {0xF9, 0x07, 0x73, 0x01, 0x15, 0xF9};
124 static uint8_t cmux_frame_dlci2_sabm_cmd[] = {0xF9, 0x0B, 0x3F, 0x01, 0x59, 0xF9};
125 static uint8_t cmux_frame_dlci2_sabm_ack[] = {0xF9, 0x0B, 0x73, 0x01, 0x92, 0xF9};
126 static uint8_t cmux_frame_dlci2_disc_cmd[] = {0xF9, 0x0B, 0x53, 0x01, 0xB8, 0xF9};
127 static uint8_t cmux_frame_dlci2_msc_cmd[] = {0xF9, 0x03, 0xEF, 0x09, 0xE3,
128 0x05, 0x0B, 0x8D, 0xFB, 0xF9};
129 static uint8_t cmux_frame_dlci2_msc_ack[] = {0xF9, 0x03, 0xEF, 0x09, 0xE1,
130 0x05, 0x0B, 0x8D, 0xFB, 0xF9};
131 static uint8_t cmux_frame_dlci2_msc_fcon_cmd[] = {0xF9, 0x03, 0xEF, 0x09, 0xE3,
132 0x05, 0x0B, 0x8F, 0xFB, 0xF9};
133 static uint8_t cmux_frame_dlci2_msc_fcon_ack[] = {0xF9, 0x03, 0xEF, 0x09, 0xE1,
134 0x05, 0x0B, 0x8F, 0xFB, 0xF9};
135 static uint8_t cmux_frame_dlci2_ua_ack[] = {0xF9, 0x0B, 0x73, 0x01, 0x92, 0xF9};
136 static uint8_t cmux_frame_control_msc_cmd[] = {0xF9, 0x01, 0xEF, 0x09, 0xE3,
137 0x05, 0x07, 0x01, 0x9A, 0xF9};
138 static uint8_t cmux_frame_control_msc_ack[] = {0xF9, 0x01, 0xEF, 0x09, 0xE1,
139 0x05, 0x07, 0x01, 0x9A, 0xF9};
140 static uint8_t cmux_frame_control_fcon_cmd[] = {0xF9, 0x01, 0xFF, 0x05, 0xA3, 0x01, 0x86, 0xF9};
141 static uint8_t cmux_frame_control_fcon_ack[] = {0xF9, 0x01, 0xFF, 0x05, 0xA1, 0x01, 0x86, 0xF9};
142 static uint8_t cmux_frame_control_fcoff_cmd[] = {0xF9, 0x01, 0xFF, 0x05, 0x63, 0x01, 0x86, 0xF9};
143 static uint8_t cmux_frame_control_fcoff_ack[] = {0xF9, 0x01, 0xFF, 0x05, 0x61, 0x01, 0x86, 0xF9};
144
145 /*************************************************************************************************/
146 /* DLCI2 AT CMUX frames */
147 /*************************************************************************************************/
148 static uint8_t cmux_frame_dlci2_at_cgdcont[] = {
149 0xF9, 0x0B, 0xEF, 0x43, 0x41, 0x54, 0x2B, 0x43, 0x47, 0x44, 0x43, 0x4F, 0x4E,
150 0x54, 0x3D, 0x31, 0x2C, 0x22, 0x49, 0x50, 0x22, 0x2C, 0x22, 0x74, 0x72, 0x61,
151 0x63, 0x6B, 0x75, 0x6E, 0x69, 0x74, 0x2E, 0x6D, 0x32, 0x6D, 0x22, 0x23, 0xF9};
152
153 static uint8_t cmux_frame_data_dlci2_at_cgdcont[] = {
154 0x41, 0x54, 0x2B, 0x43, 0x47, 0x44, 0x43, 0x4F, 0x4E, 0x54, 0x3D,
155 0x31, 0x2C, 0x22, 0x49, 0x50, 0x22, 0x2C, 0x22, 0x74, 0x72, 0x61,
156 0x63, 0x6B, 0x75, 0x6E, 0x69, 0x74, 0x2E, 0x6D, 0x32, 0x6D, 0x22};
157
158 static uint8_t cmux_frame_dlci2_at_newline[] = {0xF9, 0x0B, 0xEF, 0x05, 0x0D, 0x0A, 0xB7, 0xF9};
159
160 static uint8_t cmux_frame_data_dlci2_at_newline[] = {0x0D, 0x0A};
161
162 /*************************************************************************************************/
163 /* DLCI2 AT CMUX error frames */
164 /*************************************************************************************************/
165 static uint8_t cmux_frame_dlci2_at_cgdcont_invalid_length[] = {
166 0xF9, 0x0B, 0xEF, 0xFE, 0x41, 0x54, 0x2B, 0x43, 0x47, 0x44, 0x43, 0x4F, 0x4E,
167 0x54, 0x3D, 0x31, 0x2C, 0x22, 0x49, 0x50, 0x22, 0x2C, 0x22, 0x74, 0x72, 0x61,
168 0x63, 0x6B, 0x75, 0x6E, 0x69, 0x74, 0x2E, 0x6D, 0x32, 0x6D, 0x22, 0x23, 0xF9};
169
170 /*************************************************************************************************/
171 /* DLCI1 AT CMUX frames */
172 /*************************************************************************************************/
173 static uint8_t cmux_frame_dlci1_at_at[] = {0xF9, 0x07, 0xEF, 0x05, 0x41, 0x54, 0x30, 0xF9};
174
175 static uint8_t cmux_frame_data_dlci1_at_at[] = {0x41, 0x54};
176
177 static uint8_t cmux_frame_dlci1_at_newline[] = {0xF9, 0x07, 0xEF, 0x05, 0x0D, 0x0A, 0x30, 0xF9};
178
179 static uint8_t cmux_frame_data_dlci1_at_newline[] = {0x0D, 0x0A};
180
181 /*************************************************************************************************/
182 /* DLCI1 AT CMUX Desync frames */
183 /*************************************************************************************************/
184 static uint8_t cmux_frame_dlci1_at_at_desync[] = {0x41, 0x54, 0x30, 0xF9};
185
186 /*************************************************************************************************/
187 /* DLCI2 PPP CMUX frames */
188 /*************************************************************************************************/
189 static uint8_t cmux_frame_dlci2_ppp_52[] = {
190 0xF9, 0x0B, 0xEF, 0x69, 0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21, 0x7D, 0x21, 0x7D, 0x20, 0x7D,
191 0x20, 0x7D, 0x38, 0x7D, 0x22, 0x7D, 0x26, 0x7D, 0x20, 0x7D, 0x20, 0x7D, 0x20, 0x7D, 0x20,
192 0x7D, 0x23, 0x7D, 0x24, 0xC0, 0x23, 0x7D, 0x25, 0x7D, 0x26, 0x53, 0x96, 0x7D, 0x38, 0xAA,
193 0x7D, 0x27, 0x7D, 0x22, 0x7D, 0x28, 0x7D, 0x22, 0xD5, 0xA8, 0x7E, 0xF6, 0xF9};
194
195 static uint8_t cmux_frame_data_dlci2_ppp_52[] = {
196 0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21, 0x7D, 0x21, 0x7D, 0x20, 0x7D, 0x20, 0x7D,
197 0x38, 0x7D, 0x22, 0x7D, 0x26, 0x7D, 0x20, 0x7D, 0x20, 0x7D, 0x20, 0x7D, 0x20,
198 0x7D, 0x23, 0x7D, 0x24, 0xC0, 0x23, 0x7D, 0x25, 0x7D, 0x26, 0x53, 0x96, 0x7D,
199 0x38, 0xAA, 0x7D, 0x27, 0x7D, 0x22, 0x7D, 0x28, 0x7D, 0x22, 0xD5, 0xA8, 0x7E};
200
201 static uint8_t cmux_frame_dlci2_ppp_18[] = {0xF9, 0x0B, 0xEF, 0x25, 0x7E, 0xFF, 0x7D, 0x23,
202 0xC0, 0x21, 0x7D, 0x22, 0x7D, 0x21, 0x7D, 0x20,
203 0x7D, 0x24, 0x7D, 0x3C, 0x90, 0x7E, 0x8F, 0xF9};
204
205 static uint8_t cmux_frame_data_dlci2_ppp_18[] = {0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21,
206 0x7D, 0x22, 0x7D, 0x21, 0x7D, 0x20,
207 0x7D, 0x24, 0x7D, 0x3C, 0x90, 0x7E};
208
209 static uint8_t cmux_frame_data_large[127] = { [0 ... 126] = 0xAA };
210
211 const static struct modem_backend_mock_transaction transaction_control_cld = {
212 .get = cmux_frame_control_cld_cmd,
213 .get_size = sizeof(cmux_frame_control_cld_cmd),
214 .put = cmux_frame_control_cld_ack,
215 .put_size = sizeof(cmux_frame_control_cld_ack)
216 };
217
218 const static struct modem_backend_mock_transaction transaction_control_sabm = {
219 .get = cmux_frame_control_sabm_cmd,
220 .get_size = sizeof(cmux_frame_control_sabm_cmd),
221 .put = cmux_frame_control_sabm_ack,
222 .put_size = sizeof(cmux_frame_control_sabm_ack)
223 };
224
225 const static struct modem_backend_mock_transaction transaction_dlci1_disc = {
226 .get = cmux_frame_dlci1_disc_cmd,
227 .get_size = sizeof(cmux_frame_dlci1_disc_cmd),
228 .put = cmux_frame_dlci1_ua_ack,
229 .put_size = sizeof(cmux_frame_dlci1_ua_ack)
230 };
231
232 const static struct modem_backend_mock_transaction transaction_dlci2_disc = {
233 .get = cmux_frame_dlci2_disc_cmd,
234 .get_size = sizeof(cmux_frame_dlci2_disc_cmd),
235 .put = cmux_frame_dlci2_ua_ack,
236 .put_size = sizeof(cmux_frame_dlci2_ua_ack)
237 };
238
239 const static struct modem_backend_mock_transaction transaction_dlci1_msc = {
240 .get = cmux_frame_dlci1_msc_cmd,
241 .get_size = sizeof(cmux_frame_dlci1_msc_cmd),
242 .put = NULL,
243 .put_size = 0};
244
245 const static struct modem_backend_mock_transaction transaction_dlci2_msc = {
246 .get = cmux_frame_dlci2_msc_cmd,
247 .get_size = sizeof(cmux_frame_dlci2_msc_cmd),
248 .put = cmux_frame_dlci2_msc_ack,
249 .put_size = sizeof(cmux_frame_dlci2_msc_ack)};
250
251 const static struct modem_backend_mock_transaction transaction_dlci1_sabm = {
252 .get = cmux_frame_dlci1_sabm_cmd,
253 .get_size = sizeof(cmux_frame_dlci1_sabm_cmd),
254 .put = cmux_frame_dlci1_ua_ack,
255 .put_size = sizeof(cmux_frame_dlci1_ua_ack),
256 .next = &transaction_dlci1_msc};
257
258 const static struct modem_backend_mock_transaction transaction_dlci2_sabm = {
259 .get = cmux_frame_dlci2_sabm_cmd,
260 .get_size = sizeof(cmux_frame_dlci2_sabm_cmd),
261 .put = cmux_frame_dlci2_ua_ack,
262 .put_size = sizeof(cmux_frame_dlci2_ua_ack),
263 .next = &transaction_dlci2_msc};
264
265 const static struct modem_backend_mock_transaction transaction_dlci2_ppp_with_msc = {
266 .get = cmux_frame_dlci2_msc_fcon_cmd,
267 .get_size = sizeof(cmux_frame_dlci2_msc_fcon_cmd),
268 .put = cmux_frame_dlci2_msc_fcon_ack,
269 .put_size = sizeof(cmux_frame_dlci2_msc_fcon_ack),
270 .next = &transaction_dlci2_msc};
271
test_modem_cmux_callback(struct modem_cmux * cmux,enum modem_cmux_event event,void * user_data)272 static void test_modem_cmux_callback(struct modem_cmux *cmux, enum modem_cmux_event event,
273 void *user_data)
274 {
275 if (event == MODEM_CMUX_EVENT_CONNECTED) {
276 k_event_post(&cmux_event, EVENT_CMUX_CONNECTED);
277 return;
278 }
279
280 if (event == MODEM_CMUX_EVENT_DISCONNECTED) {
281 k_event_post(&cmux_event, EVENT_CMUX_DISCONNECTED);
282 return;
283 }
284 }
285
test_modem_cmux_setup(void)286 static void *test_modem_cmux_setup(void)
287 {
288 uint32_t events;
289
290 struct modem_cmux_dlci_config dlci1_config = {
291 .dlci_address = 1,
292 .receive_buf = dlci1_receive_buf,
293 .receive_buf_size = sizeof(dlci1_receive_buf),
294 };
295
296 struct modem_cmux_dlci_config dlci2_config = {
297 .dlci_address = 2,
298 .receive_buf = dlci2_receive_buf,
299 .receive_buf_size = sizeof(dlci2_receive_buf),
300 };
301
302 k_event_init(&cmux_event);
303
304 struct modem_cmux_config cmux_config = {
305 .callback = test_modem_cmux_callback,
306 .user_data = NULL,
307 .receive_buf = cmux_receive_buf,
308 .receive_buf_size = sizeof(cmux_receive_buf),
309 .transmit_buf = cmux_transmit_buf,
310 .transmit_buf_size = ARRAY_SIZE(cmux_transmit_buf),
311 };
312
313 modem_cmux_init(&cmux, &cmux_config);
314 dlci1_pipe = modem_cmux_dlci_init(&cmux, &dlci1, &dlci1_config);
315 dlci2_pipe = modem_cmux_dlci_init(&cmux, &dlci2, &dlci2_config);
316
317 const struct modem_backend_mock_config bus_mock_config = {
318 .rx_buf = bus_mock_rx_buf,
319 .rx_buf_size = sizeof(bus_mock_rx_buf),
320 .tx_buf = bus_mock_tx_buf,
321 .tx_buf_size = sizeof(bus_mock_tx_buf),
322 .limit = 32,
323 };
324
325 bus_mock_pipe = modem_backend_mock_init(&bus_mock, &bus_mock_config);
326 __ASSERT_NO_MSG(modem_pipe_open(bus_mock_pipe, K_SECONDS(10)) == 0);
327
328 /* Connect CMUX */
329 __ASSERT_NO_MSG(modem_cmux_attach(&cmux, bus_mock_pipe) == 0);
330 modem_backend_mock_prime(&bus_mock, &transaction_control_sabm);
331 __ASSERT_NO_MSG(modem_cmux_connect_async(&cmux) == 0);
332 events = k_event_wait(&cmux_event, EVENT_CMUX_CONNECTED, false, K_MSEC(100));
333 __ASSERT_NO_MSG(events == EVENT_CMUX_CONNECTED);
334
335 /* Open DLCI channels */
336 modem_pipe_attach(dlci1_pipe, test_modem_dlci1_pipe_callback, NULL);
337 modem_backend_mock_prime(&bus_mock, &transaction_dlci1_sabm);
338 __ASSERT_NO_MSG(modem_pipe_open_async(dlci1_pipe) == 0);
339 events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI1_OPEN, false, K_MSEC(100));
340 __ASSERT_NO_MSG((events & EVENT_CMUX_DLCI1_OPEN));
341
342 modem_pipe_attach(dlci2_pipe, test_modem_dlci2_pipe_callback, NULL);
343 modem_backend_mock_prime(&bus_mock, &transaction_dlci2_sabm);
344 __ASSERT_NO_MSG(modem_pipe_open_async(dlci2_pipe) == 0);
345 events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI2_OPEN, false, K_MSEC(100));
346 __ASSERT_NO_MSG((events & EVENT_CMUX_DLCI2_OPEN));
347
348 /* Consume the MSC command sent after DLCI opening */
349 modem_backend_mock_wait_for_transaction(&bus_mock);
350
351 return NULL;
352 }
353
test_modem_cmux_before(void * f)354 static void test_modem_cmux_before(void *f)
355 {
356 /* Reset events */
357 k_event_clear(&cmux_event, UINT32_MAX);
358
359 /* Reset mock pipes */
360 modem_backend_mock_reset(&bus_mock);
361 cmux.state = MODEM_CMUX_STATE_CONNECTED;
362 k_event_set(&cmux.event, BIT(cmux.state));
363 }
364
ZTEST(modem_cmux,test_modem_cmux_receive_dlci2_at)365 ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_at)
366 {
367 int ret;
368 uint32_t events;
369
370 modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_cgdcont,
371 sizeof(cmux_frame_dlci2_at_cgdcont));
372
373 modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_newline,
374 sizeof(cmux_frame_dlci2_at_newline));
375
376 k_msleep(TRANSMISSION_DELAY_MS);
377
378 events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY);
379 zassert_equal(events, EVENT_CMUX_DLCI2_RECEIVE_READY,
380 "Receive ready event not received for DLCI2 pipe");
381
382 ret = modem_pipe_receive(dlci2_pipe, buffer2, sizeof(buffer2));
383 zassert_true(ret == (sizeof(cmux_frame_data_dlci2_at_cgdcont) +
384 sizeof(cmux_frame_data_dlci2_at_newline)),
385 "Incorrect number of bytes received");
386
387 zassert_true(memcmp(buffer2, cmux_frame_data_dlci2_at_cgdcont,
388 sizeof(cmux_frame_data_dlci2_at_cgdcont)) == 0,
389 "Incorrect data received");
390
391 zassert_true(memcmp(&buffer2[sizeof(cmux_frame_data_dlci2_at_cgdcont)],
392 cmux_frame_data_dlci2_at_newline,
393 sizeof(cmux_frame_data_dlci2_at_newline)) == 0,
394 "Incorrect data received");
395 }
396
ZTEST(modem_cmux,test_modem_cmux_receive_dlci1_at)397 ZTEST(modem_cmux, test_modem_cmux_receive_dlci1_at)
398 {
399 int ret;
400 uint32_t events;
401
402 modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_at, sizeof(cmux_frame_dlci1_at_at));
403 modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_newline,
404 sizeof(cmux_frame_dlci1_at_newline));
405
406 k_msleep(TRANSMISSION_DELAY_MS);
407
408 events = k_event_test(&cmux_event, EVENT_CMUX_DLCI1_RECEIVE_READY);
409 zassert_equal(events, EVENT_CMUX_DLCI1_RECEIVE_READY,
410 "Receive ready event not received for DLCI1 pipe");
411
412 ret = modem_pipe_receive(dlci1_pipe, buffer1, sizeof(buffer1));
413 zassert_true(ret == (sizeof(cmux_frame_data_dlci1_at_at) +
414 sizeof(cmux_frame_data_dlci1_at_newline)),
415 "Incorrect number of bytes received");
416
417 zassert_true(memcmp(buffer1, cmux_frame_data_dlci1_at_at,
418 sizeof(cmux_frame_data_dlci1_at_at)) == 0,
419 "Incorrect data received");
420
421 zassert_true(memcmp(&buffer1[sizeof(cmux_frame_data_dlci1_at_at)],
422 cmux_frame_data_dlci1_at_newline,
423 sizeof(cmux_frame_data_dlci1_at_newline)) == 0,
424 "Incorrect data received");
425 }
426
ZTEST(modem_cmux,test_modem_cmux_receive_dlci2_ppp)427 ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_ppp)
428 {
429 int ret;
430 uint32_t events;
431
432 /* Expect MSC command with FC bit on as we push 70 bytes into buffer of 127 and
433 * threshold is set to 65 bytes
434 */
435 modem_backend_mock_prime(&bus_mock, &transaction_dlci2_ppp_with_msc);
436 modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_ppp_52, sizeof(cmux_frame_dlci2_ppp_52));
437 modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_ppp_18, sizeof(cmux_frame_dlci2_ppp_18));
438 k_msleep(TRANSMISSION_DELAY_MS);
439
440 events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY);
441 zassert_equal(events, EVENT_CMUX_DLCI2_RECEIVE_READY,
442 "Receive ready event not received for DLCI2 pipe");
443
444 ret = modem_pipe_receive(dlci2_pipe, buffer2, sizeof(buffer2));
445 zassert_true(ret == (sizeof(cmux_frame_data_dlci2_ppp_52) +
446 sizeof(cmux_frame_data_dlci2_ppp_18)),
447 "Incorrect number of bytes received");
448
449 zassert_true(memcmp(buffer2, cmux_frame_data_dlci2_ppp_52,
450 sizeof(cmux_frame_data_dlci2_ppp_52)) == 0,
451 "Incorrect data received");
452
453 zassert_true(memcmp(&buffer2[sizeof(cmux_frame_data_dlci2_ppp_52)],
454 cmux_frame_data_dlci2_ppp_18,
455 sizeof(cmux_frame_data_dlci2_ppp_18)) == 0,
456 "Incorrect data received");
457
458 modem_backend_mock_wait_for_transaction(&bus_mock);
459 }
460
ZTEST(modem_cmux,test_modem_cmux_transmit_dlci2_ppp)461 ZTEST(modem_cmux, test_modem_cmux_transmit_dlci2_ppp)
462 {
463 int ret;
464 uint32_t events;
465
466 ret = modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_ppp_52,
467 sizeof(cmux_frame_data_dlci2_ppp_52));
468 zassert_true(ret == sizeof(cmux_frame_data_dlci2_ppp_52), "Failed to send DLCI2 PPP 52");
469
470 events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE, false, K_MSEC(200));
471 zassert_equal(events, EVENT_CMUX_DLCI2_TRANSMIT_IDLE,
472 "Transmit idle event not received for DLCI2 pipe");
473
474 k_event_clear(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE);
475
476 ret = modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_ppp_18,
477 sizeof(cmux_frame_data_dlci2_ppp_18));
478 zassert_true(ret == sizeof(cmux_frame_data_dlci2_ppp_18), "Failed to send DLCI2 PPP 18");
479
480 events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE, false, K_MSEC(200));
481 zassert_equal(events, EVENT_CMUX_DLCI2_TRANSMIT_IDLE,
482 "Transmit idle event not received for DLCI2 pipe");
483
484 ret = modem_backend_mock_get(&bus_mock, buffer2, sizeof(buffer2));
485 zassert_true(ret == (sizeof(cmux_frame_dlci2_ppp_52) + sizeof(cmux_frame_dlci2_ppp_18)),
486 "Incorrect number of bytes transmitted");
487 }
488
ZTEST(modem_cmux,test_modem_cmux_resync)489 ZTEST(modem_cmux, test_modem_cmux_resync)
490 {
491 int ret;
492
493 modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_at_desync,
494 sizeof(cmux_frame_dlci1_at_at_desync));
495 modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_at, sizeof(cmux_frame_dlci1_at_at));
496 modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_newline,
497 sizeof(cmux_frame_dlci1_at_newline));
498
499 k_msleep(TRANSMISSION_DELAY_MS);
500
501 ret = modem_pipe_receive(dlci1_pipe, buffer1, sizeof(buffer1));
502
503 zassert_true(ret == (sizeof(cmux_frame_data_dlci1_at_at) +
504 sizeof(cmux_frame_data_dlci1_at_newline)),
505 "Incorrect number of bytes received");
506
507 zassert_true(memcmp(buffer1, cmux_frame_data_dlci1_at_at,
508 sizeof(cmux_frame_data_dlci1_at_at)) == 0,
509 "Incorrect data received");
510
511 zassert_true(memcmp(&buffer1[sizeof(cmux_frame_data_dlci1_at_at)],
512 cmux_frame_data_dlci1_at_newline,
513 sizeof(cmux_frame_data_dlci1_at_newline)) == 0,
514 "Incorrect data received");
515 }
516
ZTEST(modem_cmux,test_modem_cmux_flow_control_dlci2)517 ZTEST(modem_cmux, test_modem_cmux_flow_control_dlci2)
518 {
519 int ret;
520
521 modem_backend_mock_put(&bus_mock, cmux_frame_control_fcoff_cmd,
522 sizeof(cmux_frame_control_fcoff_cmd));
523
524 k_msleep(TRANSMISSION_DELAY_MS);
525
526 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
527 zassert_true(ret == sizeof(cmux_frame_control_fcoff_ack),
528 "Incorrect number of bytes received");
529
530 zassert_true(memcmp(buffer1, cmux_frame_control_fcoff_ack,
531 sizeof(cmux_frame_control_fcoff_ack)) == 0,
532 "Incorrect data received");
533
534 ret = modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_ppp_52,
535 sizeof(cmux_frame_data_dlci2_ppp_52));
536
537 zassert_true(ret == 0, "Failed to block transmit while flow control is off");
538
539 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
540 zassert_true(ret == 0, "FCOFF failed to prevent transmission of data");
541 modem_backend_mock_put(&bus_mock, cmux_frame_control_fcon_cmd,
542 sizeof(cmux_frame_control_fcon_cmd));
543
544 k_msleep(TRANSMISSION_DELAY_MS);
545
546 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
547 zassert_true(ret == sizeof(cmux_frame_control_fcon_ack),
548 "Incorrect number of bytes received");
549
550 zassert_true(memcmp(buffer1, cmux_frame_control_fcon_ack,
551 sizeof(cmux_frame_control_fcon_ack)) == 0,
552 "Incorrect data received");
553
554 ret = modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_ppp_52,
555 sizeof(cmux_frame_data_dlci2_ppp_52));
556
557 zassert_true(ret == sizeof(cmux_frame_data_dlci2_ppp_52),
558 "Transmit failed after flow control is enabled");
559
560 k_msleep(TRANSMISSION_DELAY_MS);
561
562 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
563 zassert_true(ret == sizeof(cmux_frame_dlci2_ppp_52),
564 "Transmit failed after flow control is enabled");
565
566 zassert_true(memcmp(buffer1, cmux_frame_dlci2_ppp_52,
567 sizeof(cmux_frame_dlci2_ppp_52)) == 0,
568 "Incorrect data received");
569 }
570
ZTEST(modem_cmux,test_modem_cmux_msc_cmd_ack)571 ZTEST(modem_cmux, test_modem_cmux_msc_cmd_ack)
572 {
573 int ret;
574
575 modem_backend_mock_put(&bus_mock, cmux_frame_control_msc_cmd,
576 sizeof(cmux_frame_control_msc_cmd));
577
578 k_msleep(TRANSMISSION_DELAY_MS);
579
580 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
581 zassert_true(ret == sizeof(cmux_frame_control_msc_ack),
582 "Incorrect number of bytes received");
583
584 zassert_true(memcmp(buffer1, cmux_frame_control_msc_ack,
585 sizeof(cmux_frame_control_msc_ack)) == 0,
586 "Incorrect MSC ACK received");
587 }
588
ZTEST(modem_cmux,test_modem_cmux_dlci1_close_open)589 ZTEST(modem_cmux, test_modem_cmux_dlci1_close_open)
590 {
591 int ret;
592 uint32_t events;
593
594 /* Close DLCI1 */
595 zassert_true(modem_pipe_close_async(dlci1_pipe) == 0, "Failed to close DLCI1 pipe");
596
597 k_msleep(TRANSMISSION_DELAY_MS);
598
599 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
600 zassert_true(ret == sizeof(cmux_frame_dlci1_disc_cmd),
601 "Incorrect number of bytes received for DLCI1 close cmd");
602
603 zassert_true(memcmp(buffer1, cmux_frame_dlci1_disc_cmd,
604 sizeof(cmux_frame_dlci1_disc_cmd)) == 0,
605 "Incorrect DLCI1 close cmd received");
606
607 modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_ua_ack,
608 sizeof(cmux_frame_dlci1_ua_ack));
609
610 events = k_event_wait_all(&cmux_event, (EVENT_CMUX_DLCI1_CLOSED),
611 false, K_MSEC(100));
612
613 zassert_true((events & EVENT_CMUX_DLCI1_CLOSED),
614 "DLCI1 not closed as expected");
615
616 /* Wait for potential T2 timeout */
617 k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS);
618
619 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
620 zassert_true(ret == 0, "Received unexpected data");
621
622 /* Open DLCI1 */
623 zassert_true(modem_pipe_open_async(dlci1_pipe) == 0, "Failed to open DLCI1 pipe");
624
625 k_msleep(TRANSMISSION_DELAY_MS);
626
627 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
628 zassert_true(ret == sizeof(cmux_frame_dlci1_sabm_cmd),
629 "Incorrect number of bytes received for DLCI1 open cmd");
630
631 zassert_true(memcmp(buffer1, cmux_frame_dlci1_sabm_cmd,
632 sizeof(cmux_frame_dlci1_sabm_cmd)) == 0,
633 "Incorrect DLCI1 open cmd received");
634
635 modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_sabm_ack,
636 sizeof(cmux_frame_dlci1_sabm_ack));
637
638 events = k_event_wait_all(&cmux_event, (EVENT_CMUX_DLCI1_OPEN),
639 false, K_MSEC(100));
640
641 zassert_true((events & EVENT_CMUX_DLCI1_OPEN),
642 "DLCI1 not opened as expected");
643
644 modem_backend_mock_prime(&bus_mock, &transaction_dlci1_msc);
645 modem_backend_mock_wait_for_transaction(&bus_mock);
646
647 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
648 zassert_true(ret == 0, "Received unexpected data");
649 }
650
ZTEST(modem_cmux,test_modem_cmux_disconnect_connect)651 ZTEST(modem_cmux, test_modem_cmux_disconnect_connect)
652 {
653 uint32_t events;
654 int ret;
655
656 /* Disconnect CMUX */
657 zassert_true(modem_pipe_close_async(dlci1_pipe) == 0, "Failed to close DLCI1");
658 zassert_true(modem_pipe_close_async(dlci2_pipe) == 0, "Failed to close DLCI2");
659
660 modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_ua_ack,
661 sizeof(cmux_frame_dlci1_ua_ack));
662
663 modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_ua_ack,
664 sizeof(cmux_frame_dlci2_ua_ack));
665
666 events = k_event_wait_all(&cmux_event, (EVENT_CMUX_DLCI1_CLOSED | EVENT_CMUX_DLCI2_CLOSED),
667 false, K_MSEC(100));
668
669 zassert_true((events & EVENT_CMUX_DLCI1_CLOSED), "Failed to close DLCI1");
670 zassert_true((events & EVENT_CMUX_DLCI2_CLOSED), "Failed to close DLCI2");
671
672 /* Discard CMUX DLCI DISC commands */
673 modem_backend_mock_reset(&bus_mock);
674 zassert_true(modem_cmux_disconnect_async(&cmux) == 0, "Failed to disconnect CMUX");
675
676 k_msleep(TRANSMISSION_DELAY_MS);
677
678 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
679
680 zassert_true(ret == sizeof(cmux_frame_control_cld_cmd),
681 "Incorrect number of bytes received for CLD cmd");
682
683 zassert_true(memcmp(buffer1, cmux_frame_control_cld_cmd,
684 sizeof(cmux_frame_control_cld_cmd)) == 0,
685 "Incorrect DLC cmd received");
686
687 modem_backend_mock_put(&bus_mock, cmux_frame_control_cld_ack,
688 sizeof(cmux_frame_control_cld_ack));
689
690 events = k_event_wait_all(&cmux_event, (EVENT_CMUX_DISCONNECTED), false, K_MSEC(100));
691 zassert_true((events & EVENT_CMUX_DISCONNECTED), "Failed to disconnect CMUX");
692
693 /* Wait for potential T2 timeout */
694 k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS);
695
696 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
697 zassert_true(ret == 0, "Received unexpected data");
698
699 /* Reconnect CMUX */
700 zassert_true(modem_cmux_connect_async(&cmux) == 0, "Failed to connect CMUX");
701
702 k_msleep(TRANSMISSION_DELAY_MS);
703
704 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
705 zassert_true(ret == sizeof(cmux_frame_control_sabm_cmd),
706 "Incorrect number of bytes received for SABM cmd");
707
708 zassert_true(memcmp(buffer1, cmux_frame_control_sabm_cmd,
709 sizeof(cmux_frame_control_sabm_cmd)) == 0,
710 "Incorrect SABM cmd received");
711
712 modem_backend_mock_put(&bus_mock, cmux_frame_control_sabm_ack,
713 sizeof(cmux_frame_control_sabm_ack));
714
715 events = k_event_wait_all(&cmux_event, (EVENT_CMUX_CONNECTED), false, K_MSEC(100));
716 zassert_true((events & EVENT_CMUX_CONNECTED), "Failed to connect CMUX");
717
718 /* Wait for potential T2 timeout */
719 k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS);
720
721 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
722 zassert_true(ret == 0, "Received unexpected data");
723
724 /* Open DLCI1 */
725 zassert_true(modem_pipe_open_async(dlci1_pipe) == 0, "Failed to open DLCI1 pipe");
726
727 k_msleep(TRANSMISSION_DELAY_MS);
728
729 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
730 zassert_true(ret == sizeof(cmux_frame_dlci1_sabm_cmd),
731 "Incorrect number of bytes received for DLCI1 open cmd");
732
733 zassert_true(memcmp(buffer1, cmux_frame_dlci1_sabm_cmd,
734 sizeof(cmux_frame_dlci1_sabm_cmd)) == 0,
735 "Incorrect DLCI1 open cmd received");
736
737 modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_sabm_ack,
738 sizeof(cmux_frame_dlci1_sabm_ack));
739
740 events = k_event_wait_all(&cmux_event, (EVENT_CMUX_DLCI1_OPEN),
741 false, K_MSEC(100));
742
743 zassert_true((events & EVENT_CMUX_DLCI1_OPEN),
744 "DLCI1 not opened as expected");
745
746 modem_backend_mock_prime(&bus_mock, &transaction_dlci1_msc);
747 modem_backend_mock_wait_for_transaction(&bus_mock);
748
749 /* Wait for potential T2 timeout */
750 k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS);
751
752 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
753 zassert_true(ret == 0, "Received unexpected data");
754
755 /* Open DLCI2 */
756 zassert_true(modem_pipe_open_async(dlci2_pipe) == 0, "Failed to open DLCI2 pipe");
757
758 k_msleep(TRANSMISSION_DELAY_MS);
759
760 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
761 zassert_true(ret == sizeof(cmux_frame_dlci2_sabm_cmd),
762 "Incorrect number of bytes received for DLCI1 open cmd");
763
764 zassert_true(memcmp(buffer1, cmux_frame_dlci2_sabm_cmd,
765 sizeof(cmux_frame_dlci2_sabm_cmd)) == 0,
766 "Incorrect DLCI1 open cmd received");
767
768 modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_sabm_ack,
769 sizeof(cmux_frame_dlci2_sabm_ack));
770
771 events = k_event_wait_all(&cmux_event, (EVENT_CMUX_DLCI2_OPEN),
772 false, K_MSEC(100));
773
774 zassert_true((events & EVENT_CMUX_DLCI2_OPEN), "DLCI2 not opened as expected");
775
776 modem_backend_mock_prime(&bus_mock, &transaction_dlci2_msc);
777 modem_backend_mock_wait_for_transaction(&bus_mock);
778
779 /* Wait for potential T2 timeout */
780 k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS);
781
782 ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
783 zassert_true(ret == 0, "Received unexpected data");
784 }
785
ZTEST(modem_cmux,test_modem_cmux_disconnect_connect_sync)786 ZTEST(modem_cmux, test_modem_cmux_disconnect_connect_sync)
787 {
788 modem_backend_mock_prime(&bus_mock, &transaction_dlci1_disc);
789 zassert_true(modem_pipe_close(dlci1_pipe, K_SECONDS(10)) == 0, "Failed to close DLCI1");
790 modem_backend_mock_prime(&bus_mock, &transaction_dlci2_disc);
791 zassert_true(modem_pipe_close(dlci2_pipe, K_SECONDS(10)) == 0, "Failed to close DLCI2");
792
793 /* Clear any pending data before CLD transaction */
794 modem_backend_mock_reset(&bus_mock);
795
796 modem_backend_mock_prime(&bus_mock, &transaction_control_cld);
797 zassert_true(modem_cmux_disconnect(&cmux) == 0, "Failed to disconnect CMUX");
798 zassert_true(modem_cmux_disconnect(&cmux) == -EALREADY,
799 "Should already be disconnected");
800
801 modem_backend_mock_prime(&bus_mock, &transaction_control_sabm);
802 zassert_true(modem_cmux_connect(&cmux) == 0, "Failed to connect CMUX");
803 zassert_true(modem_cmux_connect(&cmux) == -EALREADY,
804 "Should already be connected");
805
806 modem_backend_mock_prime(&bus_mock, &transaction_dlci1_sabm);
807 zassert_true(modem_pipe_open(dlci1_pipe, K_SECONDS(10)) == 0,
808 "Failed to open DLCI1 pipe");
809 modem_backend_mock_wait_for_transaction(&bus_mock);
810 modem_backend_mock_prime(&bus_mock, &transaction_dlci2_sabm);
811 zassert_true(modem_pipe_open(dlci2_pipe, K_SECONDS(10)) == 0,
812 "Failed to open DLCI2 pipe");
813 modem_backend_mock_wait_for_transaction(&bus_mock);
814 }
815
ZTEST(modem_cmux,test_modem_cmux_dlci_close_open_sync)816 ZTEST(modem_cmux, test_modem_cmux_dlci_close_open_sync)
817 {
818 modem_backend_mock_prime(&bus_mock, &transaction_dlci1_disc);
819 zassert_true(modem_pipe_close(dlci1_pipe, K_SECONDS(10)) == 0, "Failed to close DLCI1");
820 modem_backend_mock_prime(&bus_mock, &transaction_dlci2_disc);
821 zassert_true(modem_pipe_close(dlci2_pipe, K_SECONDS(10)) == 0, "Failed to close DLCI2");
822 modem_backend_mock_prime(&bus_mock, &transaction_dlci1_sabm);
823 zassert_true(modem_pipe_open(dlci1_pipe, K_SECONDS(10)) == 0,
824 "Failed to open DLCI1 pipe");
825 modem_backend_mock_wait_for_transaction(&bus_mock);
826 modem_backend_mock_prime(&bus_mock, &transaction_dlci2_sabm);
827 zassert_true(modem_pipe_open(dlci2_pipe, K_SECONDS(10)) == 0,
828 "Failed to open DLCI2 pipe");
829 modem_backend_mock_wait_for_transaction(&bus_mock);
830 }
831
ZTEST(modem_cmux,test_modem_cmux_prevent_work_while_released)832 ZTEST(modem_cmux, test_modem_cmux_prevent_work_while_released)
833 {
834 const uint8_t transmit[2];
835 uint8_t receive[2];
836
837 /* Disconnect CMUX */
838 modem_backend_mock_prime(&bus_mock, &transaction_control_cld);
839 zassert_ok(modem_cmux_disconnect(&cmux));
840
841 /* Start work to connect CMUX and open DLCI channels */
842 zassert_ok(modem_cmux_connect_async(&cmux));
843 zassert_ok(modem_pipe_open_async(dlci1_pipe));
844 zassert_ok(modem_pipe_open_async(dlci2_pipe));
845
846 /* Wait for and validate CMUX is sending requests */
847 k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS);
848 zassert_true(modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)) > 0);
849
850 /* Release CMUX and validate no more requests are sent */
851 modem_cmux_release(&cmux);
852 modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1));
853 k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS);
854 zassert_true(modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)) == 0);
855
856 /* Validate no new requests can be submitted */
857 modem_cmux_connect(&cmux);
858 modem_cmux_disconnect(&cmux);
859 modem_pipe_open(dlci1_pipe, K_SECONDS(10));
860 modem_pipe_open(dlci2_pipe, K_SECONDS(10));
861 modem_pipe_transmit(dlci1_pipe, transmit, sizeof(transmit));
862 modem_pipe_transmit(dlci2_pipe, transmit, sizeof(transmit));
863 modem_pipe_receive(dlci1_pipe, receive, sizeof(receive));
864 modem_pipe_receive(dlci2_pipe, receive, sizeof(receive));
865 modem_pipe_close(dlci1_pipe, K_SECONDS(10));
866 modem_pipe_close(dlci2_pipe, K_SECONDS(10));
867 k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS);
868 zassert_true(modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)) == 0);
869
870 /* Restore CMUX */
871 zassert_ok(modem_cmux_attach(&cmux, bus_mock_pipe));
872 modem_backend_mock_prime(&bus_mock, &transaction_control_sabm);
873 zassert_ok(modem_cmux_connect(&cmux));
874 modem_backend_mock_wait_for_transaction(&bus_mock);
875 modem_backend_mock_prime(&bus_mock, &transaction_dlci1_sabm);
876 zassert_ok(modem_pipe_open(dlci1_pipe, K_SECONDS(10)));
877 modem_backend_mock_wait_for_transaction(&bus_mock);
878 modem_backend_mock_prime(&bus_mock, &transaction_dlci2_sabm);
879 zassert_ok(modem_pipe_open(dlci2_pipe, K_SECONDS(10)));
880 modem_backend_mock_wait_for_transaction(&bus_mock);
881 }
882
ZTEST(modem_cmux,test_modem_drop_frames_with_invalid_length)883 ZTEST(modem_cmux, test_modem_drop_frames_with_invalid_length)
884 {
885 int ret;
886 uint32_t events;
887
888 modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_cgdcont_invalid_length,
889 sizeof(cmux_frame_dlci2_at_cgdcont_invalid_length));
890
891 k_msleep(TRANSMISSION_DELAY_MS);
892
893 events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY);
894
895 zassert_false(events & EVENT_CMUX_DLCI2_RECEIVE_READY,
896 "Receive event should not have been received for DLCI2 pipe");
897
898 modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_cgdcont,
899 sizeof(cmux_frame_dlci2_at_cgdcont));
900
901 modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_newline,
902 sizeof(cmux_frame_dlci2_at_newline));
903
904 k_msleep(TRANSMISSION_DELAY_MS);
905
906 events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY);
907 zassert_equal(events, EVENT_CMUX_DLCI2_RECEIVE_READY,
908 "Receive ready event not received for DLCI2 pipe");
909
910 ret = modem_pipe_receive(dlci2_pipe, buffer2, sizeof(buffer2));
911 zassert_true(ret == (sizeof(cmux_frame_data_dlci2_at_cgdcont) +
912 sizeof(cmux_frame_data_dlci2_at_newline)),
913 "Incorrect number of bytes received");
914
915 zassert_true(memcmp(buffer2, cmux_frame_data_dlci2_at_cgdcont,
916 sizeof(cmux_frame_data_dlci2_at_cgdcont)) == 0,
917 "Incorrect data received");
918
919 zassert_true(memcmp(&buffer2[sizeof(cmux_frame_data_dlci2_at_cgdcont)],
920 cmux_frame_data_dlci2_at_newline,
921 sizeof(cmux_frame_data_dlci2_at_newline)) == 0,
922 "Incorrect data received");
923 }
924
ZTEST(modem_cmux,test_modem_cmux_split_large_data)925 ZTEST(modem_cmux, test_modem_cmux_split_large_data)
926 {
927 int ret;
928 uint32_t events;
929
930 ret = modem_pipe_transmit(dlci2_pipe, cmux_frame_data_large,
931 sizeof(cmux_frame_data_large));
932 zassert_true(ret == CONFIG_MODEM_CMUX_MTU, "Failed to split large data %d", ret);
933
934 events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE, false, K_MSEC(200));
935 zassert_equal(events, EVENT_CMUX_DLCI2_TRANSMIT_IDLE,
936 "Transmit idle event not received for DLCI2 pipe");
937
938 ret = modem_backend_mock_get(&bus_mock, buffer2, sizeof(buffer2));
939 zassert_true(ret == CONFIG_MODEM_CMUX_MTU + CMUX_BASIC_HRD_SMALL_SIZE,
940 "Incorrect number of bytes transmitted %d", ret);
941 }
942
ZTEST(modem_cmux,test_modem_cmux_invalid_cr)943 ZTEST(modem_cmux, test_modem_cmux_invalid_cr)
944 {
945 uint32_t events;
946
947 /* We are initiator, so any CMD with CR set should be dropped */
948 modem_backend_mock_put(&bus_mock, cmux_frame_control_cld_cmd,
949 sizeof(cmux_frame_control_cld_cmd));
950
951 modem_backend_mock_put(&bus_mock, cmux_frame_control_sabm_cmd,
952 sizeof(cmux_frame_control_sabm_cmd));
953
954 events = k_event_wait_all(&cmux_event,
955 (MODEM_CMUX_EVENT_CONNECTED | MODEM_CMUX_EVENT_DISCONNECTED),
956 false, K_MSEC(100));
957
958 zassert_false(events, "Wrong CMD should have been ignored");
959 }
960
ZTEST(modem_cmux,test_modem_cmux_invalid_command)961 ZTEST(modem_cmux, test_modem_cmux_invalid_command)
962 {
963 static uint8_t invalid_cmd[] = {0xF9, 0x03, 0xEF, 0x09, 0x00,
964 0x00, 0x00, 0x00, 0xFB, 0xF9};
965 uint32_t events;
966
967 modem_backend_mock_put(&bus_mock, invalid_cmd,
968 sizeof(invalid_cmd));
969
970 events = k_event_wait_all(&cmux_event,
971 (MODEM_CMUX_EVENT_CONNECTED | MODEM_CMUX_EVENT_DISCONNECTED),
972 false, K_SECONDS(1));
973
974 zassert_false(events, "Wrong CMD should have been ignored");
975
976 /* Invalid command should not cause any response */
977 zassert_equal(0, modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)));
978 }
979
980 ZTEST_SUITE(modem_cmux, NULL, test_modem_cmux_setup, test_modem_cmux_before, NULL, NULL);
981