diff --git a/features/lorawan/LoRaWANBase.h b/features/lorawan/LoRaWANBase.h index 959f43d6dd..3618110ace 100644 --- a/features/lorawan/LoRaWANBase.h +++ b/features/lorawan/LoRaWANBase.h @@ -32,17 +32,47 @@ public: * @param queue A pointer to EventQueue provided by the application. * * @return LORAWAN_STATUS_OK on success, a negative error code on - * failure. + * failure: + * LORAWAN_STATUS_PARAMETER_INVALID is NULL queue is given. */ virtual lorawan_status_t initialize(events::EventQueue *queue) = 0; - /** Connect OTAA or ABP by setup. + /** Connect OTAA or ABP using Mbed-OS config system * * Connect by Over The Air Activation or Activation By Personalization. - * The connection type is selected at the setup. + * You need to configure the connection properly via the Mbed OS configuration + * system. * - * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by - * a 'CONNECTED' event. Otherwise a negative error code is returned. + * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. + * However, this is not a real error. It tells you that the connection is in progress and you will + * be notified of the completion via an event. By default, after the Join Accept message + * is received, base stations may provide the node with a CF-List that replaces + * all user-configured channels except the Join/Default channels. A CF-List can + * configure a maximum of five channels other than the default channels. + * + * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. + * By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions + * on these channels are severe and you may experience long delays or even failures in the confirmed traffic. + * If you add more channels, the aggregated duty cycle becomes much more relaxed as compared to the Join (default) channels only. + * + * **NOTES ON RECONNECTION:** + * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile + * memory storage. Therefore, the state and frame counters cannot be restored after + * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN + * protocol, the state and frame counters are saved. Connecting again would try to + * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset + * to zero for OTAA and a new Join request lets the network server know + * that the counters need a reset. The same is said about the ABP but there + * is no way to convey this information to the network server. For a network + * server, an ABP device is always connected. That's why storing the frame counters + * is important, at least for ABP. That's why we try to restore frame counters from + * session information after a disconnection. + * + * @return Common: LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if connection parameters are invalid. + * + * For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by + * a 'CONNECTED' event. Otherwise a negative error code is returned: * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. * * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call. @@ -52,15 +82,44 @@ public: */ virtual lorawan_status_t connect() = 0; - /** Connect OTAA or ABP by parameters + /** Connect OTAA or ABP with parameters * - * Connect by Over The Air Activation or Activation By Personalization. - * The connection type is selected using the parameters. - * You need to define the parameters in the main application. + * All connection parameters are chosen by the user and provided in the + * data structure passed down. * - * @param connect Options how end-device will connect to gateway + * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. + * However, this is not a real error. It tells you that connection is in progress and you will + * be notified of completion via an event. By default, after Join Accept message + * is received, base stations may provide the node with a CF-List which replaces + * all user-configured channels except the Join/Default channels. A CF-List can + * configure a maximum of five channels other than the default channels. * - * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by + * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. + * By default, the PHY layers configure only the mandatory Join + * channels. The retransmission back-off restrictions on these channels + * are severe and you may experience long delays or even + * failures in the confirmed traffic. If you add more channels, the aggregated duty + * cycle becomes much more relaxed as compared to the Join (default) channels only. + * + * **NOTES ON RECONNECTION:** + * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile + * memory storage. Therefore, the state and frame counters cannot be restored after + * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN + * protocol, the state and frame counters are saved. Connecting again would try to + * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset + * to zero for OTAA and a new Join request lets the network server know + * that the counters need a reset. The same is said about the ABP but there + * is no way to convey this information to the network server. For a network + * server, an ABP device is always connected. That's why storing the frame counters + * is important, at least for ABP. That's why we try to restore frame counters from + * session information after a disconnection. + * + * @param connect Options for an end device connection to the gateway. + * + * @return Common: LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if connection parameters are invalid. + * + * For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by * a 'CONNECTED' event. Otherwise a negative error code is returned. * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. * @@ -71,9 +130,10 @@ public: */ virtual lorawan_status_t connect(const lorawan_connect_t &connect) = 0; - /** Disconnects the current session. + /** Disconnect the current session. * - * @return LORAWAN_STATUS_OK on success, a negative error code on failure. + * @return LORAWAN_STATUS_DEVICE_OFF on success, a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), */ virtual lorawan_status_t disconnect() = 0; @@ -85,7 +145,12 @@ public: * server and once the response, i.e., LinkCheckAns MAC command is received * from the Network Server, user provided method is called. * - * This API is usable only when the link check response is callback set by + * One way to use this API may be the validation of connectivity after a long + * deep sleep. Mbed LoRaWANStack piggy-backs the MAC commands with data + * frame payload so the application needs to try sending something and the Network + * Server may respond during the RX slots. + * + * This API is usable only when the 'link_check_resp' callback is set by * the application. See add_lora_app_callbacks API. If the above mentioned * callback is not set, a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. * @@ -98,194 +163,243 @@ public: * remove_link_check_request() API. * * @return LORAWAN_STATUS_OK on successfully queuing a request, or - * a negative error code on failure. + * a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if link_check_resp callback method is not set. * */ virtual lorawan_status_t add_link_check_request() = 0; - /** Detaches Link Request MAC command. + /** Removes link check request sticky MAC command. * - * Removes sticky MAC command for link check request. + * Any already queued request may still get entertained. However, no new + * requests will be made. */ virtual void remove_link_check_request() = 0; - /** Sets up a particular data rate of choice + /** Sets up a particular data rate * - * @param data_rate Intended data rate e.g., DR_0, DR_1 etc. - * Caution is advised as the macro DR_* can mean different - * things while being in a different region. + * @param data_rate The intended data rate, for example DR_0 or DR_1. + * Please note, that the macro DR_* can mean different + * things in different regions. * @return LORAWAN_STATUS_OK if everything goes well, otherwise - * a negative error code. + * a negative error code: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if ADR is enabled or invalid datarate is given */ virtual lorawan_status_t set_datarate(uint8_t data_rate) = 0; /** Enables adaptive data rate (ADR) * - * Underlying LoRaPHY and LoRaMac layers handle the data rate automatically - * for the user based upon radio conditions (network congestion). + * The underlying LoRaPHY and LoRaMac layers handle the data rate automatically + * for the user, based upon the radio conditions (network congestion). * * @return LORAWAN_STATUS_OK on success, negative error code - * on failure. + * on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize() */ virtual lorawan_status_t enable_adaptive_datarate() = 0; /** Disables adaptive data rate * - * When adaptive data rate (ADR) is disabled, user can either set a certain - * data rate or the Mac layer will choose a default value. + * When adaptive data rate (ADR) is disabled, you can either set a certain + * data rate or the MAC layer selects a default value. * - * @return LORAWAN_STATUS_OK on success, negative error code - * on failure. + * @return LORAWAN_STATUS_OK on success, negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize() */ virtual lorawan_status_t disable_adaptive_datarate() = 0; - /** Sets up retry counter for confirmed messages + /** Sets up the retry counter for confirmed messages. * - * Valid only for confirmed messages. + * Valid for confirmed messages only. * - * Number of trials to transmit the frame, if the LoRaMAC layer did not - * receive an acknowledgment. The MAC performs a data-rate adaptation, - * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according - * to the table on page 64. + * The number of trials to transmit the frame, if the LoRaMAC layer did not + * receive an acknowledgment. The MAC performs a data rate adaptation as in + * the LoRaWAN Specification V1.0.2, chapter 18.4, table on page 64. * - * Note, that if the number of trials is set to 1 or 2, the MAC will not decrease - * the datarate, in case the LoRaMAC layer did not receive an acknowledgment. + * Note, that if number of retries is set to 1 or 2, MAC will not decrease + * the datarate, if the LoRaMAC layer did not receive an acknowledgment. * - * @param count number of retries for confirmed messages + * @param count The number of retries for confirmed messages. * - * @return LORAWAN_STATUS_OK or a negative error code + * @return LORAWAN_STATUS_OK or a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize() + * LORAWAN_STATUS_PARAMETER_INVALID if count >= 255 */ virtual lorawan_status_t set_confirmed_msg_retries(uint8_t count) = 0; - /** Sets channel plan + /** Sets the channel plan. * - * @param channel_plan The defined channel plans to be set. - * @return 0 on success, a negative error code on failure. + * You can provide a list of channels with appropriate parameters filled + * in. However, this list is not absolute. The stack applies a CF-List whenever + * available, which means that the network can overwrite your channel + * frequency settings right after Join Accept is received. You may try + * to set up any channel or channels after that, and if the channel requested + * is already active, the request is silently ignored. A negative error + * code is returned if there is any problem with parameters. + * + * Please note that this API can also be used to add a single channel to the + * existing channel plan. + * + * There is no reverse mechanism in the 1.0.2 specification for a node to request + * a particular channel. Only the network server can initiate such a request. + * You need to ensure that the corresponding base station supports the channel or channels being added. + * + * If your list includes a default channel (a channel where Join Requests + * are received) you cannot fully configure the channel parameters. + * Either leave the channel settings to default or check your + * corresponding PHY layer implementation. For example, LoRaPHYE868. + * + * @param channel_plan The channel plan to set. + * + * @return LORAWAN_STATUS_OK on success, a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if number of channels is exceeding the PHY limit, + * LORAWAN_STATUS_DATARATE_INVALID if invalid datarate is given, + * LORAWAN_STATUS_FREQUENCY_INVALID if invalid frequency is given, + * LORAWAN_STATUS_FREQ_AND_DR_INVALID if invalid datarate and freqency are given, + * LORAWAN_STATUS_BUSY if TX currently ongoing, + * LORAWAN_STATUS_SERVICE_UNKNOWN if custom channel plans are disabled in PHY */ virtual lorawan_status_t set_channel_plan(const lorawan_channelplan_t &channel_plan) = 0; - /** Gets the current channel plan. + /** Gets the channel plans from the LoRa stack. * - * @param channel_plan The current channel information. + * Once you have selected a particular PHY layer, a set of channels + * is automatically activated. Right after connecting, you can use this API + * to see the current plan. Otherwise, this API returns the channel + * plan that you have set using `set_channel_plan()`. * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. + * @param channel_plan The current channel plan information. + * + * @return LORAWAN_STATUS_OK on success, a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_SERVICE_UNKNOWN if custom channel plans are disabled in PHY */ virtual lorawan_status_t get_channel_plan(lorawan_channelplan_t &channel_plan) = 0; - /** Removes currently active channel plan + /** Removes an active channel plan. * - * Default channels (channels where Base Stations are listening) are not - * allowed to be removed. So when a plan is abolished, only non-default - * channels are removed. + * You cannot remove default channels (the channels the base stations are listening to). + * When a plan is abolished, only the non-default channels are removed. * - * @return LORAWAN_STATUS_OK on success, negative error - * code on failure + * @return LORAWAN_STATUS_OK on success, negative error code on failure + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_BUSY if TX currently ongoing, + * LORAWAN_STATUS_SERVICE_UNKNOWN if custom channel plans are disabled in PHY */ virtual lorawan_status_t remove_channel_plan() = 0; - /** Removes a given single channel + /** Removes a single channel. * - * Default channels (channels where Base Stations are listening) are not - * allowed to be removed. + * You cannot remove default channels (the channels the base stations are listening to). * - * @param index The channel index + * @param index The channel index. * - * @return LORAWAN_STATUS_OK on success, negative error - * code on failure + * @return LORAWAN_STATUS_OK on success, negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if invalid channel index is given, + * LORAWAN_STATUS_BUSY if TX currently ongoing, + * LORAWAN_STATUS_SERVICE_UNKNOWN if custom channel plans are disabled in PHY */ virtual lorawan_status_t remove_channel(uint8_t index) = 0; /** Send message to gateway * - * @param port The application port number. Port numbers 0 and 224 - * are reserved, whereas port numbers from 1 to 223 - * (0x01 to 0xDF) are valid port numbers. - * Anything out of this range is illegal. + * @param port The application port number. Port numbers 0 and 224 + * are reserved, whereas port numbers from 1 to 223 + * (0x01 to 0xDF) are valid port numbers. + * Anything out of this range is illegal. * - * @param data A pointer to the data being sent. The ownership of the - * buffer is not transferred. The data is copied to the - * internal buffers. + * @param data A pointer to the data being sent. The ownership of the + * buffer is not transferred. The data is copied to the + * internal buffers. * - * @param length The size of data in bytes. + * @param length The size of data in bytes. * - * @param flags A flag used to determine what type of - * message is being sent, for example: + * @param flags A flag used to determine what type of + * message is being sent, for example: * - * MSG_UNCONFIRMED_FLAG = 0x01 - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04 - * MSG_PROPRIETARY_FLAG = 0x08 + * MSG_UNCONFIRMED_FLAG = 0x01 + * MSG_CONFIRMED_FLAG = 0x02 + * MSG_MULTICAST_FLAG = 0x04 + * MSG_PROPRIETARY_FLAG = 0x08 * - * All flags are mutually exclusive, and MSG_MULTICAST_FLAG - * cannot be set. + * All flags are mutually exclusive, and MSG_MULTICAST_FLAG + * cannot be set. * - * @return The number of bytes sent, or - * LORAWAN_STATUS_WOULD_BLOCK if another TX is - * ongoing, or a negative error code on failure. + * @return The number of bytes sent, or a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_WOULD_BLOCK if another TX is ongoing, + * LORAWAN_STATUS_PORT_INVALID if trying to send to an invalid port (e.g. to 0) + * LORAWAN_STATUS_PARAMETER_INVALID if NULL data pointer is given or flags are invalid. */ virtual int16_t send(uint8_t port, const uint8_t *data, uint16_t length, int flags) = 0; /** Receives a message from the Network Server on a specific port. * - * @param port The application port number. Port numbers 0 and 224 - * are reserved, whereas port numbers from 1 to 223 - * (0x01 to 0xDF) are valid port numbers. - * Anything out of this range is illegal. + * @param port The application port number. Port numbers 0 and 224 + * are reserved, whereas port numbers from 1 to 223 + * (0x01 to 0xDF) are valid port numbers. + * Anything out of this range is illegal. * - * @param data A pointer to buffer where the received data will be - * stored. + * @param data A pointer to buffer where the received data will be + * stored. * - * @param length The size of data in bytes. + * @param length The size of data in bytes. * - * @param flags A flag is used to determine what type of - * message is being sent, for example: + * @param flags A flag is used to determine what type of + * message is being sent, for example: * - * MSG_UNCONFIRMED_FLAG = 0x01, - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04, - * MSG_PROPRIETARY_FLAG = 0x08 + * MSG_UNCONFIRMED_FLAG = 0x01 + * MSG_CONFIRMED_FLAG = 0x02 + * MSG_MULTICAST_FLAG = 0x04 + * MSG_PROPRIETARY_FLAG = 0x08 * - * All flags can be used in conjunction with - * one another depending on the intended use case or reception - * expectation. + * All flags can be used in conjunction with + * one another depending on the intended use case or reception + * expectation. * - * e.g., MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are - * not mutually exclusive, i.e., the user can subscribe to - * receive both CONFIRMED AND UNCONFIRMED messages at - * the same time. + * e.g., MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are + * not mutually exclusive, i.e., the user can subscribe to + * receive both CONFIRMED AND UNCONFIRMED messages at + * the same time. * - * @return It could be one of these: - * i) 0 if there is nothing else to read. - * ii) Number of bytes written to user buffer. - * iii) LORAWAN_STATUS_WOULD_BLOCK if there is - * nothing available to read at the moment. - * iv) A negative error code on failure. + * @return It could be one of these: + * i) 0 if there is nothing else to read. + * ii) Number of bytes written to user buffer. + * iii) A negative error code on failure: + * LORAWAN_STATUS_NO_ACTIVE_SESSIONS if connection is not open, + * LORAWAN_STATUS_WOULD_BLOCK if there is nothing available to read at the moment, + * LORAWAN_STATUS_PARAMETER_INVALID if NULL data or length is given, + * LORAWAN_STATUS_WOULD_BLOCK if incorrect port or flags are given, */ virtual int16_t receive(uint8_t port, uint8_t *data, uint16_t length, int flags) = 0; - /** Receives a message from the Network Server from any port. + /** Receives a message from the Network Server on any port. * - * @param data A pointer to buffer where the received data will be - * stored. + * @param data A pointer to buffer where the received data will be + * stored. * - * @param length The size of data in bytes + * @param length The size of data in bytes * - * @param port Return the number of port to which message was received. + * @param port Return the number of port to which message was received. * - * @param flags Return flags to determine what type of message was received. - * MSG_UNCONFIRMED_FLAG = 0x01 - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04 - * MSG_PROPRIETARY_FLAG = 0x08 + * @param flags Return flags to determine what type of message was received. + * MSG_UNCONFIRMED_FLAG = 0x01 + * MSG_CONFIRMED_FLAG = 0x02 + * MSG_MULTICAST_FLAG = 0x04 + * MSG_PROPRIETARY_FLAG = 0x08 * - * @return It could be one of these: - * i) 0 if there is nothing else to read. - * ii) Number of bytes written to user buffer. - * iii) LORAWAN_STATUS_WOULD_BLOCK if there is - * nothing available to read at the moment. - * iv) A negative error code on failure. + * @return It could be one of these: + * i) 0 if there is nothing else to read. + * ii) Number of bytes written to user buffer. + * iii) A negative error code on failure: + * LORAWAN_STATUS_NO_ACTIVE_SESSIONS if connection is not open, + * LORAWAN_STATUS_PARAMETER_INVALID if NULL data or length is given, + * LORAWAN_STATUS_WOULD_BLOCK if there is nothing available to read at the moment. */ virtual int16_t receive(uint8_t *data, uint16_t length, uint8_t &port, int &flags) = 0; @@ -322,11 +436,11 @@ public: * } * } * - * @param callbacks A pointer to the structure containing application - * callbacks. + * @param callbacks A pointer to the structure containing application callbacks. * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. + * @return LORAWAN_STATUS_OK on success, a negative error code on failure: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_PARAMETER_INVALID if events callback is not set */ virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks) = 0; @@ -336,9 +450,9 @@ public: * * @param device_class The device class * - * @return LORAWAN_STATUS_OK on success, - * LORAWAN_STATUS_UNSUPPORTED is requested class is not supported, - * or other negative error code if request failed. + * @return LORAWAN_STATUS_OK on success or other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_UNSUPPORTED if requested class is not supported */ virtual lorawan_status_t set_device_class(device_class_t device_class) = 0; @@ -350,11 +464,13 @@ public: * In other words, you can check for TX meta-data right after receiving the * TX_DONE event. * - * @param metadata the inbound structure that will be filled if the meta-data - * is available. + * @param metadata the inbound structure that will be filled if the meta-data + * is available. * - * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise - * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. + * @return LORAWAN_STATUS_OK if the meta-data is available, + * otherwise other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE if the meta-data is not available */ virtual lorawan_status_t get_tx_metadata(lorawan_tx_metadata &metadata) = 0; @@ -366,11 +482,13 @@ public: * In other words, you can check for RX meta-data right after receiving the * RX_DONE event. * - * @param metadata the inbound structure that will be filled if the meta-data - * is available. + * @param metadata the inbound structure that will be filled if the meta-data + * is available. * - * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise - * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. + * @return LORAWAN_STATUS_OK if the meta-data is available, + * otherwise other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE if the meta-data is not available */ virtual lorawan_status_t get_rx_metadata(lorawan_rx_metadata &metadata) = 0; @@ -388,9 +506,10 @@ public: * @param backoff the inbound integer that will be carry the backoff time if it * is available. * - * @return LORAWAN_STATUS_OK if the meta-data regarding backoff is available, - * otherwise LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. - * + * @return LORAWAN_STATUS_OK if the meta-data is available, + * otherwise other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE if the meta-data is not available */ virtual lorawan_status_t get_backoff_metadata(int &backoff) = 0; @@ -399,11 +518,13 @@ public: * This API is used to cancel any outstanding transmission in the TX pipe. * If an event for transmission is not already queued at the end of backoff timer, * the system can cancel the outstanding outgoing packet. Otherwise, the system is - * busy sending and can't be held back. - * - * @return LORAWAN_STATUS_OK if the sending is cancelled. - * LORAWAN_STATUS_BUSY otherwise. + * busy sending and can't be held back. The system will not try to re-send if the + * outgoing message was a CONFIRMED message even if the ack is not received. * + * @return LORAWAN_STATUS_OK if the sending is cancelled, otherwise + * other negative error code if request failed: + * LORAWAN_STATUS_NOT_INITIALIZED if system is not initialized with initialize(), + * LORAWAN_STATUS_BUSY if the send cannot be cancelled */ virtual lorawan_status_t cancel_sending(void) = 0; }; diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index d79c905acd..d2880d033f 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -50,470 +50,29 @@ public: virtual ~LoRaWANInterface(); - /** Initialize the LoRa stack. - * - * You must call this first to be able to use the LoRa stack. - * - * @param ev_queue A pointer to EventQueue provided by the application. - * - * @return 0 on success, a negative error code on failure. - */ - virtual lorawan_status_t initialize(events::EventQueue *ev_queue); - - /** Connect OTAA or ABP using Mbed-OS config system - * - * Connect by Over The Air Activation or Activation By Personalization. - * You need to configure the connection properly via the Mbed OS configuration - * system. - * - * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. - * However, this is not a real error. It tells you that the connection is in progress and you will - * be notified of the completion via an event. By default, after the Join Accept message - * is received, base stations may provide the node with a CF-List that replaces - * all user-configured channels except the Join/Default channels. A CF-List can - * configure a maximum of five channels other than the default channels. - * - * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. - * By default, the PHY layers configure only the mandatory Join channels. The retransmission back-off restrictions - * on these channels are severe and you may experience long delays or even failures in the confirmed traffic. - * If you add more channels, the aggregated duty cycle becomes much more relaxed as compared to the Join (default) channels only. - * - * **NOTES ON RECONNECTION:** - * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile - * memory storage. Therefore, the state and frame counters cannot be restored after - * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN - * protocol, the state and frame counters are saved. Connecting again would try to - * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset - * to zero for OTAA and a new Join request lets the network server know - * that the counters need a reset. The same is said about the ABP but there - * is no way to convey this information to the network server. For a network - * server, an ABP device is always connected. That's why storing the frame counters - * is important, at least for ABP. That's why we try to restore frame counters from - * session information after a disconnection. - * - * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by - * a 'CONNECTED' event. Otherwise a negative error code is returned. - * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. - * - * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call. - * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection - * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully). - * A 'CONNECTED' event is sent to the application when the JoinAccept is received. - */ + // From LoRaWANBase: + virtual lorawan_status_t initialize(events::EventQueue *queue); virtual lorawan_status_t connect(); - - /** Connect OTAA or ABP with parameters - * - * All connection parameters are chosen by the user and provided in the - * data structure passed down. - * - * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. - * However, this is not a real error. It tells you that connection is in progress and you will - * be notified of completion via an event. By default, after Join Accept message - * is received, base stations may provide the node with a CF-List which replaces - * all user-configured channels except the Join/Default channels. A CF-List can - * configure a maximum of five channels other than the default channels. - * - * To configure more channels, we recommend that you use the `set_channel_plan()` API after the connection. - * By default, the PHY layers configure only the mandatory Join - * channels. The retransmission back-off restrictions on these channels - * are severe and you may experience long delays or even - * failures in the confirmed traffic. If you add more channels, the aggregated duty - * cycle becomes much more relaxed as compared to the Join (default) channels only. - * - * **NOTES ON RECONNECTION:** - * Currently, the Mbed OS LoRaWAN implementation does not support non-volatile - * memory storage. Therefore, the state and frame counters cannot be restored after - * a power cycle. However, if you use the `disconnect()` API to shut down the LoRaWAN - * protocol, the state and frame counters are saved. Connecting again would try to - * restore the previous session. According to the LoRaWAN 1.0.2 specification, the frame counters are always reset - * to zero for OTAA and a new Join request lets the network server know - * that the counters need a reset. The same is said about the ABP but there - * is no way to convey this information to the network server. For a network - * server, an ABP device is always connected. That's why storing the frame counters - * is important, at least for ABP. That's why we try to restore frame counters from - * session information after a disconnection. - * - * @param connect Options for an end device connection to the gateway. - * - * @return For ABP: If everything goes well, LORAWAN_STATUS_OK is returned for first call followed by - * a 'CONNECTED' event. Otherwise a negative error code is returned. - * Any subsequent call will return LORAWAN_STATUS_ALREADY_CONNECTED and no event follows. - * - * For OTAA: When a JoinRequest is sent, LORAWAN_STATUS_CONNECT_IN_PROGRESS is returned for the first call. - * Any subsequent call will return either LORAWAN_STATUS_BUSY (if the previous request for connection - * is still underway) or LORAWAN_STATUS_ALREADY_CONNECTED (if a network was already joined successfully). - * A 'CONNECTED' event is sent to the application when the JoinAccept is received. - */ virtual lorawan_status_t connect(const lorawan_connect_t &connect); - - /** Disconnect the current session. - * - * @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown. - */ virtual lorawan_status_t disconnect(); - - /** Validate the connectivity with the network. - * - * Application may use this API to submit a request to the stack for - * validation of its connectivity to a Network Server. Under the hood, this - * API schedules a Link Check Request command (LinkCheckReq) for the network - * server and once the response, i.e., LinkCheckAns MAC command is received - * from the Network Server, user provided method is called. - * - * One way to use this API may be the validation of connectivity after a long - * deep sleep. Mbed LoRaWANStack piggy-backs the MAC commands with data - * frame payload so the application needs to try sending something and the Network - * Server may respond during the RX slots. - * - * This API is usable only when the 'link_check_resp' callback is set by - * the application. See add_lora_app_callbacks API. If the above mentioned - * callback is not set, a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. - * - * First parameter to callback function is the demodulation margin and - * the second parameter is the number of gateways that successfully received - * the last request. - * - * A 'Link Check Request' MAC command remains set for every subsequent - * transmission, until/unless application explicitly turns it off using - * remove_link_check_request() API. - * - * @return LORAWAN_STATUS_OK on successfully queuing a request, or - * a negative error code on failure. - * - */ virtual lorawan_status_t add_link_check_request(); - - /** Removes link check request sticky MAC command. - * - * Any already queued request may still get entertained. However, no new - * requests will be made. - */ virtual void remove_link_check_request(); - - /** Sets up a particular data rate - * - * `set_datarate()` first verifies whether the data rate given is valid or not. - * If it is valid, the system sets the given data rate to the channel. - * - * @param data_rate The intended data rate, for example DR_0 or DR_1. - * Please note, that the macro DR_* can mean different - * things in different regions. - * @return LORAWAN_STATUS_OK if everything goes well, otherwise - * a negative error code. - */ virtual lorawan_status_t set_datarate(uint8_t data_rate); - - /** Enables adaptive data rate (ADR). - * - * The underlying LoRaPHY and LoRaMac layers handle the data rate automatically - * for the user, based upon the radio conditions (network congestion). - * - * @return LORAWAN_STATUS_OK or negative error code otherwise. - */ virtual lorawan_status_t enable_adaptive_datarate(); - - /** Disables adaptive data rate. - * - * When adaptive data rate (ADR) is disabled, you can either set a certain - * data rate or the MAC layer selects a default value. - * - * @return LORAWAN_STATUS_OK or negative error code otherwise. - */ virtual lorawan_status_t disable_adaptive_datarate(); - - /** Sets up the retry counter for confirmed messages. - * - * Valid for confirmed messages only. - * - * The number of trials to transmit the frame, if the LoRaMAC layer did not - * receive an acknowledgment. The MAC performs a data rate adaptation as in - * the LoRaWAN Specification V1.0.2, chapter 18.4, table on page 64. - * - * Note, that if number of retries is set to 1 or 2, MAC will not decrease - * the datarate, if the LoRaMAC layer did not receive an acknowledgment. - * - * @param count The number of retries for confirmed messages. - * - * @return LORAWAN_STATUS_OK or a negative error code. - */ virtual lorawan_status_t set_confirmed_msg_retries(uint8_t count); - - /** Sets the channel plan. - * - * You can provide a list of channels with appropriate parameters filled - * in. However, this list is not absolute. The stack applies a CF-List whenever - * available, which means that the network can overwrite your channel - * frequency settings right after Join Accept is received. You may try - * to set up any channel or channels after that, and if the channel requested - * is already active, the request is silently ignored. A negative error - * code is returned if there is any problem with parameters. - * - * Please note that this API can also be used to add a single channel to the - * existing channel plan. - * - * There is no reverse mechanism in the 1.0.2 specification for a node to request - * a particular channel. Only the network server can initiate such a request. - * You need to ensure that the corresponding base station supports the channel or channels being added. - * - * If your list includes a default channel (a channel where Join Requests - * are received) you cannot fully configure the channel parameters. - * Either leave the channel settings to default or check your - * corresponding PHY layer implementation. For example, LoRaPHYE868. - * - * @param channel_plan The channel plan to set. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t set_channel_plan(const lorawan_channelplan_t &channel_plan); - - /** Gets the channel plans from the LoRa stack. - * - * Once you have selected a particular PHY layer, a set of channels - * is automatically activated. Right after connecting, you can use this API - * to see the current plan. Otherwise, this API returns the channel - * plan that you have set using `set_channel_plan()`. - * - * @param channel_plan The current channel plan information. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t get_channel_plan(lorawan_channelplan_t &channel_plan); - - /** Removes an active channel plan. - * - * You cannot remove default channels (the channels the base stations are listening to). - * When a plan is abolished, only the non-default channels are removed. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t remove_channel_plan(); - - /** Removes a single channel. - * - * You cannot remove default channels (the channels the base stations are listening to). - * - * @param index The channel index. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t remove_channel(uint8_t index); - - /** Send message to gateway - * - * @param port The application port number. Port numbers 0 and 224 - * are reserved, whereas port numbers from 1 to 223 - * (0x01 to 0xDF) are valid port numbers. - * Anything out of this range is illegal. - * - * @param data A pointer to the data being sent. The ownership of the - * buffer is not transferred. The data is copied to the - * internal buffers. - * - * @param length The size of data in bytes. - * - * @param flags A flag used to determine what type of - * message is being sent, for example: - * - * MSG_UNCONFIRMED_FLAG = 0x01 - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04 - * MSG_PROPRIETARY_FLAG = 0x08 - * - * All flags are mutually exclusive, and MSG_MULTICAST_FLAG - * cannot be set. - * - * - * @return The number of bytes sent, or - * LORAWAN_STATUS_WOULD_BLOCK if another TX is - * ongoing, or a negative error code on failure. - */ - virtual int16_t send(uint8_t port, const uint8_t *data, uint16_t length, - int flags); - - /** Receives a message from the Network Server on a specific port. - * - * @param port The application port number. Port numbers 0 and 224 - * are reserved, whereas port numbers from 1 to 223 - * (0x01 to 0xDF) are valid port numbers. - * Anything out of this range is illegal. - * - * @param data A pointer to buffer where the received data will be - * stored. - * - * @param length The size of data in bytes - * - * @param flags A flag is used to determine what type of - * message is being sent, for example: - * - * MSG_UNCONFIRMED_FLAG = 0x01, - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04, - * MSG_PROPRIETARY_FLAG = 0x08 - * - * All flags can be used in conjunction with - * one another depending on the intended use case or reception - * expectation. - * - * e.g., MSG_CONFIRMED_FLAG and MSG_UNCONFIRMED_FLAG are - * not mutually exclusive, i.e., the user can subscribe to - * receive both CONFIRMED AND UNCONFIRMED messages at - * the same time. - * - * @return It could be one of these: - * i) 0 if there is nothing else to read. - * ii) Number of bytes written to user buffer. - * iii) LORAWAN_STATUS_WOULD_BLOCK if there is - * nothing available to read at the moment. - * iv) A negative error code on failure. - */ + virtual int16_t send(uint8_t port, const uint8_t *data, uint16_t length, int flags); virtual int16_t receive(uint8_t port, uint8_t *data, uint16_t length, int flags); - - /** Receives a message from the Network Server on any port. - * - * @param data A pointer to buffer where the received data will be - * stored. - * - * @param length The size of data in bytes - * - * @param port Return the number of port to which message was received. - * - * @param flags Return flags to determine what type of message was received. - * MSG_UNCONFIRMED_FLAG = 0x01 - * MSG_CONFIRMED_FLAG = 0x02 - * MSG_MULTICAST_FLAG = 0x04 - * MSG_PROPRIETARY_FLAG = 0x08 - * - * @return It could be one of these: - * i) 0 if there is nothing else to read. - * ii) Number of bytes written to user buffer. - * iii) LORAWAN_STATUS_WOULD_BLOCK if there is - * nothing available to read at the moment. - * iv) A negative error code on failure. - */ virtual int16_t receive(uint8_t *data, uint16_t length, uint8_t &port, int &flags); - - /** Add application callbacks to the stack. - * - * 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(lorawan_event_t event) - * { - * switch(event) { - * 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. - * - * @return LORAWAN_STATUS_OK on success, a negative error - * code on failure. - */ virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks); - - /** Change device class - * - * Change current device class. - * - * @param device_class The device class - * - * @return LORAWAN_STATUS_OK on success, - * LORAWAN_STATUS_UNSUPPORTED is requested class is not supported, - * or other negative error code if request failed. - */ virtual lorawan_status_t set_device_class(const device_class_t device_class); - - /** Get hold of TX meta-data - * - * Use this method to acquire any TX meta-data related to previous - * transmission. - * TX meta-data is only available right after the transmission is completed. - * In other words, you can check for TX meta-data right after receiving the - * TX_DONE event. - * - * @param metadata the inbound structure that will be filled if the meta-data - * is available. - * - * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise - * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. - */ virtual lorawan_status_t get_tx_metadata(lorawan_tx_metadata &metadata); - - /** Get hold of RX meta-data - * - * Use this method to acquire any RX meta-data related to current - * reception. - * RX meta-data is only available right after the reception is completed. - * In other words, you can check for RX meta-data right after receiving the - * RX_DONE event. - * - * @param metadata the inbound structure that will be filled if the meta-data - * is available. - * - * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise - * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. - */ virtual lorawan_status_t get_rx_metadata(lorawan_rx_metadata &metadata); - - /** Get hold of backoff time - * - * In the TX path, because of automatic duty cycling, the transmission is delayed - * by a certain amount of time which is the backoff time. While the system schedules - * application data to be sent, the application can inquire about how much time is - * left in the actual transmission to happen. - * - * The system will provide you with a backoff time only if the application data is - * in the TX pipe. If however, the event is already queued for the transmission, this - * API returns a LORAWAN_STATUS_METADATA_NOT_AVAILABLE error code. - * - * @param backoff the inbound integer that will be carry the backoff time if it - * is available. - * - * @return LORAWAN_STATUS_OK if the meta-data regarding backoff is available, - * otherwise LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. - * - */ virtual lorawan_status_t get_backoff_metadata(int &backoff); - - /** Cancel outgoing transmission - * - * This API is used to cancel any outstanding transmission in the TX pipe. - * If an event for transmission is not already queued at the end of backoff timer, - * the system can cancel the outstanding outgoing packet. Otherwise, the system is - * busy sending and can't be held back. The system will not try to re-send if the - * outgoing message was a CONFIRMED message even if the ack is not received. - * - * @return LORAWAN_STATUS_OK if the sending is cancelled. - * LORAWAN_STATUS_BUSY otherwise. - * - */ virtual lorawan_status_t cancel_sending(void); void lock(void)