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