Zephyr API Documentation  3.5.0
A Scalable Open Source RTOS
3.5.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
cmux.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Trackunit Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7/*
8 * This library uses CMUX to create multiple data channels, called DLCIs, on a single serial bus.
9 * Each DLCI has an address from 1 to 63. DLCI address 0 is reserved for control commands.
10 *
11 * Design overview:
12 *
13 * DLCI1 <-----------+ +-------> DLCI1
14 * v v
15 * DLCI2 <---> CMUX instance <--> Serial bus <--> Client <--> DLCI2
16 * ^ ^
17 * DLCI3 <-----------+ +-------> DLCI3
18 *
19 * Writing to and from the CMUX instances is done using the modem_pipe API.
20 */
21
22#include <zephyr/kernel.h>
23#include <zephyr/types.h>
25#include <zephyr/sys/atomic.h>
26
27#include <zephyr/modem/pipe.h>
28
29#ifndef ZEPHYR_MODEM_CMUX_
30#define ZEPHYR_MODEM_CMUX_
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
43struct modem_cmux;
44
48};
49
50typedef void (*modem_cmux_callback)(struct modem_cmux *cmux, enum modem_cmux_event event,
51 void *user_data);
52
57enum modem_cmux_state {
58 MODEM_CMUX_STATE_DISCONNECTED = 0,
59 MODEM_CMUX_STATE_CONNECTING,
60 MODEM_CMUX_STATE_CONNECTED,
61 MODEM_CMUX_STATE_DISCONNECTING,
62};
63
64enum modem_cmux_receive_state {
65 MODEM_CMUX_RECEIVE_STATE_SOF = 0,
66 MODEM_CMUX_RECEIVE_STATE_RESYNC_0,
67 MODEM_CMUX_RECEIVE_STATE_RESYNC_1,
68 MODEM_CMUX_RECEIVE_STATE_RESYNC_2,
69 MODEM_CMUX_RECEIVE_STATE_RESYNC_3,
70 MODEM_CMUX_RECEIVE_STATE_ADDRESS,
71 MODEM_CMUX_RECEIVE_STATE_ADDRESS_CONT,
72 MODEM_CMUX_RECEIVE_STATE_CONTROL,
73 MODEM_CMUX_RECEIVE_STATE_LENGTH,
74 MODEM_CMUX_RECEIVE_STATE_LENGTH_CONT,
75 MODEM_CMUX_RECEIVE_STATE_DATA,
76 MODEM_CMUX_RECEIVE_STATE_FCS,
77 MODEM_CMUX_RECEIVE_STATE_DROP,
78 MODEM_CMUX_RECEIVE_STATE_EOF,
79};
80
81enum modem_cmux_dlci_state {
82 MODEM_CMUX_DLCI_STATE_CLOSED,
83 MODEM_CMUX_DLCI_STATE_OPENING,
84 MODEM_CMUX_DLCI_STATE_OPEN,
85 MODEM_CMUX_DLCI_STATE_CLOSING,
86};
87
88struct modem_cmux_dlci {
89 sys_snode_t node;
90
91 /* Pipe */
92 struct modem_pipe pipe;
93
94 /* Context */
95 uint16_t dlci_address;
96 struct modem_cmux *cmux;
97
98 /* Receive buffer */
99 struct ring_buf receive_rb;
100 struct k_mutex receive_rb_lock;
101
102 /* Work */
103 struct k_work_delayable open_work;
104 struct k_work_delayable close_work;
105
106 /* State */
107 enum modem_cmux_dlci_state state;
108};
109
110struct modem_cmux_frame {
111 uint16_t dlci_address;
112 bool cr;
113 bool pf;
114 uint8_t type;
115 const uint8_t *data;
116 uint16_t data_len;
117};
118
119struct modem_cmux_work {
120 struct k_work_delayable dwork;
121 struct modem_cmux *cmux;
122};
123
124struct modem_cmux {
125 /* Bus pipe */
126 struct modem_pipe *pipe;
127
128 /* Event handler */
129 modem_cmux_callback callback;
130 void *user_data;
131
132 /* DLCI channel contexts */
133 sys_slist_t dlcis;
134
135 /* State */
136 enum modem_cmux_state state;
137 bool flow_control_on;
138
139 /* Receive state*/
140 enum modem_cmux_receive_state receive_state;
141
142 /* Receive buffer */
143 uint8_t *receive_buf;
144 uint16_t receive_buf_size;
145 uint16_t receive_buf_len;
146
147 /* Transmit buffer */
148 struct ring_buf transmit_rb;
149 struct k_mutex transmit_rb_lock;
150
151 /* Received frame */
152 struct modem_cmux_frame frame;
153 uint8_t frame_header[5];
154 uint16_t frame_header_len;
155
156 /* Work */
157 struct k_work_delayable receive_work;
158 struct k_work_delayable transmit_work;
159 struct k_work_delayable connect_work;
160 struct k_work_delayable disconnect_work;
161
162 /* Synchronize actions */
163 struct k_event event;
164};
165
186};
187
193void modem_cmux_init(struct modem_cmux *cmux, const struct modem_cmux_config *config);
194
205};
206
214struct modem_pipe *modem_cmux_dlci_init(struct modem_cmux *cmux, struct modem_cmux_dlci *dlci,
215 const struct modem_cmux_dlci_config *config);
216
223int modem_cmux_attach(struct modem_cmux *cmux, struct modem_pipe *pipe);
224
235int modem_cmux_connect(struct modem_cmux *cmux);
236
247int modem_cmux_connect_async(struct modem_cmux *cmux);
248
259int modem_cmux_disconnect(struct modem_cmux *cmux);
260
271int modem_cmux_disconnect_async(struct modem_cmux *cmux);
272
283void modem_cmux_release(struct modem_cmux *cmux);
284
289#ifdef __cplusplus
290}
291#endif
292
293#endif /* ZEPHYR_MODEM_CMUX_ */
int modem_cmux_connect(struct modem_cmux *cmux)
Connect CMUX instance.
int modem_cmux_disconnect(struct modem_cmux *cmux)
Close down and disconnect CMUX instance.
int modem_cmux_disconnect_async(struct modem_cmux *cmux)
Close down and disconnect CMUX instance asynchronously.
void(* modem_cmux_callback)(struct modem_cmux *cmux, enum modem_cmux_event event, void *user_data)
Definition: cmux.h:50
int modem_cmux_connect_async(struct modem_cmux *cmux)
Connect CMUX instance asynchronously.
modem_cmux_event
Definition: cmux.h:45
int modem_cmux_attach(struct modem_cmux *cmux, struct modem_pipe *pipe)
Attach CMUX instance to pipe.
struct modem_pipe * modem_cmux_dlci_init(struct modem_cmux *cmux, struct modem_cmux_dlci *dlci, const struct modem_cmux_dlci_config *config)
Initialize DLCI instance and register it with CMUX instance.
void modem_cmux_init(struct modem_cmux *cmux, const struct modem_cmux_config *config)
Initialize CMUX instance.
void modem_cmux_release(struct modem_cmux *cmux)
Release CMUX instance from pipe.
@ MODEM_CMUX_EVENT_DISCONNECTED
Definition: cmux.h:47
@ MODEM_CMUX_EVENT_CONNECTED
Definition: cmux.h:46
struct _slist sys_slist_t
Single-linked list structure.
Definition: slist.h:49
struct _snode sys_snode_t
Single-linked list node structure.
Definition: slist.h:39
Public kernel APIs.
state
Definition: parser_state.h:29
__UINT8_TYPE__ uint8_t
Definition: stdint.h:88
__UINT16_TYPE__ uint16_t
Definition: stdint.h:89
Event Structure.
Definition: kernel.h:2218
Mutex Structure.
Definition: kernel.h:2911
A structure used to submit work after a delay.
Definition: kernel.h:3893
Contains CMUX instance configuration data.
Definition: cmux.h:173
uint8_t * receive_buf
Receive buffer.
Definition: cmux.h:179
modem_cmux_callback callback
Invoked when event occurs.
Definition: cmux.h:175
uint16_t receive_buf_size
Size of receive buffer in bytes [127, ...].
Definition: cmux.h:181
void * user_data
Free to use pointer passed to event handler when invoked.
Definition: cmux.h:177
uint8_t * transmit_buf
Transmit buffer.
Definition: cmux.h:183
uint16_t transmit_buf_size
Size of transmit buffer in bytes [149, ...].
Definition: cmux.h:185
CMUX DLCI configuration.
Definition: cmux.h:198
uint8_t dlci_address
DLCI channel address.
Definition: cmux.h:200
uint8_t * receive_buf
Receive buffer used by pipe.
Definition: cmux.h:202
uint16_t receive_buf_size
Size of receive buffer used by pipe [127, ...].
Definition: cmux.h:204
A structure to represent a ring buffer.
Definition: ring_buffer.h:41