mirror of https://github.com/ARMmbed/mbed-os.git
Reworking callback API
Application should be able to add some optional callbacks if it needs to. Ofcourse there is a penalty of 8-12 bytes per callback, but there can be certain needs of the application that needs to be met for example setting up a link check request etc. We have introduced a structure that contains callbacks for the application use. - 'events' callback is mandatory, user must assign it. Because this callback brings state changes for the application. We cannot segregate this into individual handlers because of RAM penalty. - Other calbacks (none of them are implemented yet are optional). Example of using the API is provided with doxygenpull/6087/head
parent
e60227cf4d
commit
05e2d29238
|
@ -177,7 +177,15 @@ int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length,
|
|||
}
|
||||
}
|
||||
|
||||
void LoRaWANInterface::lora_event_callback(mbed::Callback<void(lora_events_t)> event_cb)
|
||||
{
|
||||
stk_obj().set_lora_event_cb(event_cb);
|
||||
}
|
||||
lora_mac_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks)
|
||||
{
|
||||
|
||||
if (!callbacks || !callbacks->events) {
|
||||
// Event Callback is mandatory
|
||||
return LORA_MAC_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
stk_obj().set_lora_callbacks(callbacks);
|
||||
|
||||
return LORA_MAC_STATUS_OK;
|
||||
}
|
||||
|
|
|
@ -318,24 +318,75 @@ public:
|
|||
virtual int16_t receive(uint8_t port, uint8_t* data, uint16_t length,
|
||||
int flags);
|
||||
|
||||
/** Callback handler.
|
||||
*
|
||||
* Events that can be posted to user:
|
||||
*
|
||||
* CONNECTED - When the connection is complete
|
||||
* DISCONNECTED - When the protocol is shut down in response to disconnect()
|
||||
* TX_DONE - When a packet is sent
|
||||
* TX_TIMEOUT, - When stack was unable to send packet in TX window
|
||||
* TX_ERROR, - A general TX error
|
||||
* TX_CRYPTO_ERROR, - If MIC fails, or any other crypto relted error
|
||||
* TX_SCHEDULING_ERROR, - When stack is unable to schedule packet
|
||||
* RX_DONE, - When there is something to receive
|
||||
* RX_TIMEOUT, - Not yet mapped
|
||||
* RX_ERROR - A general RX error
|
||||
*
|
||||
* @param event_cb A callback function for catching events from the stack.
|
||||
*/
|
||||
virtual void lora_event_callback(mbed::Callback<void(lora_events_t)> event_cb);
|
||||
/** Add application callbacks to the stack.
|
||||
*
|
||||
* 'lorawan_app_callbacks' is a structure that holds pointers to the application
|
||||
* provided methods which are needed to be called in response to certain
|
||||
* requests. The structure is default constructed to set all pointers to NULL.
|
||||
* So if the user does not provide the pointer, a response will not be posted.
|
||||
* However, the 'lorawan_events' callback is mandatory to be provided as it
|
||||
* contains essential events.
|
||||
*
|
||||
* Events that can be posted to user via 'lorawan_events' are:
|
||||
*
|
||||
* CONNECTED - When the connection is complete
|
||||
* DISCONNECTED - When the protocol is shut down in response to disconnect()
|
||||
* TX_DONE - When a packet is sent
|
||||
* TX_TIMEOUT, - When stack was unable to send packet in TX window
|
||||
* TX_ERROR, - A general TX error
|
||||
* TX_CRYPTO_ERROR, - If MIC fails, or any other crypto relted error
|
||||
* TX_SCHEDULING_ERROR, - When stack is unable to schedule packet
|
||||
* RX_DONE, - When there is something to receive
|
||||
* RX_TIMEOUT, - Not yet mapped
|
||||
* RX_ERROR - A general RX error
|
||||
*
|
||||
* Other responses to certain standard requests are an item for the future.
|
||||
* For example, a link check request could be sent whenever the device tries
|
||||
* to send a message and if the network server responds with a link check resposne,
|
||||
* the stack notifies the application be calling the appropriate method. For example,
|
||||
* 'link_check_resp' callback could be used to collect a response for a link check
|
||||
* request MAC command and the result is thus transported to the application
|
||||
* via callback function provided.
|
||||
*
|
||||
* As can be seen from declaration, mbed::Callback<void(uint8_t, uint8_t)> *link_check_resp)
|
||||
* carries two parameters. First one is Demodulation Margin and the second one
|
||||
* is number of gateways involved in the path to network server.
|
||||
*
|
||||
* An example of using this API with a latch onto 'lorawan_events' could be:
|
||||
*
|
||||
* LoRaWANInterface lorawan(radio);
|
||||
* lorawan_app_callbacks cbs;
|
||||
* static void my_event_handler();
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* lorawan.initialize(&queue);
|
||||
* cbs.lorawan_events = mbed::callback(my_event_handler);
|
||||
* lorawan.add_app_callbacks(&cbs);
|
||||
* lorawan.connect();
|
||||
* }
|
||||
*
|
||||
* static void my_event_handler(lora_events_t events)
|
||||
* {
|
||||
* switch(events) {
|
||||
* case CONNECTED:
|
||||
* //do something
|
||||
* break;
|
||||
* case DISCONNECTED:
|
||||
* //do something
|
||||
* break;
|
||||
* case TX_DONE:
|
||||
* //do something
|
||||
* break;
|
||||
* default:
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param callbacks A pointer to the structure containing application
|
||||
* callbacks.
|
||||
*/
|
||||
virtual lora_mac_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks);
|
||||
};
|
||||
|
||||
#endif /* LORAWANINTERFACE_H_ */
|
||||
|
|
|
@ -483,9 +483,18 @@ void LoRaWANStack::mlme_confirm(MlmeConfirm_t *mlme_confirm)
|
|||
mlme_confirm_handler(&lora_mlme_confirm);
|
||||
}
|
||||
|
||||
void LoRaWANStack::set_lora_event_cb(mbed::Callback<void(lora_events_t)> event_cb)
|
||||
void LoRaWANStack::set_lora_callbacks(lorawan_app_callbacks_t *cbs)
|
||||
{
|
||||
_events = event_cb;
|
||||
|
||||
if (cbs) {
|
||||
if (cbs->events) {
|
||||
_callbacks.events = cbs->events;
|
||||
}
|
||||
|
||||
if (cbs->link_check_resp) {
|
||||
_callbacks.link_check_resp = cbs->link_check_resp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lora_mac_status_t LoRaWANStack::add_channels(const lora_channelplan_t &channel_plan)
|
||||
|
@ -1051,7 +1060,10 @@ void LoRaWANStack::mlme_confirm_handler(lora_mac_mlme_confirm_t *mlme_confirm)
|
|||
// Join attempt failed.
|
||||
set_device_state(DEVICE_STATE_IDLE);
|
||||
lora_state_machine();
|
||||
_queue->call(_events, JOIN_FAILURE);
|
||||
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, JOIN_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LORA_MLME_LINK_CHECK:
|
||||
|
@ -1132,14 +1144,18 @@ void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm)
|
|||
|
||||
// If sending timed out, we have a special event for that
|
||||
if (mcps_confirm->status == LORA_EVENT_INFO_STATUS_TX_TIMEOUT) {
|
||||
_queue->call(_events, TX_TIMEOUT);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, TX_TIMEOUT);
|
||||
}
|
||||
return;
|
||||
} if (mcps_confirm->status == LORA_EVENT_INFO_STATUS_RX2_TIMEOUT) {
|
||||
tr_debug("Did not receive Ack");
|
||||
}
|
||||
|
||||
// Otherwise send a general TX_ERROR event
|
||||
_queue->call(_events, TX_ERROR);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, TX_ERROR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1159,7 +1175,9 @@ void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm)
|
|||
// data rate plus frame counter.
|
||||
_lw_session.uplink_counter = mcps_confirm->uplink_counter;
|
||||
_tx_msg.tx_ongoing = false;
|
||||
_queue->call(_events, TX_DONE);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, TX_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
/** MCPS-Indication event function
|
||||
|
@ -1175,7 +1193,9 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi
|
|||
}
|
||||
|
||||
if (mcps_indication->status != LORA_EVENT_INFO_STATUS_OK) {
|
||||
_queue->call(_events, RX_ERROR);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, RX_ERROR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1224,7 +1244,9 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi
|
|||
// This may never happen as both radio and MAC are limited
|
||||
// to the size 255 bytes
|
||||
tr_debug("Cannot receive more than buffer capacity!");
|
||||
_queue->call(_events, RX_ERROR);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, RX_ERROR);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
_rx_msg.type = LORAMAC_RX_MCPS_INDICATION;
|
||||
|
@ -1238,7 +1260,9 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi
|
|||
// Notify application about received frame..
|
||||
tr_debug("Received %d bytes", _rx_msg.rx_message.mcps_indication.buffer_size);
|
||||
_rx_msg.receive_ready = true;
|
||||
_queue->call(_events, RX_DONE);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, RX_DONE);
|
||||
}
|
||||
} else {
|
||||
// Invalid port, ports 0, 224 and 225-255 are reserved.
|
||||
}
|
||||
|
@ -1805,7 +1829,9 @@ lora_mac_status_t LoRaWANStack::lora_state_machine()
|
|||
_lw_session.active = false;
|
||||
|
||||
tr_debug("LoRaWAN protocol has been shut down.");
|
||||
_queue->call(_events, DISCONNECTED);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, DISCONNECTED);
|
||||
}
|
||||
status = LORA_MAC_STATUS_DEVICE_OFF;
|
||||
break;
|
||||
case DEVICE_STATE_NOT_INITIALIZED:
|
||||
|
@ -1847,7 +1873,9 @@ lora_mac_status_t LoRaWANStack::lora_state_machine()
|
|||
// Session is now active
|
||||
_lw_session.active = true;
|
||||
// Tell the application that we are connected
|
||||
_queue->call(_events, CONNECTED);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, CONNECTED);
|
||||
}
|
||||
break;
|
||||
case DEVICE_STATE_ABP_CONNECTING:
|
||||
/*
|
||||
|
@ -1879,7 +1907,9 @@ lora_mac_status_t LoRaWANStack::lora_state_machine()
|
|||
status = LORA_MAC_STATUS_OK;
|
||||
// Session is now active
|
||||
_lw_session.active = true;
|
||||
_queue->call(_events, CONNECTED);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, CONNECTED);
|
||||
}
|
||||
break;
|
||||
case DEVICE_STATE_SEND:
|
||||
// If a transmission is ongoing, don't interrupt
|
||||
|
@ -1895,11 +1925,15 @@ lora_mac_status_t LoRaWANStack::lora_state_machine()
|
|||
break;
|
||||
case LORA_MAC_STATUS_CRYPTO_FAIL:
|
||||
tr_error("Crypto failed. Clearing TX buffers");
|
||||
_queue->call(_events, TX_CRYPTO_ERROR);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, TX_CRYPTO_ERROR);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
tr_error("Failure to schedule TX!");
|
||||
_queue->call(_events, TX_SCHEDULING_ERROR);
|
||||
if (_callbacks.events) {
|
||||
_queue->call(_callbacks.events, TX_SCHEDULING_ERROR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,11 +65,11 @@ public:
|
|||
*/
|
||||
lora_mac_status_t initialize_mac_layer(events::EventQueue *queue);
|
||||
|
||||
/** Sets all callbacks of the LoRaWAN interface.
|
||||
/** Sets all callbacks for the application.
|
||||
*
|
||||
* @param *event_cb An event structure representing all possible callbacks.
|
||||
* \param callbacks A pointer to the structure carrying callbacks.
|
||||
*/
|
||||
void set_lora_event_cb(mbed::Callback<void(lora_events_t)> event_cb);
|
||||
void set_lora_callbacks(lorawan_app_callbacks_t *callbacks);
|
||||
|
||||
/** Adds channels to use.
|
||||
*
|
||||
|
@ -412,7 +412,7 @@ private:
|
|||
|
||||
compliance_test_t _compliance_test;
|
||||
device_states_t _device_current_state;
|
||||
mbed::Callback<void(lora_events_t)> _events;
|
||||
lorawan_app_callbacks_t _callbacks;
|
||||
radio_events_t *_mac_handlers;
|
||||
lorawan_session_t _lw_session;
|
||||
lora_mac_tx_message_t _tx_msg;
|
||||
|
|
|
@ -2136,6 +2136,7 @@ static LoRaMacStatus_t ScheduleTx( void )
|
|||
// Send later - prepare timer
|
||||
LoRaMacState |= LORAMAC_TX_DELAYED;
|
||||
tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff);
|
||||
|
||||
TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff );
|
||||
TimerStart( &TxDelayedTimer );
|
||||
|
||||
|
|
|
@ -2884,6 +2884,18 @@ typedef enum lora_events {
|
|||
JOIN_FAILURE,
|
||||
} lora_events_t;
|
||||
|
||||
typedef struct {
|
||||
// Mandatory. Event Callback must be provided
|
||||
mbed::Callback<void(lora_events_t)> events;
|
||||
|
||||
// Rest are optional
|
||||
// If the user do not assign these callbacks, these callbacks would return
|
||||
// null if checked with bool operator
|
||||
// link_check_resp callback and other such callbacks will be maped in
|
||||
// future releases of Mbed-OS
|
||||
mbed::Callback<void(uint8_t, uint8_t)> link_check_resp;
|
||||
}lorawan_app_callbacks_t;
|
||||
|
||||
typedef struct lora_channelplan {
|
||||
uint8_t nb_channels; // number of channels
|
||||
lora_channels_t *channels;
|
||||
|
|
|
@ -18,6 +18,20 @@
|
|||
#ifndef LORARADIO_H_
|
||||
#define LORARADIO_H_
|
||||
|
||||
/**
|
||||
* Structure to hold RF controls for LoRa Radio.
|
||||
* SX1276 have an extra control for the crystal (used in DOSCO-L072CZ)
|
||||
*/
|
||||
typedef struct {
|
||||
PinName rf_switch_ctl1;
|
||||
PinName rf_switch_ctl2;
|
||||
PinName txctl;
|
||||
PinName rxctl;
|
||||
PinName ant_switch;
|
||||
PinName pwr_amp_ctl;
|
||||
PinName tcxo;
|
||||
} rf_ctrls;
|
||||
|
||||
/** Radio driver internal state.
|
||||
* State machine states definition.
|
||||
*/
|
||||
|
|
|
@ -230,9 +230,16 @@ public:
|
|||
virtual int16_t receive(uint8_t port, uint8_t* data, uint16_t length,
|
||||
int flags) = 0;
|
||||
|
||||
/** Callback handler.
|
||||
/** Add application callbacks to the stack.
|
||||
*
|
||||
* Events that can be posted to user:
|
||||
* 'lorawan_app_callbacks_t' is a structure that holds pointers to the application
|
||||
* provided methods which are needed to be called in response to certain
|
||||
* requests. The structure is default constructed to set all pointers to NULL.
|
||||
* So if the user does not provide the pointer, a response will not be posted.
|
||||
* However, the 'lorawan_events' callback is mandatory to be provided as it
|
||||
* contains essential events.
|
||||
*
|
||||
* Events that can be posted to user via 'lorawan_events' are:
|
||||
*
|
||||
* CONNECTED - When the connection is complete
|
||||
* DISCONNECTED - When the protocol is shut down in response to disconnect()
|
||||
|
@ -245,9 +252,53 @@ public:
|
|||
* RX_TIMEOUT, - Not yet mapped
|
||||
* RX_ERROR - A general RX error
|
||||
*
|
||||
* @param cb A pointer to the callback function.
|
||||
* Other responses to certain standard requests are an item for the future.
|
||||
* For example, a link check request could be sent whenever the device tries
|
||||
* to send a message and if the network server responds with a link check resposne,
|
||||
* the stack notifies the application be calling the appropriate method. For example,
|
||||
* 'link_check_resp' callback could be used to collect a response for a link check
|
||||
* request MAC command and the result is thus transported to the application
|
||||
* via callback function provided.
|
||||
*
|
||||
* As can be seen from declaration, mbed::Callback<void(uint8_t, uint8_t)> *link_check_resp)
|
||||
* carries two parameters. First one is Demodulation Margin and the second one
|
||||
* is number of gateways involved in the path to network server.
|
||||
*
|
||||
* An example of using this API with a latch onto 'lorawan_events' could be:
|
||||
*
|
||||
* LoRaWANInterface lorawan(radio);
|
||||
* lorawan_app_callbacks_t cbs;
|
||||
* static void my_event_handler();
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* lorawan.initialize();
|
||||
* cbs.lorawan_events = mbed::callback(my_event_handler);
|
||||
* lorawan.add_app_callbacks(&cbs);
|
||||
* lorawan.connect();
|
||||
* }
|
||||
*
|
||||
* static void my_event_handler(lora_events_t events)
|
||||
* {
|
||||
* switch(events) {
|
||||
* case CONNECTED:
|
||||
* //do something
|
||||
* break;
|
||||
* case DISCONNECTED:
|
||||
* //do something
|
||||
* break;
|
||||
* case TX_DONE:
|
||||
* //do something
|
||||
* break;
|
||||
* default:
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param callbacks A pointer to the structure containing application
|
||||
* callbacks.
|
||||
*/
|
||||
virtual void lora_event_callback(mbed::Callback<void(lora_events_t)> cb) = 0;
|
||||
virtual lora_mac_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks) = 0;
|
||||
};
|
||||
|
||||
#endif /* LORAWAN_BASE_H_ */
|
||||
|
|
Loading…
Reference in New Issue