Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
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#include <zephyr/sys/util.h>
27
28#include <zephyr/modem/pipe.h>
29#include <zephyr/modem/stats.h>
30
31#ifndef ZEPHYR_INCLUDE_MODEM_CMUX_H_
32#define ZEPHYR_INCLUDE_MODEM_CMUX_H_
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
46
47struct modem_cmux;
48
53
54typedef void (*modem_cmux_callback)(struct modem_cmux *cmux, enum modem_cmux_event event,
55 void *user_data);
56
82
86
87#if CONFIG_MODEM_CMUX_MTU > 127
88#define MODEM_CMUX_HEADER_SIZE 7
89#else
90#define MODEM_CMUX_HEADER_SIZE 6
91#endif
92
93/* Minimum required size for CMUX RX buffers */
94#define MODEM_CMUX_RX_BUFFER_SIZE_MIN 126
95
96/* Total size of the CMUX work buffers from the MTU */
97#define MODEM_CMUX_WORK_BUFFER_FROM_MTU (CONFIG_MODEM_CMUX_MTU + MODEM_CMUX_HEADER_SIZE + \
98 CONFIG_MODEM_CMUX_WORK_BUFFER_SIZE_EXTRA)
99
100/* Enforce the minimum size required by CMUX */
101#define MODEM_CMUX_WORK_BUFFER_SIZE MAX(MODEM_CMUX_WORK_BUFFER_FROM_MTU, \
102 MODEM_CMUX_RX_BUFFER_SIZE_MIN)
103
104enum modem_cmux_state {
105 MODEM_CMUX_STATE_DISCONNECTED = 0,
106 MODEM_CMUX_STATE_CONNECTING,
107 MODEM_CMUX_STATE_CONNECTED,
108 MODEM_CMUX_STATE_ENTER_POWERSAVE,
109 MODEM_CMUX_STATE_POWERSAVE,
110 MODEM_CMUX_STATE_CONFIRM_POWERSAVE,
111 MODEM_CMUX_STATE_WAKEUP,
112 MODEM_CMUX_STATE_DISCONNECTING,
113};
114
115enum modem_cmux_receive_state {
116 MODEM_CMUX_RECEIVE_STATE_SOF = 0,
117 MODEM_CMUX_RECEIVE_STATE_RESYNC,
118 MODEM_CMUX_RECEIVE_STATE_ADDRESS,
119 MODEM_CMUX_RECEIVE_STATE_ADDRESS_CONT,
120 MODEM_CMUX_RECEIVE_STATE_CONTROL,
121 MODEM_CMUX_RECEIVE_STATE_LENGTH,
122 MODEM_CMUX_RECEIVE_STATE_LENGTH_CONT,
123 MODEM_CMUX_RECEIVE_STATE_DATA,
124 MODEM_CMUX_RECEIVE_STATE_DATA_CONT,
125 MODEM_CMUX_RECEIVE_STATE_FCS,
126 MODEM_CMUX_RECEIVE_STATE_EOF,
127};
128
129enum modem_cmux_dlci_state {
130 MODEM_CMUX_DLCI_STATE_CLOSED,
131 MODEM_CMUX_DLCI_STATE_OPENING,
132 MODEM_CMUX_DLCI_STATE_OPEN,
133 MODEM_CMUX_DLCI_STATE_CLOSING,
134};
135
136struct modem_cmux_dlci {
137 sys_snode_t node;
138
139 /* Pipe */
140 struct modem_pipe pipe;
141
142 /* Context */
143 uint16_t dlci_address;
144 struct modem_cmux *cmux;
145
146 /* Receive buffer */
147 struct ring_buf receive_rb;
148 struct k_mutex receive_rb_lock;
149
150 /* Work */
151 struct k_work_delayable open_work;
152 struct k_work_delayable close_work;
153
154 /* State */
155 enum modem_cmux_dlci_state state;
156
157 /* Statistics */
158#if CONFIG_MODEM_STATS
159 struct modem_stats_buffer receive_buf_stats;
160#endif
161 /* Flow control */
162 bool flow_control : 1;
163 bool rx_full : 1;
164 bool msc_sent : 1;
165};
166
167struct modem_cmux_frame {
168 uint8_t dlci_address;
169 bool cr;
170 bool pf;
171 uint8_t type;
172 const uint8_t *data;
173 const uint8_t *tx_extra;
174 uint16_t data_len;
175 uint16_t tx_extra_len;
176};
177
178struct modem_cmux_work {
179 struct k_work_delayable dwork;
180 struct modem_cmux *cmux;
181};
182
183struct modem_cmux {
184 /* Bus pipe */
185 struct modem_pipe *pipe;
186
187 /* DLCI channel contexts */
188 sys_slist_t dlcis;
189
190 /* State */
191 enum modem_cmux_state state;
192 uint8_t retry_count;
193 bool flow_control_on : 1;
194 bool initiator : 1;
195
196 /* Work lock */
197 bool attached : 1;
198 struct k_spinlock work_lock;
199
200 /* Receive state*/
201 enum modem_cmux_receive_state receive_state;
202 int receive_buf_len;
203
204 /* Transmit buffer */
205 struct ring_buf transmit_rb;
206 struct k_mutex transmit_rb_lock;
207
208 /* Received frame */
209 struct modem_cmux_frame frame;
210 int frame_start;
211 uint16_t frame_header_len;
212
213 /* Work */
214 struct k_work_delayable receive_work;
215 struct k_work_delayable transmit_work;
216 struct k_work_delayable connect_work;
217 struct k_work_delayable disconnect_work;
218 struct k_work_delayable runtime_pm_work;
219
220 /* Synchronize actions */
221 struct k_event event;
222 k_timepoint_t t3_timepoint;
223 k_timepoint_t idle_timepoint;
224
225 /* Statistics */
226#if CONFIG_MODEM_STATS
227 struct modem_stats_buffer receive_buf_stats;
228 struct modem_stats_buffer transmit_buf_stats;
229#endif
230 struct modem_cmux_config config;
231};
232
236
242void modem_cmux_init(struct modem_cmux *cmux, const struct modem_cmux_config *config);
243
255
263struct modem_pipe *modem_cmux_dlci_init(struct modem_cmux *cmux, struct modem_cmux_dlci *dlci,
264 const struct modem_cmux_dlci_config *config);
265
272int modem_cmux_attach(struct modem_cmux *cmux, struct modem_pipe *pipe);
273
284int modem_cmux_connect(struct modem_cmux *cmux);
285
296int modem_cmux_connect_async(struct modem_cmux *cmux);
297
308int modem_cmux_disconnect(struct modem_cmux *cmux);
309
320int modem_cmux_disconnect_async(struct modem_cmux *cmux);
321
332void modem_cmux_release(struct modem_cmux *cmux);
333
337
338#ifdef __cplusplus
339}
340#endif
341
342#endif /* ZEPHYR_INCLUDE_MODEM_CMUX_H_ */
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:54
int modem_cmux_connect_async(struct modem_cmux *cmux)
Connect CMUX instance asynchronously.
modem_cmux_event
Definition cmux.h:49
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:51
@ MODEM_CMUX_EVENT_CONNECTED
Definition cmux.h:50
struct _slist sys_slist_t
Single-linked list structure.
Definition slist.h:54
struct _snode sys_snode_t
Single-linked list node structure.
Definition slist.h:44
Public kernel APIs.
state
Definition parser_state.h:29
Header file for the ring buffer API.
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
Kernel timeout type.
Definition clock.h:65
Contains CMUX instance configuration data.
Definition cmux.h:60
bool no_powersave_handshake
Skip the in-band power-save handshake on both entry and exit.
Definition cmux.h:78
bool enable_runtime_power_management
Enable runtime power management.
Definition cmux.h:74
uint8_t * receive_buf
Receive buffer.
Definition cmux.h:66
modem_cmux_callback callback
Invoked when event occurs.
Definition cmux.h:62
uint16_t receive_buf_size
Size of receive buffer in bytes [127, ...].
Definition cmux.h:68
void * user_data
Free to use pointer passed to event handler when invoked.
Definition cmux.h:64
uint8_t * transmit_buf
Transmit buffer.
Definition cmux.h:70
k_timeout_t idle_timeout
Idle timeout for power save.
Definition cmux.h:80
bool close_pipe_on_power_save
Close pipe on power save.
Definition cmux.h:76
uint16_t transmit_buf_size
Size of transmit buffer in bytes [149, ...].
Definition cmux.h:72
CMUX DLCI configuration.
Definition cmux.h:247
uint8_t dlci_address
DLCI channel address.
Definition cmux.h:249
uint8_t * receive_buf
Receive buffer used by pipe.
Definition cmux.h:251
uint16_t receive_buf_size
Size of receive buffer used by pipe [127, ...].
Definition cmux.h:253
Header file for the Atomic operations API.
Misc utilities.