diff --git a/features/lorawan/LoRaWANBase.h b/features/lorawan/LoRaWANBase.h index c122956dd6..8374b192a3 100644 --- a/features/lorawan/LoRaWANBase.h +++ b/features/lorawan/LoRaWANBase.h @@ -220,7 +220,7 @@ public: virtual int16_t send(uint8_t port, const uint8_t* data, uint16_t length, int flags) = 0; - /** Receives a message from the Network Server. + /** 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 @@ -259,8 +259,31 @@ public: * nothing available to read at the moment. * iv) A negative error code on failure. */ - virtual int16_t receive(uint8_t port, uint8_t* data, uint16_t length, - int flags) = 0; + 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. + * + * @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) = 0; /** Add application callbacks to the stack. * diff --git a/features/lorawan/LoRaWANInterface.cpp b/features/lorawan/LoRaWANInterface.cpp index 49e400ee8c..377d5279d2 100644 --- a/features/lorawan/LoRaWANInterface.cpp +++ b/features/lorawan/LoRaWANInterface.cpp @@ -107,17 +107,19 @@ lorawan_status_t LoRaWANInterface::remove_channel_plan() return stk_obj().drop_channel_list(); } -int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data, - uint16_t length, int flags) +int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data, uint16_t length, int flags) { return stk_obj().handle_tx(port, data, length, flags); - } -int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length, - int flags) +int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length, int flags) { - return stk_obj().handle_rx(port, data, length, flags); + return stk_obj().handle_rx(data, length, port, flags, true); +} + +int16_t LoRaWANInterface::receive(uint8_t* data, uint16_t length, uint8_t& port, int& flags) +{ + return stk_obj().handle_rx(data, length, port, flags, false); } lorawan_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks) diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index 038d68a0dd..a26468ef10 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -317,7 +317,7 @@ public: virtual int16_t send(uint8_t port, const uint8_t* data, uint16_t length, int flags); - /** Receives a message from the Network Server. + /** 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 @@ -356,8 +356,31 @@ public: * nothing available to read at the moment. * iv) A negative error code on failure. */ - virtual int16_t receive(uint8_t port, 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. * diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 0c6d25ca63..f15695290b 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -387,8 +387,35 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, return (status == LORAWAN_STATUS_OK) ? len : (int16_t) status; } -int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data, - uint16_t length, uint8_t flags) +int convert_to_msg_flag(const mcps_type_t type) +{ + int msg_flag = MSG_UNCONFIRMED_FLAG; + switch (type) { + case MCPS_UNCONFIRMED: + msg_flag = MSG_UNCONFIRMED_FLAG; + break; + + case MCPS_CONFIRMED: + msg_flag = MSG_CONFIRMED_FLAG; + break; + + case MCPS_MULTICAST: + msg_flag = MSG_MULTICAST_FLAG; + break; + + case MCPS_PROPRIETARY: + msg_flag = MSG_PROPRIETARY_FLAG; + break; + + default: + tr_error("Unknown message type!"); + MBED_ASSERT(0); + } + + return msg_flag; +} + +int16_t LoRaWANStack::handle_rx(uint8_t* data, uint16_t length, uint8_t& port, int& flags, bool validate_params) { if (!_lw_session.active) { return LORAWAN_STATUS_NO_ACTIVE_SESSIONS; @@ -409,36 +436,28 @@ int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data, return LORAWAN_STATUS_PARAMETER_INVALID; } - uint8_t *base_ptr = _rx_msg.msg.mcps_indication.buffer; + int received_flags = convert_to_msg_flag(_rx_msg.msg.mcps_indication.type); + if (validate_params) { + // Check received message port and flags match with the ones requested by user + received_flags &= MSG_FLAG_MASK; + + if (_rx_msg.msg.mcps_indication.port != port || !(flags & received_flags)) { + return LORAWAN_STATUS_WOULD_BLOCK; + } + } + + // Report values back to user + port = _rx_msg.msg.mcps_indication.port; + flags = received_flags; + + const uint8_t *base_ptr = _rx_msg.msg.mcps_indication.buffer; uint16_t base_size = _rx_msg.msg.mcps_indication.buffer_size; bool read_complete = false; - if (_rx_msg.msg.mcps_indication.port != port) { - // Nothing yet received for this particular port - return LORAWAN_STATUS_WOULD_BLOCK; - } - - // check if message received is a Confirmed message and user subscribed to it or not - if (_rx_msg.msg.mcps_indication.type == MCPS_CONFIRMED - && ((flags & MSG_FLAG_MASK) == MSG_CONFIRMED_FLAG - || (flags & MSG_FLAG_MASK) == MSG_CONFIRMED_MULTICAST - || (flags & MSG_FLAG_MASK) == MSG_CONFIRMED_PROPRIETARY)) { - - tr_debug("RX - Confirmed Message, flags=%d", flags); - } - - // check if message received is a Unconfirmed message and user subscribed to it or not - if (_rx_msg.msg.mcps_indication.type == MCPS_UNCONFIRMED - && ((flags & MSG_FLAG_MASK) == MSG_UNCONFIRMED_FLAG - || (flags & MSG_FLAG_MASK) == MSG_UNCONFIRMED_MULTICAST - || (flags & MSG_FLAG_MASK) == MSG_UNCONFIRMED_PROPRIETARY)) { - tr_debug("RX - Unconfirmed Message - flags=%d", flags); - } - // check the length of received message whether we can fit into user // buffer completely or not if (_rx_msg.msg.mcps_indication.buffer_size > length && - _rx_msg.prev_read_size == 0) { + _rx_msg.prev_read_size == 0) { // we can't fit into user buffer. Invoke counter measures _rx_msg.pending_size = _rx_msg.msg.mcps_indication.buffer_size - length; base_size = length; @@ -614,12 +633,12 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic default: { if (is_port_valid(mcps_indication->port) == true || mcps_indication->type == MCPS_PROPRIETARY) { - // Valid message arrived. _rx_msg.type = LORAMAC_RX_MCPS_INDICATION; _rx_msg.msg.mcps_indication.buffer_size = mcps_indication->buffer_size; _rx_msg.msg.mcps_indication.port = mcps_indication->port; _rx_msg.msg.mcps_indication.buffer = mcps_indication->buffer; + _rx_msg.msg.mcps_indication.type = mcps_indication->type; // Notify application about received frame.. tr_debug("Received %d bytes", _rx_msg.msg.mcps_indication.buffer_size); diff --git a/features/lorawan/LoRaWANStack.h b/features/lorawan/LoRaWANStack.h index b2846cffa9..1ac19063f1 100644 --- a/features/lorawan/LoRaWANStack.h +++ b/features/lorawan/LoRaWANStack.h @@ -299,16 +299,19 @@ public: uint16_t length, uint8_t flags, bool null_allowed = false); /** Receives a message from the Network Server. + * + * @param data A pointer to buffer where the received data will be + * stored. + * + * @param length The size of data in bytes * * @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 + * In return will contain the number of port to which + * message was received. * * @param flags A flag is used to determine what type of * message is being received, for example: @@ -330,6 +333,13 @@ public: * receive both CONFIRMED AND UNCONFIRMED messages at * the same time. * + * In return will contain the flags to determine what kind + * of message was received. + * + * @param validate_params If set to true, the given port and flags values will be checked + * against the values received with the message. If values do not + * match, LORAWAN_STATUS_WOULD_BLOCK will be returned. + * * @return It could be one of these: * i) 0 if there is nothing else to read. * ii) Number of bytes written to user buffer. @@ -337,8 +347,7 @@ public: * nothing available to read at the moment. * iv) A negative error code on failure. */ - int16_t handle_rx(const uint8_t port, uint8_t* data, - uint16_t length, uint8_t flags); + int16_t handle_rx(uint8_t* data, uint16_t length, uint8_t& port, int& flags, bool validate_params); /** Send Link Check Request MAC command. *