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