@@ -980,5 +980,108 @@ ZTEST(net_buf_tests, test_net_buf_fixed_append)
980
980
net_buf_unref (buf );
981
981
}
982
982
983
+ ZTEST (net_buf_tests , test_net_buf_linearize )
984
+ {
985
+ struct net_buf * buf , * frag ;
986
+ uint8_t linear_buffer [256 ];
987
+ uint8_t expected_data [256 ];
988
+ size_t copied ;
989
+
990
+ static const char fragment1_data [] = "Hello World! This is fragment 1" ;
991
+ static const char fragment2_data [] = "Fragment 2 data here" ;
992
+ static const char fragment3_data [] = "Final fragment data" ;
993
+ const size_t fragment1_len = sizeof (fragment1_data ) - 1 ;
994
+ const size_t fragment2_len = sizeof (fragment2_data ) - 1 ;
995
+ const size_t fragment3_len = sizeof (fragment3_data ) - 1 ;
996
+ const size_t total_len = fragment1_len + fragment2_len + fragment3_len ;
997
+
998
+ destroy_called = 0 ;
999
+
1000
+ /* Create a buf that does not have any data to store, it just
1001
+ * contains link to fragments.
1002
+ */
1003
+ buf = net_buf_alloc_len (& bufs_pool , 0 , K_FOREVER );
1004
+ zassert_not_null (buf , "Failed to get buffer" );
1005
+
1006
+ /* Add first fragment with some data */
1007
+ frag = net_buf_alloc_len (& bufs_pool , 50 , K_FOREVER );
1008
+ zassert_not_null (frag , "Failed to get fragment" );
1009
+ net_buf_add_mem (frag , fragment1_data , fragment1_len );
1010
+ net_buf_frag_add (buf , frag );
1011
+
1012
+ /* Add second fragment with more data */
1013
+ frag = net_buf_alloc_len (& bufs_pool , 50 , K_FOREVER );
1014
+ zassert_not_null (frag , "Failed to get fragment" );
1015
+ net_buf_add_mem (frag , fragment2_data , fragment2_len );
1016
+ net_buf_frag_add (buf , frag );
1017
+
1018
+ /* Add third fragment */
1019
+ frag = net_buf_alloc_len (& bufs_pool , 50 , K_FOREVER );
1020
+ zassert_not_null (frag , "Failed to get fragment" );
1021
+ net_buf_add_mem (frag , fragment3_data , fragment3_len );
1022
+ net_buf_frag_add (buf , frag );
1023
+
1024
+ /* Prepare expected data (all fragments concatenated) */
1025
+ memset (expected_data , 0 , sizeof (expected_data ));
1026
+ memcpy (expected_data , fragment1_data , fragment1_len );
1027
+ memcpy (expected_data + fragment1_len , fragment2_data , fragment2_len );
1028
+ memcpy (expected_data + fragment1_len + fragment2_len , fragment3_data , fragment3_len );
1029
+
1030
+ /* Test 1: Linearize entire buffer */
1031
+ memset (linear_buffer , 0 , sizeof (linear_buffer ));
1032
+ copied = net_buf_linearize (linear_buffer , sizeof (linear_buffer ), buf -> frags , 0 , total_len );
1033
+ zassert_equal (copied , total_len , "Incorrect number of bytes copied" );
1034
+ zassert_mem_equal (linear_buffer , expected_data , total_len , "Linearized data doesn't match" );
1035
+
1036
+ /* Test 2: Linearize with offset */
1037
+ memset (linear_buffer , 0 , sizeof (linear_buffer ));
1038
+ copied = net_buf_linearize (linear_buffer , sizeof (linear_buffer ), buf -> frags , 10 , 10 );
1039
+ zassert_equal (copied , 10 , "Incorrect number of bytes copied with offset" );
1040
+ zassert_mem_equal (linear_buffer , expected_data + 10 , 10 ,
1041
+ "Linearized data with offset doesn't match" );
1042
+
1043
+ /* Test 3: Linearize across fragment boundary */
1044
+ memset (linear_buffer , 0 , sizeof (linear_buffer ));
1045
+ copied = net_buf_linearize (linear_buffer , sizeof (linear_buffer ), buf -> frags ,
1046
+ fragment1_len - 5 , 20 );
1047
+ zassert_equal (copied , 20 , "Incorrect number of bytes copied across boundary" );
1048
+ zassert_mem_equal (linear_buffer , expected_data + fragment1_len - 5 , 20 ,
1049
+ "Linearized data across boundary doesn't match" );
1050
+
1051
+ /* Test 4: Linearize with destination buffer too small */
1052
+ memset (linear_buffer , 0 , sizeof (linear_buffer ));
1053
+ copied = net_buf_linearize (linear_buffer , 10 , buf -> frags , 0 , total_len );
1054
+ zassert_equal (copied , 10 , "Should copy only up to destination buffer size" );
1055
+ zassert_mem_equal (linear_buffer , expected_data , 10 ,
1056
+ "Partial linearized data doesn't match" );
1057
+
1058
+ /* Test 5: Linearize with offset beyond available data */
1059
+ memset (linear_buffer , 0 , sizeof (linear_buffer ));
1060
+ copied = net_buf_linearize (linear_buffer , sizeof (linear_buffer ), buf -> frags , total_len + 10 ,
1061
+ 20 );
1062
+ zassert_equal (copied , 0 , "Should copy 0 bytes when offset is beyond data" );
1063
+
1064
+ /* Test 6: Linearize with len beyond available data */
1065
+ memset (linear_buffer , 0 , sizeof (linear_buffer ));
1066
+ copied = net_buf_linearize (linear_buffer , sizeof (linear_buffer ), buf -> frags , 0 ,
1067
+ total_len + 10 );
1068
+ zassert_equal (copied , total_len , "Should copy only available data when len exceeds data" );
1069
+
1070
+ /* Test 7: Linearize with NULL source */
1071
+ copied = net_buf_linearize (linear_buffer , sizeof (linear_buffer ), NULL , 0 , 20 );
1072
+ zassert_equal (copied , 0 , "Should return 0 for NULL source" );
1073
+
1074
+ /* Test 8: Linearize with zero length */
1075
+ memset (linear_buffer , 0 , sizeof (linear_buffer ));
1076
+ copied = net_buf_linearize (linear_buffer , sizeof (linear_buffer ), buf -> frags , 0 , 0 );
1077
+ zassert_equal (copied , 0 , "Should copy 0 bytes when len is 0" );
1078
+
1079
+ /* Test 9: Linearize with zero destination length */
1080
+ copied = net_buf_linearize (linear_buffer , 0 , buf -> frags , 0 , 20 );
1081
+ zassert_equal (copied , 0 , "Should copy 0 bytes when destination length is 0" );
1082
+
1083
+ net_buf_unref (buf );
1084
+ zassert_equal (destroy_called , 4 , "Incorrect destroy callback count" );
1085
+ }
983
1086
984
1087
ZTEST_SUITE (net_buf_tests , NULL , NULL , NULL , NULL , NULL );
0 commit comments