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