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 : /* Idle */
54 : MODEM_PPP_TRANSMIT_STATE_IDLE = 0,
55 : /* Writing header */
56 : MODEM_PPP_TRANSMIT_STATE_SOF,
57 : MODEM_PPP_TRANSMIT_STATE_HDR_FF,
58 : MODEM_PPP_TRANSMIT_STATE_HDR_7D,
59 : MODEM_PPP_TRANSMIT_STATE_HDR_23,
60 : /* Writing protocol */
61 : MODEM_PPP_TRANSMIT_STATE_PROTOCOL_HIGH,
62 : MODEM_PPP_TRANSMIT_STATE_ESCAPING_PROTOCOL_HIGH,
63 : MODEM_PPP_TRANSMIT_STATE_PROTOCOL_LOW,
64 : MODEM_PPP_TRANSMIT_STATE_ESCAPING_PROTOCOL_LOW,
65 : /* Writing data */
66 : MODEM_PPP_TRANSMIT_STATE_DATA,
67 : MODEM_PPP_TRANSMIT_STATE_ESCAPING_DATA,
68 : /* Writing FCS */
69 : MODEM_PPP_TRANSMIT_STATE_FCS_LOW,
70 : MODEM_PPP_TRANSMIT_STATE_ESCAPING_FCS_LOW,
71 : MODEM_PPP_TRANSMIT_STATE_FCS_HIGH,
72 : MODEM_PPP_TRANSMIT_STATE_ESCAPING_FCS_HIGH,
73 : /* Writing end of frame */
74 : MODEM_PPP_TRANSMIT_STATE_EOF,
75 : };
76 :
77 : struct modem_ppp {
78 : /* Network interface instance is bound to */
79 : struct net_if *iface;
80 :
81 : /* Hook for PPP L2 network interface initialization */
82 : modem_ppp_init_iface init_iface;
83 :
84 : atomic_t state;
85 :
86 : /* Buffers used for processing partial frames */
87 : uint8_t *receive_buf;
88 : uint8_t *transmit_buf;
89 : uint16_t buf_size;
90 :
91 : /* Wrapped PPP frames are sent and received through this pipe */
92 : struct modem_pipe *pipe;
93 :
94 : /* Receive PPP frame state */
95 : enum modem_ppp_receive_state receive_state;
96 :
97 : /* Allocated network packet being created */
98 : struct net_pkt *rx_pkt;
99 :
100 : /* Packet being sent */
101 : enum modem_ppp_transmit_state transmit_state;
102 : struct net_pkt *tx_pkt;
103 : uint8_t tx_pkt_escaped;
104 : uint16_t tx_pkt_protocol;
105 : uint16_t tx_pkt_fcs;
106 :
107 : /* Ring buffer used for transmitting partial PPP frame */
108 : struct ring_buf transmit_rb;
109 :
110 : struct k_fifo tx_pkt_fifo;
111 :
112 : /* Work */
113 : struct k_work send_work;
114 : struct k_work process_work;
115 :
116 : #if defined(CONFIG_NET_STATISTICS_PPP)
117 : struct net_stats_ppp stats;
118 : #endif
119 :
120 : #if CONFIG_MODEM_STATS
121 : struct modem_stats_buffer receive_buf_stats;
122 : struct modem_stats_buffer transmit_buf_stats;
123 : #endif
124 : };
125 :
126 : /**
127 : * @endcond
128 : */
129 :
130 : /**
131 : * @brief Attach pipe to instance and connect
132 : *
133 : * @param ppp Modem PPP instance
134 : * @param pipe Pipe to attach to modem PPP instance
135 : */
136 1 : int modem_ppp_attach(struct modem_ppp *ppp, struct modem_pipe *pipe);
137 :
138 : /**
139 : * @brief Get network interface modem PPP instance is bound to
140 : *
141 : * @param ppp Modem PPP instance
142 : * @returns Pointer to network interface modem PPP instance is bound to
143 : */
144 1 : struct net_if *modem_ppp_get_iface(struct modem_ppp *ppp);
145 :
146 : /**
147 : * @brief Release pipe from instance
148 : *
149 : * @param ppp Modem PPP instance
150 : */
151 1 : void modem_ppp_release(struct modem_ppp *ppp);
152 :
153 : /**
154 : * @cond INTERNAL_HIDDEN
155 : */
156 :
157 : /**
158 : * @brief Initialize modem PPP instance device
159 : * @param dev Device instance associated with network interface
160 : * @warning Should not be used directly
161 : */
162 : int modem_ppp_init_internal(const struct device *dev);
163 :
164 : /**
165 : * @endcond
166 : */
167 :
168 : /**
169 : * @brief Define a modem PPP module and bind it to a network interface
170 : *
171 : * @details This macro defines the modem_ppp instance, initializes a PPP L2
172 : * network device instance, and binds the modem_ppp instance to the PPP L2
173 : * instance.
174 : *
175 : * @param _name Name of the statically defined modem_ppp instance
176 : * @param _init_iface Hook for the PPP L2 network interface init function
177 : * @param _prio Initialization priority of the PPP L2 net iface
178 : * @param _mtu Max size of net_pkt data sent and received on PPP L2 net iface
179 : * @param _buf_size Size of partial PPP frame transmit and receive buffers
180 : */
181 1 : #define MODEM_PPP_DEFINE(_name, _init_iface, _prio, _mtu, _buf_size) \
182 : extern const struct ppp_api modem_ppp_ppp_api; \
183 : \
184 : static uint8_t _CONCAT(_name, _receive_buf)[_buf_size]; \
185 : static uint8_t _CONCAT(_name, _transmit_buf)[_buf_size]; \
186 : \
187 : static struct modem_ppp _name = { \
188 : .init_iface = _init_iface, \
189 : .receive_buf = _CONCAT(_name, _receive_buf), \
190 : .transmit_buf = _CONCAT(_name, _transmit_buf), \
191 : .buf_size = _buf_size, \
192 : }; \
193 : \
194 : NET_DEVICE_INIT(_CONCAT(ppp_net_dev_, _name), "modem_ppp_" # _name, \
195 : modem_ppp_init_internal, NULL, &_name, NULL, _prio, &modem_ppp_ppp_api, \
196 : PPP_L2, NET_L2_GET_CTX_TYPE(PPP_L2), _mtu)
197 :
198 : /**
199 : * @}
200 : */
201 :
202 : #ifdef __cplusplus
203 : }
204 : #endif
205 :
206 : #endif /* ZEPHYR_MODEM_PPP_ */
|