1 /*
2  * Copyright (c) 2020 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(gsm_mux, CONFIG_GSM_MUX_LOG_LEVEL);
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/sys/util.h>
12 #include <zephyr/sys/crc.h>
13 #include <zephyr/net/buf.h>
14 #include <zephyr/net/ppp.h>
15 
16 #include "uart_mux_internal.h"
17 #include "gsm_mux.h"
18 
19 /* Default values are from the specification 07.10 */
20 #define T1_MSEC 100  /* 100 ms */
21 #define T2_MSEC 340  /* 333 ms */
22 
23 #define N1 256 /* default I frame size, GSM 07.10 ch 6.2.2.1 */
24 #define N2 3   /* retry 3 times */
25 
26 /* CRC8 is the reflected CRC8/ROHC algorithm */
27 #define FCS_POLYNOMIAL 0xe0 /* reversed crc8 */
28 #define FCS_INIT_VALUE 0xFF
29 #define FCS_GOOD_VALUE 0xCF
30 
31 #define GSM_EA 0x01  /* Extension bit      */
32 #define GSM_CR 0x02  /* Command / Response */
33 #define GSM_PF 0x10  /* Poll / Final       */
34 
35 /* Frame types */
36 #define FT_RR      0x01  /* Receive Ready                            */
37 #define FT_UI      0x03  /* Unnumbered Information                   */
38 #define FT_RNR     0x05  /* Receive Not Ready                        */
39 #define FT_REJ     0x09  /* Reject                                   */
40 #define FT_DM      0x0F  /* Disconnected Mode                        */
41 #define FT_SABM    0x2F  /* Set Asynchronous Balanced Mode           */
42 #define FT_DISC    0x43  /* Disconnect                               */
43 #define FT_UA      0x63  /* Unnumbered Acknowledgement               */
44 #define FT_UIH     0xEF  /* Unnumbered Information with Header check */
45 
46 /* Control channel commands */
47 #define CMD_NSC    0x08  /* Non Supported Command Response           */
48 #define CMD_TEST   0x10  /* Test Command                             */
49 #define CMD_PSC    0x20  /* Power Saving Control                     */
50 #define CMD_RLS    0x28  /* Remote Line Status Command               */
51 #define CMD_FCOFF  0x30  /* Flow Control Off Command                 */
52 #define CMD_PN     0x40  /* DLC parameter negotiation                */
53 #define CMD_RPN    0x48  /* Remote Port Negotiation Command          */
54 #define CMD_FCON   0x50  /* Flow Control On Command                  */
55 #define CMD_CLD    0x60  /* Multiplexer close down                   */
56 #define CMD_SNC    0x68  /* Service Negotiation Command              */
57 #define CMD_MSC    0x70  /* Modem Status Command                     */
58 
59 /* Flag sequence field between messages (start of frame) */
60 #define SOF_MARKER 0xF9
61 
62 /* Mux parsing states */
63 enum gsm_mux_state {
64 	GSM_MUX_SOF,      /* Start of frame       */
65 	GSM_MUX_ADDRESS,  /* Address field        */
66 	GSM_MUX_CONTROL,  /* Control field        */
67 	GSM_MUX_LEN_0,    /* First length byte    */
68 	GSM_MUX_LEN_1,    /* Second length byte   */
69 	GSM_MUX_DATA,     /* Data                 */
70 	GSM_MUX_FCS,      /* Frame Check Sequence */
71 	GSM_MUX_EOF       /* End of frame         */
72 };
73 
74 struct gsm_mux {
75 	/* UART device to use. This device is the real UART, not the
76 	 * muxed one.
77 	 */
78 	const struct device *uart;
79 
80 	/* Buf to use when TX mux packet (hdr + data). For RX it only contains
81 	 * the data (not hdr).
82 	 */
83 	struct net_buf *buf;
84 	int mru;
85 
86 	enum gsm_mux_state state;
87 
88 	/* Control DLCI is not included in this list so -1 here */
89 	uint8_t dlci_to_create[CONFIG_GSM_MUX_DLCI_MAX - 1];
90 
91 	uint16_t msg_len;     /* message length */
92 	uint16_t received;    /* bytes so far received */
93 
94 	struct k_work_delayable t2_timer;
95 	sys_slist_t pending_ctrls;
96 
97 	uint16_t t1_timeout_value; /* T1 default value */
98 	uint16_t t2_timeout_value; /* T2 default value */
99 
100 	/* Information from currently read packet */
101 	uint8_t address;      /* dlci address (only one byte address supported) */
102 	uint8_t control;      /* type of the frame */
103 	uint8_t fcs;          /* calculated frame check sequence */
104 	uint8_t received_fcs; /* packet fcs */
105 	uint8_t retries;      /* N2 counter */
106 
107 	bool in_use : 1;
108 	bool is_initiator : 1;   /* Did we initiate the connection attempt */
109 	bool refuse_service : 1; /* Do not try to talk to this modem */
110 };
111 
112 /* DLCI states */
113 enum gsm_dlci_state {
114 	GSM_DLCI_CLOSED,
115 	GSM_DLCI_OPENING,
116 	GSM_DLCI_OPEN,
117 	GSM_DLCI_CLOSING
118 };
119 
120 enum gsm_dlci_mode {
121 	GSM_DLCI_MODE_ABM = 0,  /* Normal Asynchronous Balanced Mode */
122 	GSM_DLCI_MODE_ADM = 1,  /* Asynchronous Disconnected Mode */
123 };
124 
125 typedef int (*dlci_process_msg_t)(struct gsm_dlci *dlci, bool cmd,
126 				  struct net_buf *buf);
127 typedef void (*dlci_command_cb_t)(struct gsm_dlci *dlci, bool connected);
128 
129 struct gsm_dlci {
130 	sys_snode_t node;
131 	struct k_sem disconnect_sem;
132 	struct gsm_mux *mux;
133 	dlci_process_msg_t handler;
134 	dlci_command_cb_t command_cb;
135 	gsm_mux_dlci_created_cb_t dlci_created_cb;
136 	void *user_data;
137 	const struct device *uart;
138 	enum gsm_dlci_state state;
139 	enum gsm_dlci_mode mode;
140 	int num;
141 	uint32_t req_start;
142 	uint8_t retries;
143 	bool refuse_service : 1; /* Do not try to talk to this channel */
144 	bool in_use : 1;
145 };
146 
147 struct gsm_control_msg {
148 	sys_snode_t node;
149 	struct net_buf *buf;
150 	uint32_t req_start;
151 	uint8_t cmd;
152 	bool finished : 1;
153 };
154 
155 /* From 07.10, Maximum Frame Size [1 - 128] in Basic mode */
156 #define MAX_MRU CONFIG_GSM_MUX_MRU_MAX_LEN
157 
158 /* Assume that there are 3 network buffers (one for RX and one for TX, and one
159  * extra when parsing data) going on at the same time.
160  */
161 #define MIN_BUF_COUNT (CONFIG_GSM_MUX_MAX * 3)
162 
163 NET_BUF_POOL_DEFINE(gsm_mux_pool, MIN_BUF_COUNT, MAX_MRU, 0, NULL);
164 
165 #define BUF_ALLOC_TIMEOUT K_MSEC(50)
166 
167 static struct gsm_mux muxes[CONFIG_GSM_MUX_MAX];
168 
169 static struct gsm_dlci dlcis[CONFIG_GSM_MUX_DLCI_MAX];
170 static sys_slist_t dlci_free_entries;
171 static sys_slist_t dlci_active_t1_timers;
172 static struct k_work_delayable t1_timer;
173 
174 static struct gsm_control_msg ctrls[CONFIG_GSM_MUX_PENDING_CMD_MAX];
175 static sys_slist_t ctrls_free_entries;
176 
177 static bool gsm_mux_init_done;
178 
get_frame_type_str(uint8_t frame_type)179 static const char *get_frame_type_str(uint8_t frame_type)
180 {
181 	switch (frame_type) {
182 	case FT_RR:
183 		return "RR";
184 	case FT_UI:
185 		return "UI";
186 	case FT_RNR:
187 		return "RNR";
188 	case FT_REJ:
189 		return "REJ";
190 	case FT_DM:
191 		return "DM";
192 	case FT_SABM:
193 		return "SABM";
194 	case FT_DISC:
195 		return "DISC";
196 	case FT_UA:
197 		return "UA";
198 	case FT_UIH:
199 		return "UIH";
200 	}
201 
202 	return NULL;
203 }
204 
hexdump_packet(const char * header,uint8_t address,bool cmd_rsp,uint8_t control,const uint8_t * data,size_t len)205 static void hexdump_packet(const char *header, uint8_t address, bool cmd_rsp,
206 			   uint8_t control, const uint8_t *data, size_t len)
207 {
208 	const char *frame_type;
209 	char out[128];
210 	int ret;
211 
212 	if (!IS_ENABLED(CONFIG_GSM_MUX_LOG_LEVEL_DBG)) {
213 		return;
214 	}
215 
216 	memset(out, 0, sizeof(out));
217 
218 	ret = snprintk(out, sizeof(out), "%s: DLCI %d %s ",
219 		       header, address, cmd_rsp ? "cmd" : "resp");
220 	if (ret >= sizeof(out)) {
221 		LOG_DBG("%d: Too long msg (%ld)", __LINE__, (long)(ret - sizeof(out)));
222 		goto print;
223 	}
224 
225 	frame_type = get_frame_type_str(control & ~GSM_PF);
226 	if (frame_type) {
227 		ret += snprintk(out + ret, sizeof(out) - ret, "%s ",
228 				frame_type);
229 	} else if (!(control & 0x01)) {
230 		ret += snprintk(out + ret, sizeof(out) - ret,
231 				"I N(S)%d N(R)%d ",
232 				(control & 0x0E) >> 1,
233 				(control & 0xE0) >> 5);
234 	} else {
235 		frame_type = get_frame_type_str(control & 0x0F);
236 		if (frame_type) {
237 			ret += snprintk(out + ret, sizeof(out) - ret,
238 					"%s(%d) ", frame_type,
239 					(control & 0xE0) >> 5);
240 		} else {
241 			ret += snprintk(out + ret, sizeof(out) - ret,
242 					"[%02X] ", control);
243 		}
244 	}
245 
246 	if (ret >= sizeof(out)) {
247 		LOG_DBG("%d: Too long msg (%ld)", __LINE__, (long)(ret - sizeof(out)));
248 		goto print;
249 	}
250 
251 	ret += snprintk(out + ret, sizeof(out) - ret, "%s", (control & GSM_PF) ? "(P)" : "(F)");
252 	if (ret >= sizeof(out)) {
253 		LOG_DBG("%d: Too long msg (%ld)", __LINE__, (long)(ret - sizeof(out)));
254 		goto print;
255 	}
256 
257 print:
258 	if (IS_ENABLED(CONFIG_GSM_MUX_VERBOSE_DEBUG)) {
259 		if (len > 0) {
260 			LOG_HEXDUMP_DBG(data, len, out);
261 		} else {
262 			LOG_DBG("%s", out);
263 		}
264 	} else {
265 		LOG_DBG("%s", out);
266 	}
267 }
268 
gsm_mux_fcs_add_buf(uint8_t fcs,const uint8_t * buf,size_t len)269 static uint8_t gsm_mux_fcs_add_buf(uint8_t fcs, const uint8_t *buf, size_t len)
270 {
271 	return crc8(buf, len, FCS_POLYNOMIAL, fcs, true);
272 }
273 
gsm_mux_fcs_add(uint8_t fcs,uint8_t recv_byte)274 static uint8_t gsm_mux_fcs_add(uint8_t fcs, uint8_t recv_byte)
275 {
276 	return gsm_mux_fcs_add_buf(fcs, &recv_byte, 1);
277 }
278 
gsm_mux_read_ea(int * value,uint8_t recv_byte)279 static bool gsm_mux_read_ea(int *value, uint8_t recv_byte)
280 {
281 	/* As the value can be larger than one byte, collect the read
282 	 * bytes to given variable.
283 	 */
284 	*value <<= 7;
285 	*value |= recv_byte >> 1;
286 
287 	/* When the address has been read fully, the EA bit is 1 */
288 	return recv_byte & GSM_EA;
289 }
290 
gsm_mux_read_msg_len(struct gsm_mux * mux,uint8_t recv_byte)291 static bool gsm_mux_read_msg_len(struct gsm_mux *mux, uint8_t recv_byte)
292 {
293 	int value = mux->msg_len;
294 	bool ret;
295 
296 	ret = gsm_mux_read_ea(&value, recv_byte);
297 
298 	mux->msg_len = value;
299 
300 	return ret;
301 }
302 
gsm_mux_alloc_buf(k_timeout_t timeout,void * user_data)303 static struct net_buf *gsm_mux_alloc_buf(k_timeout_t timeout, void *user_data)
304 {
305 	struct net_buf *buf;
306 
307 	ARG_UNUSED(user_data);
308 
309 	buf = net_buf_alloc(&gsm_mux_pool, timeout);
310 	if (!buf) {
311 		LOG_ERR("Cannot allocate buffer");
312 	}
313 
314 	return buf;
315 }
316 
hexdump_buf(const char * header,struct net_buf * buf)317 static void hexdump_buf(const char *header, struct net_buf *buf)
318 {
319 	if (IS_ENABLED(CONFIG_GSM_MUX_VERBOSE_DEBUG)) {
320 		while (buf) {
321 			LOG_HEXDUMP_DBG(buf->data, buf->len, header);
322 			buf = buf->frags;
323 		}
324 	}
325 }
326 
gsm_dlci_process_data(struct gsm_dlci * dlci,bool cmd,struct net_buf * buf)327 static int gsm_dlci_process_data(struct gsm_dlci *dlci, bool cmd,
328 				 struct net_buf *buf)
329 {
330 	int len = 0;
331 
332 	LOG_DBG("[%p] DLCI %d data %s", dlci->mux, dlci->num,
333 		cmd ? "request" : "response");
334 	hexdump_buf("buf", buf);
335 
336 	while (buf) {
337 		uart_mux_recv(dlci->uart, dlci, buf->data, buf->len);
338 		len += buf->len;
339 		buf = buf->frags;
340 	}
341 
342 	return len;
343 }
344 
gsm_dlci_get(struct gsm_mux * mux,uint8_t dlci_address)345 static struct gsm_dlci *gsm_dlci_get(struct gsm_mux *mux, uint8_t dlci_address)
346 {
347 	int i;
348 
349 	for (i = 0; i < ARRAY_SIZE(dlcis); i++) {
350 		if (dlcis[i].in_use &&
351 		    dlcis[i].mux == mux &&
352 		    dlcis[i].num == dlci_address) {
353 			return &dlcis[i];
354 		}
355 	}
356 
357 	return NULL;
358 }
359 
gsm_mux_modem_send(struct gsm_mux * mux,const uint8_t * buf,size_t size)360 static int gsm_mux_modem_send(struct gsm_mux *mux, const uint8_t *buf, size_t size)
361 {
362 	if (mux->uart == NULL) {
363 		return -ENOENT;
364 	}
365 
366 	if (size == 0) {
367 		return 0;
368 	}
369 
370 	return uart_mux_send(mux->uart, buf, size);
371 }
372 
gsm_mux_send_data_msg(struct gsm_mux * mux,bool cmd,struct gsm_dlci * dlci,uint8_t frame_type,const uint8_t * buf,size_t size)373 static int gsm_mux_send_data_msg(struct gsm_mux *mux, bool cmd,
374 				 struct gsm_dlci *dlci, uint8_t frame_type,
375 				 const uint8_t *buf, size_t size)
376 {
377 	uint8_t hdr[7];
378 	int pos;
379 	int ret;
380 
381 	hdr[0] = SOF_MARKER;
382 	hdr[1] = (dlci->num << 2) | ((uint8_t)cmd << 1) | GSM_EA;
383 	hdr[2] = frame_type;
384 
385 	if (size < 128) {
386 		hdr[3] = (size << 1) | GSM_EA;
387 		pos = 4;
388 	} else {
389 		hdr[3] = (size & 127) << 1;
390 		hdr[4] = (size >> 7);
391 		pos = 5;
392 	}
393 
394 	/* Write the header and data in smaller chunks in order to avoid
395 	 * allocating a big buffer.
396 	 */
397 	(void)gsm_mux_modem_send(mux, &hdr[0], pos);
398 
399 	if (size > 0) {
400 		(void)gsm_mux_modem_send(mux, buf, size);
401 	}
402 
403 	/* FSC is calculated only for address, type and length fields
404 	 * for UIH frames
405 	 */
406 	hdr[pos] = 0xFF - gsm_mux_fcs_add_buf(FCS_INIT_VALUE, &hdr[1],
407 					      pos - 1);
408 	if ((frame_type & ~GSM_PF) != FT_UIH) {
409 		hdr[pos] = gsm_mux_fcs_add_buf(hdr[pos], buf, size);
410 	}
411 
412 	hdr[pos + 1] = SOF_MARKER;
413 
414 	ret = gsm_mux_modem_send(mux, &hdr[pos], 2);
415 
416 	hexdump_packet("Sending", dlci->num, cmd, frame_type,
417 		       buf, size);
418 	return ret;
419 }
420 
gsm_mux_send_control_msg(struct gsm_mux * mux,bool cmd,uint8_t dlci_address,uint8_t frame_type)421 static int gsm_mux_send_control_msg(struct gsm_mux *mux, bool cmd,
422 				    uint8_t dlci_address, uint8_t frame_type)
423 {
424 	uint8_t buf[6];
425 
426 	buf[0] = SOF_MARKER;
427 	buf[1] = (dlci_address << 2) | ((uint8_t)cmd << 1) | GSM_EA;
428 	buf[2] = frame_type;
429 	buf[3] = GSM_EA;
430 	buf[4] = 0xFF - gsm_mux_fcs_add_buf(FCS_INIT_VALUE, buf + 1, 3);
431 	buf[5] = SOF_MARKER;
432 
433 	hexdump_packet("Sending", dlci_address, cmd, frame_type,
434 		       buf, sizeof(buf));
435 
436 	return gsm_mux_modem_send(mux, buf, sizeof(buf));
437 }
438 
gsm_mux_send_command(struct gsm_mux * mux,uint8_t dlci_address,uint8_t frame_type)439 static int gsm_mux_send_command(struct gsm_mux *mux, uint8_t dlci_address,
440 				uint8_t frame_type)
441 {
442 	return gsm_mux_send_control_msg(mux, true, dlci_address, frame_type);
443 }
444 
gsm_mux_send_response(struct gsm_mux * mux,uint8_t dlci_address,uint8_t frame_type)445 static int gsm_mux_send_response(struct gsm_mux *mux, uint8_t dlci_address,
446 				 uint8_t frame_type)
447 {
448 	return gsm_mux_send_control_msg(mux, false, dlci_address, frame_type);
449 }
450 
dlci_run_timer(uint32_t current_time)451 static void dlci_run_timer(uint32_t current_time)
452 {
453 	struct gsm_dlci *dlci, *next;
454 	uint32_t new_timer = UINT_MAX;
455 
456 	(void)k_work_cancel_delayable(&t1_timer);
457 
458 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&dlci_active_t1_timers,
459 					  dlci, next, node) {
460 		uint32_t current_timer = dlci->req_start +
461 			dlci->mux->t1_timeout_value - current_time;
462 
463 		new_timer = MIN(current_timer, new_timer);
464 	}
465 
466 	if (new_timer != UINT_MAX) {
467 		k_work_reschedule(&t1_timer, K_MSEC(new_timer));
468 	}
469 }
470 
gsm_dlci_open(struct gsm_dlci * dlci)471 static void gsm_dlci_open(struct gsm_dlci *dlci)
472 {
473 	LOG_DBG("[%p/%d] DLCI id %d open", dlci, dlci->num, dlci->num);
474 	dlci->state = GSM_DLCI_OPEN;
475 
476 	/* Remove this DLCI from pending T1 timers */
477 	sys_slist_remove(&dlci_active_t1_timers, NULL, &dlci->node);
478 	dlci_run_timer(k_uptime_get_32());
479 
480 	if (dlci->command_cb) {
481 		dlci->command_cb(dlci, true);
482 	}
483 }
484 
gsm_dlci_close(struct gsm_dlci * dlci)485 static void gsm_dlci_close(struct gsm_dlci *dlci)
486 {
487 	LOG_DBG("[%p/%d] DLCI id %d closed", dlci, dlci->num, dlci->num);
488 	dlci->state = GSM_DLCI_CLOSED;
489 
490 	k_sem_give(&dlci->disconnect_sem);
491 
492 	/* Remove this DLCI from pending T1 timers */
493 	sys_slist_remove(&dlci_active_t1_timers, NULL, &dlci->node);
494 	dlci_run_timer(k_uptime_get_32());
495 
496 	if (dlci->command_cb) {
497 		dlci->command_cb(dlci, false);
498 	}
499 
500 	if (dlci->num == 0) {
501 		dlci->mux->refuse_service = true;
502 	}
503 }
504 
505 /* Return true if we need to retry, false otherwise */
handle_t1_timeout(struct gsm_dlci * dlci)506 static bool handle_t1_timeout(struct gsm_dlci *dlci)
507 {
508 	LOG_DBG("[%p/%d] T1 timeout", dlci, dlci->num);
509 
510 	if (dlci->state == GSM_DLCI_OPENING) {
511 		dlci->retries--;
512 		if (dlci->retries) {
513 			dlci->req_start = k_uptime_get_32();
514 			(void)gsm_mux_send_command(dlci->mux, dlci->num, FT_SABM | GSM_PF);
515 			return true;
516 		}
517 
518 		if (dlci->command_cb) {
519 			dlci->command_cb(dlci, false);
520 		}
521 
522 		if (dlci->num == 0 && dlci->mux->control == (FT_DM | GSM_PF)) {
523 			LOG_DBG("DLCI %d -> ADM mode", dlci->num);
524 			dlci->mode = GSM_DLCI_MODE_ADM;
525 			gsm_dlci_open(dlci);
526 		} else {
527 			gsm_dlci_close(dlci);
528 		}
529 	} else if (dlci->state == GSM_DLCI_CLOSING) {
530 		dlci->retries--;
531 		if (dlci->retries) {
532 			(void)gsm_mux_send_command(dlci->mux, dlci->num, FT_DISC | GSM_PF);
533 			return true;
534 		}
535 
536 		gsm_dlci_close(dlci);
537 	}
538 
539 	return false;
540 }
541 
dlci_t1_timeout(struct k_work * work)542 static void dlci_t1_timeout(struct k_work *work)
543 {
544 	uint32_t current_time = k_uptime_get_32();
545 	struct gsm_dlci *entry, *next;
546 	sys_snode_t *prev_node = NULL;
547 
548 	ARG_UNUSED(work);
549 
550 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&dlci_active_t1_timers,
551 					  entry, next, node) {
552 		if ((int32_t)(entry->req_start +
553 			    entry->mux->t1_timeout_value - current_time) > 0) {
554 			prev_node = &entry->node;
555 			break;
556 		}
557 
558 		if (!handle_t1_timeout(entry)) {
559 			sys_slist_remove(&dlci_active_t1_timers, prev_node,
560 					 &entry->node);
561 		}
562 	}
563 
564 	dlci_run_timer(current_time);
565 }
566 
gsm_ctrl_msg_get_free(void)567 static struct gsm_control_msg *gsm_ctrl_msg_get_free(void)
568 {
569 	sys_snode_t *node;
570 
571 	node = sys_slist_peek_head(&ctrls_free_entries);
572 	if (!node) {
573 		return NULL;
574 	}
575 
576 	sys_slist_remove(&ctrls_free_entries, NULL, node);
577 
578 	return CONTAINER_OF(node, struct gsm_control_msg, node);
579 }
580 
gsm_mux_alloc_control_msg(struct net_buf * buf,uint8_t cmd)581 static struct gsm_control_msg *gsm_mux_alloc_control_msg(struct net_buf *buf,
582 							 uint8_t cmd)
583 {
584 	struct gsm_control_msg *msg;
585 
586 	msg = gsm_ctrl_msg_get_free();
587 	if (!msg) {
588 		return NULL;
589 	}
590 
591 	msg->buf = buf;
592 	msg->cmd = cmd;
593 
594 	return msg;
595 }
596 
ctrl_msg_cleanup(struct gsm_control_msg * entry,bool pending)597 static void ctrl_msg_cleanup(struct gsm_control_msg *entry, bool pending)
598 {
599 	if (pending) {
600 		LOG_DBG("Releasing pending buf %p (ref %d)",
601 			entry->buf, entry->buf->ref - 1);
602 		net_buf_unref(entry->buf);
603 		entry->buf = NULL;
604 	}
605 }
606 
607 /* T2 timeout is for control message retransmits */
gsm_mux_t2_timeout(struct k_work * work)608 static void gsm_mux_t2_timeout(struct k_work *work)
609 {
610 	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
611 	struct gsm_mux *mux = CONTAINER_OF(dwork, struct gsm_mux, t2_timer);
612 	uint32_t current_time = k_uptime_get_32();
613 	struct gsm_control_msg *entry, *next;
614 
615 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&mux->pending_ctrls, entry, next,
616 					  node) {
617 		if ((int32_t)(entry->req_start + T2_MSEC - current_time) > 0) {
618 			break;
619 		}
620 
621 		ctrl_msg_cleanup(entry, true);
622 
623 		sys_slist_remove(&mux->pending_ctrls, NULL, &entry->node);
624 		sys_slist_append(&ctrls_free_entries, &entry->node);
625 
626 		entry = NULL;
627 	}
628 
629 	if (entry) {
630 		k_work_reschedule(
631 			&mux->t2_timer,
632 			K_MSEC(entry->req_start + T2_MSEC - current_time));
633 	}
634 }
635 
gsm_mux_send_control_message(struct gsm_mux * mux,uint8_t dlci_address,int cmd,uint8_t * data,size_t data_len)636 static int gsm_mux_send_control_message(struct gsm_mux *mux, uint8_t dlci_address,
637 					int cmd, uint8_t *data, size_t data_len)
638 {
639 	struct gsm_control_msg *ctrl;
640 	struct net_buf *buf;
641 
642 	/* We create a net_buf for the control message so that we can
643 	 * resend it easily if needed.
644 	 */
645 	buf = gsm_mux_alloc_buf(BUF_ALLOC_TIMEOUT, NULL);
646 	if (!buf) {
647 		LOG_ERR("[%p] Cannot allocate header", mux);
648 		return -ENOMEM;
649 	}
650 
651 	if (data && data_len > 0) {
652 		size_t added;
653 
654 		added = net_buf_append_bytes(buf, data_len, data,
655 					     BUF_ALLOC_TIMEOUT,
656 					     gsm_mux_alloc_buf, NULL);
657 		if (added != data_len) {
658 			net_buf_unref(buf);
659 			return -ENOMEM;
660 		}
661 	}
662 
663 	ctrl = gsm_mux_alloc_control_msg(buf, cmd);
664 	if (!ctrl) {
665 		net_buf_unref(buf);
666 		return -ENOMEM;
667 	}
668 
669 	sys_slist_append(&mux->pending_ctrls, &ctrl->node);
670 	ctrl->req_start = k_uptime_get_32();
671 
672 	/* Let's start the timer if necessary */
673 	if (!k_work_delayable_remaining_get(&mux->t2_timer)) {
674 		k_work_reschedule(&mux->t2_timer, K_MSEC(T2_MSEC));
675 	}
676 
677 	return gsm_mux_modem_send(mux, buf->data, buf->len);
678 }
679 
gsm_dlci_opening_or_closing(struct gsm_dlci * dlci,enum gsm_dlci_state state,int command,dlci_command_cb_t cb)680 static int gsm_dlci_opening_or_closing(struct gsm_dlci *dlci,
681 				       enum gsm_dlci_state state,
682 				       int command,
683 				       dlci_command_cb_t cb)
684 {
685 	dlci->retries = dlci->mux->retries;
686 	dlci->req_start = k_uptime_get_32();
687 	dlci->state = state;
688 	dlci->command_cb = cb;
689 
690 	/* Let's start the timer if necessary */
691 	if (!k_work_delayable_remaining_get(&t1_timer)) {
692 		k_work_reschedule(&t1_timer,
693 				  K_MSEC(dlci->mux->t1_timeout_value));
694 	}
695 
696 	sys_slist_append(&dlci_active_t1_timers, &dlci->node);
697 
698 	return gsm_mux_send_command(dlci->mux, dlci->num, command | GSM_PF);
699 }
700 
gsm_dlci_closing(struct gsm_dlci * dlci,dlci_command_cb_t cb)701 static int gsm_dlci_closing(struct gsm_dlci *dlci, dlci_command_cb_t cb)
702 {
703 	if (dlci->state == GSM_DLCI_CLOSED ||
704 	    dlci->state == GSM_DLCI_CLOSING) {
705 		return -EALREADY;
706 	}
707 
708 	LOG_DBG("[%p] DLCI %d closing", dlci, dlci->num);
709 
710 	return gsm_dlci_opening_or_closing(dlci, GSM_DLCI_CLOSING, FT_DISC,
711 					   cb);
712 }
713 
gsm_dlci_opening(struct gsm_dlci * dlci,dlci_command_cb_t cb)714 static int gsm_dlci_opening(struct gsm_dlci *dlci, dlci_command_cb_t cb)
715 {
716 	if (dlci->state == GSM_DLCI_OPEN || dlci->state == GSM_DLCI_OPENING) {
717 		return -EALREADY;
718 	}
719 
720 	LOG_DBG("[%p] DLCI %d opening", dlci, dlci->num);
721 
722 	return gsm_dlci_opening_or_closing(dlci, GSM_DLCI_OPENING, FT_SABM,
723 					   cb);
724 }
725 
gsm_mux_disconnect(struct gsm_mux * mux,k_timeout_t timeout)726 int gsm_mux_disconnect(struct gsm_mux *mux, k_timeout_t timeout)
727 {
728 	struct gsm_dlci *dlci;
729 
730 	dlci = gsm_dlci_get(mux, 0);
731 	if (dlci == NULL) {
732 		return -ENOENT;
733 	}
734 
735 	(void)gsm_mux_send_control_message(dlci->mux, dlci->num,
736 					   CMD_CLD, NULL, 0);
737 
738 	(void)k_work_cancel_delayable(&mux->t2_timer);
739 
740 	(void)gsm_dlci_closing(dlci, NULL);
741 
742 	return k_sem_take(&dlci->disconnect_sem, timeout);
743 }
744 
gsm_mux_control_reply(struct gsm_dlci * dlci,bool sub_cr,uint8_t sub_cmd,const uint8_t * buf,size_t len)745 static int gsm_mux_control_reply(struct gsm_dlci *dlci, bool sub_cr,
746 				 uint8_t sub_cmd, const uint8_t *buf, size_t len)
747 {
748 	/* As this is a reply to received command, set the value according
749 	 * to initiator status. See GSM 07.10 page 17.
750 	 */
751 	bool cmd = !dlci->mux->is_initiator;
752 
753 	return gsm_mux_send_data_msg(dlci->mux, cmd, dlci, FT_UIH | GSM_PF, buf, len);
754 }
755 
get_field(struct net_buf * buf,int * ret_value)756 static bool get_field(struct net_buf *buf, int *ret_value)
757 {
758 	int value = 0;
759 	uint8_t recv_byte;
760 
761 	while (buf->len) {
762 		recv_byte = net_buf_pull_u8(buf);
763 
764 		if (gsm_mux_read_ea(&value, recv_byte)) {
765 			*ret_value = value;
766 			return true;
767 		}
768 
769 		if (buf->len == 0) {
770 			buf = net_buf_frag_del(NULL, buf);
771 			if (buf == NULL) {
772 				break;
773 			}
774 		}
775 	}
776 
777 	return false;
778 }
779 
gsm_mux_msc_reply(struct gsm_dlci * dlci,bool cmd,struct net_buf * buf,size_t len)780 static int gsm_mux_msc_reply(struct gsm_dlci *dlci, bool cmd,
781 			     struct net_buf *buf, size_t len)
782 {
783 	uint32_t modem_sig = 0, break_sig = 0;
784 	int ret;
785 
786 	ret = get_field(buf, &modem_sig);
787 	if (!ret) {
788 		LOG_DBG("[%p] Malformed data", dlci->mux);
789 		return -EINVAL;
790 	}
791 
792 	if (buf->len > 0) {
793 		ret = get_field(buf, &break_sig);
794 		if (!ret) {
795 			LOG_DBG("[%p] Malformed data", dlci->mux);
796 			return -EINVAL;
797 		}
798 	}
799 
800 	LOG_DBG("Modem signal 0x%02x break signal 0x%02x", modem_sig,
801 		break_sig);
802 
803 	/* FIXME to return proper status back */
804 
805 	return gsm_mux_control_reply(dlci, cmd, CMD_MSC, buf->data, len);
806 }
807 
gsm_mux_control_message(struct gsm_dlci * dlci,struct net_buf * buf)808 static int gsm_mux_control_message(struct gsm_dlci *dlci, struct net_buf *buf)
809 {
810 	uint32_t command = 0, len = 0;
811 	int ret = 0;
812 	bool cr;
813 
814 	__ASSERT_NO_MSG(dlci != NULL);
815 
816 	/* Remove the C/R bit from sub-command */
817 	cr = buf->data[0] & GSM_CR;
818 	buf->data[0] &= ~GSM_CR;
819 
820 	ret = get_field(buf, &command);
821 	if (!ret) {
822 		LOG_DBG("[%p] Malformed data", dlci->mux);
823 		return -EINVAL;
824 	}
825 
826 	ret = get_field(buf, &len);
827 	if (!ret) {
828 		LOG_DBG("[%p] Malformed data", dlci->mux);
829 		return -EINVAL;
830 	}
831 
832 	LOG_DBG("[%p] DLCI %d %s 0x%02x len %u", dlci->mux, dlci->num,
833 		cr ? "cmd" : "rsp", command, len);
834 
835 	/* buf->data should now point to start of dlci command data */
836 
837 	switch (command) {
838 	case CMD_CLD:
839 		/* Modem closing down */
840 		dlci->mux->refuse_service = true;
841 		dlci->refuse_service = true;
842 		gsm_dlci_closing(dlci, NULL);
843 		break;
844 
845 	case CMD_FCOFF:
846 		/* Do not accept data */
847 		ret = gsm_mux_control_reply(dlci, cr, CMD_FCOFF, NULL, 0);
848 		break;
849 
850 	case CMD_FCON:
851 		/* Accepting data */
852 		ret = gsm_mux_control_reply(dlci, cr, CMD_FCON, NULL, 0);
853 		break;
854 
855 	case CMD_MSC:
856 		/* Modem status information */
857 		/* FIXME: WIP: MSC reply does not work */
858 		if (0) {
859 			ret = gsm_mux_msc_reply(dlci, cr, buf, len);
860 		}
861 
862 		break;
863 
864 	case CMD_PSC:
865 		/* Modem wants to enter power saving state */
866 		ret = gsm_mux_control_reply(dlci, cr, CMD_PSC, NULL, len);
867 		break;
868 
869 	case CMD_RLS:
870 		/* Out of band error reception for a DLCI */
871 		break;
872 
873 	case CMD_TEST:
874 		/* Send test message back */
875 		ret = gsm_mux_control_reply(dlci, cr, CMD_TEST,
876 					    buf->data, len);
877 		break;
878 
879 	/* Optional and currently unsupported commands */
880 	case CMD_PN:	/* Parameter negotiation */
881 	case CMD_RPN:	/* Remote port negotiation */
882 	case CMD_SNC:	/* Service negotiation command */
883 	default:
884 		/* Reply to bad commands with an NSC */
885 		buf->data[0] = command | (cr ? GSM_CR : 0);
886 		buf->len = 1;
887 		ret = gsm_mux_control_reply(dlci, cr, CMD_NSC, buf->data, len);
888 		break;
889 	}
890 
891 	return ret;
892 }
893 
894 /* Handle a response to our control message */
gsm_mux_control_response(struct gsm_dlci * dlci,struct net_buf * buf)895 static int gsm_mux_control_response(struct gsm_dlci *dlci, struct net_buf *buf)
896 {
897 	struct gsm_control_msg *entry, *next;
898 
899 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&dlci->mux->pending_ctrls,
900 					  entry, next, node) {
901 		if (dlci->mux->control == entry->cmd) {
902 			sys_slist_remove(&dlci->mux->pending_ctrls, NULL,
903 					 &entry->node);
904 			sys_slist_append(&ctrls_free_entries, &entry->node);
905 			entry->finished = true;
906 
907 			if (dlci->command_cb) {
908 				dlci->command_cb(dlci, true);
909 			}
910 
911 			break;
912 		}
913 	}
914 
915 	return 0;
916 }
917 
gsm_dlci_process_command(struct gsm_dlci * dlci,bool cmd,struct net_buf * buf)918 static int gsm_dlci_process_command(struct gsm_dlci *dlci, bool cmd,
919 				    struct net_buf *buf)
920 {
921 	int ret;
922 
923 	LOG_DBG("[%p] DLCI %d control %s", dlci->mux, dlci->num,
924 		cmd ? "request" : "response");
925 	hexdump_buf("buf", buf);
926 
927 	if (cmd) {
928 		ret = gsm_mux_control_message(dlci, buf);
929 	} else {
930 		ret = gsm_mux_control_response(dlci, buf);
931 	}
932 
933 	return ret;
934 }
935 
gsm_dlci_free(struct gsm_mux * mux,uint8_t address)936 static void gsm_dlci_free(struct gsm_mux *mux, uint8_t address)
937 {
938 	struct gsm_dlci *dlci;
939 	int i;
940 
941 	for (i = 0; i < ARRAY_SIZE(dlcis); i++) {
942 		if (!dlcis[i].in_use) {
943 			continue;
944 		}
945 
946 		dlci = &dlcis[i];
947 
948 		if (dlci->mux == mux && dlci->num == address) {
949 			dlci->in_use = false;
950 
951 			sys_slist_prepend(&dlci_free_entries, &dlci->node);
952 		}
953 
954 		break;
955 	}
956 }
957 
gsm_dlci_get_free(void)958 static struct gsm_dlci *gsm_dlci_get_free(void)
959 {
960 	sys_snode_t *node;
961 
962 	node = sys_slist_peek_head(&dlci_free_entries);
963 	if (!node) {
964 		return NULL;
965 	}
966 
967 	sys_slist_remove(&dlci_free_entries, NULL, node);
968 
969 	return CONTAINER_OF(node, struct gsm_dlci, node);
970 }
971 
gsm_dlci_alloc(struct gsm_mux * mux,uint8_t address,const struct device * uart,gsm_mux_dlci_created_cb_t dlci_created_cb,void * user_data)972 static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *mux, uint8_t address,
973 		const struct device *uart,
974 		gsm_mux_dlci_created_cb_t dlci_created_cb,
975 		void *user_data)
976 {
977 	struct gsm_dlci *dlci;
978 
979 	dlci = gsm_dlci_get_free();
980 	if (!dlci) {
981 		return NULL;
982 	}
983 
984 	k_sem_init(&dlci->disconnect_sem, 1, 1);
985 
986 	dlci->mux = mux;
987 	dlci->num = address;
988 	dlci->in_use = true;
989 	dlci->retries = mux->retries;
990 	dlci->state = GSM_DLCI_CLOSED;
991 	dlci->uart = uart;
992 	dlci->user_data = user_data;
993 	dlci->dlci_created_cb = dlci_created_cb;
994 
995 	/* Command channel (0) handling is separated from data */
996 	if (dlci->num) {
997 		dlci->handler = gsm_dlci_process_data;
998 	} else {
999 		dlci->handler = gsm_dlci_process_command;
1000 	}
1001 
1002 	return dlci;
1003 }
1004 
gsm_mux_process_pkt(struct gsm_mux * mux)1005 static int gsm_mux_process_pkt(struct gsm_mux *mux)
1006 {
1007 	uint8_t dlci_address = mux->address >> 2;
1008 	int ret = 0;
1009 	bool cmd;   /* C/R bit, command (true) / response (false) */
1010 	struct gsm_dlci *dlci;
1011 
1012 	/* This function is only called for received packets so if the
1013 	 * command is set, then it means a response if we are initiator.
1014 	 */
1015 	cmd = (mux->address >> 1) & 0x01;
1016 
1017 	if (mux->is_initiator) {
1018 		cmd = !cmd;
1019 	}
1020 
1021 	hexdump_packet("Received", dlci_address, cmd, mux->control,
1022 		       mux->buf ? mux->buf->data : NULL,
1023 		       mux->buf ? mux->buf->len : 0);
1024 
1025 	dlci = gsm_dlci_get(mux, dlci_address);
1026 
1027 	/* What to do next */
1028 	switch (mux->control) {
1029 	case FT_SABM | GSM_PF:
1030 		if (cmd == false) {
1031 			ret = -ENOENT;
1032 			goto fail;
1033 		}
1034 
1035 		if (dlci == NULL) {
1036 			const struct device *uart;
1037 
1038 			uart = uart_mux_find(dlci_address);
1039 			if (uart == NULL) {
1040 				ret = -ENOENT;
1041 				goto fail;
1042 			}
1043 
1044 			dlci = gsm_dlci_alloc(mux, dlci_address, uart, NULL,
1045 					      NULL);
1046 			if (dlci == NULL) {
1047 				ret = -ENOENT;
1048 				goto fail;
1049 			}
1050 		}
1051 
1052 		if (dlci->refuse_service) {
1053 			ret = gsm_mux_send_response(mux, dlci_address, FT_DM);
1054 		} else {
1055 			ret = gsm_mux_send_response(mux, dlci_address, FT_UA);
1056 			gsm_dlci_open(dlci);
1057 		}
1058 
1059 		break;
1060 
1061 	case FT_DISC | GSM_PF:
1062 		if (cmd == false) {
1063 			ret = -ENOENT;
1064 			goto fail;
1065 		}
1066 
1067 		if (dlci == NULL || dlci->state == GSM_DLCI_CLOSED) {
1068 			(void)gsm_mux_send_response(mux, dlci_address, FT_DM);
1069 			ret = -ENOENT;
1070 			goto out;
1071 		}
1072 
1073 		ret = gsm_mux_send_command(mux, dlci_address, FT_UA);
1074 		gsm_dlci_close(dlci);
1075 		break;
1076 
1077 	case FT_UA | GSM_PF:
1078 	case FT_UA:
1079 		if (cmd == true || dlci == NULL) {
1080 			ret = -ENOENT;
1081 			goto out;
1082 		}
1083 
1084 		switch (dlci->state) {
1085 		case GSM_DLCI_CLOSING:
1086 			gsm_dlci_close(dlci);
1087 			break;
1088 		case GSM_DLCI_OPENING:
1089 			gsm_dlci_open(dlci);
1090 			break;
1091 		default:
1092 			break;
1093 		}
1094 
1095 		break;
1096 
1097 	case FT_DM | GSM_PF:
1098 	case FT_DM:
1099 		if (cmd == true || dlci == NULL) {
1100 			ret = -ENOENT;
1101 			goto fail;
1102 		}
1103 
1104 		gsm_dlci_close(dlci);
1105 		break;
1106 
1107 	case FT_UI | GSM_PF:
1108 	case FT_UI:
1109 	case FT_UIH | GSM_PF:
1110 	case FT_UIH:
1111 		if (dlci == NULL || dlci->state != GSM_DLCI_OPEN) {
1112 			(void)gsm_mux_send_command(mux, dlci_address, FT_DM | GSM_PF);
1113 			ret = -ENOENT;
1114 			goto out;
1115 		}
1116 
1117 		ret = dlci->handler(dlci, cmd, mux->buf);
1118 
1119 		if (mux->buf) {
1120 			net_buf_unref(mux->buf);
1121 			mux->buf = NULL;
1122 		}
1123 
1124 		break;
1125 
1126 	default:
1127 		ret = -EINVAL;
1128 		goto fail;
1129 	}
1130 
1131 out:
1132 	return ret;
1133 
1134 fail:
1135 	LOG_ERR("Cannot handle command (0x%02x) (%d)", mux->control, ret);
1136 	return ret;
1137 }
1138 
is_UI(struct gsm_mux * mux)1139 static bool is_UI(struct gsm_mux *mux)
1140 {
1141 	return (mux->control & ~GSM_PF) == FT_UI;
1142 }
1143 
gsm_mux_state_str(enum gsm_mux_state state)1144 static const char *gsm_mux_state_str(enum gsm_mux_state state)
1145 {
1146 #if (CONFIG_GSM_MUX_LOG_LEVEL >= LOG_LEVEL_DBG) || defined(CONFIG_NET_SHELL)
1147 	switch (state) {
1148 	case GSM_MUX_SOF:
1149 		return "Start-Of-Frame";
1150 	case GSM_MUX_ADDRESS:
1151 		return "Address";
1152 	case GSM_MUX_CONTROL:
1153 		return "Control";
1154 	case GSM_MUX_LEN_0:
1155 		return "Len0";
1156 	case GSM_MUX_LEN_1:
1157 		return "Len1";
1158 	case GSM_MUX_DATA:
1159 		return "Data";
1160 	case GSM_MUX_FCS:
1161 		return "FCS";
1162 	case GSM_MUX_EOF:
1163 		return "End-Of-Frame";
1164 	}
1165 #else
1166 	ARG_UNUSED(state);
1167 #endif
1168 
1169 	return "";
1170 }
1171 
1172 #if CONFIG_GSM_MUX_LOG_LEVEL >= LOG_LEVEL_DBG
validate_state_transition(enum gsm_mux_state current,enum gsm_mux_state new)1173 static void validate_state_transition(enum gsm_mux_state current,
1174 				      enum gsm_mux_state new)
1175 {
1176 	static const uint8_t valid_transitions[] = {
1177 		[GSM_MUX_SOF] = 1 << GSM_MUX_ADDRESS,
1178 		[GSM_MUX_ADDRESS] = 1 << GSM_MUX_CONTROL,
1179 		[GSM_MUX_CONTROL] = 1 << GSM_MUX_LEN_0,
1180 		[GSM_MUX_LEN_0] = 1 << GSM_MUX_LEN_1 |
1181 				1 << GSM_MUX_DATA |
1182 				1 << GSM_MUX_FCS |
1183 				1 << GSM_MUX_SOF,
1184 		[GSM_MUX_LEN_1] = 1 << GSM_MUX_DATA |
1185 				1 << GSM_MUX_FCS |
1186 				1 << GSM_MUX_SOF,
1187 		[GSM_MUX_DATA] = 1 << GSM_MUX_FCS |
1188 				1 << GSM_MUX_SOF,
1189 		[GSM_MUX_FCS] = 1 << GSM_MUX_EOF,
1190 		[GSM_MUX_EOF] = 1 << GSM_MUX_SOF
1191 	};
1192 
1193 	if (!(valid_transitions[current] & 1 << new)) {
1194 		LOG_DBG("Invalid state transition: %s (%d) => %s (%d)",
1195 			gsm_mux_state_str(current), current,
1196 			gsm_mux_state_str(new), new);
1197 	}
1198 }
1199 #else
validate_state_transition(enum gsm_mux_state current,enum gsm_mux_state new)1200 static inline void validate_state_transition(enum gsm_mux_state current,
1201 					     enum gsm_mux_state new)
1202 {
1203 	ARG_UNUSED(current);
1204 	ARG_UNUSED(new);
1205 }
1206 #endif
1207 
gsm_mux_get_state(const struct gsm_mux * mux)1208 static inline enum gsm_mux_state gsm_mux_get_state(const struct gsm_mux *mux)
1209 {
1210 	return (enum gsm_mux_state)mux->state;
1211 }
1212 
gsm_mux_change_state(struct gsm_mux * mux,enum gsm_mux_state new_state)1213 void gsm_mux_change_state(struct gsm_mux *mux, enum gsm_mux_state new_state)
1214 {
1215 	__ASSERT_NO_MSG(mux);
1216 
1217 	if (gsm_mux_get_state(mux) == new_state) {
1218 		return;
1219 	}
1220 
1221 	LOG_DBG("[%p] state %s (%d) => %s (%d)",
1222 		mux, gsm_mux_state_str(mux->state), mux->state,
1223 		gsm_mux_state_str(new_state), new_state);
1224 
1225 	validate_state_transition(mux->state, new_state);
1226 
1227 	mux->state = new_state;
1228 }
1229 
gsm_mux_process_data(struct gsm_mux * mux,uint8_t recv_byte)1230 static void gsm_mux_process_data(struct gsm_mux *mux, uint8_t recv_byte)
1231 {
1232 	size_t bytes_added;
1233 
1234 	switch (mux->state) {
1235 	case GSM_MUX_SOF:
1236 		/* This is the initial state where we look for SOF char */
1237 		if (recv_byte == SOF_MARKER) {
1238 			gsm_mux_change_state(mux, GSM_MUX_ADDRESS);
1239 			mux->fcs = FCS_INIT_VALUE;
1240 			mux->received = 0;
1241 
1242 			/* Avoid memory leak by freeing all the allocated
1243 			 * buffers at start.
1244 			 */
1245 			if (mux->buf) {
1246 				net_buf_unref(mux->buf);
1247 				mux->buf = NULL;
1248 			}
1249 		}
1250 
1251 		break;
1252 
1253 	case GSM_MUX_ADDRESS:
1254 		/* DLCI (Data Link Connection Identifier) address we want to
1255 		 * talk. This address field also contains C/R bit.
1256 		 * Currently we only support one byte addresses.
1257 		 */
1258 		mux->address = recv_byte;
1259 		LOG_DBG("[%p] recv %d address %d C/R %d", mux, recv_byte,
1260 			mux->address >> 2, !!(mux->address & GSM_CR));
1261 		gsm_mux_change_state(mux, GSM_MUX_CONTROL);
1262 		mux->fcs = gsm_mux_fcs_add(mux->fcs, recv_byte);
1263 		break;
1264 
1265 	case GSM_MUX_CONTROL:
1266 		mux->control = recv_byte;
1267 		LOG_DBG("[%p] recv %s (0x%02x) control 0x%02x P/F %d", mux,
1268 			get_frame_type_str(recv_byte & ~GSM_PF), recv_byte,
1269 			mux->control & ~GSM_PF, !!(mux->control & GSM_PF));
1270 		gsm_mux_change_state(mux, GSM_MUX_LEN_0);
1271 		mux->fcs = gsm_mux_fcs_add(mux->fcs, recv_byte);
1272 		break;
1273 
1274 	case GSM_MUX_LEN_0:
1275 		mux->fcs = gsm_mux_fcs_add(mux->fcs, recv_byte);
1276 		mux->msg_len = 0;
1277 
1278 		if (gsm_mux_read_msg_len(mux, recv_byte)) {
1279 			if (mux->msg_len > mux->mru) {
1280 				gsm_mux_change_state(mux, GSM_MUX_SOF);
1281 			} else if (mux->msg_len == 0) {
1282 				gsm_mux_change_state(mux, GSM_MUX_FCS);
1283 			} else {
1284 				gsm_mux_change_state(mux, GSM_MUX_DATA);
1285 
1286 				LOG_DBG("[%p] data len %d", mux, mux->msg_len);
1287 			}
1288 		} else {
1289 			gsm_mux_change_state(mux, GSM_MUX_LEN_1);
1290 		}
1291 
1292 		break;
1293 
1294 	case GSM_MUX_LEN_1:
1295 		mux->fcs = gsm_mux_fcs_add(mux->fcs, recv_byte);
1296 
1297 		mux->msg_len |= recv_byte << 7;
1298 		if (mux->msg_len > mux->mru) {
1299 			gsm_mux_change_state(mux, GSM_MUX_SOF);
1300 		} else if (mux->msg_len == 0) {
1301 			gsm_mux_change_state(mux, GSM_MUX_FCS);
1302 		} else {
1303 			gsm_mux_change_state(mux, GSM_MUX_DATA);
1304 
1305 			LOG_DBG("[%p] data len %d", mux, mux->msg_len);
1306 		}
1307 
1308 		break;
1309 
1310 	case GSM_MUX_DATA:
1311 		if (mux->buf == NULL) {
1312 			mux->buf = net_buf_alloc(&gsm_mux_pool,
1313 						 BUF_ALLOC_TIMEOUT);
1314 			if (mux->buf == NULL) {
1315 				LOG_ERR("[%p] Can't allocate RX data! "
1316 					"Skipping data!", mux);
1317 				gsm_mux_change_state(mux, GSM_MUX_SOF);
1318 				break;
1319 			}
1320 		}
1321 
1322 		bytes_added = net_buf_append_bytes(mux->buf, 1,
1323 						   (void *)&recv_byte,
1324 						   BUF_ALLOC_TIMEOUT,
1325 						   gsm_mux_alloc_buf,
1326 						   &gsm_mux_pool);
1327 		if (bytes_added != 1) {
1328 			gsm_mux_change_state(mux, GSM_MUX_SOF);
1329 		} else if (++mux->received == mux->msg_len) {
1330 			gsm_mux_change_state(mux, GSM_MUX_FCS);
1331 		}
1332 
1333 		break;
1334 
1335 	case GSM_MUX_FCS:
1336 		mux->received_fcs = recv_byte;
1337 
1338 		/* Update the FCS for Unnumbered Information field (UI) */
1339 		if (is_UI(mux)) {
1340 			struct net_buf *buf = mux->buf;
1341 
1342 			while (buf) {
1343 				mux->fcs = gsm_mux_fcs_add_buf(mux->fcs,
1344 							       buf->data,
1345 							       buf->len);
1346 				buf = buf->frags;
1347 			}
1348 		}
1349 
1350 		mux->fcs = gsm_mux_fcs_add(mux->fcs, mux->received_fcs);
1351 		if (mux->fcs == FCS_GOOD_VALUE) {
1352 			int ret = gsm_mux_process_pkt(mux);
1353 
1354 			if (ret < 0) {
1355 				LOG_DBG("[%p] Cannot process pkt (%d)", mux,
1356 					ret);
1357 			}
1358 		}
1359 
1360 		gsm_mux_change_state(mux, GSM_MUX_EOF);
1361 		break;
1362 
1363 	case GSM_MUX_EOF:
1364 		if (recv_byte == SOF_MARKER) {
1365 			gsm_mux_change_state(mux, GSM_MUX_SOF);
1366 		}
1367 
1368 		break;
1369 	}
1370 }
1371 
gsm_mux_recv_buf(struct gsm_mux * mux,uint8_t * buf,int len)1372 void gsm_mux_recv_buf(struct gsm_mux *mux, uint8_t *buf, int len)
1373 {
1374 	int i = 0;
1375 
1376 	LOG_DBG("Received %d bytes", len);
1377 
1378 	while (i < len) {
1379 		gsm_mux_process_data(mux, buf[i++]);
1380 	}
1381 }
1382 
dlci_done(struct gsm_dlci * dlci,bool connected)1383 static void dlci_done(struct gsm_dlci *dlci, bool connected)
1384 {
1385 	LOG_DBG("[%p] DLCI id %d %screated", dlci, dlci->num,
1386 		connected == false ? "not " : "");
1387 
1388 	/* Let the UART mux to continue */
1389 	if (dlci->dlci_created_cb) {
1390 		dlci->dlci_created_cb(dlci, connected, dlci->user_data);
1391 	}
1392 }
1393 
gsm_dlci_create(struct gsm_mux * mux,const struct device * uart,int dlci_address,gsm_mux_dlci_created_cb_t dlci_created_cb,void * user_data,struct gsm_dlci ** dlci)1394 int gsm_dlci_create(struct gsm_mux *mux,
1395 		    const struct device *uart,
1396 		    int dlci_address,
1397 		    gsm_mux_dlci_created_cb_t dlci_created_cb,
1398 		    void *user_data,
1399 		    struct gsm_dlci **dlci)
1400 {
1401 	int ret;
1402 
1403 	*dlci = gsm_dlci_alloc(mux, dlci_address, uart, dlci_created_cb,
1404 			       user_data);
1405 	if (!*dlci) {
1406 		LOG_ERR("[%p] Cannot allocate DLCI %d", mux, dlci_address);
1407 		ret = -ENOMEM;
1408 		goto fail;
1409 	}
1410 
1411 	ret = gsm_dlci_opening(*dlci, dlci_done);
1412 	if (ret < 0 && ret != -EALREADY) {
1413 		LOG_ERR("[%p] Cannot open DLCI %d", mux, dlci_address);
1414 		gsm_dlci_free(mux, dlci_address);
1415 		*dlci = NULL;
1416 	} else {
1417 		ret = 0;
1418 	}
1419 
1420 fail:
1421 	return ret;
1422 }
1423 
gsm_dlci_send(struct gsm_dlci * dlci,const uint8_t * buf,size_t size)1424 int gsm_dlci_send(struct gsm_dlci *dlci, const uint8_t *buf, size_t size)
1425 {
1426 	/* Mux the data and send to UART */
1427 	return gsm_mux_send_data_msg(dlci->mux, true, dlci, FT_UIH, buf, size);
1428 }
1429 
gsm_dlci_id(struct gsm_dlci * dlci)1430 int gsm_dlci_id(struct gsm_dlci *dlci)
1431 {
1432 	return dlci->num;
1433 }
1434 
gsm_mux_create(const struct device * uart)1435 struct gsm_mux *gsm_mux_create(const struct device *uart)
1436 {
1437 	struct gsm_mux *mux = NULL;
1438 	int i;
1439 
1440 	if (!gsm_mux_init_done) {
1441 		LOG_ERR("GSM mux not initialized!");
1442 		return NULL;
1443 	}
1444 
1445 	for (i = 0; i < ARRAY_SIZE(muxes); i++) {
1446 		if (muxes[i].in_use) {
1447 			/* If the mux was already created, return it */
1448 			if (uart && muxes[i].uart == uart) {
1449 				return &muxes[i];
1450 			}
1451 
1452 			continue;
1453 		}
1454 
1455 		mux = &muxes[i];
1456 
1457 		memset(mux, 0, sizeof(*mux));
1458 
1459 		mux->in_use = true;
1460 		mux->uart = uart;
1461 		mux->mru = CONFIG_GSM_MUX_MRU_DEFAULT_LEN;
1462 		mux->retries = N2;
1463 		mux->t1_timeout_value = CONFIG_GSM_MUX_T1_TIMEOUT ?
1464 			CONFIG_GSM_MUX_T1_TIMEOUT : T1_MSEC;
1465 		mux->t2_timeout_value = T2_MSEC;
1466 		mux->is_initiator = CONFIG_GSM_MUX_INITIATOR;
1467 		mux->state = GSM_MUX_SOF;
1468 		mux->buf = NULL;
1469 
1470 		k_work_init_delayable(&mux->t2_timer, gsm_mux_t2_timeout);
1471 		sys_slist_init(&mux->pending_ctrls);
1472 
1473 		/* The system will continue after the control DLCI is
1474 		 * created or timeout occurs.
1475 		 */
1476 		break;
1477 	}
1478 
1479 	return mux;
1480 }
1481 
gsm_mux_send(struct gsm_mux * mux,uint8_t dlci_address,const uint8_t * buf,size_t size)1482 int gsm_mux_send(struct gsm_mux *mux, uint8_t dlci_address,
1483 		 const uint8_t *buf, size_t size)
1484 {
1485 	struct gsm_dlci *dlci;
1486 
1487 	dlci = gsm_dlci_get(mux, dlci_address);
1488 	if (!dlci) {
1489 		return -ENOENT;
1490 	}
1491 
1492 	/* Mux the data and send to UART */
1493 	return gsm_mux_send_data_msg(mux, true, dlci, FT_UIH, buf, size);
1494 }
1495 
gsm_mux_detach(struct gsm_mux * mux)1496 void gsm_mux_detach(struct gsm_mux *mux)
1497 {
1498 	struct gsm_dlci *dlci;
1499 
1500 	for (int i = 0; i < ARRAY_SIZE(dlcis); i++) {
1501 		dlci = &dlcis[i];
1502 
1503 		if (mux != dlci->mux || !dlci->in_use) {
1504 			continue;
1505 		}
1506 
1507 		dlci->in_use = false;
1508 		sys_slist_prepend(&dlci_free_entries, &dlci->node);
1509 	}
1510 }
1511 
gsm_mux_init(void)1512 void gsm_mux_init(void)
1513 {
1514 	int i;
1515 
1516 	if (gsm_mux_init_done) {
1517 		return;
1518 	}
1519 
1520 	gsm_mux_init_done = true;
1521 
1522 	sys_slist_init(&ctrls_free_entries);
1523 
1524 	for (i = 0; i < ARRAY_SIZE(ctrls); i++) {
1525 		sys_slist_prepend(&ctrls_free_entries, &ctrls[i].node);
1526 	}
1527 
1528 	sys_slist_init(&dlci_free_entries);
1529 
1530 	for (i = 0; i < ARRAY_SIZE(dlcis); i++) {
1531 		sys_slist_prepend(&dlci_free_entries, &dlcis[i].node);
1532 	}
1533 
1534 	k_work_init_delayable(&t1_timer, dlci_t1_timeout);
1535 }
1536