Line data Source code
1 0 : /*
2 : * Copyright (c) 2022 Trackunit Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #include <zephyr/kernel.h>
8 : #include <zephyr/types.h>
9 : #include <zephyr/net/net_if.h>
10 : #include <zephyr/net/net_pkt.h>
11 : #include <zephyr/sys/ring_buffer.h>
12 : #include <zephyr/sys/atomic.h>
13 :
14 : #include <zephyr/modem/pipe.h>
15 : #include <zephyr/modem/stats.h>
16 :
17 : #ifndef ZEPHYR_MODEM_PPP_
18 0 : #define ZEPHYR_MODEM_PPP_
19 :
20 : #ifdef __cplusplus
21 : extern "C" {
22 : #endif
23 :
24 : /**
25 : * @brief Modem PPP
26 : * @defgroup modem_ppp Modem PPP
27 : * @since 3.5
28 : * @version 1.0.0
29 : * @ingroup modem
30 : * @{
31 : */
32 :
33 : /** L2 network interface init callback */
34 1 : typedef void (*modem_ppp_init_iface)(struct net_if *iface);
35 :
36 : /**
37 : * @cond INTERNAL_HIDDEN
38 : */
39 :
40 : enum modem_ppp_receive_state {
41 : /* Searching for start of frame and header */
42 : MODEM_PPP_RECEIVE_STATE_HDR_SOF = 0,
43 : MODEM_PPP_RECEIVE_STATE_HDR_FF,
44 : MODEM_PPP_RECEIVE_STATE_HDR_7D,
45 : MODEM_PPP_RECEIVE_STATE_HDR_23,
46 : /* Writing bytes to network packet */
47 : MODEM_PPP_RECEIVE_STATE_WRITING,
48 : /* Unescaping next byte before writing to network packet */
49 : MODEM_PPP_RECEIVE_STATE_UNESCAPING,
50 : };
51 :
52 : enum modem_ppp_transmit_state {
53 : MODEM_PPP_TRANSMIT_STATE_IDLE = 0,
54 : MODEM_PPP_TRANSMIT_STATE_SOF,
55 : MODEM_PPP_TRANSMIT_STATE_PROTOCOL,
56 : MODEM_PPP_TRANSMIT_STATE_DATA,
57 : MODEM_PPP_TRANSMIT_STATE_EOF,
58 : };
59 :
60 : struct modem_ppp {
61 : /* Network interface instance is bound to */
62 : struct net_if *iface;
63 :
64 : /* Hook for PPP L2 network interface initialization */
65 : modem_ppp_init_iface init_iface;
66 :
67 : atomic_t state;
68 :
69 : /* Buffers used for processing partial frames */
70 : uint8_t *receive_buf;
71 : uint8_t *transmit_buf;
72 : uint16_t buf_size;
73 :
74 : /* Wrapped PPP frames are sent and received through this pipe */
75 : struct modem_pipe *pipe;
76 :
77 : /* Receive PPP frame state */
78 : enum modem_ppp_receive_state receive_state;
79 :
80 : /* Allocated network packet being created */
81 : struct net_pkt *rx_pkt;
82 :
83 : /* Packet being sent */
84 : enum modem_ppp_transmit_state transmit_state;
85 : struct net_pkt *tx_pkt;
86 : uint16_t tx_pkt_fcs;
87 :
88 : /* Ring buffer used for transmitting partial PPP frame */
89 : struct ring_buf transmit_rb;
90 :
91 : struct k_fifo tx_pkt_fifo;
92 :
93 : /* Work */
94 : struct k_work send_work;
95 : struct k_work process_work;
96 :
97 : #if defined(CONFIG_NET_STATISTICS_PPP)
98 : struct net_stats_ppp stats;
99 : #endif
100 :
101 : #if CONFIG_MODEM_STATS
102 : struct modem_stats_buffer receive_buf_stats;
103 : struct modem_stats_buffer transmit_buf_stats;
104 : #endif
105 : };
106 :
107 : struct modem_ppp_config {
108 : const struct device *dev;
109 : };
110 :
111 : /**
112 : * @endcond
113 : */
114 :
115 : /**
116 : * @brief Attach pipe to instance and connect
117 : *
118 : * @param ppp Modem PPP instance
119 : * @param pipe Pipe to attach to modem PPP instance
120 : */
121 1 : int modem_ppp_attach(struct modem_ppp *ppp, struct modem_pipe *pipe);
122 :
123 : /**
124 : * @brief Get network interface modem PPP instance is bound to
125 : *
126 : * @param ppp Modem PPP instance
127 : * @returns Pointer to network interface modem PPP instance is bound to
128 : */
129 1 : struct net_if *modem_ppp_get_iface(struct modem_ppp *ppp);
130 :
131 : /**
132 : * @brief Release pipe from instance
133 : *
134 : * @param ppp Modem PPP instance
135 : */
136 1 : void modem_ppp_release(struct modem_ppp *ppp);
137 :
138 : /**
139 : * @cond INTERNAL_HIDDEN
140 : */
141 :
142 : /**
143 : * @brief Initialize modem PPP instance device
144 : * @param dev Device instance associated with network interface
145 : * @warning Should not be used directly
146 : */
147 : int modem_ppp_init_internal(const struct device *dev);
148 :
149 : /**
150 : * @endcond
151 : */
152 :
153 : /**
154 : * @brief Define a modem PPP module and bind it to a network interface
155 : *
156 : * @details This macro defines the modem_ppp instance, initializes a PPP L2
157 : * network device instance, and binds the modem_ppp instance to the PPP L2
158 : * instance.
159 : *
160 : * If underlying cellular device is given, the PPP interface will manage the
161 : * power state of the cellular device when starting and stopping the PPP.
162 : *
163 : * @param _dev Cellular device instance for power management or NULL if not used
164 : * @param _name Name of the statically defined modem_ppp instance
165 : * @param _init_iface Hook for the PPP L2 network interface init function
166 : * @param _prio Initialization priority of the PPP L2 net iface
167 : * @param _mtu Max size of net_pkt data sent and received on PPP L2 net iface
168 : * @param _buf_size Size of partial PPP frame transmit and receive buffers
169 : */
170 1 : #define MODEM_DEV_PPP_DEFINE(_dev, _name, _init_iface, _prio, _mtu, _buf_size) \
171 : extern const struct ppp_api modem_ppp_ppp_api; \
172 : \
173 : static uint8_t _CONCAT(_name, _receive_buf)[_buf_size]; \
174 : static uint8_t _CONCAT(_name, _transmit_buf)[_buf_size]; \
175 : \
176 : static struct modem_ppp _name = { \
177 : .init_iface = _init_iface, \
178 : .receive_buf = _CONCAT(_name, _receive_buf), \
179 : .transmit_buf = _CONCAT(_name, _transmit_buf), \
180 : .buf_size = _buf_size, \
181 : }; \
182 : static const struct modem_ppp_config _CONCAT(_name, _config) = { \
183 : .dev = _dev, \
184 : }; \
185 : \
186 : NET_DEVICE_INIT(_CONCAT(ppp_net_dev_, _name), "modem_ppp_" #_name, \
187 : modem_ppp_init_internal, NULL, &_name, &_CONCAT(_name, _config), _prio, \
188 : &modem_ppp_ppp_api, PPP_L2, NET_L2_GET_CTX_TYPE(PPP_L2), _mtu)
189 :
190 : /**
191 : * @brief Define a modem PPP module for cellular device tree instance.
192 : *
193 : * @see MODEM_DEV_PPP_DEFINE
194 : */
195 1 : #define MODEM_DT_INST_PPP_DEFINE(inst, _name, _init_iface, _prio, _mtu, _buf_size) \
196 : MODEM_DEV_PPP_DEFINE(DEVICE_DT_INST_GET(inst), _name, _init_iface, _prio, _mtu, _buf_size)
197 :
198 : /**
199 : * @brief Define a modem PPP module without a device and bind it to a network interface.
200 : *
201 : * @see MODEM_DEV_PPP_DEFINE
202 : */
203 1 : #define MODEM_PPP_DEFINE(_name, _init_iface, _prio, _mtu, _buf_size) \
204 : MODEM_DEV_PPP_DEFINE(NULL, _name, _init_iface, _prio, _mtu, _buf_size)
205 :
206 : /**
207 : * @}
208 : */
209 :
210 : #ifdef __cplusplus
211 : }
212 : #endif
213 :
214 : #endif /* ZEPHYR_MODEM_PPP_ */
|