1 /* buf_simple.c - Simple network buffer management */
2
3 /*
4 * Copyright (c) 2015-2019 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(net_buf_simple, CONFIG_NET_BUF_LOG_LEVEL);
11
12 #include <stdio.h>
13 #include <stddef.h>
14 #include <string.h>
15 #include <zephyr/sys/byteorder.h>
16
17 #include <zephyr/net/buf.h>
18
19 #if defined(CONFIG_NET_BUF_SIMPLE_LOG)
20 #define NET_BUF_SIMPLE_DBG(fmt, ...) LOG_DBG("(%p) " fmt, k_current_get(), \
21 ##__VA_ARGS__)
22 #define NET_BUF_SIMPLE_ERR(fmt, ...) LOG_ERR(fmt, ##__VA_ARGS__)
23 #define NET_BUF_SIMPLE_WARN(fmt, ...) LOG_WRN(fmt, ##__VA_ARGS__)
24 #define NET_BUF_SIMPLE_INFO(fmt, ...) LOG_INF(fmt, ##__VA_ARGS__)
25 #else
26 #define NET_BUF_SIMPLE_DBG(fmt, ...)
27 #define NET_BUF_SIMPLE_ERR(fmt, ...)
28 #define NET_BUF_SIMPLE_WARN(fmt, ...)
29 #define NET_BUF_SIMPLE_INFO(fmt, ...)
30 #endif /* CONFIG_NET_BUF_SIMPLE_LOG */
31
net_buf_simple_init_with_data(struct net_buf_simple * buf,void * data,size_t size)32 void net_buf_simple_init_with_data(struct net_buf_simple *buf,
33 void *data, size_t size)
34 {
35 buf->__buf = data;
36 buf->data = data;
37 buf->size = size;
38 buf->len = size;
39 }
40
net_buf_simple_reserve(struct net_buf_simple * buf,size_t reserve)41 void net_buf_simple_reserve(struct net_buf_simple *buf, size_t reserve)
42 {
43 __ASSERT_NO_MSG(buf);
44 __ASSERT_NO_MSG(buf->len == 0U);
45 NET_BUF_SIMPLE_DBG("buf %p reserve %zu", buf, reserve);
46
47 buf->data = buf->__buf + reserve;
48 }
49
net_buf_simple_clone(const struct net_buf_simple * original,struct net_buf_simple * clone)50 void net_buf_simple_clone(const struct net_buf_simple *original,
51 struct net_buf_simple *clone)
52 {
53 memcpy(clone, original, sizeof(struct net_buf_simple));
54 }
55
net_buf_simple_add(struct net_buf_simple * buf,size_t len)56 void *net_buf_simple_add(struct net_buf_simple *buf, size_t len)
57 {
58 uint8_t *tail = net_buf_simple_tail(buf);
59
60 NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len);
61
62 __ASSERT_NO_MSG(net_buf_simple_tailroom(buf) >= len);
63
64 buf->len += len;
65 return tail;
66 }
67
net_buf_simple_add_mem(struct net_buf_simple * buf,const void * mem,size_t len)68 void *net_buf_simple_add_mem(struct net_buf_simple *buf, const void *mem,
69 size_t len)
70 {
71 NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len);
72
73 return memcpy(net_buf_simple_add(buf, len), mem, len);
74 }
75
net_buf_simple_add_u8(struct net_buf_simple * buf,uint8_t val)76 uint8_t *net_buf_simple_add_u8(struct net_buf_simple *buf, uint8_t val)
77 {
78 uint8_t *u8;
79
80 NET_BUF_SIMPLE_DBG("buf %p val 0x%02x", buf, val);
81
82 u8 = net_buf_simple_add(buf, 1);
83 *u8 = val;
84
85 return u8;
86 }
87
net_buf_simple_add_le16(struct net_buf_simple * buf,uint16_t val)88 void net_buf_simple_add_le16(struct net_buf_simple *buf, uint16_t val)
89 {
90 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
91
92 sys_put_le16(val, net_buf_simple_add(buf, sizeof(val)));
93 }
94
net_buf_simple_add_be16(struct net_buf_simple * buf,uint16_t val)95 void net_buf_simple_add_be16(struct net_buf_simple *buf, uint16_t val)
96 {
97 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
98
99 sys_put_be16(val, net_buf_simple_add(buf, sizeof(val)));
100 }
101
net_buf_simple_add_le24(struct net_buf_simple * buf,uint32_t val)102 void net_buf_simple_add_le24(struct net_buf_simple *buf, uint32_t val)
103 {
104 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
105
106 sys_put_le24(val, net_buf_simple_add(buf, 3));
107 }
108
net_buf_simple_add_be24(struct net_buf_simple * buf,uint32_t val)109 void net_buf_simple_add_be24(struct net_buf_simple *buf, uint32_t val)
110 {
111 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
112
113 sys_put_be24(val, net_buf_simple_add(buf, 3));
114 }
115
net_buf_simple_add_le32(struct net_buf_simple * buf,uint32_t val)116 void net_buf_simple_add_le32(struct net_buf_simple *buf, uint32_t val)
117 {
118 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
119
120 sys_put_le32(val, net_buf_simple_add(buf, sizeof(val)));
121 }
122
net_buf_simple_add_be32(struct net_buf_simple * buf,uint32_t val)123 void net_buf_simple_add_be32(struct net_buf_simple *buf, uint32_t val)
124 {
125 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
126
127 sys_put_be32(val, net_buf_simple_add(buf, sizeof(val)));
128 }
129
net_buf_simple_add_le48(struct net_buf_simple * buf,uint64_t val)130 void net_buf_simple_add_le48(struct net_buf_simple *buf, uint64_t val)
131 {
132 NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val);
133
134 sys_put_le48(val, net_buf_simple_add(buf, 6));
135 }
136
net_buf_simple_add_be48(struct net_buf_simple * buf,uint64_t val)137 void net_buf_simple_add_be48(struct net_buf_simple *buf, uint64_t val)
138 {
139 NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val);
140
141 sys_put_be48(val, net_buf_simple_add(buf, 6));
142 }
143
net_buf_simple_add_le64(struct net_buf_simple * buf,uint64_t val)144 void net_buf_simple_add_le64(struct net_buf_simple *buf, uint64_t val)
145 {
146 NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val);
147
148 sys_put_le64(val, net_buf_simple_add(buf, sizeof(val)));
149 }
150
net_buf_simple_add_be64(struct net_buf_simple * buf,uint64_t val)151 void net_buf_simple_add_be64(struct net_buf_simple *buf, uint64_t val)
152 {
153 NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val);
154
155 sys_put_be64(val, net_buf_simple_add(buf, sizeof(val)));
156 }
157
net_buf_simple_remove_mem(struct net_buf_simple * buf,size_t len)158 void *net_buf_simple_remove_mem(struct net_buf_simple *buf, size_t len)
159 {
160 NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len);
161
162 __ASSERT_NO_MSG(buf->len >= len);
163
164 buf->len -= len;
165 return buf->data + buf->len;
166 }
167
net_buf_simple_remove_u8(struct net_buf_simple * buf)168 uint8_t net_buf_simple_remove_u8(struct net_buf_simple *buf)
169 {
170 uint8_t val;
171 void *ptr;
172
173 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
174 val = *(uint8_t *)ptr;
175
176 return val;
177 }
178
net_buf_simple_remove_le16(struct net_buf_simple * buf)179 uint16_t net_buf_simple_remove_le16(struct net_buf_simple *buf)
180 {
181 uint16_t val;
182 void *ptr;
183
184 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
185 val = UNALIGNED_GET((uint16_t *)ptr);
186
187 return sys_le16_to_cpu(val);
188 }
189
net_buf_simple_remove_be16(struct net_buf_simple * buf)190 uint16_t net_buf_simple_remove_be16(struct net_buf_simple *buf)
191 {
192 uint16_t val;
193 void *ptr;
194
195 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
196 val = UNALIGNED_GET((uint16_t *)ptr);
197
198 return sys_be16_to_cpu(val);
199 }
200
net_buf_simple_remove_le24(struct net_buf_simple * buf)201 uint32_t net_buf_simple_remove_le24(struct net_buf_simple *buf)
202 {
203 struct uint24 {
204 uint32_t u24 : 24;
205 } __packed val;
206 void *ptr;
207
208 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
209 val = UNALIGNED_GET((struct uint24 *)ptr);
210
211 return sys_le24_to_cpu(val.u24);
212 }
213
net_buf_simple_remove_be24(struct net_buf_simple * buf)214 uint32_t net_buf_simple_remove_be24(struct net_buf_simple *buf)
215 {
216 struct uint24 {
217 uint32_t u24 : 24;
218 } __packed val;
219 void *ptr;
220
221 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
222 val = UNALIGNED_GET((struct uint24 *)ptr);
223
224 return sys_be24_to_cpu(val.u24);
225 }
226
net_buf_simple_remove_le32(struct net_buf_simple * buf)227 uint32_t net_buf_simple_remove_le32(struct net_buf_simple *buf)
228 {
229 uint32_t val;
230 void *ptr;
231
232 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
233 val = UNALIGNED_GET((uint32_t *)ptr);
234
235 return sys_le32_to_cpu(val);
236 }
237
net_buf_simple_remove_be32(struct net_buf_simple * buf)238 uint32_t net_buf_simple_remove_be32(struct net_buf_simple *buf)
239 {
240 uint32_t val;
241 void *ptr;
242
243 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
244 val = UNALIGNED_GET((uint32_t *)ptr);
245
246 return sys_be32_to_cpu(val);
247 }
248
net_buf_simple_remove_le48(struct net_buf_simple * buf)249 uint64_t net_buf_simple_remove_le48(struct net_buf_simple *buf)
250 {
251 struct uint48 {
252 uint64_t u48 : 48;
253 } __packed val;
254 void *ptr;
255
256 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
257 val = UNALIGNED_GET((struct uint48 *)ptr);
258
259 return sys_le48_to_cpu(val.u48);
260 }
261
net_buf_simple_remove_be48(struct net_buf_simple * buf)262 uint64_t net_buf_simple_remove_be48(struct net_buf_simple *buf)
263 {
264 struct uint48 {
265 uint64_t u48 : 48;
266 } __packed val;
267 void *ptr;
268
269 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
270 val = UNALIGNED_GET((struct uint48 *)ptr);
271
272 return sys_be48_to_cpu(val.u48);
273 }
274
net_buf_simple_remove_le64(struct net_buf_simple * buf)275 uint64_t net_buf_simple_remove_le64(struct net_buf_simple *buf)
276 {
277 uint64_t val;
278 void *ptr;
279
280 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
281 val = UNALIGNED_GET((uint64_t *)ptr);
282
283 return sys_le64_to_cpu(val);
284 }
285
net_buf_simple_remove_be64(struct net_buf_simple * buf)286 uint64_t net_buf_simple_remove_be64(struct net_buf_simple *buf)
287 {
288 uint64_t val;
289 void *ptr;
290
291 ptr = net_buf_simple_remove_mem(buf, sizeof(val));
292 val = UNALIGNED_GET((uint64_t *)ptr);
293
294 return sys_be64_to_cpu(val);
295 }
296
net_buf_simple_push(struct net_buf_simple * buf,size_t len)297 void *net_buf_simple_push(struct net_buf_simple *buf, size_t len)
298 {
299 NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len);
300
301 __ASSERT_NO_MSG(net_buf_simple_headroom(buf) >= len);
302
303 buf->data -= len;
304 buf->len += len;
305 return buf->data;
306 }
307
net_buf_simple_push_mem(struct net_buf_simple * buf,const void * mem,size_t len)308 void *net_buf_simple_push_mem(struct net_buf_simple *buf, const void *mem,
309 size_t len)
310 {
311 NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len);
312
313 return memcpy(net_buf_simple_push(buf, len), mem, len);
314 }
315
net_buf_simple_push_le16(struct net_buf_simple * buf,uint16_t val)316 void net_buf_simple_push_le16(struct net_buf_simple *buf, uint16_t val)
317 {
318 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
319
320 sys_put_le16(val, net_buf_simple_push(buf, sizeof(val)));
321 }
322
net_buf_simple_push_be16(struct net_buf_simple * buf,uint16_t val)323 void net_buf_simple_push_be16(struct net_buf_simple *buf, uint16_t val)
324 {
325 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
326
327 sys_put_be16(val, net_buf_simple_push(buf, sizeof(val)));
328 }
329
net_buf_simple_push_u8(struct net_buf_simple * buf,uint8_t val)330 void net_buf_simple_push_u8(struct net_buf_simple *buf, uint8_t val)
331 {
332 uint8_t *data = net_buf_simple_push(buf, 1);
333
334 *data = val;
335 }
336
net_buf_simple_push_le24(struct net_buf_simple * buf,uint32_t val)337 void net_buf_simple_push_le24(struct net_buf_simple *buf, uint32_t val)
338 {
339 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
340
341 sys_put_le24(val, net_buf_simple_push(buf, 3));
342 }
343
net_buf_simple_push_be24(struct net_buf_simple * buf,uint32_t val)344 void net_buf_simple_push_be24(struct net_buf_simple *buf, uint32_t val)
345 {
346 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
347
348 sys_put_be24(val, net_buf_simple_push(buf, 3));
349 }
350
net_buf_simple_push_le32(struct net_buf_simple * buf,uint32_t val)351 void net_buf_simple_push_le32(struct net_buf_simple *buf, uint32_t val)
352 {
353 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
354
355 sys_put_le32(val, net_buf_simple_push(buf, sizeof(val)));
356 }
357
net_buf_simple_push_be32(struct net_buf_simple * buf,uint32_t val)358 void net_buf_simple_push_be32(struct net_buf_simple *buf, uint32_t val)
359 {
360 NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
361
362 sys_put_be32(val, net_buf_simple_push(buf, sizeof(val)));
363 }
364
net_buf_simple_push_le48(struct net_buf_simple * buf,uint64_t val)365 void net_buf_simple_push_le48(struct net_buf_simple *buf, uint64_t val)
366 {
367 NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val);
368
369 sys_put_le48(val, net_buf_simple_push(buf, 6));
370 }
371
net_buf_simple_push_be48(struct net_buf_simple * buf,uint64_t val)372 void net_buf_simple_push_be48(struct net_buf_simple *buf, uint64_t val)
373 {
374 NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val);
375
376 sys_put_be48(val, net_buf_simple_push(buf, 6));
377 }
378
net_buf_simple_push_le64(struct net_buf_simple * buf,uint64_t val)379 void net_buf_simple_push_le64(struct net_buf_simple *buf, uint64_t val)
380 {
381 NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val);
382
383 sys_put_le64(val, net_buf_simple_push(buf, sizeof(val)));
384 }
385
net_buf_simple_push_be64(struct net_buf_simple * buf,uint64_t val)386 void net_buf_simple_push_be64(struct net_buf_simple *buf, uint64_t val)
387 {
388 NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val);
389
390 sys_put_be64(val, net_buf_simple_push(buf, sizeof(val)));
391 }
392
net_buf_simple_pull(struct net_buf_simple * buf,size_t len)393 void *net_buf_simple_pull(struct net_buf_simple *buf, size_t len)
394 {
395 NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len);
396
397 __ASSERT_NO_MSG(buf->len >= len);
398
399 buf->len -= len;
400 return buf->data += len;
401 }
402
net_buf_simple_pull_mem(struct net_buf_simple * buf,size_t len)403 void *net_buf_simple_pull_mem(struct net_buf_simple *buf, size_t len)
404 {
405 void *data = buf->data;
406
407 NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len);
408
409 __ASSERT_NO_MSG(buf->len >= len);
410
411 buf->len -= len;
412 buf->data += len;
413
414 return data;
415 }
416
net_buf_simple_pull_u8(struct net_buf_simple * buf)417 uint8_t net_buf_simple_pull_u8(struct net_buf_simple *buf)
418 {
419 uint8_t val;
420
421 val = buf->data[0];
422 net_buf_simple_pull(buf, 1);
423
424 return val;
425 }
426
net_buf_simple_pull_le16(struct net_buf_simple * buf)427 uint16_t net_buf_simple_pull_le16(struct net_buf_simple *buf)
428 {
429 uint16_t val;
430
431 val = UNALIGNED_GET((uint16_t *)buf->data);
432 net_buf_simple_pull(buf, sizeof(val));
433
434 return sys_le16_to_cpu(val);
435 }
436
net_buf_simple_pull_be16(struct net_buf_simple * buf)437 uint16_t net_buf_simple_pull_be16(struct net_buf_simple *buf)
438 {
439 uint16_t val;
440
441 val = UNALIGNED_GET((uint16_t *)buf->data);
442 net_buf_simple_pull(buf, sizeof(val));
443
444 return sys_be16_to_cpu(val);
445 }
446
net_buf_simple_pull_le24(struct net_buf_simple * buf)447 uint32_t net_buf_simple_pull_le24(struct net_buf_simple *buf)
448 {
449 struct uint24 {
450 uint32_t u24:24;
451 } __packed val;
452
453 val = UNALIGNED_GET((struct uint24 *)buf->data);
454 net_buf_simple_pull(buf, sizeof(val));
455
456 return sys_le24_to_cpu(val.u24);
457 }
458
net_buf_simple_pull_be24(struct net_buf_simple * buf)459 uint32_t net_buf_simple_pull_be24(struct net_buf_simple *buf)
460 {
461 struct uint24 {
462 uint32_t u24:24;
463 } __packed val;
464
465 val = UNALIGNED_GET((struct uint24 *)buf->data);
466 net_buf_simple_pull(buf, sizeof(val));
467
468 return sys_be24_to_cpu(val.u24);
469 }
470
net_buf_simple_pull_le32(struct net_buf_simple * buf)471 uint32_t net_buf_simple_pull_le32(struct net_buf_simple *buf)
472 {
473 uint32_t val;
474
475 val = UNALIGNED_GET((uint32_t *)buf->data);
476 net_buf_simple_pull(buf, sizeof(val));
477
478 return sys_le32_to_cpu(val);
479 }
480
net_buf_simple_pull_be32(struct net_buf_simple * buf)481 uint32_t net_buf_simple_pull_be32(struct net_buf_simple *buf)
482 {
483 uint32_t val;
484
485 val = UNALIGNED_GET((uint32_t *)buf->data);
486 net_buf_simple_pull(buf, sizeof(val));
487
488 return sys_be32_to_cpu(val);
489 }
490
net_buf_simple_pull_le48(struct net_buf_simple * buf)491 uint64_t net_buf_simple_pull_le48(struct net_buf_simple *buf)
492 {
493 struct uint48 {
494 uint64_t u48:48;
495 } __packed val;
496
497 val = UNALIGNED_GET((struct uint48 *)buf->data);
498 net_buf_simple_pull(buf, sizeof(val));
499
500 return sys_le48_to_cpu(val.u48);
501 }
502
net_buf_simple_pull_be48(struct net_buf_simple * buf)503 uint64_t net_buf_simple_pull_be48(struct net_buf_simple *buf)
504 {
505 struct uint48 {
506 uint64_t u48:48;
507 } __packed val;
508
509 val = UNALIGNED_GET((struct uint48 *)buf->data);
510 net_buf_simple_pull(buf, sizeof(val));
511
512 return sys_be48_to_cpu(val.u48);
513 }
514
net_buf_simple_pull_le64(struct net_buf_simple * buf)515 uint64_t net_buf_simple_pull_le64(struct net_buf_simple *buf)
516 {
517 uint64_t val;
518
519 val = UNALIGNED_GET((uint64_t *)buf->data);
520 net_buf_simple_pull(buf, sizeof(val));
521
522 return sys_le64_to_cpu(val);
523 }
524
net_buf_simple_pull_be64(struct net_buf_simple * buf)525 uint64_t net_buf_simple_pull_be64(struct net_buf_simple *buf)
526 {
527 uint64_t val;
528
529 val = UNALIGNED_GET((uint64_t *)buf->data);
530 net_buf_simple_pull(buf, sizeof(val));
531
532 return sys_be64_to_cpu(val);
533 }
534
net_buf_simple_headroom(struct net_buf_simple * buf)535 size_t net_buf_simple_headroom(struct net_buf_simple *buf)
536 {
537 return buf->data - buf->__buf;
538 }
539
net_buf_simple_tailroom(struct net_buf_simple * buf)540 size_t net_buf_simple_tailroom(struct net_buf_simple *buf)
541 {
542 return buf->size - net_buf_simple_headroom(buf) - buf->len;
543 }
544
net_buf_simple_max_len(struct net_buf_simple * buf)545 uint16_t net_buf_simple_max_len(struct net_buf_simple *buf)
546 {
547 return buf->size - net_buf_simple_headroom(buf);
548 }
549