Morse Micro IoT SDK  2.6.4-esp32
mmpkt.h
1/*
2 * Copyright 2022-2024 Morse Micro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
15#pragma once
16
17#include <stdbool.h>
18#include <stddef.h>
19#include <stdint.h>
20
21#include "mmosal.h"
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27
33#ifndef MM_FAST_ROUND_UP
34#define MM_FAST_ROUND_UP(x, m) ((((x)-1) | ((m)-1)) + 1)
35#endif
36
37struct mmdrv_cmd_metadata;
38struct mmdrv_tx_metadata;
39struct mmdrv_rx_metadata;
40struct mmpkt_ops;
41
50 void *opaque;
52 struct mmdrv_tx_metadata *tx;
54 struct mmdrv_rx_metadata *rx;
56 struct mmdrv_cmd_metadata *cmd;
57};
58
78struct mmpkt
79{
81 uint8_t *buf;
83 uint32_t buf_len;
85 uint32_t start_offset;
87 uint32_t data_len;
91 const struct mmpkt_ops *ops;
93 struct mmpkt *volatile next;
94};
95
98{
100 void (*free_mmpkt)(void *mmpkt);
101};
102
114struct mmpktview;
115
125static inline void mmpkt_init(struct mmpkt *mmpkt, uint8_t *buf, uint32_t buf_len,
126 uint32_t data_start_offset, const struct mmpkt_ops *ops)
127{
128 memset(mmpkt, 0, sizeof(*mmpkt));
129 mmpkt->buf = buf;
130 mmpkt->buf_len = buf_len;
131 mmpkt->start_offset = data_start_offset;
132 mmpkt->ops = ops;
133}
134
152static inline struct mmpkt *mmpkt_init_buf(uint8_t *buf, uint32_t buf_len,
153 uint32_t space_at_start, uint32_t space_at_end,
154 uint32_t metadata_size, const struct mmpkt_ops *ops)
155{
156 struct mmpkt *mmpkt = (struct mmpkt *)buf;
157
158 uint8_t *data_start;
159 uint32_t header_size = MM_FAST_ROUND_UP(sizeof(*mmpkt), 4);
160 uint32_t data_len = MM_FAST_ROUND_UP(space_at_start + space_at_end, 4);
161 metadata_size = MM_FAST_ROUND_UP(metadata_size, 4);
162
163 if (header_size + data_len + metadata_size > buf_len)
164 {
165 return NULL;
166 }
167
168 data_start = ((uint8_t *)mmpkt) + header_size;
169
170 mmpkt_init(mmpkt, data_start, data_len, space_at_start, ops);
171
172 if (metadata_size != 0)
173 {
174 mmpkt->metadata.opaque = data_start + data_len;
175 memset(mmpkt->metadata.opaque, 0, metadata_size);
176 }
177
178 return mmpkt;
179}
180
181
194struct mmpkt *mmpkt_alloc_on_heap(uint32_t space_at_start, uint32_t space_at_end,
195 uint32_t metadata_size);
196
204
218static inline struct mmpktview *mmpkt_open(struct mmpkt *mmpkt)
219{
220 return (struct mmpktview *)mmpkt;
221}
222
229static inline void mmpkt_close(struct mmpktview **view)
230{
231 (void)(view);
232}
233
241static inline struct mmpkt *mmpkt_from_view(struct mmpktview *view)
242{
243 return (struct mmpkt *)view;
244}
245
253static inline uint8_t *mmpkt_get_data_start(struct mmpktview *view)
254{
255 struct mmpkt *mmpkt = (struct mmpkt *)view;
256 return mmpkt->buf + mmpkt->start_offset;
257}
258
266static inline uint8_t *mmpkt_get_data_end(struct mmpktview *view)
267{
268 struct mmpkt *mmpkt = (struct mmpkt *)view;
270}
271
280static inline uint32_t mmpkt_peek_data_length(struct mmpkt *mmpkt)
281{
282 return mmpkt->data_len;
283}
284
293static inline uint32_t mmpkt_get_data_length(struct mmpktview *view)
294{
295 struct mmpkt *mmpkt = (struct mmpkt *)view;
296 return mmpkt->data_len;
297}
298
306static inline uint32_t mmpkt_available_space_at_start(struct mmpktview *view)
307{
308 struct mmpkt *mmpkt = (struct mmpkt *)view;
309 return mmpkt->start_offset;
310}
311
319static inline uint32_t mmpkt_available_space_at_end(struct mmpktview *view)
320{
321 struct mmpkt *mmpkt = (struct mmpkt *)view;
323}
324
338static inline uint8_t *mmpkt_prepend(struct mmpktview *view, uint32_t len)
339{
340 struct mmpkt *mmpkt = (struct mmpkt *)view;
342 mmpkt->start_offset -= len;
343 mmpkt->data_len += len;
344 return mmpkt->buf + mmpkt->start_offset;
345}
346
358static inline void mmpkt_prepend_data(struct mmpktview *view, const uint8_t * data, uint32_t len)
359{
360 uint8_t *dest = mmpkt_prepend(view, len);
361 memcpy(dest, data, len);
362}
363
377static inline uint8_t *mmpkt_append(struct mmpktview *view, uint32_t len)
378{
379 struct mmpkt *mmpkt = (struct mmpkt *)view;
380 uint8_t *ret = mmpkt_get_data_end(view);
382 mmpkt->data_len += len;
383 return ret;
384}
385
395static inline void mmpkt_append_data(struct mmpktview *view, const uint8_t *data, uint32_t len)
396{
397 uint8_t *dest = mmpkt_append(view, len);
398 memcpy(dest, data, len);
399}
400
409{
410 return mmpkt->metadata;
411}
412
421static inline uint8_t *mmpkt_remove_from_start(struct mmpktview *view, uint32_t len)
422{
423 struct mmpkt *mmpkt = (struct mmpkt *)view;
424 uint8_t *ret;
425
426 if (mmpkt_get_data_length(view) < len)
427 {
428 return NULL;
429 }
430
431 ret = mmpkt_get_data_start(view);
432
433 mmpkt->start_offset += len;
434 mmpkt->data_len -= len;
435
436 return ret;
437}
438
447static inline uint8_t *mmpkt_remove_from_end(struct mmpktview *view, uint32_t len)
448{
449 struct mmpkt *mmpkt = (struct mmpkt *)view;
450 uint8_t *ret;
451
452 if (mmpkt_get_data_length(view) < len)
453 {
454 return NULL;
455 }
456
457 ret = mmpkt_get_data_end(view) - len;
458
459 mmpkt->data_len -= len;
460
461 return ret;
462}
463
471static inline void mmpkt_truncate(struct mmpkt *mmpkt, uint32_t len)
472{
473 MMOSAL_ASSERT(len <= mmpkt->data_len);
474 mmpkt->data_len = len;
475}
476
486static inline struct mmpkt *mmpkt_get_next(struct mmpkt *mmpkt)
487{
488 return mmpkt->next;
489}
490
499static inline void mmpkt_set_next(struct mmpkt *mmpkt, struct mmpkt *next)
500{
501 mmpkt->next = next;
502}
503
515static inline bool mmpkt_contains_ptr(struct mmpktview *view, const void *ptr)
516{
517 struct mmpkt *mmpkt = (struct mmpkt *)view;
518 return ((const uint8_t *)ptr >= &mmpkt->buf[0]
519 && (const uint8_t *)ptr < &mmpkt->buf[mmpkt->buf_len]);
520}
521
522#ifdef __cplusplus
523}
524#endif
525
#define MMOSAL_ASSERT(expr)
Assert that the given expression evaluates to true and abort execution if not.
Definition: mmosal.h:967
struct mmpkt * mmpkt_alloc_on_heap(uint32_t space_at_start, uint32_t space_at_end, uint32_t metadata_size)
Allocate a new mmpkt on the heap (using mmosal_malloc()).
static void mmpkt_append_data(struct mmpktview *view, const uint8_t *data, uint32_t len)
Appends the given data to the data already in the mmpkt.
Definition: mmpkt.h:395
static struct mmpkt * mmpkt_init_buf(uint8_t *buf, uint32_t buf_len, uint32_t space_at_start, uint32_t space_at_end, uint32_t metadata_size, const struct mmpkt_ops *ops)
Initialize an mmpkt in a single buffer using the given values.
Definition: mmpkt.h:152
static struct mmpkt * mmpkt_from_view(struct mmpktview *view)
Get the underlying mmpkt from an opened view.
Definition: mmpkt.h:241
static void mmpkt_close(struct mmpktview **view)
Close the given view.
Definition: mmpkt.h:229
void mmpkt_release(struct mmpkt *mmpkt)
Release a reference to the given mmpkt.
static void mmpkt_init(struct mmpkt *mmpkt, uint8_t *buf, uint32_t buf_len, uint32_t data_start_offset, const struct mmpkt_ops *ops)
Initialize an mmpkt header with the given values.
Definition: mmpkt.h:125
static union mmpkt_metadata_ptr mmpkt_get_metadata(struct mmpkt *mmpkt)
Retrieve a reference to the metadata associated with the given mmpkt.
Definition: mmpkt.h:408
static struct mmpkt * mmpkt_get_next(struct mmpkt *mmpkt)
Get the next pointer embedded in the mmpkt.
Definition: mmpkt.h:486
static uint32_t mmpkt_available_space_at_start(struct mmpktview *view)
Returns the amount of space available for prepending to the data in the buffer.
Definition: mmpkt.h:306
static uint32_t mmpkt_peek_data_length(struct mmpkt *mmpkt)
Peek the length of the data currently from an unopened mmpkt.
Definition: mmpkt.h:280
#define MM_FAST_ROUND_UP(x, m)
Round x up to the next multiple of m (where m is a power of 2).
Definition: mmpkt.h:34
static uint8_t * mmpkt_get_data_end(struct mmpktview *view)
Gets a pointer to the end of the data in the mmpkt.
Definition: mmpkt.h:266
static uint8_t * mmpkt_prepend(struct mmpktview *view, uint32_t len)
Reserves space immediately before the data currently in the given mmpkt and returns a pointer to this...
Definition: mmpkt.h:338
static void mmpkt_truncate(struct mmpkt *mmpkt, uint32_t len)
Truncate the mmpkt data to the given length.
Definition: mmpkt.h:471
static uint32_t mmpkt_get_data_length(struct mmpktview *view)
Gets the length of the data currently in the mmpkt.
Definition: mmpkt.h:293
static uint32_t mmpkt_available_space_at_end(struct mmpktview *view)
Returns the amount of space available for appending to the data in the buffer.
Definition: mmpkt.h:319
static void mmpkt_prepend_data(struct mmpktview *view, const uint8_t *data, uint32_t len)
Prepends the given data to the data already in the mmpkt.
Definition: mmpkt.h:358
static uint8_t * mmpkt_remove_from_end(struct mmpktview *view, uint32_t len)
Remove data from the end of the mmpkt.
Definition: mmpkt.h:447
static struct mmpktview * mmpkt_open(struct mmpkt *mmpkt)
Open a view of the given mmpkt.
Definition: mmpkt.h:218
static uint8_t * mmpkt_append(struct mmpktview *view, uint32_t len)
Reserves space immediately after the data currently in the given mmpkt and returns a pointer to this ...
Definition: mmpkt.h:377
static uint8_t * mmpkt_get_data_start(struct mmpktview *view)
Gets a pointer to the start of the data in the mmpkt.
Definition: mmpkt.h:253
static bool mmpkt_contains_ptr(struct mmpktview *view, const void *ptr)
Check whether the given pointer is pointing inside the mmpkt's buffer.
Definition: mmpkt.h:515
static uint8_t * mmpkt_remove_from_start(struct mmpktview *view, uint32_t len)
Remove data from the start of the mmpkt.
Definition: mmpkt.h:421
static void mmpkt_set_next(struct mmpkt *mmpkt, struct mmpkt *next)
Set the next pointer embedded in the mmpkt.
Definition: mmpkt.h:499
Operations data structure for mmpkt.
Definition: mmpkt.h:98
void(* free_mmpkt)(void *mmpkt)
Free the given mmpkt.
Definition: mmpkt.h:100
Core mmpkt data structure.
Definition: mmpkt.h:79
uint32_t buf_len
Length of the buffer.
Definition: mmpkt.h:83
uint32_t data_len
Length of actual data in the buffer.
Definition: mmpkt.h:87
uint32_t start_offset
Offset where actual data starts in the buffer.
Definition: mmpkt.h:85
const struct mmpkt_ops * ops
Reference to operations data structure for this mmpkt.
Definition: mmpkt.h:91
uint8_t * buf
The buffer where data is stored.
Definition: mmpkt.h:81
union mmpkt_metadata_ptr metadata
Packet metadata used by driver (context dependent).
Definition: mmpkt.h:89
struct mmpkt *volatile next
Pointer that can be used to construct linked lists.
Definition: mmpkt.h:93
Union of pointer types for mmpkt metadata.
Definition: mmpkt.h:48
struct mmdrv_rx_metadata * rx
Metadata for a packet which is being received.
Definition: mmpkt.h:54
struct mmdrv_tx_metadata * tx
Metadata for a packet which is being transmitted.
Definition: mmpkt.h:52
void * opaque
Opaque pointer for contexts which are unaware of the specific metadata structure.
Definition: mmpkt.h:50
struct mmdrv_cmd_metadata * cmd
Control block for a command response sent to the host.
Definition: mmpkt.h:56