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