flexPTP 1.0
An IEEE 1588 PTP implementation designed for microcontrollers
Loading...
Searching...
No Matches
msg_buf.c
Go to the documentation of this file.
1#include "msg_buf.h"
2
3#include <stdlib.h>
4
5#include "minmax.h"
6#include "ptp_core.h"
7
8#ifndef MSGB_DEBUG
9#define MSGB_DEBUG 0
10#endif
11
12void msgb_init(PtpMsgBuf *buf, PtpMsgBufBlock *pool, uint32_t n) {
13 buf->blocks = pool;
14 buf->lastUId = 0;
15 buf->n = n;
16 buf->used = 0;
17}
18
27static PtpMsgBufBlock *msgb_get_entry_by_tag(PtpMsgBuf *buf, uint32_t tag) {
28 for (uint32_t i = 0; i < buf->n; i++) {
29 PtpMsgBufBlock *block = buf->blocks + i;
30 if ((block->allocated) && (block->tag == tag)) {
31 return block;
32 }
33 }
34 return NULL;
35}
36
37static void msgb_free_block(PtpMsgBuf *buf, PtpMsgBufBlock *block);
38
39RawPtpMessage *msgb_alloc(PtpMsgBuf *buf, uint32_t tag, uint32_t ttl) {
40 // signal if the buffer is full and no possible overwrite is instructed
41 if ((buf->used == buf->n) && !((tag & MSGBUF_TAG_OVERWRITE) && (msgb_get_entry_by_tag(buf, tag & (~MSGBUF_TAG_OVERWRITE))))) {
42 CLILOG(MSGB_DEBUG, "[% 8u] (%u) Buffer full!\n", ptp_get_tick(), tag);
43 return NULL;
44 }
45
46 // let's see if the tag is unique or generate a unique tag
47 if ((tag & (~MSGBUF_TAG_OVERWRITE)) == 0) {
48 do {
49 tag = rand() & (~((uint32_t)MSGBUF_TAG_OVERWRITE));
50 } while (msgb_get_entry_by_tag(buf, tag) != NULL);
51 } else {
52 PtpMsgBufBlock * block = msgb_get_entry_by_tag(buf, tag);
53 if (block != NULL) {
54 if (tag & MSGBUF_TAG_OVERWRITE) {
55 msgb_free_block(buf, block);
56 } else {
57 CLILOG(MSGB_DEBUG, "[% 8u] (%u) Tag already exists!\n", ptp_get_tick(), tag);
58 return NULL;
59 }
60 }
61 }
62
63 // allocate a new block
64 PtpMsgBufBlock *block = NULL;
65 for (uint32_t i = 0; i < buf->n; i++) {
66 PtpMsgBufBlock *blockIter = buf->blocks + i;
67 if (!blockIter->allocated) {
68 block = blockIter;
69 break;
70 }
71 }
72
73 // avert some impossible errors
74 if (block == NULL) {
75 CLILOG(MSGB_DEBUG, "[% 8u] (%u) Strange error!\n", ptp_get_tick(), tag);
76 return NULL;
77 }
78
79 // indicate that this block is now allocated but has not been committed yet
80 block->allocated = true;
81 block->committed = false;
82 block->sent = false;
83
84 // set UID and user-defined options
85 block->uid = ++buf->lastUId;
86 block->tag = tag;
87 block->ttl = ttl;
88
89 // a new block has been allocated
90 buf->used++;
91
92 // return the allocated message area
93 return &(block->msg);
94}
95
96#define RAW_MSG_TO_BLOCK(rmsg) ((PtpMsgBufBlock *)(((uint8_t *)(rmsg)) - (sizeof(PtpMsgBufBlock) - sizeof(RawPtpMessage))))
97
99 PtpMsgBufBlock *block = RAW_MSG_TO_BLOCK(msg);
100 block->committed = true;
101}
102
109static void msgb_free_block(PtpMsgBuf *buf, PtpMsgBufBlock *block) {
110 block->allocated = 0;
111 block->committed = 0;
112 buf->used--;
113}
114
116 PtpMsgBufBlock *block = RAW_MSG_TO_BLOCK(msg);
117 msgb_free_block(buf, block);
118}
119
128 if (buf->used == 0) {
129 return NULL;
130 }
131
132 PtpMsgBufBlock *oldestBlock = NULL;
133 for (uint32_t i = 0; i < buf->n; i++) {
134 PtpMsgBufBlock *block = buf->blocks + i;
135 if (block->allocated && block->committed &&
136 ((oldestBlock == NULL) || (block->uid < oldestBlock->uid))) {
137 oldestBlock = block;
138 }
139 }
140 return oldestBlock;
141}
142
145 if (block == NULL) {
146 return NULL;
147 } else {
148 return &(block->msg);
149 }
150}
151
160static PtpMsgBufBlock *msgb_get_block_by_uid(PtpMsgBuf *buf, uint32_t uid) {
161 for (uint32_t i = 0; i < buf->n; i++) {
162 PtpMsgBufBlock *block = buf->blocks + i;
163 if (block->allocated && block->committed && (block->uid == uid)) {
164 return block;
165 }
166 }
167 return NULL;
168}
169
171 PtpMsgBufBlock *block = msgb_get_block_by_uid(buf, uid);
172 if (block == NULL) {
173 return NULL;
174 } else {
175 return &(block->msg);
176 }
177}
178
188 for (uint32_t i = 0; i < buf->n; i++) {
189 PtpMsgBufBlock *block = buf->blocks + i;
190 if (block->allocated && block->committed && block->sent && (block->tag == tag)) {
191 return block;
192 }
193 }
194 return NULL;
195}
196
199 if (block == NULL) {
200 return NULL;
201 } else {
202 return &(block->msg);
203 }
204}
205
213 block->sent = true;
214}
215
217 PtpMsgBufBlock *block = RAW_MSG_TO_BLOCK(msg);
218 msgb_set_block_sent(buf, block);
219}
220
221uint32_t msgb_get_uid(const PtpMsgBuf *buf, const RawPtpMessage *msg) {
222 PtpMsgBufBlock *block = RAW_MSG_TO_BLOCK(msg);
223 return block->uid;
224}
225
227 for (uint32_t i = 0; i < buf->n; i++) {
228 PtpMsgBufBlock *block = buf->blocks + i;
229 if (block->allocated && (block->ttl != MSGBUF_TTL_DONT_AGE)) {
230 if (block->ttl == 0) {
231 //MSG("[% 8u] %u has expired!\n", ptp_get_tick(), block->uid);
232 msgb_free_block(buf, block);
233 } else {
234 block->ttl = (block->ttl > 0) ? (block->ttl - 1) : block->ttl;
235 }
236 }
237 }
238}
239
241 MSG("----------------------------------\n");
242 for (uint32_t i = 0; i < buf->n; i++) {
243 PtpMsgBufBlock * block = buf->blocks + i;
244 if (block->allocated) {
245 MSG("[% 3u] A % 8X % 8X % 4u %c %c\n", i, block->tag, block->uid, block->ttl, block->committed ? 'C' : ' ', block->sent ? 'S' : ' ');
246 } else {
247 MSG("[% 3u] F -------------------\n", i);
248 }
249 }
250 MSG("----------------------------------\n");
251}
252
253uint32_t msgb_get_error(PtpMsgBuf * buf) {
254 PtpMsgBufError err = buf->error;
255 buf->error = MSGB_ERR_NONE;
256 return err;
257}
#define CLILOG(en,...)
void msgb_set_sent(PtpMsgBuf *buf, RawPtpMessage *msg)
Definition: msg_buf.c:216
static PtpMsgBufBlock * msgb_get_oldest_block(PtpMsgBuf *buf)
Definition: msg_buf.c:127
RawPtpMessage * msgb_get_oldest(PtpMsgBuf *buf)
Definition: msg_buf.c:143
static void msgb_set_block_sent(PtpMsgBuf *buf, PtpMsgBufBlock *block)
Definition: msg_buf.c:212
RawPtpMessage * msgb_get_by_uid(PtpMsgBuf *buf, uint32_t uid)
Definition: msg_buf.c:170
static PtpMsgBufBlock * msgb_get_entry_by_tag(PtpMsgBuf *buf, uint32_t tag)
Definition: msg_buf.c:27
static PtpMsgBufBlock * msgb_get_block_by_uid(PtpMsgBuf *buf, uint32_t uid)
Definition: msg_buf.c:160
void msgb_report(PtpMsgBuf *buf)
Definition: msg_buf.c:240
void msgb_init(PtpMsgBuf *buf, PtpMsgBufBlock *pool, uint32_t n)
Definition: msg_buf.c:12
void msgb_commit(PtpMsgBuf *buf, RawPtpMessage *msg)
Definition: msg_buf.c:98
RawPtpMessage * msgb_get_sent_by_tag(PtpMsgBuf *buf, uint32_t tag)
Definition: msg_buf.c:197
uint32_t msgb_get_uid(const PtpMsgBuf *buf, const RawPtpMessage *msg)
Definition: msg_buf.c:221
static void msgb_free_block(PtpMsgBuf *buf, PtpMsgBufBlock *block)
Definition: msg_buf.c:109
#define MSGB_DEBUG
Message buffer debugging.
Definition: msg_buf.c:9
static PtpMsgBufBlock * msgb_get_sent_block_by_tag(PtpMsgBuf *buf, uint32_t tag)
Definition: msg_buf.c:187
RawPtpMessage * msgb_alloc(PtpMsgBuf *buf, uint32_t tag, uint32_t ttl)
Definition: msg_buf.c:39
#define RAW_MSG_TO_BLOCK(rmsg)
Get block address by message address.
Definition: msg_buf.c:96
void msgb_free(PtpMsgBuf *buf, RawPtpMessage *msg)
Definition: msg_buf.c:115
void msgb_tick(PtpMsgBuf *buf)
Definition: msg_buf.c:226
uint32_t msgb_get_error(PtpMsgBuf *buf)
Definition: msg_buf.c:253
#define MSGBUF_TTL_DONT_AGE
Do not age messages.
Definition: msg_buf.h:13
#define MSGBUF_TAG_OVERWRITE
Overwrite if a message exists with the same tag.
Definition: msg_buf.h:15
PtpMsgBufError
Error enumeration for the message buffer.
Definition: msg_buf.h:33
@ MSGB_ERR_NONE
No error.
Definition: msg_buf.h:34
uint32_t ptp_get_tick()
Definition: ptp_core.c:230
Core of the PTP implementation. Defines functions for message processing, clock tuning,...
PTP message buffer entry.
Definition: msg_buf.h:20
bool allocated
This block has been allocated.
Definition: msg_buf.h:21
uint32_t tag
Block tag.
Definition: msg_buf.h:24
bool committed
This block has been committed.
Definition: msg_buf.h:22
RawPtpMessage msg
The contained PTP message.
Definition: msg_buf.h:27
bool sent
This block has been sent.
Definition: msg_buf.h:23
uint32_t ttl
Time-to-Live in ticks.
Definition: msg_buf.h:26
uint32_t uid
Unique ID, a sequence number.
Definition: msg_buf.h:25
PTP message buffer.
Definition: msg_buf.h:43
PtpMsgBufBlock * blocks
Block pool.
Definition: msg_buf.h:48
uint32_t n
Number of blocks.
Definition: msg_buf.h:44
uint32_t used
Number of used blocks.
Definition: msg_buf.h:45
uint32_t lastUId
Last UID.
Definition: msg_buf.h:46
uint32_t error
Last error.
Definition: msg_buf.h:47