Skip to content

Commit bf3da29

Browse files
committed
modem_ppp: handle escaped bytes in a more general manner
1 parent ca954a6 commit bf3da29

File tree

2 files changed

+33
-43
lines changed

2 files changed

+33
-43
lines changed

include/zephyr/modem/ppp.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,10 @@ typedef void (*modem_ppp_init_iface)(struct net_if *iface);
3838
enum modem_ppp_receive_state {
3939
/* Searching for start of frame and header */
4040
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,
41+
MODEM_PPP_RECEIVE_STATE_HDR_ADDRESS_FIELD,
42+
MODEM_PPP_RECEIVE_STATE_HDR_CONTROL_FIELD,
4443
/* Writing bytes to network packet */
4544
MODEM_PPP_RECEIVE_STATE_WRITING,
46-
/* Unescaping next byte before writing to network packet */
47-
MODEM_PPP_RECEIVE_STATE_UNESCAPING,
4845
};
4946

5047
enum modem_ppp_transmit_state {
@@ -81,6 +78,9 @@ struct modem_ppp {
8178

8279
atomic_t state;
8380

81+
/* Indicates whether the last read byte was 0x7D */
82+
bool prev_byte_was_escape_byte;
83+
8484
/* Buffers used for processing partial frames */
8585
uint8_t *receive_buf;
8686
uint8_t *transmit_buf;

subsys/modem/modem_ppp.c

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -203,34 +203,43 @@ static bool modem_ppp_is_byte_expected(uint8_t byte, uint8_t expected_byte)
203203

204204
static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte)
205205
{
206+
// Previous bytes was 0x7D, so we need to unescape the currenty byte
207+
if (ppp->prev_byte_was_escape_byte) {
208+
ppp->prev_byte_was_escape_byte = false;
209+
byte ^= MODEM_PPP_VALUE_ESCAPE;
210+
}
211+
212+
// At any point between start and end of frame, we can receive an escape byte.
213+
if (ppp->receive_state != MODEM_PPP_RECEIVE_STATE_HDR_SOF) {
214+
if (byte == MODEM_PPP_CODE_ESCAPE) {
215+
ppp->prev_byte_was_escape_byte = true;
216+
return;
217+
}
218+
}
219+
206220
switch (ppp->receive_state) {
221+
// Start of frame
207222
case MODEM_PPP_RECEIVE_STATE_HDR_SOF:
208223
if (modem_ppp_is_byte_expected(byte, MODEM_PPP_CODE_DELIMITER)) {
209-
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_FF;
224+
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_ADDRESS_FIELD;
210225
}
211226
break;
212-
213-
case MODEM_PPP_RECEIVE_STATE_HDR_FF:
227+
case MODEM_PPP_RECEIVE_STATE_HDR_ADDRESS_FIELD:
214228
if (byte == MODEM_PPP_CODE_DELIMITER) {
215229
break;
216230
}
217231
if (modem_ppp_is_byte_expected(byte, 0xFF)) {
218-
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_7D;
219-
} else {
220-
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF;
232+
// address field is always 0xFF (broadcast)
233+
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_CONTROL_FIELD;
221234
}
222-
break;
223-
224-
case MODEM_PPP_RECEIVE_STATE_HDR_7D:
225-
if (modem_ppp_is_byte_expected(byte, MODEM_PPP_CODE_ESCAPE)) {
226-
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_23;
227-
} else {
235+
else {
228236
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF;
229237
}
230238
break;
231239

232-
case MODEM_PPP_RECEIVE_STATE_HDR_23:
233-
if (modem_ppp_is_byte_expected(byte, 0x23)) {
240+
case MODEM_PPP_RECEIVE_STATE_HDR_CONTROL_FIELD:
241+
if (modem_ppp_is_byte_expected(byte, 0x03)) {
242+
// control field is always 0x03 (Unnumbered Information frame, UI)
234243
ppp->rx_pkt = net_pkt_rx_alloc_with_buffer(ppp->iface,
235244
CONFIG_MODEM_PPP_NET_BUF_FRAG_SIZE, AF_UNSPEC, 0, K_NO_WAIT);
236245

@@ -243,10 +252,10 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte)
243252
LOG_DBG("Receiving PPP frame");
244253
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_WRITING;
245254
net_pkt_cursor_init(ppp->rx_pkt);
246-
} else {
255+
}
256+
else {
247257
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF;
248258
}
249-
250259
break;
251260

252261
case MODEM_PPP_RECEIVE_STATE_WRITING:
@@ -264,13 +273,13 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte)
264273

265274
ppp->rx_pkt = NULL;
266275
/* Skip SOF because the delimiter may be omitted for successive frames. */
267-
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_FF;
276+
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_ADDRESS_FIELD;
268277
break;
269278
}
270279

271280
if (net_pkt_available_buffer(ppp->rx_pkt) == 1) {
272281
if (net_pkt_alloc_buffer(ppp->rx_pkt, CONFIG_MODEM_PPP_NET_BUF_FRAG_SIZE,
273-
AF_INET, K_NO_WAIT) < 0) {
282+
AF_INET, K_NO_WAIT) < 0) {
274283
LOG_WRN("Failed to alloc buffer");
275284
net_pkt_unref(ppp->rx_pkt);
276285
ppp->rx_pkt = NULL;
@@ -279,11 +288,6 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte)
279288
}
280289
}
281290

282-
if (byte == MODEM_PPP_CODE_ESCAPE) {
283-
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_UNESCAPING;
284-
break;
285-
}
286-
287291
if (net_pkt_write_u8(ppp->rx_pkt, byte) < 0) {
288292
LOG_WRN("Dropped PPP frame");
289293
net_pkt_unref(ppp->rx_pkt);
@@ -295,21 +299,6 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte)
295299
}
296300

297301
break;
298-
299-
case MODEM_PPP_RECEIVE_STATE_UNESCAPING:
300-
if (net_pkt_write_u8(ppp->rx_pkt, (byte ^ MODEM_PPP_VALUE_ESCAPE)) < 0) {
301-
LOG_WRN("Dropped PPP frame");
302-
net_pkt_unref(ppp->rx_pkt);
303-
ppp->rx_pkt = NULL;
304-
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF;
305-
#if defined(CONFIG_NET_STATISTICS_PPP)
306-
ppp->stats.drop++;
307-
#endif
308-
break;
309-
}
310-
311-
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_WRITING;
312-
break;
313302
}
314303
}
315304

@@ -556,6 +545,7 @@ void modem_ppp_release(struct modem_ppp *ppp)
556545
k_work_cancel_sync(&ppp->process_work, &sync);
557546
ppp->pipe = NULL;
558547
ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF;
548+
ppp->prev_byte_was_escape_byte = false;
559549

560550
if (ppp->rx_pkt != NULL) {
561551
net_pkt_unref(ppp->rx_pkt);

0 commit comments

Comments
 (0)