1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2015 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/types.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <zephyr/sys/printk.h>
13 
14 #include <zephyr/net/buf.h>
15 
16 #include <zephyr/ztest.h>
17 
18 #define TEST_TIMEOUT K_SECONDS(1)
19 
20 #define USER_DATA_HEAP	4
21 #define USER_DATA_FIXED	0
22 #define USER_DATA_VAR	63
23 #define FIXED_BUFFER_SIZE 128
24 
25 struct bt_data {
26 	void *hci_sync;
27 
28 	union {
29 		uint16_t hci_opcode;
30 		uint16_t acl_handle;
31 	};
32 
33 	uint8_t type;
34 };
35 
36 struct in6_addr {
37 	union {
38 		uint8_t u6_addr8[16];
39 		uint16_t u6_addr16[8];          /* In big endian */
40 		uint32_t u6_addr32[4];          /* In big endian */
41 	} in6_u;
42 #define s6_addr         in6_u.u6_addr8
43 #define s6_addr16       in6_u.u6_addr16
44 #define s6_addr32       in6_u.u6_addr32
45 };
46 
47 struct ipv6_hdr {
48 	uint8_t vtc;
49 	uint8_t tcflow;
50 	uint16_t flow;
51 	uint8_t len[2];
52 	uint8_t nexthdr;
53 	uint8_t hop_limit;
54 	struct in6_addr src;
55 	struct in6_addr dst;
56 } __attribute__((__packed__));
57 
58 struct udp_hdr {
59 	uint16_t src_port;
60 	uint16_t dst_port;
61 	uint16_t len;
62 	uint16_t chksum;
63 } __attribute__((__packed__));
64 
65 static int destroy_called;
66 
67 static void buf_destroy(struct net_buf *buf);
68 static void fixed_destroy(struct net_buf *buf);
69 static void var_destroy(struct net_buf *buf);
70 
71 NET_BUF_POOL_HEAP_DEFINE(bufs_pool, 10, USER_DATA_HEAP, buf_destroy);
72 NET_BUF_POOL_FIXED_DEFINE(fixed_pool, 10, FIXED_BUFFER_SIZE, USER_DATA_FIXED, fixed_destroy);
73 NET_BUF_POOL_VAR_DEFINE(var_pool, 10, 1024, USER_DATA_VAR, var_destroy);
74 
buf_destroy(struct net_buf * buf)75 static void buf_destroy(struct net_buf *buf)
76 {
77 	struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id);
78 
79 	destroy_called++;
80 	zassert_equal(pool, &bufs_pool, "Invalid free pointer in buffer");
81 	net_buf_destroy(buf);
82 }
83 
fixed_destroy(struct net_buf * buf)84 static void fixed_destroy(struct net_buf *buf)
85 {
86 	struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id);
87 
88 	destroy_called++;
89 	zassert_equal(pool, &fixed_pool, "Invalid free pointer in buffer");
90 	net_buf_destroy(buf);
91 }
92 
var_destroy(struct net_buf * buf)93 static void var_destroy(struct net_buf *buf)
94 {
95 	struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id);
96 
97 	destroy_called++;
98 	zassert_equal(pool, &var_pool, "Invalid free pointer in buffer");
99 	net_buf_destroy(buf);
100 }
101 
102 static const char example_data[] = "0123456789"
103 				   "abcdefghijklmnopqrstuvxyz"
104 				   "!#¤%&/()=?";
105 
ZTEST(net_buf_tests,test_net_buf_1)106 ZTEST(net_buf_tests, test_net_buf_1)
107 {
108 	struct net_buf *bufs[bufs_pool.buf_count];
109 	struct net_buf *buf;
110 	int i;
111 
112 	for (i = 0; i < bufs_pool.buf_count; i++) {
113 		buf = net_buf_alloc_len(&bufs_pool, 74, K_NO_WAIT);
114 		zassert_not_null(buf, "Failed to get buffer");
115 		bufs[i] = buf;
116 	}
117 
118 	for (i = 0; i < ARRAY_SIZE(bufs); i++) {
119 		net_buf_unref(bufs[i]);
120 	}
121 
122 	zassert_equal(destroy_called, ARRAY_SIZE(bufs),
123 		      "Incorrect destroy callback count");
124 }
125 
ZTEST(net_buf_tests,test_net_buf_2)126 ZTEST(net_buf_tests, test_net_buf_2)
127 {
128 	struct net_buf *frag, *head;
129 	static struct k_fifo fifo;
130 	int i;
131 
132 	head = net_buf_alloc_len(&bufs_pool, 74, K_NO_WAIT);
133 	zassert_not_null(head, "Failed to get fragment list head");
134 
135 	frag = head;
136 	for (i = 0; i < bufs_pool.buf_count - 1; i++) {
137 		frag->frags = net_buf_alloc_len(&bufs_pool, 74, K_NO_WAIT);
138 		zassert_not_null(frag->frags, "Failed to get fragment");
139 		frag = frag->frags;
140 	}
141 
142 	k_fifo_init(&fifo);
143 	net_buf_put(&fifo, head);
144 	head = net_buf_get(&fifo, K_NO_WAIT);
145 
146 	destroy_called = 0;
147 	net_buf_unref(head);
148 	zassert_equal(destroy_called, bufs_pool.buf_count,
149 		      "Incorrect fragment destroy callback count");
150 }
151 
test_3_thread(void * arg1,void * arg2,void * arg3)152 static void test_3_thread(void *arg1, void *arg2, void *arg3)
153 {
154 	ARG_UNUSED(arg3);
155 
156 	struct k_fifo *fifo = (struct k_fifo *)arg1;
157 	struct k_sem *sema = (struct k_sem *)arg2;
158 	struct net_buf *buf;
159 
160 	k_sem_give(sema);
161 
162 	buf = net_buf_get(fifo, TEST_TIMEOUT);
163 	zassert_not_null(buf, "Unable to get buffer");
164 
165 	destroy_called = 0;
166 	net_buf_unref(buf);
167 	zassert_equal(destroy_called, bufs_pool.buf_count,
168 		      "Incorrect destroy callback count");
169 
170 	k_sem_give(sema);
171 }
172 
173 static K_THREAD_STACK_DEFINE(test_3_thread_stack, 1024);
174 
ZTEST(net_buf_tests,test_net_buf_3)175 ZTEST(net_buf_tests, test_net_buf_3)
176 {
177 	static struct k_thread test_3_thread_data;
178 	struct net_buf *frag, *head;
179 	static struct k_fifo fifo;
180 	static struct k_sem sema;
181 	int i;
182 
183 	head = net_buf_alloc_len(&bufs_pool, 74, K_NO_WAIT);
184 	zassert_not_null(head, "Failed to get fragment list head");
185 
186 	frag = head;
187 	for (i = 0; i < bufs_pool.buf_count - 1; i++) {
188 		frag->frags = net_buf_alloc_len(&bufs_pool, 74, K_NO_WAIT);
189 		zassert_not_null(frag->frags, "Failed to get fragment");
190 		frag = frag->frags;
191 	}
192 
193 	k_fifo_init(&fifo);
194 	k_sem_init(&sema, 0, UINT_MAX);
195 
196 	k_thread_create(&test_3_thread_data, test_3_thread_stack,
197 			K_THREAD_STACK_SIZEOF(test_3_thread_stack),
198 			test_3_thread, &fifo, &sema, NULL,
199 			K_PRIO_COOP(7), 0, K_NO_WAIT);
200 
201 	zassert_true(k_sem_take(&sema, TEST_TIMEOUT) == 0,
202 		     "Timeout while waiting for semaphore");
203 
204 	net_buf_put(&fifo, head);
205 
206 	zassert_true(k_sem_take(&sema, TEST_TIMEOUT) == 0,
207 		     "Timeout while waiting for semaphore");
208 }
209 
ZTEST(net_buf_tests,test_net_buf_4)210 ZTEST(net_buf_tests, test_net_buf_4)
211 {
212 	struct net_buf *frags[bufs_pool.buf_count - 1];
213 	struct net_buf *buf, *frag;
214 	int i, removed;
215 
216 	destroy_called = 0;
217 
218 	/* Create a buf that does not have any data to store, it just
219 	 * contains link to fragments.
220 	 */
221 	buf = net_buf_alloc_len(&bufs_pool, 0, K_FOREVER);
222 
223 	zassert_equal(buf->size, 0, "Invalid buffer size");
224 
225 	/* Test the fragments by appending after last fragment */
226 	for (i = 0; i < bufs_pool.buf_count - 2; i++) {
227 		frag = net_buf_alloc_len(&bufs_pool, 74, K_FOREVER);
228 		net_buf_frag_add(buf, frag);
229 		frags[i] = frag;
230 	}
231 
232 	/* And one as a first fragment */
233 	frag = net_buf_alloc_len(&bufs_pool, 74, K_FOREVER);
234 	net_buf_frag_insert(buf, frag);
235 	frags[i] = frag;
236 
237 	frag = buf->frags;
238 
239 	i = 0;
240 	while (frag) {
241 		frag = frag->frags;
242 		i++;
243 	}
244 
245 	zassert_equal(i, bufs_pool.buf_count - 1, "Incorrect fragment count");
246 
247 	/* Remove about half of the fragments and verify count */
248 	i = removed = 0;
249 	frag = buf->frags;
250 	while (frag) {
251 		struct net_buf *next = frag->frags;
252 
253 		if ((i % 2) && next) {
254 			net_buf_frag_del(frag, next);
255 			net_buf_unref(next);
256 			removed++;
257 		} else {
258 			frag = next;
259 		}
260 		i++;
261 	}
262 
263 	i = 0;
264 	frag = buf->frags;
265 	while (frag) {
266 		frag = frag->frags;
267 		i++;
268 	}
269 
270 	zassert_equal(1 + i + removed, bufs_pool.buf_count,
271 		      "Incorrect removed fragment count");
272 
273 	removed = 0;
274 
275 	while (buf->frags) {
276 		struct net_buf *frag2 = buf->frags;
277 
278 		net_buf_frag_del(buf, frag2);
279 		net_buf_unref(frag2);
280 		removed++;
281 	}
282 
283 	zassert_equal(removed, i, "Incorrect removed fragment count");
284 	zassert_equal(destroy_called, bufs_pool.buf_count - 1,
285 		      "Incorrect frag destroy callback count");
286 
287 	/* Add the fragments back and verify that they are properly unref
288 	 * by freeing the top buf.
289 	 */
290 	for (i = 0; i < bufs_pool.buf_count - 4; i++) {
291 		net_buf_frag_add(buf,
292 				 net_buf_alloc_len(&bufs_pool, 74, K_FOREVER));
293 	}
294 
295 	/* Create a fragment list and add it to frags list after first
296 	 * element
297 	 */
298 	frag = net_buf_alloc_len(&bufs_pool, 74, K_FOREVER);
299 	net_buf_frag_add(frag, net_buf_alloc_len(&bufs_pool, 74, K_FOREVER));
300 	net_buf_frag_insert(frag, net_buf_alloc_len(&bufs_pool, 74, K_FOREVER));
301 	net_buf_frag_insert(buf->frags->frags, frag);
302 
303 	i = 0;
304 	frag = buf->frags;
305 	while (frag) {
306 		frag = frag->frags;
307 		i++;
308 	}
309 
310 	zassert_equal(i, bufs_pool.buf_count - 1, "Incorrect fragment count");
311 
312 	destroy_called = 0;
313 
314 	net_buf_unref(buf);
315 
316 	zassert_equal(destroy_called, bufs_pool.buf_count,
317 		      "Incorrect frag destroy callback count");
318 }
319 
ZTEST(net_buf_tests,test_net_buf_big_buf)320 ZTEST(net_buf_tests, test_net_buf_big_buf)
321 {
322 	struct net_buf *big_frags[bufs_pool.buf_count];
323 	struct net_buf *buf, *frag;
324 	struct ipv6_hdr *ipv6;
325 	struct udp_hdr *udp;
326 	int i, len;
327 
328 	destroy_called = 0;
329 
330 	buf = net_buf_alloc_len(&bufs_pool, 0, K_FOREVER);
331 
332 	/* We reserve some space in front of the buffer for protocol
333 	 * headers (IPv6 + UDP). Link layer headers are ignored in
334 	 * this example.
335 	 */
336 #define PROTO_HEADERS (sizeof(struct ipv6_hdr) + sizeof(struct udp_hdr))
337 	frag = net_buf_alloc_len(&bufs_pool, 1280, K_FOREVER);
338 	net_buf_reserve(frag, PROTO_HEADERS);
339 	big_frags[0] = frag;
340 
341 	/* First add some application data */
342 	len = strlen(example_data);
343 	for (i = 0; i < 2; i++) {
344 		zassert_true(net_buf_tailroom(frag) >= len,
345 			     "Allocated buffer is too small");
346 		memcpy(net_buf_add(frag, len), example_data, len);
347 	}
348 
349 	ipv6 = (struct ipv6_hdr *)(frag->data - net_buf_headroom(frag));
350 	udp = (struct udp_hdr *)((uint8_t *)ipv6 + sizeof(*ipv6));
351 
352 	net_buf_frag_add(buf, frag);
353 	net_buf_unref(buf);
354 
355 	zassert_equal(destroy_called, 2, "Incorrect destroy callback count");
356 }
357 
ZTEST(net_buf_tests,test_net_buf_multi_frags)358 ZTEST(net_buf_tests, test_net_buf_multi_frags)
359 {
360 	struct net_buf *frags[bufs_pool.buf_count];
361 	struct net_buf *buf;
362 	struct ipv6_hdr *ipv6;
363 	struct udp_hdr *udp;
364 	int i, len, avail = 0, occupied = 0;
365 
366 	destroy_called = 0;
367 
368 	/* Example of multi fragment scenario with IPv6 */
369 	buf = net_buf_alloc_len(&bufs_pool, 0, K_FOREVER);
370 
371 	/* We reserve some space in front of the buffer for link layer headers.
372 	 * In this example, we use min MTU (81 bytes) defined in rfc 4944 ch. 4
373 	 *
374 	 * Note that with IEEE 802.15.4 we typically cannot have zero-copy
375 	 * in sending side because of the IPv6 header compression.
376 	 */
377 
378 #define LL_HEADERS (127 - 81)
379 	for (i = 0; i < bufs_pool.buf_count - 2; i++) {
380 		frags[i] = net_buf_alloc_len(&bufs_pool, 128, K_FOREVER);
381 		net_buf_reserve(frags[i], LL_HEADERS);
382 		avail += net_buf_tailroom(frags[i]);
383 		net_buf_frag_add(buf, frags[i]);
384 	}
385 
386 	/* Place the IP + UDP header in the first fragment */
387 	frags[i] = net_buf_alloc_len(&bufs_pool, 128, K_FOREVER);
388 	net_buf_reserve(frags[i], LL_HEADERS + (sizeof(struct ipv6_hdr) +
389 						sizeof(struct udp_hdr)));
390 	avail += net_buf_tailroom(frags[i]);
391 	net_buf_frag_insert(buf, frags[i]);
392 
393 	/* First add some application data */
394 	len = strlen(example_data);
395 	for (i = 0; i < bufs_pool.buf_count - 2; i++) {
396 		zassert_true(net_buf_tailroom(frags[i]) >= len,
397 			     "Allocated buffer is too small");
398 		memcpy(net_buf_add(frags[i], len), example_data, len);
399 		occupied += frags[i]->len;
400 	}
401 
402 	ipv6 = (struct ipv6_hdr *)(frags[i]->data - net_buf_headroom(frags[i]));
403 	udp = (struct udp_hdr *)((uint8_t *)ipv6 + sizeof(*ipv6));
404 
405 	net_buf_unref(buf);
406 
407 	zassert_equal(destroy_called, bufs_pool.buf_count,
408 		      "Incorrect frag destroy callback count");
409 }
410 
ZTEST(net_buf_tests,test_net_buf_clone_ref_count)411 ZTEST(net_buf_tests, test_net_buf_clone_ref_count)
412 {
413 	struct net_buf *buf, *clone;
414 
415 	destroy_called = 0;
416 
417 	/* Heap pool supports reference counting */
418 	buf = net_buf_alloc_len(&bufs_pool, 74, K_NO_WAIT);
419 	zassert_not_null(buf, "Failed to get buffer");
420 
421 	clone = net_buf_clone(buf, K_NO_WAIT);
422 	zassert_not_null(clone, "Failed to get clone buffer");
423 	zassert_equal(buf->data, clone->data, "Incorrect clone data pointer");
424 
425 	net_buf_unref(buf);
426 	net_buf_unref(clone);
427 
428 	zassert_equal(destroy_called, 2, "Incorrect destroy callback count");
429 }
430 
ZTEST(net_buf_tests,test_net_buf_clone_no_ref_count)431 ZTEST(net_buf_tests, test_net_buf_clone_no_ref_count)
432 {
433 	struct net_buf *buf, *clone;
434 	const uint8_t data[3] = {0x11, 0x22, 0x33};
435 
436 	destroy_called = 0;
437 
438 	/* Fixed pool does not support reference counting */
439 	buf = net_buf_alloc_len(&fixed_pool, 3, K_NO_WAIT);
440 	zassert_not_null(buf, "Failed to get buffer");
441 	net_buf_add_mem(buf, data, sizeof(data));
442 
443 	clone = net_buf_clone(buf, K_NO_WAIT);
444 	zassert_not_null(clone, "Failed to get clone buffer");
445 	zassert_not_equal(buf->data, clone->data,
446 			  "No reference counting support, different pointers expected");
447 	zassert_mem_equal(clone->data, data, sizeof(data));
448 
449 	net_buf_unref(buf);
450 	net_buf_unref(clone);
451 
452 	zassert_equal(destroy_called, 2, "Incorrect destroy callback count");
453 }
454 
455 /* Regression test: Zero sized buffers must be copy-able, not trigger a NULL pointer dereference */
ZTEST(net_buf_tests,test_net_buf_clone_reference_counted_zero_sized_buffer)456 ZTEST(net_buf_tests, test_net_buf_clone_reference_counted_zero_sized_buffer)
457 {
458 	struct net_buf *buf, *clone;
459 
460 	buf = net_buf_alloc_len(&var_pool, 0, K_NO_WAIT);
461 	zassert_not_null(buf, "Failed to get buffer");
462 
463 	clone = net_buf_clone(buf, K_NO_WAIT);
464 	zassert_not_null(clone, "Failed to clone zero sized buffer");
465 
466 	net_buf_unref(buf);
467 }
468 
ZTEST(net_buf_tests,test_net_buf_clone_user_data)469 ZTEST(net_buf_tests, test_net_buf_clone_user_data)
470 {
471 	struct net_buf *original, *clone;
472 	uint32_t *buf_user_data, *clone_user_data;
473 
474 	/* Requesting size 1 because all we are interested in are the user data */
475 	original = net_buf_alloc_len(&bufs_pool, 1, K_NO_WAIT);
476 	zassert_not_null(original, "Failed to get buffer");
477 	buf_user_data = net_buf_user_data(original);
478 	*buf_user_data = 0xAABBCCDD;
479 
480 	clone = net_buf_clone(original, K_NO_WAIT);
481 	zassert_not_null(clone, "Failed to get clone buffer");
482 	clone_user_data = net_buf_user_data(clone);
483 	zexpect_equal(*clone_user_data, 0xAABBCCDD, "User data copy is invalid");
484 
485 	net_buf_unref(original);
486 	net_buf_unref(clone);
487 }
488 
ZTEST(net_buf_tests,test_net_buf_fixed_pool)489 ZTEST(net_buf_tests, test_net_buf_fixed_pool)
490 {
491 	struct net_buf *buf;
492 
493 	destroy_called = 0;
494 
495 	buf = net_buf_alloc_len(&fixed_pool, 20, K_NO_WAIT);
496 	zassert_not_null(buf, "Failed to get buffer");
497 
498 	/* Verify buffer's size and len - even though we requested less bytes we
499 	 * should get a buffer with the fixed size.
500 	 */
501 	zassert_equal(buf->size, FIXED_BUFFER_SIZE, "Invalid fixed buffer size");
502 	zassert_equal(buf->len, 0, "Invalid fixed buffer length");
503 
504 	net_buf_unref(buf);
505 
506 	zassert_equal(destroy_called, 1, "Incorrect destroy callback count");
507 }
508 
ZTEST(net_buf_tests,test_net_buf_var_pool)509 ZTEST(net_buf_tests, test_net_buf_var_pool)
510 {
511 	struct net_buf *buf1, *buf2, *buf3;
512 
513 	destroy_called = 0;
514 
515 	buf1 = net_buf_alloc_len(&var_pool, 20, K_NO_WAIT);
516 	zassert_not_null(buf1, "Failed to get buffer");
517 
518 	buf2 = net_buf_alloc_len(&var_pool, 200, K_NO_WAIT);
519 	zassert_not_null(buf2, "Failed to get buffer");
520 
521 	buf3 = net_buf_clone(buf2, K_NO_WAIT);
522 	zassert_not_null(buf3, "Failed to clone buffer");
523 	zassert_equal(buf3->data, buf2->data, "Cloned data doesn't match");
524 
525 	net_buf_unref(buf1);
526 	net_buf_unref(buf2);
527 	net_buf_unref(buf3);
528 
529 	zassert_equal(destroy_called, 3, "Incorrect destroy callback count");
530 }
531 
ZTEST(net_buf_tests,test_net_buf_byte_order)532 ZTEST(net_buf_tests, test_net_buf_byte_order)
533 {
534 	struct net_buf *buf;
535 	uint8_t le16[2] = { 0x02, 0x01 };
536 	uint8_t be16[2] = { 0x01, 0x02 };
537 	uint8_t le24[3] = { 0x03, 0x02, 0x01 };
538 	uint8_t be24[3] = { 0x01, 0x02, 0x03 };
539 	uint8_t le32[4] = { 0x04, 0x03, 0x02, 0x01 };
540 	uint8_t be32[4] = { 0x01, 0x02, 0x03, 0x04 };
541 	uint8_t le40[5] = { 0x05, 0x04, 0x03, 0x02, 0x01 };
542 	uint8_t be40[5] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
543 	uint8_t le48[6] = { 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
544 	uint8_t be48[6] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
545 	uint8_t le64[8] = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
546 	uint8_t be64[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
547 	uint16_t u16;
548 	uint32_t u32;
549 	uint64_t u64;
550 
551 	buf = net_buf_alloc_len(&fixed_pool, 16, K_FOREVER);
552 	zassert_not_null(buf, "Failed to get buffer");
553 
554 	/* add/pull byte order */
555 	net_buf_add_mem(buf, &le16, sizeof(le16));
556 	net_buf_add_mem(buf, &be16, sizeof(be16));
557 
558 	u16 = net_buf_pull_le16(buf);
559 	zassert_equal(u16, net_buf_pull_be16(buf),
560 		      "Invalid 16 bits byte order");
561 
562 	net_buf_reset(buf);
563 
564 	net_buf_add_le16(buf, u16);
565 	net_buf_add_be16(buf, u16);
566 
567 	zassert_mem_equal(le16, net_buf_pull_mem(buf, sizeof(le16)),
568 			  sizeof(le16), "Invalid 16 bits byte order");
569 	zassert_mem_equal(be16, net_buf_pull_mem(buf, sizeof(be16)),
570 			  sizeof(be16), "Invalid 16 bits byte order");
571 
572 	net_buf_reset(buf);
573 
574 	net_buf_add_mem(buf, &le24, sizeof(le24));
575 	net_buf_add_mem(buf, &be24, sizeof(be24));
576 
577 	u32 = net_buf_pull_le24(buf);
578 	zassert_equal(u32, net_buf_pull_be24(buf),
579 		      "Invalid 24 bits byte order");
580 
581 	net_buf_reset(buf);
582 
583 	net_buf_add_le24(buf, u32);
584 	net_buf_add_be24(buf, u32);
585 
586 	zassert_mem_equal(le24, net_buf_pull_mem(buf, sizeof(le24)),
587 			  sizeof(le24), "Invalid 24 bits byte order");
588 	zassert_mem_equal(be24, net_buf_pull_mem(buf, sizeof(be24)),
589 			  sizeof(be24), "Invalid 24 bits byte order");
590 
591 	net_buf_reset(buf);
592 
593 	net_buf_add_mem(buf, &le32, sizeof(le32));
594 	net_buf_add_mem(buf, &be32, sizeof(be32));
595 
596 	u32 = net_buf_pull_le32(buf);
597 	zassert_equal(u32, net_buf_pull_be32(buf),
598 		      "Invalid 32 bits byte order");
599 
600 	net_buf_reset(buf);
601 
602 	net_buf_add_le32(buf, u32);
603 	net_buf_add_be32(buf, u32);
604 
605 	zassert_mem_equal(le32, net_buf_pull_mem(buf, sizeof(le32)),
606 			  sizeof(le32), "Invalid 32 bits byte order");
607 	zassert_mem_equal(be32, net_buf_pull_mem(buf, sizeof(be32)),
608 			  sizeof(be32), "Invalid 32 bits byte order");
609 
610 	net_buf_reset(buf);
611 
612 	net_buf_add_mem(buf, &le40, sizeof(le40));
613 	net_buf_add_mem(buf, &be40, sizeof(be40));
614 
615 	u64 = net_buf_pull_le40(buf);
616 	zassert_equal(u64, net_buf_pull_be40(buf), "Invalid 40 bits byte order");
617 
618 	net_buf_reset(buf);
619 
620 	net_buf_add_le40(buf, u64);
621 	net_buf_add_be40(buf, u64);
622 
623 	zassert_mem_equal(le40, net_buf_pull_mem(buf, sizeof(le40)), sizeof(le40),
624 			  "Invalid 40 bits byte order");
625 	zassert_mem_equal(be40, net_buf_pull_mem(buf, sizeof(be40)), sizeof(be40),
626 			  "Invalid 40 bits byte order");
627 
628 	net_buf_reset(buf);
629 
630 	net_buf_add_mem(buf, &le48, sizeof(le48));
631 	net_buf_add_mem(buf, &be48, sizeof(be48));
632 
633 	u64 = net_buf_pull_le48(buf);
634 	zassert_equal(u64, net_buf_pull_be48(buf),
635 		      "Invalid 48 bits byte order");
636 
637 	net_buf_reset(buf);
638 
639 	net_buf_add_le48(buf, u64);
640 	net_buf_add_be48(buf, u64);
641 
642 	zassert_mem_equal(le48, net_buf_pull_mem(buf, sizeof(le48)),
643 			  sizeof(le48), "Invalid 48 bits byte order");
644 	zassert_mem_equal(be48, net_buf_pull_mem(buf, sizeof(be48)),
645 			  sizeof(be48), "Invalid 48 bits byte order");
646 
647 	net_buf_reset(buf);
648 
649 	net_buf_add_mem(buf, &le64, sizeof(le64));
650 	net_buf_add_mem(buf, &be64, sizeof(be64));
651 
652 	u64 = net_buf_pull_le64(buf);
653 	zassert_equal(u64, net_buf_pull_be64(buf),
654 		      "Invalid 64 bits byte order");
655 
656 	net_buf_reset(buf);
657 
658 	net_buf_add_le64(buf, u64);
659 	net_buf_add_be64(buf, u64);
660 
661 	zassert_mem_equal(le64, net_buf_pull_mem(buf, sizeof(le64)),
662 			  sizeof(le64), "Invalid 64 bits byte order");
663 	zassert_mem_equal(be64, net_buf_pull_mem(buf, sizeof(be64)),
664 			  sizeof(be64), "Invalid 64 bits byte order");
665 
666 	/* push/remove byte order */
667 	net_buf_reset(buf);
668 	net_buf_reserve(buf, 16);
669 
670 	net_buf_push_mem(buf, &le16, sizeof(le16));
671 	net_buf_push_mem(buf, &be16, sizeof(be16));
672 
673 	u16 = net_buf_remove_le16(buf);
674 	zassert_equal(u16, net_buf_remove_be16(buf),
675 		      "Invalid 16 bits byte order");
676 
677 	net_buf_reset(buf);
678 	net_buf_reserve(buf, 16);
679 
680 	net_buf_push_le16(buf, u16);
681 	net_buf_push_be16(buf, u16);
682 
683 	zassert_mem_equal(le16, net_buf_remove_mem(buf, sizeof(le16)),
684 			  sizeof(le16),  "Invalid 16 bits byte order");
685 	zassert_mem_equal(be16, net_buf_remove_mem(buf, sizeof(be16)),
686 			  sizeof(be16),  "Invalid 16 bits byte order");
687 
688 	net_buf_reset(buf);
689 	net_buf_reserve(buf, 16);
690 
691 	net_buf_push_mem(buf, &le24, sizeof(le24));
692 	net_buf_push_mem(buf, &be24, sizeof(be24));
693 
694 	u32 = net_buf_remove_le24(buf);
695 	zassert_equal(u32, net_buf_remove_be24(buf),
696 		      "Invalid 24 bits byte order");
697 
698 	net_buf_reset(buf);
699 	net_buf_reserve(buf, 16);
700 
701 	net_buf_push_le24(buf, u32);
702 	net_buf_push_be24(buf, u32);
703 
704 	zassert_mem_equal(le24, net_buf_remove_mem(buf, sizeof(le24)),
705 			  sizeof(le24),  "Invalid 24 bits byte order");
706 	zassert_mem_equal(be24, net_buf_remove_mem(buf, sizeof(be24)),
707 			  sizeof(be24),  "Invalid 24 bits byte order");
708 
709 	net_buf_reset(buf);
710 	net_buf_reserve(buf, 16);
711 
712 	net_buf_push_mem(buf, &le32, sizeof(le32));
713 	net_buf_push_mem(buf, &be32, sizeof(be32));
714 
715 	u32 = net_buf_remove_le32(buf);
716 	zassert_equal(u32, net_buf_remove_be32(buf),
717 		      "Invalid 32 bits byte order");
718 
719 	net_buf_reset(buf);
720 	net_buf_reserve(buf, 16);
721 
722 	net_buf_push_le32(buf, u32);
723 	net_buf_push_be32(buf, u32);
724 
725 	zassert_mem_equal(le32, net_buf_remove_mem(buf, sizeof(le32)),
726 			  sizeof(le32), "Invalid 32 bits byte order");
727 	zassert_mem_equal(be32, net_buf_remove_mem(buf, sizeof(be32)),
728 			  sizeof(be32), "Invalid 32 bits byte order");
729 
730 	net_buf_reset(buf);
731 	net_buf_reserve(buf, 16);
732 
733 	net_buf_push_mem(buf, &le40, sizeof(le40));
734 	net_buf_push_mem(buf, &be40, sizeof(be40));
735 
736 	u64 = net_buf_remove_le40(buf);
737 	zassert_equal(u64, net_buf_remove_be40(buf), "Invalid 40 bits byte order");
738 
739 	net_buf_reset(buf);
740 	net_buf_reserve(buf, 16);
741 
742 	net_buf_push_le40(buf, u64);
743 	net_buf_push_be40(buf, u64);
744 
745 	zassert_mem_equal(le40, net_buf_remove_mem(buf, sizeof(le40)), sizeof(le40),
746 			  "Invalid 40 bits byte order");
747 	zassert_mem_equal(be40, net_buf_remove_mem(buf, sizeof(be40)), sizeof(be40),
748 			  "Invalid 40 bits byte order");
749 
750 	net_buf_reset(buf);
751 	net_buf_reserve(buf, 16);
752 
753 	net_buf_push_mem(buf, &le48, sizeof(le48));
754 	net_buf_push_mem(buf, &be48, sizeof(be48));
755 
756 	u64 = net_buf_remove_le48(buf);
757 	zassert_equal(u64, net_buf_remove_be48(buf),
758 		      "Invalid 48 bits byte order");
759 
760 	net_buf_reset(buf);
761 	net_buf_reserve(buf, 16);
762 
763 	net_buf_push_le48(buf, u64);
764 	net_buf_push_be48(buf, u64);
765 
766 	zassert_mem_equal(le48, net_buf_remove_mem(buf, sizeof(le48)),
767 			  sizeof(le48),  "Invalid 48 bits byte order");
768 	zassert_mem_equal(be48, net_buf_remove_mem(buf, sizeof(be48)),
769 			  sizeof(be48),  "Invalid 48 bits byte order");
770 
771 	net_buf_reset(buf);
772 	net_buf_reserve(buf, 16);
773 
774 	net_buf_push_mem(buf, &le64, sizeof(le64));
775 	net_buf_push_mem(buf, &be64, sizeof(be64));
776 
777 	u64 = net_buf_remove_le64(buf);
778 	zassert_equal(u64, net_buf_remove_be64(buf),
779 		      "Invalid 64 bits byte order");
780 
781 	net_buf_reset(buf);
782 	net_buf_reserve(buf, 16);
783 
784 	net_buf_push_le64(buf, u64);
785 	net_buf_push_be64(buf, u64);
786 
787 	zassert_mem_equal(le64, net_buf_remove_mem(buf, sizeof(le64)),
788 			  sizeof(le64), "Invalid 64 bits byte order");
789 	zassert_mem_equal(be64, net_buf_remove_mem(buf, sizeof(be64)),
790 			  sizeof(be64), "Invalid 64 bits byte order");
791 
792 	net_buf_unref(buf);
793 }
794 
ZTEST(net_buf_tests,test_net_buf_user_data)795 ZTEST(net_buf_tests, test_net_buf_user_data)
796 {
797 	struct net_buf *buf;
798 
799 	/* Fixed Pool */
800 	buf = net_buf_alloc(&fixed_pool, K_NO_WAIT);
801 	zassert_not_null(buf, "Failed to get buffer");
802 
803 	zassert_equal(USER_DATA_FIXED, fixed_pool.user_data_size,
804 		"Bad user_data_size");
805 	zassert_equal(USER_DATA_FIXED, buf->user_data_size,
806 		"Bad user_data_size");
807 
808 	net_buf_unref(buf);
809 
810 	/* Heap Pool */
811 	buf = net_buf_alloc_len(&bufs_pool, 20, K_NO_WAIT);
812 	zassert_not_null(buf, "Failed to get buffer");
813 
814 	zassert_equal(USER_DATA_HEAP, bufs_pool.user_data_size,
815 		"Bad user_data_size");
816 	zassert_equal(USER_DATA_HEAP, buf->user_data_size,
817 		"Bad user_data_size");
818 
819 	net_buf_unref(buf);
820 
821 	/* Var Pool */
822 	buf = net_buf_alloc_len(&var_pool, 20, K_NO_WAIT);
823 	zassert_not_null(buf, "Failed to get buffer");
824 
825 	zassert_equal(USER_DATA_VAR, var_pool.user_data_size,
826 		"Bad user_data_size");
827 	zassert_equal(USER_DATA_VAR, buf->user_data_size,
828 		"Bad user_data_size");
829 
830 	net_buf_unref(buf);
831 }
832 
ZTEST(net_buf_tests,test_net_buf_user_data_copy)833 ZTEST(net_buf_tests, test_net_buf_user_data_copy)
834 {
835 	struct net_buf *buf_user_data_small, *buf_user_data_big;
836 	uint32_t *src_user_data, *dst_user_data;
837 
838 	buf_user_data_small = net_buf_alloc_len(&bufs_pool, 1, K_NO_WAIT);
839 	zassert_not_null(buf_user_data_small, "Failed to get buffer");
840 	src_user_data = net_buf_user_data(buf_user_data_small);
841 	*src_user_data = 0xAABBCCDD;
842 
843 	/* Happy case: Size of user data in destination buf is bigger than the source buf one */
844 	buf_user_data_big = net_buf_alloc_len(&var_pool, 1, K_NO_WAIT);
845 	zassert_not_null(buf_user_data_big, "Failed to get buffer");
846 	dst_user_data = net_buf_user_data(buf_user_data_big);
847 	*dst_user_data = 0x11223344;
848 
849 	zassert_ok(net_buf_user_data_copy(buf_user_data_big, buf_user_data_small));
850 	zassert_equal(*src_user_data, 0xAABBCCDD);
851 
852 	/* Error case: User data size of destination buffer is too small */
853 	zassert_not_ok(net_buf_user_data_copy(buf_user_data_small, buf_user_data_big),
854 		       "User data size in destination buffer too small");
855 
856 	net_buf_unref(buf_user_data_big);
857 
858 	/* Corner case: Same buffer used as source and target */
859 	zassert_ok(net_buf_user_data_copy(buf_user_data_small, buf_user_data_small),
860 		   "No-op is tolerated");
861 	zassert_equal(*src_user_data, 0xAABBCCDD, "User data remains the same");
862 
863 	net_buf_unref(buf_user_data_small);
864 }
865 
ZTEST(net_buf_tests,test_net_buf_comparison)866 ZTEST(net_buf_tests, test_net_buf_comparison)
867 {
868 	struct net_buf *buf;
869 	size_t written;
870 	size_t offset;
871 	size_t to_compare;
872 	size_t res;
873 	uint8_t data[FIXED_BUFFER_SIZE * 2];
874 
875 	/* Fill data buffer */
876 	for (int i = 0; i < sizeof(data); ++i) {
877 		data[i] = (uint8_t)i;
878 	}
879 
880 	/* Allocate a single net_buf  */
881 	buf = net_buf_alloc(&fixed_pool, K_NO_WAIT);
882 	zassert_not_null(buf, "Failed to get buffer");
883 
884 	written = net_buf_append_bytes(buf, buf->size, data, K_NO_WAIT, NULL, NULL);
885 	zassert_equal(written, buf->size, "Failed to fill the buffer");
886 	zassert_equal(buf->frags, NULL, "Additional buffer allocated");
887 
888 	/* Compare the whole buffer */
889 	res = net_buf_data_match(buf, 0, data, buf->size);
890 	zassert_equal(res, buf->size, "Whole net_buf comparison failed");
891 
892 	/* Compare from the offset */
893 	offset = buf->size / 2;
894 	to_compare = written - offset;
895 
896 	res = net_buf_data_match(buf, offset, &data[offset], to_compare);
897 	zassert_equal(res, to_compare, "Comparison with offset failed");
898 
899 	/* Write more data (it allocates more buffers) */
900 	written = net_buf_append_bytes(buf, sizeof(data) - written, &data[buf->size], K_NO_WAIT,
901 				       NULL, NULL);
902 	zassert_true(buf->frags, "Failed to allocate an additional net_buf");
903 
904 	/* Compare whole data with buffers' content */
905 	res = net_buf_data_match(buf, 0, data, sizeof(data));
906 	zassert_equal(res, sizeof(data), "Failed to compare data with multiple buffers");
907 
908 	/* Compare data with offset at the edge between two fragments */
909 	offset = buf->size - (buf->size / 2);
910 	res = net_buf_data_match(buf, offset, &data[offset], buf->size);
911 	zassert_equal(res, buf->size, "Failed to compare bytes within two buffers with offset");
912 
913 	/* Compare data with partial matching - change the data in the middle */
914 	data[sizeof(data) / 2] += 1;
915 	res = net_buf_data_match(buf, 0, data, sizeof(data));
916 	zassert_equal(res, sizeof(data) / 2, "Partial matching failed");
917 
918 	/* No buffer - expect 0 matching bytes */
919 	res = net_buf_data_match(NULL, 0, data, sizeof(data));
920 	zassert_equal(res, 0, "Matching without a buffer must fail");
921 
922 	/* No data - expect 0 matching bytes */
923 	res = net_buf_data_match(buf, 0, NULL, sizeof(data));
924 	zassert_equal(res, 0, "Matching without data must fail");
925 
926 	/* Too high offset - expect 0 matching bytes */
927 	res = net_buf_data_match(buf, FIXED_BUFFER_SIZE * 2, data, sizeof(data));
928 	zassert_equal(res, 0, "Matching with too high offset must fail");
929 
930 	/* Try to match more bytes than are in buffers - expect only partial match */
931 	offset = (FIXED_BUFFER_SIZE * 2) - 8;
932 	res = net_buf_data_match(buf, offset, &data[offset], 16);
933 	zassert_equal(res, 8, "Reaching out of bounds must return a partial match");
934 
935 	net_buf_unref(buf);
936 }
937 
ZTEST(net_buf_tests,test_net_buf_fixed_append)938 ZTEST(net_buf_tests, test_net_buf_fixed_append)
939 {
940 	struct net_buf *buf;
941 	uint8_t data[FIXED_BUFFER_SIZE * 2];
942 
943 	/* Fill data buffer */
944 	for (int i = 0; i < sizeof(data); ++i) {
945 		data[i] = (uint8_t)i;
946 	}
947 
948 	/* Fixed Pool */
949 	buf = net_buf_alloc(&fixed_pool, K_NO_WAIT);
950 	zassert_not_null(buf, "Failed to get fixed buffer");
951 	zassert_equal(buf->size, FIXED_BUFFER_SIZE, "Invalid fixed buffer size");
952 
953 	/* For fixed pool appending less bytes than buffer's free space must
954 	 * not add a new fragment
955 	 */
956 	net_buf_append_bytes(buf, buf->size - 8, data, K_NO_WAIT, NULL, NULL);
957 	zassert_equal(buf->len, buf->size - 8, "Invalid buffer len");
958 	zassert_is_null(buf->frags, "Unexpected buffer fragment");
959 
960 	/* Filling rest of the space should not add an additional buffer */
961 	net_buf_append_bytes(buf, 8, data, K_NO_WAIT, NULL, NULL);
962 	zassert_equal(buf->len, buf->size, "Invalid buffer len");
963 	zassert_is_null(buf->frags, "Unexpected buffer fragment");
964 
965 	/* Appending any number of bytes allocates an additional fragment */
966 	net_buf_append_bytes(buf, 1, data, K_NO_WAIT, NULL, NULL);
967 	zassert_not_null(buf->frags, "Lack of expected buffer fragment");
968 	zassert_equal(buf->frags->len, 1, "Expected single byte in the new fragment");
969 	zassert_equal(buf->frags->size, buf->size, "Different size of the fragment");
970 
971 	/* Remove 1-byte buffer */
972 	net_buf_frag_del(buf, buf->frags);
973 
974 	/* Appending size bigger than single buffer's size will allocate multiple fragments */
975 	net_buf_append_bytes(buf, sizeof(data), data, K_NO_WAIT, NULL, NULL);
976 	zassert_not_null(buf->frags, "Missing first buffer fragment");
977 	zassert_not_null(buf->frags->frags, "Missing second buffer fragment");
978 	zassert_is_null(buf->frags->frags->frags, "Unexpected buffer fragment");
979 
980 	net_buf_unref(buf);
981 }
982 
983 
984 ZTEST_SUITE(net_buf_tests, NULL, NULL, NULL, NULL, NULL);
985