@@ -173,6 +173,18 @@ static void data_buf_add_le16_offset(struct net_buf_simple *buf,
173
173
}
174
174
}
175
175
176
+ static void data_buf_add_mem_offset (struct net_buf_simple * buf , uint8_t * data , size_t len ,
177
+ size_t * offset )
178
+ {
179
+ if (* offset >= len ) {
180
+ * offset -= len ;
181
+ return ;
182
+ }
183
+
184
+ net_buf_simple_add_mem (buf , data + * offset , len - * offset );
185
+ * offset = 0 ;
186
+ }
187
+
176
188
static void comp_add_model (struct bt_mesh_model * mod , struct bt_mesh_elem * elem ,
177
189
bool vnd , void * user_data )
178
190
{
@@ -187,20 +199,6 @@ static void comp_add_model(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
187
199
}
188
200
189
201
#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV )
190
- static void data_buf_add_mem_offset (struct net_buf_simple * buf ,
191
- const void * mem , size_t len ,
192
- size_t * offset )
193
- {
194
- if (* offset >= len ) {
195
- * offset -= len ;
196
- return ;
197
- } else if (* offset > 0 ) {
198
- net_buf_simple_add_mem (buf , ((uint8_t * )mem ), (len - * offset ));
199
-
200
- } else {
201
- net_buf_simple_add_mem (buf , mem , len );
202
- }
203
- }
204
202
205
203
static size_t metadata_model_size (struct bt_mesh_model * mod ,
206
204
struct bt_mesh_elem * elem , bool vnd )
@@ -366,23 +364,6 @@ int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset)
366
364
}
367
365
#endif
368
366
369
- size_t bt_mesh_comp_page_0_size (void )
370
- {
371
- const struct bt_mesh_comp * comp ;
372
- const struct bt_mesh_elem * elem ;
373
- size_t size = 10 ;
374
- int i ;
375
-
376
- comp = bt_mesh_comp_get ();
377
-
378
- for (i = 0 ; i < comp -> elem_count ; i ++ ) {
379
- elem = & comp -> elem [i ];
380
- size += bt_mesh_comp_elem_size (elem );
381
- }
382
-
383
- return size ;
384
- }
385
-
386
367
static int comp_add_elem (struct net_buf_simple * buf , struct bt_mesh_elem * elem ,
387
368
size_t * offset )
388
369
{
@@ -398,7 +379,7 @@ static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem,
398
379
return 0 ;
399
380
}
400
381
401
- if (net_buf_simple_tailroom (buf ) < (elem_size + BT_MESH_MIC_SHORT )) {
382
+ if (net_buf_simple_tailroom (buf ) < (( elem_size - * offset ) + BT_MESH_MIC_SHORT )) {
402
383
if (IS_ENABLED (CONFIG_BT_MESH_LARGE_COMP_DATA_SRV )) {
403
384
/* Mesh Profile 1.1 Section 4.4.1.2.2:
404
385
* If the complete list of models does not fit in the Data field,
@@ -516,8 +497,8 @@ static bool is_cor_present(struct bt_mesh_model *mod, uint8_t *cor_id)
516
497
return false;
517
498
}
518
499
519
- static void prep_model_item_header (struct bt_mesh_model * mod , uint8_t * cor_id ,
520
- uint8_t * mod_cnt , struct net_buf_simple * buf )
500
+ static void prep_model_item_header (struct bt_mesh_model * mod , uint8_t * cor_id , uint8_t * mod_cnt ,
501
+ struct net_buf_simple * buf , size_t * offset )
521
502
{
522
503
uint8_t ext_mod_cnt ;
523
504
bool cor_present ;
@@ -536,41 +517,41 @@ static void prep_model_item_header(struct bt_mesh_model *mod, uint8_t *cor_id,
536
517
if (cor_present ) {
537
518
mod_elem_info |= BIT (0 );
538
519
}
539
- net_buf_simple_add_u8 (buf , mod_elem_info );
520
+ data_buf_add_u8_offset (buf , mod_elem_info , offset );
540
521
541
522
if (cor_present ) {
542
- net_buf_simple_add_u8 (buf , * cor_id );
523
+ data_buf_add_u8_offset (buf , * cor_id , offset );
543
524
}
544
525
memset (mod_cnt , ext_mod_cnt , sizeof (uint8_t ));
545
526
}
546
527
547
528
static void add_items_to_page (struct net_buf_simple * buf , struct bt_mesh_model * mod ,
548
- uint8_t ext_mod_cnt )
529
+ uint8_t ext_mod_cnt , size_t * offset )
549
530
{
550
- int i , offset ;
531
+ int i , elem_offset ;
551
532
uint8_t mod_idx ;
552
533
553
534
MOD_REL_LIST_FOR_EACH (i ) {
554
535
if (IS_MOD_EXTENSION (mod , i )) {
555
- offset = mod -> elem_idx - mod_rel_list [i ].elem_base ;
536
+ elem_offset = mod -> elem_idx - mod_rel_list [i ].elem_base ;
556
537
mod_idx = mod_rel_list [i ].idx_base ;
557
538
if (ext_mod_cnt < 32 &&
558
- offset < 4 &&
559
- offset > -5 ) {
539
+ elem_offset < 4 &&
540
+ elem_offset > -5 ) {
560
541
/* short format */
561
- if (offset < 0 ) {
562
- offset += 8 ;
542
+ if (elem_offset < 0 ) {
543
+ elem_offset += 8 ;
563
544
}
564
545
565
- offset |= mod_idx << 3 ;
566
- net_buf_simple_add_u8 (buf , offset );
546
+ elem_offset |= mod_idx << 3 ;
547
+ data_buf_add_u8_offset (buf , elem_offset , offset );
567
548
} else {
568
549
/* long format */
569
- if (offset < 0 ) {
570
- offset += 256 ;
550
+ if (elem_offset < 0 ) {
551
+ elem_offset += 256 ;
571
552
}
572
- net_buf_simple_add_u8 (buf , offset );
573
- net_buf_simple_add_u8 (buf , mod_idx );
553
+ data_buf_add_u8_offset (buf , elem_offset , offset );
554
+ data_buf_add_u8_offset (buf , mod_idx , offset );
574
555
}
575
556
}
576
557
}
@@ -613,7 +594,7 @@ static size_t page1_elem_size(struct bt_mesh_elem *elem)
613
594
return temp_size ;
614
595
}
615
596
616
- static int bt_mesh_comp_data_get_page_1 (struct net_buf_simple * buf )
597
+ static int bt_mesh_comp_data_get_page_1 (struct net_buf_simple * buf , size_t offset )
617
598
{
618
599
const struct bt_mesh_comp * comp ;
619
600
uint8_t cor_id = 0 ;
@@ -623,8 +604,14 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf)
623
604
comp = bt_mesh_comp_get ();
624
605
625
606
for (i = 0 ; i < comp -> elem_count ; i ++ ) {
626
- if (net_buf_simple_tailroom (buf ) <
627
- (page1_elem_size (& comp -> elem [i ]) + BT_MESH_MIC_SHORT )) {
607
+ size_t elem_size = page1_elem_size (& comp -> elem [i ]);
608
+
609
+ if (offset >= elem_size ) {
610
+ offset -= elem_size ;
611
+ continue ;
612
+ }
613
+
614
+ if (net_buf_simple_tailroom (buf ) < ((elem_size - offset ) + BT_MESH_MIC_SHORT )) {
628
615
if (IS_ENABLED (CONFIG_BT_MESH_LARGE_COMP_DATA_SRV )) {
629
616
/* Mesh Profile 1.1 Section 4.4.1.2.2:
630
617
* If the complete list of models does not fit in the Data field,
@@ -639,70 +626,74 @@ static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf)
639
626
return - E2BIG ;
640
627
}
641
628
642
- net_buf_simple_add_u8 (buf , comp -> elem [i ].model_count );
643
- net_buf_simple_add_u8 (buf , comp -> elem [i ].vnd_model_count );
629
+ data_buf_add_u8_offset (buf , comp -> elem [i ].model_count , & offset );
630
+ data_buf_add_u8_offset (buf , comp -> elem [i ].vnd_model_count , & offset );
644
631
for (j = 0 ; j < comp -> elem [i ].model_count ; j ++ ) {
645
- prep_model_item_header (& comp -> elem [i ].models [j ],
646
- & cor_id , & ext_mod_cnt , buf );
632
+ prep_model_item_header (& comp -> elem [i ].models [j ], & cor_id , & ext_mod_cnt , buf ,
633
+ & offset );
647
634
if (ext_mod_cnt != 0 ) {
648
- add_items_to_page (buf ,
649
- & comp -> elem [i ].models [j ],
650
- ext_mod_cnt );
635
+ add_items_to_page (buf , & comp -> elem [i ].models [j ], ext_mod_cnt ,
636
+ & offset );
651
637
}
652
638
}
653
639
654
640
for (j = 0 ; j < comp -> elem [i ].vnd_model_count ; j ++ ) {
655
- prep_model_item_header (& comp -> elem [i ].vnd_models [j ],
656
- & cor_id , & ext_mod_cnt , buf );
641
+ prep_model_item_header (& comp -> elem [i ].vnd_models [j ], & cor_id , & ext_mod_cnt ,
642
+ buf , & offset );
657
643
if (ext_mod_cnt != 0 ) {
658
- add_items_to_page (buf ,
659
- & comp -> elem [i ].vnd_models [j ],
660
- ext_mod_cnt );
644
+ add_items_to_page (buf , & comp -> elem [i ].vnd_models [j ], ext_mod_cnt ,
645
+ & offset );
661
646
}
662
647
}
663
648
}
664
649
return 0 ;
665
650
}
666
651
667
- static int bt_mesh_comp_data_get_page_2 (struct net_buf_simple * buf )
652
+ static int bt_mesh_comp_data_get_page_2 (struct net_buf_simple * buf , size_t offset )
668
653
{
669
654
if (!dev_comp2 ) {
670
655
LOG_ERR ("Composition data P2 not registered" );
671
656
return - ENODEV ;
672
657
}
673
658
659
+ size_t elem_size ;
660
+
674
661
for (int i = 0 ; i < dev_comp2 -> record_cnt ; i ++ ) {
675
- if (net_buf_simple_tailroom (buf ) <
676
- (8 + dev_comp2 -> record [i ].elem_offset_cnt + dev_comp2 -> record [i ].data_len +
677
- BT_MESH_MIC_SHORT )) {
662
+ elem_size =
663
+ 8 + dev_comp2 -> record [i ].elem_offset_cnt + dev_comp2 -> record [i ].data_len ;
664
+ if (offset >= elem_size ) {
665
+ offset -= elem_size ;
666
+ continue ;
667
+ }
668
+
669
+ if (net_buf_simple_tailroom (buf ) < ((elem_size - offset ) + BT_MESH_MIC_SHORT )) {
678
670
if (IS_ENABLED (CONFIG_BT_MESH_LARGE_COMP_DATA_SRV )) {
679
671
/* Mesh Profile 1.1 Section 4.4.1.2.2:
680
672
* If the complete list of models does not fit in the Data field,
681
673
* the element shall not be reported.
682
674
*/
683
- LOG_DBG ("Record 0x%04x didn't fit in the Data field" ,
684
- i );
675
+ LOG_DBG ("Record 0x%04x didn't fit in the Data field" , i );
685
676
return 0 ;
686
677
}
687
678
688
679
LOG_ERR ("Too large device composition" );
689
680
return - E2BIG ;
690
681
}
691
682
692
- net_buf_simple_add_le16 (buf , dev_comp2 -> record [i ].id );
693
- net_buf_simple_add_u8 (buf , dev_comp2 -> record [i ].version .x );
694
- net_buf_simple_add_u8 (buf , dev_comp2 -> record [i ].version .y );
695
- net_buf_simple_add_u8 (buf , dev_comp2 -> record [i ].version .z );
696
- net_buf_simple_add_u8 (buf , dev_comp2 -> record [i ].elem_offset_cnt );
683
+ data_buf_add_le16_offset (buf , dev_comp2 -> record [i ].id , & offset );
684
+ data_buf_add_u8_offset (buf , dev_comp2 -> record [i ].version .x , & offset );
685
+ data_buf_add_u8_offset (buf , dev_comp2 -> record [i ].version .y , & offset );
686
+ data_buf_add_u8_offset (buf , dev_comp2 -> record [i ].version .z , & offset );
687
+ data_buf_add_u8_offset (buf , dev_comp2 -> record [i ].elem_offset_cnt , & offset );
697
688
if (dev_comp2 -> record [i ].elem_offset_cnt ) {
698
- net_buf_simple_add_mem (buf , dev_comp2 -> record [i ].elem_offset ,
699
- dev_comp2 -> record [i ].elem_offset_cnt );
689
+ data_buf_add_mem_offset (buf , ( uint8_t * ) dev_comp2 -> record [i ].elem_offset ,
690
+ dev_comp2 -> record [i ].elem_offset_cnt , & offset );
700
691
}
701
692
702
- net_buf_simple_add_le16 (buf , dev_comp2 -> record [i ].data_len );
693
+ data_buf_add_le16_offset (buf , dev_comp2 -> record [i ].data_len , & offset );
703
694
if (dev_comp2 -> record [i ].data_len ) {
704
- net_buf_simple_add_mem (buf , dev_comp2 -> record [i ].data ,
705
- dev_comp2 -> record [i ].data_len );
695
+ data_buf_add_mem_offset (buf , ( uint8_t * ) dev_comp2 -> record [i ].data ,
696
+ dev_comp2 -> record [i ].data_len , & offset );
706
697
}
707
698
}
708
699
@@ -2212,20 +2203,89 @@ int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t o
2212
2203
if (page == 0 || page == 128 ) {
2213
2204
return bt_mesh_comp_data_get_page_0 (buf , offset );
2214
2205
} else if (IS_ENABLED (CONFIG_BT_MESH_COMP_PAGE_1 ) && (page == 1 || page == 129 )) {
2215
- return bt_mesh_comp_data_get_page_1 (buf );
2206
+ return bt_mesh_comp_data_get_page_1 (buf , offset );
2216
2207
} else if (IS_ENABLED (CONFIG_BT_MESH_COMP_PAGE_2 ) && (page == 2 || page == 130 )) {
2217
- return bt_mesh_comp_data_get_page_2 (buf );
2208
+ return bt_mesh_comp_data_get_page_2 (buf , offset );
2218
2209
}
2219
2210
2220
2211
return - EINVAL ;
2221
2212
}
2222
2213
2214
+ size_t comp_page_0_size (void )
2215
+ {
2216
+ const struct bt_mesh_comp * comp ;
2217
+ const struct bt_mesh_elem * elem ;
2218
+ size_t size = 10 ; /* Non-variable length params of comp page 0. */
2219
+
2220
+ comp = bt_mesh_comp_get ();
2221
+
2222
+ for (int i = 0 ; i < comp -> elem_count ; i ++ ) {
2223
+ elem = & comp -> elem [i ];
2224
+ size += bt_mesh_comp_elem_size (elem );
2225
+ }
2226
+
2227
+ return size ;
2228
+ }
2229
+
2230
+ size_t comp_page_1_size (void )
2231
+ {
2232
+ const struct bt_mesh_comp * comp ;
2233
+ size_t size = 0 ;
2234
+
2235
+ comp = bt_mesh_comp_get ();
2236
+
2237
+ for (int i = 0 ; i < comp -> elem_count ; i ++ ) {
2238
+
2239
+ size += page1_elem_size (& comp -> elem [i ]);
2240
+ }
2241
+
2242
+ return size ;
2243
+ }
2244
+
2245
+ size_t comp_page_2_size (void )
2246
+ {
2247
+ size_t size = 0 ;
2248
+
2249
+ if (!dev_comp2 ) {
2250
+ LOG_ERR ("Composition data P2 not registered" );
2251
+ return size ;
2252
+ }
2253
+
2254
+ for (int i = 0 ; i < dev_comp2 -> record_cnt ; i ++ ) {
2255
+ size += 8 + dev_comp2 -> record [i ].elem_offset_cnt + dev_comp2 -> record [i ].data_len ;
2256
+ }
2257
+ return size ;
2258
+ }
2259
+
2260
+ size_t bt_mesh_comp_page_size (uint8_t page )
2261
+ {
2262
+ if (page == 0 || page == 128 ) {
2263
+ return comp_page_0_size ();
2264
+ } else if (IS_ENABLED (CONFIG_BT_MESH_COMP_PAGE_1 ) && (page == 1 || page == 129 )) {
2265
+ return comp_page_1_size ();
2266
+ } else if (IS_ENABLED (CONFIG_BT_MESH_COMP_PAGE_2 ) && (page == 2 || page == 130 )) {
2267
+ return comp_page_2_size ();
2268
+ }
2269
+
2270
+ return 0 ;
2271
+ }
2272
+
2223
2273
int bt_mesh_comp_store (void )
2224
2274
{
2225
- NET_BUF_SIMPLE_DEFINE (buf , BT_MESH_TX_SDU_MAX );
2275
+ #if IS_ENABLED (CONFIG_BT_MESH_V1d1 )
2276
+ NET_BUF_SIMPLE_DEFINE (buf , CONFIG_BT_MESH_COMP_PST_BUF_SIZE );
2226
2277
int err ;
2227
2278
2228
2279
for (int i = 0 ; i < ARRAY_SIZE (comp_data_pages ); i ++ ) {
2280
+ size_t page_size = bt_mesh_comp_page_size (i );
2281
+
2282
+ if (page_size > CONFIG_BT_MESH_COMP_PST_BUF_SIZE ) {
2283
+ LOG_WRN ("CDP%d is larger than the CDP persistence buffer. "
2284
+ "Please increase the CDP persistence buffer size "
2285
+ "to the required size (%d bytes)" ,
2286
+ i , page_size );
2287
+ }
2288
+
2229
2289
net_buf_simple_reset (& buf );
2230
2290
2231
2291
err = bt_mesh_comp_data_get_page (& buf , comp_data_pages [i ].page , 0 );
@@ -2242,7 +2302,7 @@ int bt_mesh_comp_store(void)
2242
2302
2243
2303
LOG_DBG ("Stored CDP%d" , comp_data_pages [i ].page );
2244
2304
}
2245
-
2305
+ #endif
2246
2306
return 0 ;
2247
2307
}
2248
2308
0 commit comments