@@ -150,7 +150,10 @@ static void publish_sent(int err, void *user_data)
150
150
151
151
if (delay ) {
152
152
BT_DBG ("Publishing next time in %dms" , delay );
153
- k_delayed_work_submit (& mod -> pub -> timer , K_MSEC (delay ));
153
+ /* Using schedule() in case the application has already called
154
+ * bt_mesh_publish, and a publication is pending.
155
+ */
156
+ k_work_schedule (& mod -> pub -> timer , K_MSEC (delay ));
154
157
}
155
158
}
156
159
@@ -161,6 +164,7 @@ static void publish_start(uint16_t duration, int err, void *user_data)
161
164
162
165
if (err ) {
163
166
BT_ERR ("Failed to publish: err %d" , err );
167
+ publish_sent (err , user_data );
164
168
return ;
165
169
}
166
170
@@ -175,7 +179,7 @@ static const struct bt_mesh_send_cb pub_sent_cb = {
175
179
.end = publish_sent ,
176
180
};
177
181
178
- static int publish_retransmit (struct bt_mesh_model * mod )
182
+ static int publish_transmit (struct bt_mesh_model * mod )
179
183
{
180
184
NET_BUF_SIMPLE_DEFINE (sdu , BT_MESH_TX_SDU_MAX );
181
185
struct bt_mesh_model_pub * pub = mod -> pub ;
@@ -192,67 +196,68 @@ static int publish_retransmit(struct bt_mesh_model *mod)
192
196
193
197
net_buf_simple_add_mem (& sdu , pub -> msg -> data , pub -> msg -> len );
194
198
195
- pub -> count -- ;
196
-
197
199
return bt_mesh_trans_send (& tx , & sdu , & pub_sent_cb , mod );
198
200
}
199
201
200
- static void publish_retransmit_end ( int err , struct bt_mesh_model_pub * pub )
202
+ static int pub_period_start ( struct bt_mesh_model_pub * pub )
201
203
{
202
- /* Cancel all retransmits for this publish attempt */
203
- pub -> count = 0U ;
204
- /* Make sure the publish timer gets reset */
205
- publish_sent (err , pub -> mod );
204
+ int err ;
205
+
206
+ pub -> count = BT_MESH_PUB_TRANSMIT_COUNT (pub -> retransmit );
207
+
208
+ if (!pub -> update ) {
209
+ return 0 ;
210
+ }
211
+
212
+ err = pub -> update (pub -> mod );
213
+ if (err ) {
214
+ /* Skip this publish attempt. */
215
+ BT_DBG ("Update failed, skipping publish (err: %d)" , err );
216
+ pub -> count = 0 ;
217
+ pub -> period_start = k_uptime_get_32 ();
218
+ publish_sent (err , pub );
219
+ return err ;
220
+ }
221
+
222
+ return 0 ;
206
223
}
207
224
208
225
static void mod_publish (struct k_work * work )
209
226
{
210
- struct bt_mesh_model_pub * pub = CONTAINER_OF (work ,
227
+ struct k_work_delayable * dwork = k_work_delayable_from_work (work );
228
+ struct bt_mesh_model_pub * pub = CONTAINER_OF (dwork ,
211
229
struct bt_mesh_model_pub ,
212
- timer .work );
213
- int32_t period_ms ;
230
+ timer );
214
231
int err ;
215
232
216
- BT_DBG ("" );
233
+ if (pub -> addr == BT_MESH_ADDR_UNASSIGNED ||
234
+ atomic_test_bit (bt_mesh .flags , BT_MESH_SUSPENDED )) {
235
+ /* Publication is no longer active, but the cancellation of the
236
+ * delayed work failed. Abandon recurring timer.
237
+ */
238
+ return ;
239
+ }
217
240
218
- period_ms = bt_mesh_model_pub_period_get (pub -> mod );
219
- BT_DBG ("period %u ms" , period_ms );
241
+ BT_DBG ("" );
220
242
221
243
if (pub -> count ) {
222
- err = publish_retransmit (pub -> mod );
244
+ pub -> count -- ;
245
+ } else {
246
+ /* First publication in this period */
247
+ err = pub_period_start (pub );
223
248
if (err ) {
224
- BT_ERR ("Failed to retransmit (err %d)" , err );
225
-
226
- pub -> count = 0U ;
227
-
228
- /* Continue with normal publication */
229
- if (period_ms ) {
230
- k_delayed_work_submit (& pub -> timer ,
231
- K_MSEC (period_ms ));
232
- }
249
+ return ;
233
250
}
234
-
235
- return ;
236
251
}
237
252
238
- if (!period_ms ) {
239
- return ;
240
- }
241
-
242
- __ASSERT_NO_MSG (pub -> update != NULL );
243
-
244
- err = pub -> update (pub -> mod );
253
+ err = publish_transmit (pub -> mod );
245
254
if (err ) {
246
- /* Cancel this publish attempt. */
247
- BT_DBG ("Update failed, skipping publish (err: %d)" , err );
248
- pub -> period_start = k_uptime_get_32 ();
249
- publish_retransmit_end (err , pub );
250
- return ;
251
- }
255
+ BT_ERR ("Failed to publish (err %d)" , err );
256
+ if (pub -> count == BT_MESH_PUB_TRANSMIT_COUNT (pub -> retransmit )) {
257
+ pub -> period_start = k_uptime_get_32 ();
258
+ }
252
259
253
- err = bt_mesh_model_publish (pub -> mod );
254
- if (err ) {
255
- BT_ERR ("Publishing failed (err %d)" , err );
260
+ publish_sent (err , pub -> mod );
256
261
}
257
262
}
258
263
@@ -301,7 +306,7 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
301
306
302
307
if (mod -> pub ) {
303
308
mod -> pub -> mod = mod ;
304
- k_delayed_work_init (& mod -> pub -> timer , mod_publish );
309
+ k_work_init_delayable (& mod -> pub -> timer , mod_publish );
305
310
}
306
311
307
312
for (i = 0 ; i < ARRAY_SIZE (mod -> keys ); i ++ ) {
@@ -630,102 +635,67 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
630
635
}
631
636
}
632
637
633
- static int model_send (struct bt_mesh_model * model ,
634
- struct bt_mesh_net_tx * tx , bool implicit_bind ,
635
- struct net_buf_simple * msg ,
636
- const struct bt_mesh_send_cb * cb , void * cb_data )
638
+ int bt_mesh_model_send (struct bt_mesh_model * model , struct bt_mesh_msg_ctx * ctx ,
639
+ struct net_buf_simple * msg ,
640
+ const struct bt_mesh_send_cb * cb , void * cb_data )
637
641
{
638
- BT_DBG ("net_idx 0x%04x app_idx 0x%04x dst 0x%04x" , tx -> ctx -> net_idx ,
639
- tx -> ctx -> app_idx , tx -> ctx -> addr );
642
+ struct bt_mesh_net_tx tx = {
643
+ .ctx = ctx ,
644
+ .src = bt_mesh_model_elem (model )-> addr ,
645
+ };
646
+
647
+ BT_DBG ("net_idx 0x%04x app_idx 0x%04x dst 0x%04x" , tx .ctx -> net_idx ,
648
+ tx .ctx -> app_idx , tx .ctx -> addr );
640
649
BT_DBG ("len %u: %s" , msg -> len , bt_hex (msg -> data , msg -> len ));
641
650
642
651
if (!bt_mesh_is_provisioned ()) {
643
652
BT_ERR ("Local node is not yet provisioned" );
644
653
return - EAGAIN ;
645
654
}
646
655
647
- if (net_buf_simple_tailroom ( msg ) < 4 ) {
648
- BT_ERR ("Not enough tailroom for TransMIC" );
656
+ if (! model_has_key ( model , tx . ctx -> app_idx ) ) {
657
+ BT_ERR ("Model not bound to AppKey 0x%04x" , tx . ctx -> app_idx );
649
658
return - EINVAL ;
650
659
}
651
660
652
- if (msg -> len > BT_MESH_TX_SDU_MAX - 4 ) {
653
- BT_ERR ("Too big message" );
654
- return - EMSGSIZE ;
655
- }
656
-
657
- if (!implicit_bind && !model_has_key (model , tx -> ctx -> app_idx )) {
658
- BT_ERR ("Model not bound to AppKey 0x%04x" , tx -> ctx -> app_idx );
659
- return - EINVAL ;
660
- }
661
-
662
- return bt_mesh_trans_send (tx , msg , cb , cb_data );
663
- }
664
-
665
- int bt_mesh_model_send (struct bt_mesh_model * model ,
666
- struct bt_mesh_msg_ctx * ctx ,
667
- struct net_buf_simple * msg ,
668
- const struct bt_mesh_send_cb * cb , void * cb_data )
669
- {
670
- struct bt_mesh_net_tx tx = {
671
- .ctx = ctx ,
672
- .src = bt_mesh_model_elem (model )-> addr ,
673
- };
674
-
675
- return model_send (model , & tx , false, msg , cb , cb_data );
661
+ return bt_mesh_trans_send (& tx , msg , cb , cb_data );
676
662
}
677
663
678
664
int bt_mesh_model_publish (struct bt_mesh_model * model )
679
665
{
680
- NET_BUF_SIMPLE_DEFINE (sdu , BT_MESH_TX_SDU_MAX );
681
666
struct bt_mesh_model_pub * pub = model -> pub ;
682
667
683
668
if (!pub ) {
684
669
return - ENOTSUP ;
685
670
}
686
671
687
- struct bt_mesh_msg_ctx ctx = {
688
- .addr = pub -> addr ,
689
- .send_ttl = pub -> ttl ,
690
- .send_rel = pub -> send_rel ,
691
- .app_idx = pub -> key ,
692
- };
693
- struct bt_mesh_net_tx tx = {
694
- .ctx = & ctx ,
695
- .src = bt_mesh_model_elem (model )-> addr ,
696
- };
697
- int err ;
698
-
699
672
BT_DBG ("" );
700
673
701
674
if (pub -> addr == BT_MESH_ADDR_UNASSIGNED ) {
702
675
return - EADDRNOTAVAIL ;
703
676
}
704
677
705
- if (pub -> msg -> len + 4 > BT_MESH_TX_SDU_MAX ) {
678
+ if (!pub -> msg || !pub -> msg -> len ) {
679
+ BT_ERR ("No publication message" );
680
+ return - EINVAL ;
681
+ }
682
+
683
+ if (pub -> msg -> len + BT_MESH_MIC_SHORT > BT_MESH_TX_SDU_MAX ) {
706
684
BT_ERR ("Message does not fit maximum SDU size" );
707
685
return - EMSGSIZE ;
708
686
}
709
687
710
688
if (pub -> count ) {
711
689
BT_WARN ("Clearing publish retransmit timer" );
712
- k_delayed_work_cancel (& pub -> timer );
713
690
}
714
691
715
- net_buf_simple_add_mem (& sdu , pub -> msg -> data , pub -> msg -> len );
716
-
717
- tx .friend_cred = pub -> cred ;
718
-
719
- pub -> count = BT_MESH_PUB_TRANSMIT_COUNT (pub -> retransmit );
692
+ /* Account for initial transmission */
693
+ pub -> count = BT_MESH_PUB_TRANSMIT_COUNT (pub -> retransmit ) + 1 ;
720
694
721
695
BT_DBG ("Publish Retransmit Count %u Interval %ums" , pub -> count ,
722
696
BT_MESH_PUB_TRANSMIT_INT (pub -> retransmit ));
723
697
724
- err = model_send (model , & tx , true, & sdu , & pub_sent_cb , model );
725
- if (err ) {
726
- publish_retransmit_end (err , pub );
727
- return err ;
728
- }
698
+ k_work_reschedule (& pub -> timer , K_NO_WAIT );
729
699
730
700
return 0 ;
731
701
}
@@ -1208,7 +1178,7 @@ static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
1208
1178
1209
1179
if (ms > 0 ) {
1210
1180
BT_DBG ("Starting publish timer (period %u ms)" , ms );
1211
- k_delayed_work_submit (& mod -> pub -> timer , K_MSEC (ms ));
1181
+ k_work_schedule (& mod -> pub -> timer , K_MSEC (ms ));
1212
1182
}
1213
1183
}
1214
1184
0 commit comments