Re: [PATCH v8 4/5] iio: osf: add authenticated stream parser
Jonathan Cameron <[email protected]>
| Newsgroups | org.kernel.vger.linux-doc,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-iio,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260821034748.5049aca0@jic23-huawei> |
On Thu, 20 Aug 2026 14:06:07 +0900 Jinseob Kim <[email protected]> wrote: > Add a UART byte-stream parser for Open Sensor Fusion frames. > > The parser searches for the OSF0 wire magic, keeps partial frames > buffered, checks header length and payload bounds, and passes complete > candidate frames to a registered frame callback. > > Candidates rejected before authentication drop only the current head > byte before resynchronizing, so a corrupted unauthenticated payload length > cannot make the parser skip later valid frames. CRC-valid authenticated > frames are consumed in full and classified as handled, ignored, or > rejected. > > Use a direct callback member with an opaque context and keep explicit > statistics for authenticated outcomes and framing failures. > > Signed-off-by: Jinseob Kim <[email protected]> One really trivial thing inline. Please check to see if other areas of code alignment would benefit from a bit of a reorg. > diff --git a/drivers/iio/opensensorfusion/osf_stream.c b/drivers/iio/opensensorfusion/osf_stream.c > new file mode 100644 > index 000000000000..7ce45e631648 > --- /dev/null > +++ b/drivers/iio/opensensorfusion/osf_stream.c ... > + > +static int osf_stream_process(struct osf_stream *stream) > +{ > + size_t discarded; > + size_t frame_len; > + u32 payload_len; > + int frame_result; > + int first_err = 0; > + > + while (stream->len) { > + discarded = osf_stream_discard_to_magic(stream); > + if (discarded) { > + stream->stats.bad_magic_resyncs++; > + stream->stats.dropped_bytes += discarded; > + if (!first_err) > + first_err = -EPROTO; > + } > + > + if (!stream->len) > + break; > + > + if (stream->len < OSF_FRAME_HEADER_LEN) > + break; > + > + if (get_unaligned_le16(stream->buf + 6) != OSF_FRAME_HEADER_LEN) { > + stream->stats.dropped_bytes++; > + osf_stream_drop_invalid_head(stream); > + if (!first_err) > + first_err = -EPROTO; > + continue; > + } > + > + payload_len = get_unaligned_le32(stream->buf + 10); > + if (payload_len > OSF_STREAM_MAX_PAYLOAD_LEN) { > + stream->stats.dropped_bytes++; > + osf_stream_drop_invalid_head(stream); > + if (!first_err) > + first_err = -EMSGSIZE; > + continue; > + } > + > + frame_len = OSF_FRAME_HEADER_LEN + payload_len + OSF_FRAME_CRC_LEN; > + if (stream->len < frame_len) > + break; > + > + frame_result = stream->receive_frame(stream->frame_context, > + stream->buf, frame_len); Align after ( > + if (frame_result < 0) { > + if (frame_result == -EBADMSG) > + stream->stats.bad_crc_frames++; > + > + /* > + * Decoding failed before the frame was authenticated; > + * payload_len is still untrusted. Drop only the current > + * head and resynchronize. > + */ > + stream->stats.dropped_bytes++; > + osf_stream_drop_invalid_head(stream); > + if (!first_err) > + first_err = frame_result; > + continue; > + } > + > + /* Count exactly one outcome for every authenticated frame. */ > + stream->stats.authenticated_frames++; > + switch (frame_result) { > + case OSF_STREAM_FRAME_HANDLED: > + stream->stats.handled_frames++; > + break; > + case OSF_STREAM_FRAME_IGNORED: > + stream->stats.ignored_frames++; > + break; > + case OSF_STREAM_FRAME_REJECTED: > + stream->stats.rejected_frames++; > + break; > + default: > + /* > + * Preserve the authenticated boundary without scanning the > + * payload for another magic value. > + */ > + stream->stats.rejected_frames++; > + if (!first_err) > + first_err = -EPROTO; > + break; > + } > + osf_stream_discard(stream, frame_len); > + } > + > + return first_err; > +}