@@ -150,7 +150,10 @@ static void publish_sent(int err, void *user_data)
150150
151151 if (delay ) {
152152 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 ));
154157 }
155158}
156159
@@ -161,6 +164,7 @@ static void publish_start(uint16_t duration, int err, void *user_data)
161164
162165 if (err ) {
163166 BT_ERR ("Failed to publish: err %d" , err );
167+ publish_sent (err , user_data );
164168 return ;
165169 }
166170
@@ -175,7 +179,7 @@ static const struct bt_mesh_send_cb pub_sent_cb = {
175179 .end = publish_sent ,
176180};
177181
178- static int publish_retransmit (struct bt_mesh_model * mod )
182+ static int publish_transmit (struct bt_mesh_model * mod )
179183{
180184 NET_BUF_SIMPLE_DEFINE (sdu , BT_MESH_TX_SDU_MAX );
181185 struct bt_mesh_model_pub * pub = mod -> pub ;
@@ -192,67 +196,68 @@ static int publish_retransmit(struct bt_mesh_model *mod)
192196
193197 net_buf_simple_add_mem (& sdu , pub -> msg -> data , pub -> msg -> len );
194198
195- pub -> count -- ;
196-
197199 return bt_mesh_trans_send (& tx , & sdu , & pub_sent_cb , mod );
198200}
199201
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 )
201203{
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 ;
206223}
207224
208225static void mod_publish (struct k_work * work )
209226{
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 ,
211229 struct bt_mesh_model_pub ,
212- timer .work );
213- int32_t period_ms ;
230+ timer );
214231 int err ;
215232
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+ }
217240
218- period_ms = bt_mesh_model_pub_period_get (pub -> mod );
219- BT_DBG ("period %u ms" , period_ms );
241+ BT_DBG ("" );
220242
221243 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 );
223248 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 ;
233250 }
234-
235- return ;
236251 }
237252
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 );
245254 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+ }
252259
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 );
256261 }
257262}
258263
@@ -301,7 +306,7 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
301306
302307 if (mod -> pub ) {
303308 mod -> pub -> mod = mod ;
304- k_delayed_work_init (& mod -> pub -> timer , mod_publish );
309+ k_work_init_delayable (& mod -> pub -> timer , mod_publish );
305310 }
306311
307312 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)
630635 }
631636}
632637
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 )
637641{
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 );
640649 BT_DBG ("len %u: %s" , msg -> len , bt_hex (msg -> data , msg -> len ));
641650
642651 if (!bt_mesh_is_provisioned ()) {
643652 BT_ERR ("Local node is not yet provisioned" );
644653 return - EAGAIN ;
645654 }
646655
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 );
649658 return - EINVAL ;
650659 }
651660
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 );
676662}
677663
678664int bt_mesh_model_publish (struct bt_mesh_model * model )
679665{
680- NET_BUF_SIMPLE_DEFINE (sdu , BT_MESH_TX_SDU_MAX );
681666 struct bt_mesh_model_pub * pub = model -> pub ;
682667
683668 if (!pub ) {
684669 return - ENOTSUP ;
685670 }
686671
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-
699672 BT_DBG ("" );
700673
701674 if (pub -> addr == BT_MESH_ADDR_UNASSIGNED ) {
702675 return - EADDRNOTAVAIL ;
703676 }
704677
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 ) {
706684 BT_ERR ("Message does not fit maximum SDU size" );
707685 return - EMSGSIZE ;
708686 }
709687
710688 if (pub -> count ) {
711689 BT_WARN ("Clearing publish retransmit timer" );
712- k_delayed_work_cancel (& pub -> timer );
713690 }
714691
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 ;
720694
721695 BT_DBG ("Publish Retransmit Count %u Interval %ums" , pub -> count ,
722696 BT_MESH_PUB_TRANSMIT_INT (pub -> retransmit ));
723697
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 );
729699
730700 return 0 ;
731701}
@@ -1208,7 +1178,7 @@ static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
12081178
12091179 if (ms > 0 ) {
12101180 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 ));
12121182 }
12131183 }
12141184
0 commit comments