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