1 /*
2  * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _FIXED_PKT_QUEUE_H_
8 #define _FIXED_PKT_QUEUE_H_
9 
10 
11 #include "osi/pkt_queue.h"
12 #include "osi/semaphore.h"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 #ifndef FIXED_PKT_QUEUE_SIZE_MAX
19 #define FIXED_PKT_QUEUE_SIZE_MAX                    254
20 #endif
21 
22 #define FIXED_PKT_QUEUE_MAX_TIMEOUT                 OSI_SEM_MAX_TIMEOUT
23 
24 struct fixed_pkt_queue_t;
25 
26 typedef struct fixed_pkt_queue_t fixed_pkt_queue_t;
27 
28 typedef void (*fixed_pkt_queue_free_cb)(pkt_linked_item_t *data);
29 typedef void (*fixed_pkt_queue_cb)(fixed_pkt_queue_t *queue);
30 
31 // Creates a new fixed queue with the given |capacity|. If more elements than
32 // |capacity| are added to the queue, the caller is blocked until space is
33 // made available in the queue. Returns NULL on failure. The caller must free
34 // the returned queue with |fixed_pkt_queue_free|.
35 fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity);
36 
37 // Freeing a queue that is currently in use (i.e. has waiters
38 // blocked on it) results in undefined behaviour.
39 void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb);
40 
41 // Returns a value indicating whether the given |queue| is empty. If |queue|
42 // is NULL, the return value is true.
43 bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue);
44 
45 // Returns the length of the |queue|. If |queue| is NULL, the return value
46 // is 0.
47 size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue);
48 
49 // Returns the maximum number of elements this queue may hold. |queue| may
50 // not be NULL.
51 size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue);
52 
53 // Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
54 // If enqueue failed, it will return false, otherwise return true
55 bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout);
56 
57 // Dequeues the next element from |queue|. If the queue is currently empty,
58 // this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
59 // If dequeue failed, it will return NULL, otherwise return a point.
60 pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout);
61 
62 // Returns the first element from |queue|, if present, without dequeuing it.
63 // This function will never block the caller. Returns NULL if there are no
64 // elements in the queue or |queue| is NULL.
65 pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue);
66 
67 // Registers |queue| with |reactor| for dequeue operations. When there is an element
68 // in the queue, ready_cb will be called. The |context| parameter is passed, untouched,
69 // to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL.
70 // |context| may be NULL.
71 void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb);
72 
73 // Unregisters the dequeue ready callback for |queue| from whichever reactor
74 // it is registered with, if any. This function is idempotent.
75 void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue);
76 
77 void fixed_pkt_queue_process(fixed_pkt_queue_t *queue);
78 
79 #endif
80