@@ -58,19 +58,19 @@ using namespace events;
58
58
/* ****************************************************************************
59
59
* Private Member Functions *
60
60
****************************************************************************/
61
- bool LoRaWANStack::is_port_valid (uint8_t port)
61
+ bool LoRaWANStack::is_port_valid (uint8_t port, bool allow_port_0 )
62
62
{
63
63
// Application should not use reserved and illegal port numbers.
64
- if (port >= 224 || port == 0 ) {
65
- return false ;
64
+ if (port == 0 ) {
65
+ return allow_port_0 ;
66
66
} else {
67
67
return true ;
68
68
}
69
69
}
70
70
71
- lorawan_status_t LoRaWANStack::set_application_port (uint8_t port)
71
+ lorawan_status_t LoRaWANStack::set_application_port (uint8_t port, bool allow_port_0 )
72
72
{
73
- if (is_port_valid (port)) {
73
+ if (is_port_valid (port, allow_port_0 )) {
74
74
_app_port = port;
75
75
return LORAWAN_STATUS_OK;
76
76
}
@@ -236,10 +236,14 @@ void LoRaWANStack::mlme_indication_handler(loramac_mlme_indication_t *mlmeIndica
236
236
switch ( mlmeIndication->indication_type )
237
237
{
238
238
case MLME_SCHEDULE_UPLINK:
239
- {// The MAC signals that we shall provide an uplink as soon as possible
240
- // TODO: Sending implementation missing and will be implemented using
241
- // another task.
242
- // OnTxNextPacketTimerEvent( );
239
+ {
240
+ // The MAC signals that we shall provide an uplink as soon as possible
241
+ #if (MBED_CONF_LORA_AUTOMATIC_UPLINK_MESSAGE)
242
+ tr_debug (" mlme indication: sending empty uplink to port 0 to acknowledge MAC commands..." );
243
+ send_automatic_uplink_message (0 );
244
+ #else
245
+ send_event_to_application (UPLINK_REQUIRED);
246
+ #endif
243
247
break ;
244
248
}
245
249
default :
@@ -332,8 +336,26 @@ lorawan_status_t LoRaWANStack::set_channel_data_rate(uint8_t data_rate)
332
336
return _loramac.set_channel_data_rate (data_rate);
333
337
}
334
338
339
+ void LoRaWANStack::send_event_to_application (const lorawan_event_t event) const
340
+ {
341
+ if (_callbacks.events ) {
342
+ const int ret = _queue->call (_callbacks.events , event);
343
+ MBED_ASSERT (ret != 0 );
344
+ (void )ret;
345
+ }
346
+ }
347
+
348
+ void LoRaWANStack::send_automatic_uplink_message (const uint8_t port)
349
+ {
350
+ const int16_t ret = handle_tx (port, NULL , 0 , MSG_CONFIRMED_FLAG, true , true );
351
+ if (ret < 0 ) {
352
+ send_event_to_application (AUTOMATIC_UPLINK_ERROR);
353
+ }
354
+ }
355
+
335
356
int16_t LoRaWANStack::handle_tx (uint8_t port, const uint8_t * data,
336
- uint16_t length, uint8_t flags, bool null_allowed)
357
+ uint16_t length, uint8_t flags,
358
+ bool null_allowed, bool allow_port_0)
337
359
{
338
360
if (!null_allowed && !data) {
339
361
return LORAWAN_STATUS_PARAMETER_INVALID;
@@ -364,7 +386,7 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
364
386
return LORAWAN_STATUS_NO_NETWORK_JOINED;
365
387
}
366
388
367
- status = set_application_port (port);
389
+ status = set_application_port (port, allow_port_0 );
368
390
369
391
if (status != LORAWAN_STATUS_OK) {
370
392
tr_error (" Illegal application port definition." );
@@ -379,7 +401,6 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
379
401
380
402
int16_t len = _loramac.prepare_ongoing_tx (port, data, length, flags, _num_retry);
381
403
382
-
383
404
status = lora_state_machine (DEVICE_STATE_SEND);
384
405
385
406
// send user the length of data which is scheduled now.
@@ -501,11 +522,7 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
501
522
tr_error (" Lora state machine did not return DEVICE_STATE_IDLE !" );
502
523
}
503
524
504
- if (_callbacks.events ) {
505
- const int ret = _queue->call (_callbacks.events , JOIN_FAILURE);
506
- MBED_ASSERT (ret != 0 );
507
- (void )ret;
508
- }
525
+ send_event_to_application (JOIN_FAILURE);
509
526
}
510
527
break ;
511
528
case MLME_LINK_CHECK:
@@ -541,21 +558,13 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
541
558
tr_error (" mcps_confirm_handler: Error code = %d" , mcps_confirm->status );
542
559
543
560
if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT) {
544
- if (_callbacks.events ) {
545
- const int ret = _queue->call (_callbacks.events , TX_TIMEOUT);
546
- MBED_ASSERT (ret != 0 );
547
- (void )ret;
548
- }
561
+ send_event_to_application (TX_TIMEOUT);
549
562
return ;
550
563
} else if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT) {
551
564
tr_debug (" Did not receive Ack" );
552
565
}
553
566
554
- if (_callbacks.events ) {
555
- const int ret = _queue->call (_callbacks.events , TX_ERROR);
556
- MBED_ASSERT (ret != 0 );
557
- (void )ret;
558
- }
567
+ send_event_to_application (TX_ERROR);
559
568
return ;
560
569
}
561
570
@@ -566,22 +575,14 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
566
575
567
576
_lw_session.uplink_counter = mcps_confirm->ul_frame_counter ;
568
577
_loramac.set_tx_ongoing (false );
569
- if (_callbacks.events ) {
570
- const int ret = _queue->call (_callbacks.events , TX_DONE);
571
- MBED_ASSERT (ret != 0 );
572
- (void )ret;
573
- }
578
+ send_event_to_application (TX_DONE);
574
579
}
575
580
576
581
void LoRaWANStack::mcps_indication_handler (loramac_mcps_indication_t *mcps_indication)
577
582
{
578
583
if (mcps_indication->status != LORAMAC_EVENT_INFO_STATUS_OK) {
579
- if (_callbacks.events ) {
580
- tr_error (" RX_ERROR: mcps_indication status = %d" , mcps_indication->status );
581
- const int ret = _queue->call (_callbacks.events , RX_ERROR);
582
- MBED_ASSERT (ret != 0 );
583
- (void )ret;
584
- }
584
+ tr_error (" RX_ERROR: mcps_indication status = %d" , mcps_indication->status );
585
+ send_event_to_application (RX_ERROR);
585
586
return ;
586
587
}
587
588
@@ -645,32 +646,28 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
645
646
tr_debug (" Received %d bytes" , _rx_msg.msg .mcps_indication .buffer_size );
646
647
_rx_msg.receive_ready = true ;
647
648
648
- if (_callbacks.events ) {
649
- const int ret = _queue->call (_callbacks.events , RX_DONE);
650
- MBED_ASSERT (ret != 0 );
651
- (void )ret;
652
- }
653
-
654
- // TODO: below if clauses can be combined,
655
- // because those are calling same function with same parameters
656
-
657
- // If fPending bit is set we try to generate an empty packet
658
- // with CONFIRMED flag set. We always set a CONFIRMED flag so
659
- // that we could retry a certain number of times if the uplink
660
- // failed for some reason
661
- if (_loramac.get_device_class () != CLASS_C && mcps_indication->fpending_status ) {
662
- tr_debug (" Pending bit set. Sending empty message to receive pending data..." );
663
- handle_tx (mcps_indication->port , NULL , 0 , MSG_CONFIRMED_FLAG, true );
664
- }
665
-
666
- // Class C and node received a confirmed message so we need to
667
- // send an empty packet to acknowledge the message.
668
- // This scenario is unspecified by LoRaWAN 1.0.2 specification,
669
- // but version 1.1.0 says that network SHALL not send any new
670
- // confirmed messages until ack has been sent
671
- if (_loramac.get_device_class () == CLASS_C && mcps_indication->type == MCPS_CONFIRMED) {
672
- tr_debug (" Acknowledging confirmed message (class C)..." );
673
- handle_tx (mcps_indication->port , NULL , 0 , MSG_CONFIRMED_FLAG, true );
649
+ send_event_to_application (RX_DONE);
650
+
651
+ /*
652
+ * If fPending bit is set we try to generate an empty packet
653
+ * with CONFIRMED flag set. We always set a CONFIRMED flag so
654
+ * that we could retry a certain number of times if the uplink
655
+ * failed for some reason
656
+ * or
657
+ * Class C and node received a confirmed message so we need to
658
+ * send an empty packet to acknowledge the message.
659
+ * This scenario is unspecified by LoRaWAN 1.0.2 specification,
660
+ * but version 1.1.0 says that network SHALL not send any new
661
+ * confirmed messages until ack has been sent
662
+ */
663
+ if ((_loramac.get_device_class () != CLASS_C && mcps_indication->fpending_status ) ||
664
+ (_loramac.get_device_class () == CLASS_C && mcps_indication->type == MCPS_CONFIRMED)) {
665
+ #if (MBED_CONF_LORA_AUTOMATIC_UPLINK_MESSAGE)
666
+ tr_debug (" Sending empty uplink message..." );
667
+ send_automatic_uplink_message (mcps_indication->port );
668
+ #else
669
+ send_event_to_application (UPLINK_REQUIRED);
670
+ #endif
674
671
}
675
672
} else {
676
673
// Invalid port, ports 0, 224 and 225-255 are reserved.
@@ -741,11 +738,7 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
741
738
_lw_session.active = false ;
742
739
743
740
tr_debug (" LoRaWAN protocol has been shut down." );
744
- if (_callbacks.events ) {
745
- const int ret = _queue->call (_callbacks.events , DISCONNECTED);
746
- MBED_ASSERT (ret != 0 );
747
- (void )ret;
748
- }
741
+ send_event_to_application (DISCONNECTED);
749
742
status = LORAWAN_STATUS_DEVICE_OFF;
750
743
break ;
751
744
case DEVICE_STATE_NOT_INITIALIZED:
@@ -773,11 +766,7 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
773
766
774
767
_lw_session.active = true ;
775
768
776
- if (_callbacks.events ) {
777
- const int ret = _queue->call (_callbacks.events , CONNECTED);
778
- MBED_ASSERT (ret != 0 );
779
- (void )ret;
780
- }
769
+ send_event_to_application (CONNECTED);
781
770
status = LORAWAN_STATUS_OK;
782
771
break ;
783
772
case DEVICE_STATE_ABP_CONNECTING:
@@ -789,11 +778,7 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
789
778
status = LORAWAN_STATUS_OK;
790
779
791
780
_lw_session.active = true ;
792
- if (_callbacks.events ) {
793
- const int ret = _queue->call (_callbacks.events , CONNECTED);
794
- MBED_ASSERT (ret != 0 );
795
- (void )ret;
796
- }
781
+ send_event_to_application (CONNECTED);
797
782
break ;
798
783
case DEVICE_STATE_SEND:
799
784
if (_loramac.tx_ongoing ()) {
@@ -808,19 +793,11 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
808
793
break ;
809
794
case LORAWAN_STATUS_CRYPTO_FAIL:
810
795
tr_error (" Crypto failed. Clearing TX buffers" );
811
- if (_callbacks.events ) {
812
- const int ret = _queue->call (_callbacks.events , TX_CRYPTO_ERROR);
813
- MBED_ASSERT (ret != 0 );
814
- (void )ret;
815
- }
796
+ send_event_to_application (TX_CRYPTO_ERROR);
816
797
break ;
817
798
default :
818
799
tr_error (" Failure to schedule TX!" );
819
- if (_callbacks.events ) {
820
- const int ret = _queue->call (_callbacks.events , TX_SCHEDULING_ERROR);
821
- MBED_ASSERT (ret != 0 );
822
- (void )ret;
823
- }
800
+ send_event_to_application (TX_SCHEDULING_ERROR);
824
801
break ;
825
802
}
826
803
}
0 commit comments