mirror of https://github.com/ARMmbed/mbed-os.git
Style Changes in MAC layer
Style changed according to Mbed-OS guidelines.pull/6059/head
parent
20bce2f21c
commit
7224fbae1c
|
@ -130,7 +130,7 @@ LoRaWANStack& LoRaWANStack::get_lorawan_stack()
|
|||
radio_events_t *LoRaWANStack::bind_radio_driver(LoRaRadio& radio)
|
||||
{
|
||||
// Store pointer to callback routines inside MAC layer (non-IRQ safe)
|
||||
_mac_handlers = _loramac.GetPhyEventHandlers();
|
||||
_mac_handlers = _loramac.get_phy_event_handlers();
|
||||
// passes the reference to radio driver down to PHY layer
|
||||
_lora_phy.set_radio_instance(radio);
|
||||
return _mac_handlers;
|
||||
|
@ -154,7 +154,7 @@ lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue)
|
|||
#endif
|
||||
|
||||
_lora_time.activate_timer_subsystem(queue);
|
||||
_loramac.LoRaMacInitialization(&LoRaMacPrimitives, &_lora_phy, queue);
|
||||
_loramac.initialize(&LoRaMacPrimitives, &_lora_phy, queue);
|
||||
|
||||
loramac_mib_req_confirm_t mib_req;
|
||||
|
||||
|
@ -267,7 +267,7 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac()
|
|||
uint16_t LoRaWANStack::check_possible_tx_size(uint16_t size)
|
||||
{
|
||||
loramac_tx_info_t tx_info;
|
||||
if (_loramac.LoRaMacQueryTxPossible(size, &tx_info) == LORAWAN_STATUS_LENGTH_ERROR) {
|
||||
if (_loramac.query_tx_possible(size, &tx_info) == LORAWAN_STATUS_LENGTH_ERROR) {
|
||||
// Cannot transmit this much. Return how much data can be sent
|
||||
// at the moment
|
||||
return tx_info.max_possible_payload_size;
|
||||
|
@ -404,7 +404,7 @@ lorawan_status_t LoRaWANStack::add_channels(const lorawan_channelplan_t &channel
|
|||
return LORAWAN_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return _loramac.AddChannelPlan(channel_plan);
|
||||
return _loramac.add_channel_plan(channel_plan);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::drop_channel_list()
|
||||
|
@ -414,7 +414,7 @@ lorawan_status_t LoRaWANStack::drop_channel_list()
|
|||
return LORAWAN_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return _loramac.RemoveChannelPlan();
|
||||
return _loramac.remove_channel_plan();
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id)
|
||||
|
@ -425,7 +425,7 @@ lorawan_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id)
|
|||
return LORAWAN_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return _loramac.RemoveSingleChannel(channel_id);
|
||||
return _loramac.remove_single_channel(channel_id);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::get_enabled_channels(lorawan_channelplan_t& channel_plan)
|
||||
|
@ -438,7 +438,7 @@ lorawan_status_t LoRaWANStack::get_enabled_channels(lorawan_channelplan_t& chann
|
|||
return LORAWAN_STATUS_BUSY;
|
||||
}
|
||||
|
||||
return _loramac.GetChannelPlan(channel_plan);
|
||||
return _loramac.get_channel_plan(channel_plan);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::enable_adaptive_datarate(bool adr_enabled)
|
||||
|
@ -771,7 +771,7 @@ lorawan_status_t LoRaWANStack::mlme_request_handler(loramac_mlme_req_t *mlme_req
|
|||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
return _loramac.LoRaMacMlmeRequest(mlme_request);
|
||||
return _loramac.mlme_request(mlme_request);
|
||||
}
|
||||
|
||||
/** MLME-Confirm event function
|
||||
|
@ -843,7 +843,7 @@ lorawan_status_t LoRaWANStack::mcps_request_handler(loramac_mcps_req_t *mcps_req
|
|||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
return _loramac.LoRaMacMcpsRequest(mcps_request);
|
||||
return _loramac.mcps_request(mcps_request);
|
||||
}
|
||||
|
||||
/** MCPS-Confirm event function
|
||||
|
@ -1154,7 +1154,7 @@ lorawan_status_t LoRaWANStack::mib_set_request(loramac_mib_req_confirm_t *mib_se
|
|||
if (NULL == mib_set_params) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
return _loramac.LoRaMacMibSetRequestConfirm(mib_set_params);
|
||||
return _loramac.mib_set_request_confirm(mib_set_params);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::mib_get_request(loramac_mib_req_confirm_t *mib_get_params)
|
||||
|
@ -1162,7 +1162,7 @@ lorawan_status_t LoRaWANStack::mib_get_request(loramac_mib_req_confirm_t *mib_ge
|
|||
if(NULL == mib_get_params) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
return _loramac.LoRaMacMibGetRequestConfirm(mib_get_params);
|
||||
return _loramac.mib_get_request_confirm(mib_get_params);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANStack::set_link_check_request()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,8 +37,8 @@
|
|||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_H__
|
||||
#define __LORAMAC_H__
|
||||
#ifndef MBED_LORAWAN_MAC_H__
|
||||
#define MBED_LORAWAN_MAC_H__
|
||||
|
||||
#include "lorawan/system/LoRaWANTimer.h"
|
||||
#include "lorastack/phy/LoRaPHY.h"
|
||||
|
@ -50,63 +50,63 @@
|
|||
#include "lorastack/mac/LoRaMacMib.h"
|
||||
#include "lorastack/mac/LoRaMacChannelPlan.h"
|
||||
|
||||
class LoRaMac
|
||||
{
|
||||
class LoRaMac {
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
LoRaMac(LoRaWANTimeHandler &lora_time);
|
||||
|
||||
/*!
|
||||
* \brief Destructor
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~LoRaMac();
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC layer initialization
|
||||
/**
|
||||
* @brief LoRaMAC layer initialization
|
||||
*
|
||||
* \details In addition to the initialization of the LoRaMAC layer, this
|
||||
* @details In addition to the initialization of the LoRaMAC layer, this
|
||||
* function initializes the callback primitives of the MCPS and
|
||||
* MLME services. Every data field of \ref loramac_primitives_t must be
|
||||
* set to a valid callback function.
|
||||
*
|
||||
* \param primitives [in] - A pointer to the structure defining the LoRaMAC
|
||||
* @param primitives [in] A pointer to the structure defining the LoRaMAC
|
||||
* event functions. Refer to \ref loramac_primitives_t.
|
||||
*
|
||||
* \param phy [in]- A pointer to the selected PHY layer.
|
||||
* @param phy [in] A pointer to the selected PHY layer.
|
||||
*
|
||||
* \param queue [in]- A pointer to the application provided EventQueue.
|
||||
* @param queue [in] A pointer to the application provided EventQueue.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t LoRaMacInitialization(loramac_primitives_t *primitives,
|
||||
LoRaPHY *phy,
|
||||
events::EventQueue *queue);
|
||||
lorawan_status_t initialize(loramac_primitives_t *primitives, LoRaPHY *phy,
|
||||
events::EventQueue *queue);
|
||||
|
||||
/*!
|
||||
* \brief Disconnect LoRaMac layer
|
||||
/**
|
||||
* @brief Disconnect LoRaMac layer
|
||||
*
|
||||
* \details Cancels all outstanding requests and sets LoRaMac's
|
||||
* @details Cancels all outstanding requests and sets LoRaMac's
|
||||
* internal state to idle.
|
||||
*/
|
||||
void disconnect(void);
|
||||
|
||||
/*!
|
||||
* \brief Queries the LoRaMAC whether it is possible to send the next frame with
|
||||
/**
|
||||
* @brief Queries the LoRaMAC whether it is possible to send the next frame with
|
||||
* a given payload size. The LoRaMAC takes the scheduled MAC commands into
|
||||
* account and reports when the frame can be sent.
|
||||
*
|
||||
* \param size [in]- The size of the applicable payload to be sent next.
|
||||
* \param txInfo [out] - The structure \ref loramac_tx_info_t contains
|
||||
* information on the actual maximum payload possible
|
||||
* (according to the configured datarate or the next
|
||||
* datarate according to ADR), and the maximum frame
|
||||
* size, taking the scheduled MAC commands into account.
|
||||
* @param size [in] The size of the applicable payload to be sent next.
|
||||
* @param tx_info [out] The structure \ref loramac_tx_info_t contains
|
||||
* information on the actual maximum payload possible
|
||||
* (according to the configured datarate or the next
|
||||
* datarate according to ADR), and the maximum frame
|
||||
* size, taking the scheduled MAC commands into account.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. When the parameters are
|
||||
* @return `lorawan_status_t` The status of the operation. When the parameters are
|
||||
* not valid, the function returns \ref LORAWAN_STATUS_PARAMETER_INVALID.
|
||||
* In case of a length error caused by the applicable payload in combination
|
||||
* with the MAC commands, the function returns \ref LORAWAN_STATUS_LENGTH_ERROR.
|
||||
|
@ -116,192 +116,201 @@ public:
|
|||
* If the query is valid, and the LoRaMAC is able to send the frame,
|
||||
* the function returns \ref LORAWAN_STATUS_OK.
|
||||
*/
|
||||
lorawan_status_t LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_t* txInfo );
|
||||
lorawan_status_t query_tx_possible(uint8_t size, loramac_tx_info_t* tx_info);
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel plan to the system.
|
||||
/**
|
||||
* @brief Adds a channel plan to the system.
|
||||
*
|
||||
* \details Adds a whole channel plan or a single new channel to the.
|
||||
* @details Adds a whole channel plan or a single new channel if the plan
|
||||
* contains only one channel and 'plan.nb_channels' is set to 1.
|
||||
* Please note that this functionality is not available in all regions.
|
||||
* Information on the allowed ranges is available at the
|
||||
* LoRaWAN Regional Parameters V1.0.2rB.
|
||||
*
|
||||
* \param plan [in] - A reference to application provided channel plan.
|
||||
* @param plan [in] A reference to application provided channel plan.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t AddChannelPlan(const lorawan_channelplan_t& plan);
|
||||
lorawan_status_t add_channel_plan(const lorawan_channelplan_t& plan);
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel plan from the system.
|
||||
/**
|
||||
* @brief Removes a channel plan from the system.
|
||||
*
|
||||
* \details Removes the whole active channel plan except the 'Default Channels'..
|
||||
* @details Removes the whole active channel plan except the 'Default Channels'.
|
||||
* Please note that this functionality is not available in all regions.
|
||||
* Information on the allowed ranges is available at the
|
||||
* LoRaWAN Regional Parameters V1.0.2rB.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t RemoveChannelPlan();
|
||||
lorawan_status_t remove_channel_plan();
|
||||
|
||||
/*!
|
||||
* \brief Access active channel plan.
|
||||
/**
|
||||
* @brief Access active channel plan.
|
||||
*
|
||||
* \details Provides access to the current active channel plan.
|
||||
* @details Provides access to the current active channel plan.
|
||||
*
|
||||
* \param plan [out] - A reference to application provided channel plan data
|
||||
* structure which will be filled in with active channel
|
||||
* plan.
|
||||
* @param plan [out] A reference to application provided channel plan data
|
||||
* structure which will be filled in with active channel
|
||||
* plan.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t GetChannelPlan(lorawan_channelplan_t& plan);
|
||||
lorawan_status_t get_channel_plan(lorawan_channelplan_t& plan);
|
||||
|
||||
/*!
|
||||
* \brief Remove a given channel from the active plan.
|
||||
/**
|
||||
* @brief Remove a given channel from the active plan.
|
||||
*
|
||||
* \details Deactivates the given channel.
|
||||
* @details Deactivates the given channel.
|
||||
*
|
||||
* \param id - Id of the channel.
|
||||
* @param id Id of the channel.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t RemoveSingleChannel( uint8_t id );
|
||||
lorawan_status_t remove_single_channel(uint8_t id);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC multicast channel link service.
|
||||
/**
|
||||
* @brief LoRaMAC multicast channel link service.
|
||||
*
|
||||
* \details Links a multicast channel into the linked list.
|
||||
* @details Links a multicast channel into the linked list.
|
||||
*
|
||||
* \param [in] channelParam - The multicast channel parameters to link.
|
||||
* @param [in] channel_param The multicast channel parameters to link.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t LoRaMacMulticastChannelLink( multicast_params_t *channelParam );
|
||||
lorawan_status_t multicast_channel_link(multicast_params_t *channel_param);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC multicast channel unlink service.
|
||||
/**
|
||||
* @brief LoRaMAC multicast channel unlink service.
|
||||
*
|
||||
* \details Unlinks a multicast channel from the linked list.
|
||||
* @details Unlinks a multicast channel from the linked list.
|
||||
*
|
||||
* \param [in] channelParam - The multicast channel parameters to unlink.
|
||||
* @param [in] channel_param The multicast channel parameters to unlink.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t LoRaMacMulticastChannelUnlink( multicast_params_t *channelParam );
|
||||
lorawan_status_t multicast_channel_unlink(multicast_params_t *channel_param);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC MIB-GET.
|
||||
/**
|
||||
* @brief Get parameter values from MIB service.
|
||||
*
|
||||
* \details The MAC information base service to get the attributes of the LoRaMac layer.
|
||||
* @details The MAC information base service to get the attributes of the LoRaMac layer.
|
||||
*
|
||||
* The following code-snippet shows how to use the API to get the
|
||||
* parameter `AdrEnable`, defined by the enumeration type
|
||||
* \ref MIB_ADR.
|
||||
* \code
|
||||
* MibRequestConfirm_t mibReq;
|
||||
* mibReq.Type = MIB_ADR;
|
||||
*
|
||||
* if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAWAN_STATUS_OK )
|
||||
* {
|
||||
* @code
|
||||
*
|
||||
* loramac_mib_req_confirm_t mib_get;
|
||||
* mib_get.type = MIB_ADR;
|
||||
*
|
||||
* if (mib_get_request_confirm(&mib_get) == LORAWAN_STATUS_OK) {
|
||||
* // LoRaMAC updated the parameter mibParam.AdrEnable
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \param [in] mibGet - The MIB-GET request to perform. Refer to \ref loramac_mib_req_confirm_t.
|
||||
* @endcode
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @param [in] mib_get The MIB-GET request to perform. Refer to
|
||||
* \ref loramac_mib_req_confirm_t.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation.
|
||||
* The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t LoRaMacMibGetRequestConfirm( loramac_mib_req_confirm_t *mibGet );
|
||||
lorawan_status_t mib_get_request_confirm(loramac_mib_req_confirm_t *mib_get);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC MIB-SET.
|
||||
/**
|
||||
* @brief Set attributes for MAC layer using MIB service.
|
||||
*
|
||||
* \details The MAC information base service to set the attributes of the LoRaMac layer.
|
||||
* @details The MAC information base service to set the attributes of the LoRaMac layer.
|
||||
*
|
||||
* The following code-snippet shows how to use the API to set the
|
||||
* parameter `AdrEnable`, defined by the enumeration type
|
||||
* parameter `adr_enable`, defined by the enumeration type
|
||||
* \ref MIB_ADR.
|
||||
*
|
||||
* \code
|
||||
* MibRequestConfirm_t mibReq;
|
||||
* mibReq.Type = MIB_ADR;
|
||||
* mibReq.Param.AdrEnable = true;
|
||||
* @code
|
||||
*
|
||||
* if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAWAN_STATUS_OK )
|
||||
* {
|
||||
* loramac_mib_req_confirm_t mib_set;
|
||||
* mib_set.Type = MIB_ADR;
|
||||
* mib_set.param.adr_enable = true;
|
||||
*
|
||||
* if (mib_set_request_confirm(&mib_set) == LORAWAN_STATUS_OK) {
|
||||
* // LoRaMAC updated the parameter
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \param [in] mibSet - The MIB-SET request to perform. Refer to \ref loramac_mib_req_confirm_t.
|
||||
* @endcode
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @param [in] mib_set The MIB-SET request to perform. Refer to
|
||||
* \ref loramac_mib_req_confirm_t.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_SERVICE_UNKNOWN
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
lorawan_status_t LoRaMacMibSetRequestConfirm( loramac_mib_req_confirm_t *mibSet );
|
||||
lorawan_status_t mib_set_request_confirm(loramac_mib_req_confirm_t *mib_set);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC MLME request
|
||||
/**
|
||||
* @brief Set forth an MLME request.
|
||||
*
|
||||
* \details The MAC layer management entity handles the management services. The
|
||||
* @details The MAC layer management entity handles the management services. The
|
||||
* following code-snippet shows how to use the API to perform a
|
||||
* network join request.
|
||||
*
|
||||
* \code
|
||||
* static uint8_t DevEui[] =
|
||||
* @code
|
||||
*
|
||||
* static uint8_t dev_eui[] =
|
||||
* {
|
||||
* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
* };
|
||||
* static uint8_t AppEui[] =
|
||||
* static uint8_t app_eui[] =
|
||||
* {
|
||||
* 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
* };
|
||||
* static uint8_t AppKey[] =
|
||||
* static uint8_t app_key[] =
|
||||
* {
|
||||
* 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
|
||||
* 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
|
||||
* };
|
||||
*
|
||||
* MlmeReq_t mlmeReq;
|
||||
* mlmeReq.Type = MLME_JOIN;
|
||||
* mlmeReq.Req.Join.DevEui = DevEui;
|
||||
* mlmeReq.Req.Join.AppEui = AppEui;
|
||||
* mlmeReq.Req.Join.AppKey = AppKey;
|
||||
* loramac_mlme_req_t mlme_req;
|
||||
* mlme_req.Type = MLME_JOIN;
|
||||
* mlme_req.req.join.dev_eui = dev_eui;
|
||||
* mlme_req.req.join.app_eui = app_eui;
|
||||
* mlme_req.req.join.app_key = app_key;
|
||||
*
|
||||
* if( LoRaMacMlmeRequest( &mlmeReq ) == LORAWAN_STATUS_OK )
|
||||
* {
|
||||
* if (LoRaMacMlmeRequest(&mlme_req) == LORAWAN_STATUS_OK) {
|
||||
* // Service started successfully. Waiting for the Mlme-Confirm event
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \param [in] mlmeRequest - The MLME request to perform. Refer to \ref loramac_mlme_req_t.
|
||||
* @endcode
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @param [in] request The MLME request to perform.
|
||||
* Refer to \ref loramac_mlme_req_t.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_SERVICE_UNKNOWN
|
||||
|
@ -310,33 +319,35 @@ public:
|
|||
* \ref LORAWAN_STATUS_LENGTH_ERROR
|
||||
* \ref LORAWAN_STATUS_DEVICE_OFF
|
||||
*/
|
||||
lorawan_status_t LoRaMacMlmeRequest( loramac_mlme_req_t *mlmeRequest );
|
||||
lorawan_status_t mlme_request(loramac_mlme_req_t *request);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC MCPS request
|
||||
/**
|
||||
* @brief Set forth an MCPS request.
|
||||
*
|
||||
* \details The MAC Common Part Sublayer handles the data services. The following
|
||||
* @details The MAC Common Part Sublayer handles the data services. The following
|
||||
* code-snippet shows how to use the API to send an unconfirmed
|
||||
* LoRaMAC frame.
|
||||
*
|
||||
* \code
|
||||
* uint8_t myBuffer[] = { 1, 2, 3 };
|
||||
* @code
|
||||
*
|
||||
* McpsReq_t mcpsReq;
|
||||
* mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||
* mcpsReq.Req.Unconfirmed.fPort = 1;
|
||||
* mcpsReq.Req.Unconfirmed.fBuffer = myBuffer;
|
||||
* mcpsReq.Req.Unconfirmed.fBufferSize = sizeof( myBuffer );
|
||||
* uint8_t buffer[] = {1, 2, 3};
|
||||
*
|
||||
* if( LoRaMacMcpsRequest( &mcpsReq ) == LORAWAN_STATUS_OK )
|
||||
* {
|
||||
* loramac_mcps_req_t request;
|
||||
* request.type = MCPS_UNCONFIRMED;
|
||||
* request.req.unconfirmed.fport = 1;
|
||||
* request.req.unconfirmed.f_buffer = buffer;
|
||||
* request.req.unconfirmed.f_buffer_size = sizeof(buffer);
|
||||
*
|
||||
* if (mcps_request(&request) == LORAWAN_STATUS_OK) {
|
||||
* // Service started successfully. Waiting for the MCPS-Confirm event
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \param [in] mcpsRequest - The MCPS request to perform. Refer to \ref loramac_mcps_req_t.
|
||||
* @endcode
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* @param [in] request The MCPS request to perform.
|
||||
* Refer to \ref loramac_mcps_req_t.
|
||||
*
|
||||
* @return `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_BUSY
|
||||
* \ref LORAWAN_STATUS_SERVICE_UNKNOWN
|
||||
|
@ -345,65 +356,76 @@ public:
|
|||
* \ref LORAWAN_STATUS_LENGTH_ERROR
|
||||
* \ref LORAWAN_STATUS_DEVICE_OFF
|
||||
*/
|
||||
lorawan_status_t LoRaMacMcpsRequest( loramac_mcps_req_t *mcpsRequest );
|
||||
lorawan_status_t mcps_request(loramac_mcps_req_t *request);
|
||||
|
||||
/**
|
||||
* \brief LoRaMAC layer provides its callback functions for
|
||||
* PHY layer
|
||||
* @brief LoRaMAC layer provides its callback functions for
|
||||
* PHY layer.
|
||||
*
|
||||
* \return Pointer to callback functions for radio events
|
||||
* @return Pointer to callback functions for radio events
|
||||
*/
|
||||
radio_events_t *GetPhyEventHandlers();
|
||||
radio_events_t *get_phy_event_handlers();
|
||||
|
||||
/*!
|
||||
* \brief Configures the events to trigger an MLME-Indication with
|
||||
/**
|
||||
* @brief Configures the events to trigger an MLME-Indication with
|
||||
* a MLME type of MLME_SCHEDULE_UPLINK.
|
||||
*/
|
||||
void SetMlmeScheduleUplinkIndication( void );
|
||||
void set_mlme_schedule_ul_indication(void);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC layer generic send frame
|
||||
/**
|
||||
* @brief Schedules the frame for sending.
|
||||
*
|
||||
* \param [in] macHdr MAC header field
|
||||
* \param [in] fPort MAC payload port
|
||||
* \param [in] fBuffer MAC data buffer to be sent
|
||||
* \param [in] fBufferSize MAC data buffer size
|
||||
* \retval status Status of the operation.
|
||||
* @details Prepares a full MAC frame and schedules it for physical
|
||||
* transmission.
|
||||
*
|
||||
* @param [in] mac_hdr MAC frame header field
|
||||
* @param [in] fport Payload port
|
||||
* @param [in] fbuffer MAC frame data buffer to be sent
|
||||
* @param [in] fbuffer_size MAC frame data buffer size
|
||||
*
|
||||
* @return status Status of the operation. LORAWAN_STATUS_OK in case
|
||||
* of success and a negative error code in case of
|
||||
* failure.
|
||||
*/
|
||||
lorawan_status_t Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize );
|
||||
lorawan_status_t send(loramac_mhdr_t *mac_hdr, uint8_t fport, void *fbuffer,
|
||||
uint16_t fbuffer_size);
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio in continuous transmission mode
|
||||
/**
|
||||
* @brief Puts the system in continuous transmission mode
|
||||
*
|
||||
* \remark Uses the radio parameters set on the previous transmission.
|
||||
* @remark Uses the radio parameters set on the previous transmission.
|
||||
*
|
||||
* \param [in] timeout Time in seconds while the radio is kept in continuous wave mode
|
||||
* \retval status Status of the operation.
|
||||
* @param [in] timeout Time in seconds while the radio is kept in continuous wave mode
|
||||
*
|
||||
* @return status Status of the operation. LORAWAN_STATUS_OK in case
|
||||
* of success and a negative error code in case of
|
||||
* failure.
|
||||
*/
|
||||
lorawan_status_t SetTxContinuousWave( uint16_t timeout );
|
||||
lorawan_status_t set_tx_continuous_wave(uint16_t timeout);
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio in continuous transmission mode
|
||||
/**
|
||||
* @brief Puts the system in continuous transmission mode
|
||||
*
|
||||
* \remark Uses the radio parameters set on the previous transmission.
|
||||
* @param [in] timeout Time in seconds while the radio is kept in continuous wave mode
|
||||
* @param [in] frequency RF frequency to be set.
|
||||
* @param [in] power RF output power to be set.
|
||||
*
|
||||
* \param [in] timeout Time in seconds while the radio is kept in continuous wave mode
|
||||
* \param [in] frequency RF frequency to be set.
|
||||
* \param [in] power RF output power to be set.
|
||||
* \retval status Status of the operation.
|
||||
* @return status Status of the operation. LORAWAN_STATUS_OK in case
|
||||
* of success and a negative error code in case of
|
||||
* failure.
|
||||
*/
|
||||
lorawan_status_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power );
|
||||
lorawan_status_t set_tx_continuous_wave1(uint16_t timeout, uint32_t frequency, uint8_t power);
|
||||
|
||||
/*!
|
||||
* \brief Resets MAC specific parameters to default
|
||||
/**
|
||||
* @brief Resets MAC specific parameters to default
|
||||
*/
|
||||
void ResetMacParameters( void );
|
||||
void reset_mac_parameters(void);
|
||||
|
||||
/*!
|
||||
* \brief Opens up a continuous RX 2 window. This is used for
|
||||
/**
|
||||
* @brief Opens up a continuous RX 2 window. This is used for
|
||||
* class c devices.
|
||||
*/
|
||||
void OpenContinuousRx2Window(void);
|
||||
void open_continuous_rx2_window(void);
|
||||
|
||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||
public: // Test interface
|
||||
|
@ -415,7 +437,7 @@ public: // Test interface
|
|||
*
|
||||
* \param [in] NextTxTime - Periodic time for next uplink.
|
||||
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \retval `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
|
@ -426,7 +448,7 @@ public: // Test interface
|
|||
*
|
||||
* \details Stops the next tx timer.
|
||||
*
|
||||
* \retval `LoRaMacStatus_t` The status of the operation. The possible values are:
|
||||
* \retval `lorawan_status_t` The status of the operation. The possible values are:
|
||||
* \ref LORAWAN_STATUS_OK
|
||||
* \ref LORAWAN_STATUS_PARAMETER_INVALID
|
||||
*/
|
||||
|
@ -480,138 +502,103 @@ private:
|
|||
#endif
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Function to be executed on Radio Tx Done event
|
||||
/**
|
||||
* Function to be executed on Radio Tx Done event
|
||||
*/
|
||||
void OnRadioTxDone( void );
|
||||
|
||||
/*!
|
||||
* \brief This function prepares the MAC to abort the execution of function
|
||||
* OnRadioRxDone in case of a reception error.
|
||||
*/
|
||||
void PrepareRxDoneAbort( void );
|
||||
|
||||
/*!
|
||||
* \brief Function to be executed on Radio Rx Done event
|
||||
*/
|
||||
void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
|
||||
|
||||
/*!
|
||||
* \brief Function executed on Radio Tx Timeout event
|
||||
*/
|
||||
void OnRadioTxTimeout( void );
|
||||
|
||||
/*!
|
||||
* \brief Function executed on Radio Rx error event
|
||||
*/
|
||||
void OnRadioRxError( void );
|
||||
|
||||
/*!
|
||||
* \brief Function executed on Radio Rx Timeout event
|
||||
*/
|
||||
void OnRadioRxTimeout( void );
|
||||
|
||||
/*!
|
||||
* \brief Function executed on Resend Frame timer event.
|
||||
*/
|
||||
void OnMacStateCheckTimerEvent( void );
|
||||
|
||||
/*!
|
||||
* \brief Function executed on duty cycle delayed Tx timer event
|
||||
*/
|
||||
void OnTxDelayedTimerEvent( void );
|
||||
void on_radio_tx_done(void);
|
||||
|
||||
/**
|
||||
* \brief Function to be executed when next Tx is possible
|
||||
* This function prepares the MAC to abort the execution of function
|
||||
* on_radio_rx_done() in case of a reception error.
|
||||
*/
|
||||
void OnNextTx( void );
|
||||
void prepare_rx_done_abort(void);
|
||||
|
||||
/*!
|
||||
* \brief Function executed on first Rx window timer event
|
||||
/**
|
||||
* Function to be executed on Radio Rx Done event
|
||||
*/
|
||||
void OnRxWindow1TimerEvent( void );
|
||||
void on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
||||
int8_t snr);
|
||||
|
||||
/*!
|
||||
* \brief Function executed on second Rx window timer event
|
||||
/**
|
||||
* Function executed on Radio Tx Timeout event
|
||||
*/
|
||||
void OnRxWindow2TimerEvent( void );
|
||||
void on_radio_tx_timeout(void);
|
||||
|
||||
/*!
|
||||
* \brief Function executed on AckTimeout timer event
|
||||
/**
|
||||
* Function executed on Radio Rx error event
|
||||
*/
|
||||
void OnAckTimeoutTimerEvent( void );
|
||||
void on_radio_rx_error(void);
|
||||
|
||||
/*!
|
||||
* \brief Initializes and opens the reception window
|
||||
*
|
||||
* \param [in] rxContinuous Set to true, if the RX is in continuous mode
|
||||
* \param [in] maxRxWindow Maximum RX window timeout
|
||||
/**
|
||||
* Function executed on Radio Rx Timeout event
|
||||
*/
|
||||
void RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow );
|
||||
void on_radio_rx_timeout(void);
|
||||
|
||||
/*!
|
||||
* \brief Validates if the payload fits into the frame, taking the datarate
|
||||
* into account.
|
||||
*
|
||||
* \details Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0
|
||||
*
|
||||
* \param lenN Length of the application payload. The length depends on the
|
||||
* datarate and is region specific
|
||||
*
|
||||
* \param datarate Current datarate
|
||||
*
|
||||
* \param fOptsLen Length of the fOpts field
|
||||
*
|
||||
* \retval [false: payload does not fit into the frame, true: payload fits into
|
||||
* the frame]
|
||||
/**
|
||||
*Function executed on Resend Frame timer event.
|
||||
*/
|
||||
bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen );
|
||||
void on_mac_state_check_timer_event(void);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC layer frame buffer initialization
|
||||
*
|
||||
* \param [in] macHdr MAC header field
|
||||
* \param [in] fCtrl MAC frame control field
|
||||
* \param [in] fPort MAC payload port
|
||||
* \param [in] fBuffer MAC data buffer to be sent
|
||||
* \param [in] fBufferSize MAC data buffer size
|
||||
* \retval status Status of the operation.
|
||||
/**
|
||||
* Function executed on duty cycle delayed Tx timer event
|
||||
*/
|
||||
lorawan_status_t PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ctrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize );
|
||||
void on_tx_delayed_timer_event(void);
|
||||
|
||||
/*
|
||||
* \brief Schedules the frame according to the duty cycle
|
||||
*
|
||||
* \retval Status of the operation
|
||||
/**
|
||||
* Function executed on first Rx window timer event
|
||||
*/
|
||||
lorawan_status_t ScheduleTx( void );
|
||||
void on_rx_window1_timer_event(void);
|
||||
|
||||
/*
|
||||
* \brief Calculates the back-off time for the band of a channel.
|
||||
*
|
||||
* \param [in] channel The last Tx channel index
|
||||
/**
|
||||
* Function executed on second Rx window timer event
|
||||
*/
|
||||
void CalculateBackOff( uint8_t channel );
|
||||
void on_rx_window2_timer_event(void);
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC layer prepared frame buffer transmission with channel specification
|
||||
*
|
||||
* \remark PrepareFrame must be called at least once before calling this
|
||||
* function.
|
||||
*
|
||||
* \param [in] channel Channel to transmit on
|
||||
* \retval status Status of the operation.
|
||||
/**
|
||||
* Function executed on AckTimeout timer event
|
||||
*/
|
||||
lorawan_status_t SendFrameOnChannel( uint8_t channel );
|
||||
void on_ack_timeout_timer_event(void);
|
||||
|
||||
/*!
|
||||
* \brief Resets MAC specific parameters to default
|
||||
*
|
||||
* \param [in] fPort The fPort
|
||||
*
|
||||
* \retval [false: fPort not allowed, true: fPort allowed]
|
||||
/**
|
||||
* Initializes and opens the reception window
|
||||
*/
|
||||
bool IsFPortAllowed( uint8_t fPort );
|
||||
void rx_window_setup(bool rx_continuous, uint32_t max_rx_window_time);
|
||||
|
||||
/**
|
||||
* Validates if the payload fits into the frame, taking the datarate
|
||||
* into account.
|
||||
*
|
||||
* Please Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0.2
|
||||
*/
|
||||
bool validate_payload_length(uint8_t length, int8_t datarate, uint8_t fopts_len);
|
||||
|
||||
/**
|
||||
* Prepares MAC frame on the behest of send() API.
|
||||
*/
|
||||
lorawan_status_t prepare_frame(loramac_mhdr_t *mac_hdr,
|
||||
loramac_frame_ctrl_t *fctrl, uint8_t fport,
|
||||
void *fbuffer, uint16_t fbuffer_size);
|
||||
|
||||
/**
|
||||
* Schedules a transmission on the behest of send() API.
|
||||
*/
|
||||
lorawan_status_t schedule_tx(void);
|
||||
|
||||
/**
|
||||
* Calculates the back-off time for the band of a channel.
|
||||
* Takes in the last used channel id as a parameter.
|
||||
*/
|
||||
void calculate_backOff(uint8_t channel_id);
|
||||
|
||||
/**
|
||||
* Hands over the MAC frame to PHY layer.
|
||||
*/
|
||||
lorawan_status_t send_frame_on_channel(uint8_t channel);
|
||||
|
||||
/**
|
||||
* Checks for Port validity.
|
||||
*/
|
||||
bool is_fPort_allowed(uint8_t fPort);
|
||||
|
||||
/**
|
||||
* Prototypes for ISR handlers
|
||||
|
@ -660,7 +647,7 @@ private:
|
|||
/**
|
||||
* Channel planning subsystem
|
||||
*/
|
||||
LoRaMacChannelPlan ch_plan;
|
||||
LoRaMacChannelPlan channel_plan;
|
||||
|
||||
/**
|
||||
* Timer subsystem handle
|
||||
|
@ -675,12 +662,12 @@ private:
|
|||
/**
|
||||
* Radio event callback handlers for MAC
|
||||
*/
|
||||
radio_events_t RadioEvents;
|
||||
radio_events_t radio_events;
|
||||
|
||||
/*!
|
||||
/**
|
||||
* LoRaMac upper layer event functions
|
||||
*/
|
||||
loramac_primitives_t *LoRaMacPrimitives;
|
||||
loramac_primitives_t *mac_primitives;
|
||||
|
||||
/**
|
||||
* EventQueue object storage
|
||||
|
@ -688,4 +675,4 @@ private:
|
|||
events::EventQueue *ev_queue;
|
||||
};
|
||||
|
||||
#endif // __LORAMAC_H__
|
||||
#endif // MBED_LORAWAN_MAC_H__
|
||||
|
|
|
@ -33,183 +33,167 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
#define tr_error(...) (void(0)) //dummies if feature common pal is not added
|
||||
#endif //defined(FEATURE_COMMON_PAL)
|
||||
|
||||
/*!
|
||||
/**
|
||||
* LoRaMAC max EIRP (dBm) table.
|
||||
*/
|
||||
static const uint8_t LoRaMacMaxEirpTable[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21, 24, 26, 27, 29, 30, 33, 36 };
|
||||
static const uint8_t max_eirp_table[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21, 24, 26, 27, 29, 30, 33, 36 };
|
||||
|
||||
|
||||
LoRaMacCommand::LoRaMacCommand(LoRaMac& lora_mac)
|
||||
: _lora_mac(lora_mac)
|
||||
{
|
||||
MacCommandsInNextTx = false;
|
||||
MacCommandsBufferIndex = 0;
|
||||
MacCommandsBufferToRepeatIndex = 0;
|
||||
mac_cmd_in_next_tx = false;
|
||||
mac_cmd_buf_idx = 0;
|
||||
mac_cmd_buf_idx_to_repeat = 0;
|
||||
|
||||
memset(MacCommandsBuffer, 0, sizeof(MacCommandsBuffer));
|
||||
memset(MacCommandsBufferToRepeat, 0, sizeof(MacCommandsBufferToRepeat));
|
||||
memset(mac_cmd_buffer, 0, sizeof(mac_cmd_buffer));
|
||||
memset(mac_cmd_buffer_to_repeat, 0, sizeof(mac_cmd_buffer_to_repeat));
|
||||
}
|
||||
|
||||
LoRaMacCommand::~LoRaMacCommand()
|
||||
{
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2)
|
||||
lorawan_status_t LoRaMacCommand::add_mac_command(uint8_t cmd, uint8_t p1,
|
||||
uint8_t p2)
|
||||
{
|
||||
lorawan_status_t status = LORAWAN_STATUS_BUSY;
|
||||
// The maximum buffer length must take MAC commands to re-send into account.
|
||||
const uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex;
|
||||
const uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH
|
||||
- mac_cmd_buf_idx_to_repeat;
|
||||
|
||||
switch( cmd )
|
||||
{
|
||||
switch (cmd) {
|
||||
case MOTE_MAC_LINK_CHECK_REQ:
|
||||
if( MacCommandsBufferIndex < bufLen )
|
||||
{
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// No payload for this command
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_LINK_ADR_ANS:
|
||||
if( MacCommandsBufferIndex < ( bufLen - 1 ) )
|
||||
{
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
|
||||
if (mac_cmd_buf_idx < (bufLen - 1)) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// Margin
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_DUTY_CYCLE_ANS:
|
||||
if( MacCommandsBufferIndex < bufLen )
|
||||
{
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// No payload for this answer
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_RX_PARAM_SETUP_ANS:
|
||||
if( MacCommandsBufferIndex < ( bufLen - 1 ) )
|
||||
{
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
|
||||
if (mac_cmd_buf_idx < (bufLen - 1)) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// Status: Datarate ACK, Channel ACK
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
// This is a sticky MAC command answer. Setup indication
|
||||
_lora_mac.SetMlmeScheduleUplinkIndication();
|
||||
_lora_mac.set_mlme_schedule_ul_indication();
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_DEV_STATUS_ANS:
|
||||
if( MacCommandsBufferIndex < ( bufLen - 2 ) )
|
||||
{
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
|
||||
if (mac_cmd_buf_idx < (bufLen - 2)) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// 1st byte Battery
|
||||
// 2nd byte Margin
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p2;
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_NEW_CHANNEL_ANS:
|
||||
if( MacCommandsBufferIndex < ( bufLen - 1 ) )
|
||||
{
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
|
||||
if (mac_cmd_buf_idx < (bufLen - 1)) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// Status: Datarate range OK, Channel frequency OK
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_RX_TIMING_SETUP_ANS:
|
||||
if( MacCommandsBufferIndex < bufLen )
|
||||
{
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// No payload for this answer
|
||||
// This is a sticky MAC command answer. Setup indication
|
||||
_lora_mac.SetMlmeScheduleUplinkIndication();
|
||||
_lora_mac.set_mlme_schedule_ul_indication();
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_TX_PARAM_SETUP_ANS:
|
||||
if( MacCommandsBufferIndex < bufLen )
|
||||
{
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// No payload for this answer
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
case MOTE_MAC_DL_CHANNEL_ANS:
|
||||
if( MacCommandsBufferIndex < bufLen )
|
||||
{
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
|
||||
if (mac_cmd_buf_idx < bufLen) {
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = cmd;
|
||||
// Status: Uplink frequency exists, Channel frequency OK
|
||||
MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
|
||||
mac_cmd_buffer[mac_cmd_buf_idx++] = p1;
|
||||
// This is a sticky MAC command answer. Setup indication
|
||||
_lora_mac.SetMlmeScheduleUplinkIndication();
|
||||
_lora_mac.set_mlme_schedule_ul_indication();
|
||||
status = LORAWAN_STATUS_OK;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
}
|
||||
if( status == LORAWAN_STATUS_OK )
|
||||
{
|
||||
MacCommandsInNextTx = true;
|
||||
if (status == LORAWAN_STATUS_OK) {
|
||||
mac_cmd_in_next_tx = true;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void LoRaMacCommand::ClearCommandBuffer()
|
||||
void LoRaMacCommand::clear_command_buffer()
|
||||
{
|
||||
MacCommandsBufferIndex = 0;
|
||||
mac_cmd_buf_idx = 0;
|
||||
}
|
||||
|
||||
uint8_t LoRaMacCommand::GetLength() const
|
||||
uint8_t LoRaMacCommand::get_mac_cmd_length() const
|
||||
{
|
||||
return MacCommandsBufferIndex;
|
||||
return mac_cmd_buf_idx;
|
||||
}
|
||||
|
||||
uint8_t *LoRaMacCommand::GetMacCommandsBuffer()
|
||||
uint8_t *LoRaMacCommand::get_mac_commands_buffer()
|
||||
{
|
||||
return MacCommandsBuffer;
|
||||
return mac_cmd_buffer;
|
||||
}
|
||||
|
||||
void LoRaMacCommand::ParseMacCommandsToRepeat()
|
||||
void LoRaMacCommand::parse_mac_commands_to_repeat()
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t cmdCount = 0;
|
||||
uint8_t cmd_cnt = 0;
|
||||
|
||||
for( i = 0; i < MacCommandsBufferIndex; i++ )
|
||||
{
|
||||
switch( MacCommandsBuffer[i] )
|
||||
{
|
||||
for (i = 0; i < mac_cmd_buf_idx; i++) {
|
||||
switch (mac_cmd_buffer[i]) {
|
||||
// STICKY
|
||||
case MOTE_MAC_DL_CHANNEL_ANS:
|
||||
case MOTE_MAC_RX_PARAM_SETUP_ANS:
|
||||
{ // 1 byte payload
|
||||
MacCommandsBufferToRepeat[cmdCount++] = MacCommandsBuffer[i++];
|
||||
MacCommandsBufferToRepeat[cmdCount++] = MacCommandsBuffer[i];
|
||||
case MOTE_MAC_RX_PARAM_SETUP_ANS: { // 1 byte payload
|
||||
mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i++];
|
||||
mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i];
|
||||
break;
|
||||
}
|
||||
case MOTE_MAC_RX_TIMING_SETUP_ANS:
|
||||
{ // 0 byte payload
|
||||
MacCommandsBufferToRepeat[cmdCount++] = MacCommandsBuffer[i];
|
||||
case MOTE_MAC_RX_TIMING_SETUP_ANS: { // 0 byte payload
|
||||
mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i];
|
||||
break;
|
||||
}
|
||||
// NON-STICKY
|
||||
case MOTE_MAC_DEV_STATUS_ANS:
|
||||
{ // 2 bytes payload
|
||||
// NON-STICKY
|
||||
case MOTE_MAC_DEV_STATUS_ANS: { // 2 bytes payload
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
case MOTE_MAC_LINK_ADR_ANS:
|
||||
case MOTE_MAC_NEW_CHANNEL_ANS:
|
||||
{ // 1 byte payload
|
||||
case MOTE_MAC_NEW_CHANNEL_ANS: { // 1 byte payload
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
case MOTE_MAC_TX_PARAM_SETUP_ANS:
|
||||
case MOTE_MAC_DUTY_CYCLE_ANS:
|
||||
case MOTE_MAC_LINK_CHECK_REQ:
|
||||
{ // 0 byte payload
|
||||
case MOTE_MAC_LINK_CHECK_REQ: { // 0 byte payload
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -217,213 +201,210 @@ void LoRaMacCommand::ParseMacCommandsToRepeat()
|
|||
}
|
||||
}
|
||||
|
||||
if( cmdCount > 0 ) {
|
||||
MacCommandsInNextTx = true;
|
||||
if (cmd_cnt > 0) {
|
||||
mac_cmd_in_next_tx = true;
|
||||
} else {
|
||||
MacCommandsInNextTx = false;
|
||||
mac_cmd_in_next_tx = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LoRaMacCommand::ClearRepeatBuffer()
|
||||
void LoRaMacCommand::clear_repeat_buffer()
|
||||
{
|
||||
MacCommandsBufferToRepeatIndex = 0;
|
||||
mac_cmd_buf_idx_to_repeat = 0;
|
||||
}
|
||||
|
||||
void LoRaMacCommand::CopyRepeatCommandsToBuffer()
|
||||
void LoRaMacCommand::copy_repeat_commands_to_buffer()
|
||||
{
|
||||
// Copy the MAC commands which must be re-send into the MAC command buffer
|
||||
memcpy(&MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex);
|
||||
MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex;
|
||||
memcpy(&mac_cmd_buffer[mac_cmd_buf_idx], mac_cmd_buffer_to_repeat, mac_cmd_buf_idx_to_repeat);
|
||||
mac_cmd_buf_idx += mac_cmd_buf_idx_to_repeat;
|
||||
}
|
||||
|
||||
uint8_t LoRaMacCommand::GetRepeatLength() const
|
||||
uint8_t LoRaMacCommand::get_repeat_commands_length() const
|
||||
{
|
||||
return MacCommandsBufferToRepeatIndex;
|
||||
return mac_cmd_buf_idx_to_repeat;
|
||||
}
|
||||
|
||||
void LoRaMacCommand::ClearMacCommandsInNextTx()
|
||||
void LoRaMacCommand::clear_mac_commands_in_next_tx()
|
||||
{
|
||||
MacCommandsInNextTx = false;
|
||||
mac_cmd_in_next_tx = false;
|
||||
}
|
||||
|
||||
bool LoRaMacCommand::IsMacCommandsInNextTx() const
|
||||
bool LoRaMacCommand::is_mac_command_in_next_tx() const
|
||||
{
|
||||
return MacCommandsInNextTx;
|
||||
return mac_cmd_in_next_tx;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex,
|
||||
uint8_t commandsSize, uint8_t snr,
|
||||
loramac_mlme_confirm_t& MlmeConfirm,
|
||||
lora_mac_system_params_t &LoRaMacParams,
|
||||
LoRaPHY &lora_phy)
|
||||
lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload,
|
||||
uint8_t mac_index,
|
||||
uint8_t commands_size,
|
||||
uint8_t snr,
|
||||
loramac_mlme_confirm_t& mlme_conf,
|
||||
lora_mac_system_params_t &mac_sys_params,
|
||||
LoRaPHY &lora_phy)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
lorawan_status_t ret_value = LORAWAN_STATUS_OK;
|
||||
|
||||
while( macIndex < commandsSize )
|
||||
{
|
||||
while (mac_index < commands_size) {
|
||||
// Decode Frame MAC commands
|
||||
switch( payload[macIndex++] )
|
||||
{
|
||||
switch (payload[mac_index++]) {
|
||||
case SRV_MAC_LINK_CHECK_ANS:
|
||||
MlmeConfirm.status = LORAMAC_EVENT_INFO_STATUS_OK;
|
||||
MlmeConfirm.demod_margin = payload[macIndex++];
|
||||
MlmeConfirm.nb_gateways = payload[macIndex++];
|
||||
mlme_conf.status = LORAMAC_EVENT_INFO_STATUS_OK;
|
||||
mlme_conf.demod_margin = payload[mac_index++];
|
||||
mlme_conf.nb_gateways = payload[mac_index++];
|
||||
break;
|
||||
case SRV_MAC_LINK_ADR_REQ:
|
||||
{
|
||||
adr_req_params_t linkAdrReq;
|
||||
int8_t linkAdrDatarate = DR_0;
|
||||
int8_t linkAdrTxPower = TX_POWER_0;
|
||||
uint8_t linkAdrNbRep = 0;
|
||||
uint8_t linkAdrNbBytesParsed = 0;
|
||||
case SRV_MAC_LINK_ADR_REQ: {
|
||||
adr_req_params_t linkAdrReq;
|
||||
int8_t linkAdrDatarate = DR_0;
|
||||
int8_t linkAdrTxPower = TX_POWER_0;
|
||||
uint8_t linkAdrNbRep = 0;
|
||||
uint8_t linkAdrNbBytesParsed = 0;
|
||||
|
||||
// Fill parameter structure
|
||||
linkAdrReq.payload = &payload[macIndex - 1];
|
||||
linkAdrReq.payload_size = commandsSize - ( macIndex - 1 );
|
||||
linkAdrReq.adr_enabled = LoRaMacParams.adr_on;
|
||||
linkAdrReq.ul_dwell_time = LoRaMacParams.uplink_dwell_time;
|
||||
linkAdrReq.current_datarate = LoRaMacParams.channel_data_rate;
|
||||
linkAdrReq.current_tx_power = LoRaMacParams.channel_tx_power;
|
||||
linkAdrReq.current_nb_rep = LoRaMacParams.retry_num;
|
||||
// Fill parameter structure
|
||||
linkAdrReq.payload = &payload[mac_index - 1];
|
||||
linkAdrReq.payload_size = commands_size - (mac_index - 1);
|
||||
linkAdrReq.adr_enabled = mac_sys_params.adr_on;
|
||||
linkAdrReq.ul_dwell_time = mac_sys_params.uplink_dwell_time;
|
||||
linkAdrReq.current_datarate = mac_sys_params.channel_data_rate;
|
||||
linkAdrReq.current_tx_power = mac_sys_params.channel_tx_power;
|
||||
linkAdrReq.current_nb_rep = mac_sys_params.retry_num;
|
||||
|
||||
// Process the ADR requests
|
||||
status = lora_phy.link_ADR_request(&linkAdrReq, &linkAdrDatarate,
|
||||
&linkAdrTxPower, &linkAdrNbRep,
|
||||
&linkAdrNbBytesParsed);
|
||||
// Process the ADR requests
|
||||
status = lora_phy.link_ADR_request(&linkAdrReq,
|
||||
&linkAdrDatarate,
|
||||
&linkAdrTxPower,
|
||||
&linkAdrNbRep,
|
||||
&linkAdrNbBytesParsed);
|
||||
|
||||
if( ( status & 0x07 ) == 0x07 )
|
||||
{
|
||||
LoRaMacParams.channel_data_rate = linkAdrDatarate;
|
||||
LoRaMacParams.channel_tx_power = linkAdrTxPower;
|
||||
LoRaMacParams.retry_num = linkAdrNbRep;
|
||||
}
|
||||
|
||||
// Add the answers to the buffer
|
||||
for( uint8_t i = 0; i < ( linkAdrNbBytesParsed / 5 ); i++ )
|
||||
{
|
||||
ret_value = AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 );
|
||||
}
|
||||
// Update MAC index
|
||||
macIndex += linkAdrNbBytesParsed - 1;
|
||||
if ((status & 0x07) == 0x07) {
|
||||
mac_sys_params.channel_data_rate = linkAdrDatarate;
|
||||
mac_sys_params.channel_tx_power = linkAdrTxPower;
|
||||
mac_sys_params.retry_num = linkAdrNbRep;
|
||||
}
|
||||
|
||||
// Add the answers to the buffer
|
||||
for (uint8_t i = 0; i < (linkAdrNbBytesParsed / 5); i++) {
|
||||
ret_value = add_mac_command(MOTE_MAC_LINK_ADR_ANS, status, 0);
|
||||
}
|
||||
// Update MAC index
|
||||
mac_index += linkAdrNbBytesParsed - 1;
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_DUTY_CYCLE_REQ:
|
||||
LoRaMacParams.max_duty_cycle = payload[macIndex++];
|
||||
LoRaMacParams.aggregated_duty_cycle = 1 << LoRaMacParams.max_duty_cycle;
|
||||
ret_value = AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 );
|
||||
mac_sys_params.max_duty_cycle = payload[mac_index++];
|
||||
mac_sys_params.aggregated_duty_cycle = 1 << mac_sys_params.max_duty_cycle;
|
||||
ret_value = add_mac_command(MOTE_MAC_DUTY_CYCLE_ANS, 0, 0);
|
||||
break;
|
||||
case SRV_MAC_RX_PARAM_SETUP_REQ:
|
||||
{
|
||||
rx_param_setup_req_t rxParamSetupReq;
|
||||
case SRV_MAC_RX_PARAM_SETUP_REQ: {
|
||||
rx_param_setup_req_t rxParamSetupReq;
|
||||
|
||||
rxParamSetupReq.dr_offset = ( payload[macIndex] >> 4 ) & 0x07;
|
||||
rxParamSetupReq.datarate = payload[macIndex] & 0x0F;
|
||||
macIndex++;
|
||||
rxParamSetupReq.dr_offset = (payload[mac_index] >> 4) & 0x07;
|
||||
rxParamSetupReq.datarate = payload[mac_index] & 0x0F;
|
||||
mac_index++;
|
||||
|
||||
rxParamSetupReq.frequency = ( uint32_t )payload[macIndex++];
|
||||
rxParamSetupReq.frequency |= ( uint32_t )payload[macIndex++] << 8;
|
||||
rxParamSetupReq.frequency |= ( uint32_t )payload[macIndex++] << 16;
|
||||
rxParamSetupReq.frequency *= 100;
|
||||
rxParamSetupReq.frequency = (uint32_t) payload[mac_index++];
|
||||
rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++]
|
||||
<< 8;
|
||||
rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++]
|
||||
<< 16;
|
||||
rxParamSetupReq.frequency *= 100;
|
||||
|
||||
// Perform request on region
|
||||
status = lora_phy.accept_rx_param_setup_req(&rxParamSetupReq);
|
||||
// Perform request on region
|
||||
status = lora_phy.accept_rx_param_setup_req(&rxParamSetupReq);
|
||||
|
||||
if( ( status & 0x07 ) == 0x07 )
|
||||
{
|
||||
LoRaMacParams.rx2_channel.datarate = rxParamSetupReq.datarate;
|
||||
LoRaMacParams.rx2_channel.frequency = rxParamSetupReq.frequency;
|
||||
LoRaMacParams.rx1_dr_offset = rxParamSetupReq.dr_offset;
|
||||
}
|
||||
ret_value = AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 );
|
||||
if ((status & 0x07) == 0x07) {
|
||||
mac_sys_params.rx2_channel.datarate =
|
||||
rxParamSetupReq.datarate;
|
||||
mac_sys_params.rx2_channel.frequency =
|
||||
rxParamSetupReq.frequency;
|
||||
mac_sys_params.rx1_dr_offset = rxParamSetupReq.dr_offset;
|
||||
}
|
||||
ret_value = add_mac_command(MOTE_MAC_RX_PARAM_SETUP_ANS, status,
|
||||
0);
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_DEV_STATUS_REQ:
|
||||
{
|
||||
uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
|
||||
// we don't have a mechanism at the moment to measure
|
||||
// battery levels
|
||||
ret_value = AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr );
|
||||
break;
|
||||
}
|
||||
case SRV_MAC_NEW_CHANNEL_REQ:
|
||||
{
|
||||
new_channel_req_params_t newChannelReq;
|
||||
channel_params_t chParam;
|
||||
|
||||
newChannelReq.channel_id = payload[macIndex++];
|
||||
newChannelReq.new_channel = &chParam;
|
||||
|
||||
chParam.frequency = ( uint32_t )payload[macIndex++];
|
||||
chParam.frequency |= ( uint32_t )payload[macIndex++] << 8;
|
||||
chParam.frequency |= ( uint32_t )payload[macIndex++] << 16;
|
||||
chParam.frequency *= 100;
|
||||
chParam.rx1_frequency = 0;
|
||||
chParam.dr_range.value = payload[macIndex++];
|
||||
|
||||
status = lora_phy.request_new_channel(&newChannelReq);
|
||||
|
||||
ret_value = AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 );
|
||||
}
|
||||
case SRV_MAC_DEV_STATUS_REQ: {
|
||||
uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
|
||||
// we don't have a mechanism at the moment to measure
|
||||
// battery levels
|
||||
ret_value = add_mac_command(MOTE_MAC_DEV_STATUS_ANS,
|
||||
batteryLevel, snr);
|
||||
break;
|
||||
case SRV_MAC_RX_TIMING_SETUP_REQ:
|
||||
{
|
||||
uint8_t delay = payload[macIndex++] & 0x0F;
|
||||
}
|
||||
case SRV_MAC_NEW_CHANNEL_REQ: {
|
||||
new_channel_req_params_t newChannelReq;
|
||||
channel_params_t chParam;
|
||||
|
||||
if( delay == 0 )
|
||||
{
|
||||
delay++;
|
||||
}
|
||||
LoRaMacParams.recv_delay1 = delay * 1000;
|
||||
LoRaMacParams.recv_delay2 = LoRaMacParams.recv_delay1 + 1000;
|
||||
ret_value = AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 );
|
||||
}
|
||||
newChannelReq.channel_id = payload[mac_index++];
|
||||
newChannelReq.new_channel = &chParam;
|
||||
|
||||
chParam.frequency = (uint32_t) payload[mac_index++];
|
||||
chParam.frequency |= (uint32_t) payload[mac_index++] << 8;
|
||||
chParam.frequency |= (uint32_t) payload[mac_index++] << 16;
|
||||
chParam.frequency *= 100;
|
||||
chParam.rx1_frequency = 0;
|
||||
chParam.dr_range.value = payload[mac_index++];
|
||||
|
||||
status = lora_phy.request_new_channel(&newChannelReq);
|
||||
|
||||
ret_value = add_mac_command(MOTE_MAC_NEW_CHANNEL_ANS, status, 0);
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_TX_PARAM_SETUP_REQ:
|
||||
{
|
||||
tx_param_setup_req_t txParamSetupReq;
|
||||
uint8_t eirpDwellTime = payload[macIndex++];
|
||||
case SRV_MAC_RX_TIMING_SETUP_REQ: {
|
||||
uint8_t delay = payload[mac_index++] & 0x0F;
|
||||
|
||||
txParamSetupReq.ul_dwell_time = 0;
|
||||
txParamSetupReq.dl_dwell_time = 0;
|
||||
|
||||
if( ( eirpDwellTime & 0x20 ) == 0x20 )
|
||||
{
|
||||
txParamSetupReq.dl_dwell_time = 1;
|
||||
}
|
||||
if( ( eirpDwellTime & 0x10 ) == 0x10 )
|
||||
{
|
||||
txParamSetupReq.ul_dwell_time = 1;
|
||||
}
|
||||
txParamSetupReq.max_eirp = eirpDwellTime & 0x0F;
|
||||
|
||||
// Check the status for correctness
|
||||
if(lora_phy.accept_tx_param_setup_req(&txParamSetupReq))
|
||||
{
|
||||
// Accept command
|
||||
LoRaMacParams.uplink_dwell_time = txParamSetupReq.ul_dwell_time;
|
||||
LoRaMacParams.downlink_dwell_time = txParamSetupReq.dl_dwell_time;
|
||||
LoRaMacParams.max_eirp = LoRaMacMaxEirpTable[txParamSetupReq.max_eirp];
|
||||
// Add command response
|
||||
ret_value = AddMacCommand( MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0 );
|
||||
}
|
||||
if (delay == 0) {
|
||||
delay++;
|
||||
}
|
||||
mac_sys_params.recv_delay1 = delay * 1000;
|
||||
mac_sys_params.recv_delay2 = mac_sys_params.recv_delay1 + 1000;
|
||||
ret_value = add_mac_command(MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0);
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_DL_CHANNEL_REQ:
|
||||
{
|
||||
dl_channel_req_params_t dlChannelReq;
|
||||
case SRV_MAC_TX_PARAM_SETUP_REQ: {
|
||||
tx_param_setup_req_t txParamSetupReq;
|
||||
uint8_t eirpDwellTime = payload[mac_index++];
|
||||
|
||||
dlChannelReq.channel_id = payload[macIndex++];
|
||||
dlChannelReq.rx1_frequency = ( uint32_t )payload[macIndex++];
|
||||
dlChannelReq.rx1_frequency |= ( uint32_t )payload[macIndex++] << 8;
|
||||
dlChannelReq.rx1_frequency |= ( uint32_t )payload[macIndex++] << 16;
|
||||
dlChannelReq.rx1_frequency *= 100;
|
||||
txParamSetupReq.ul_dwell_time = 0;
|
||||
txParamSetupReq.dl_dwell_time = 0;
|
||||
|
||||
status = lora_phy.dl_channel_request(&dlChannelReq);
|
||||
|
||||
ret_value = AddMacCommand( MOTE_MAC_DL_CHANNEL_ANS, status, 0 );
|
||||
if ((eirpDwellTime & 0x20) == 0x20) {
|
||||
txParamSetupReq.dl_dwell_time = 1;
|
||||
}
|
||||
if ((eirpDwellTime & 0x10) == 0x10) {
|
||||
txParamSetupReq.ul_dwell_time = 1;
|
||||
}
|
||||
txParamSetupReq.max_eirp = eirpDwellTime & 0x0F;
|
||||
|
||||
// Check the status for correctness
|
||||
if (lora_phy.accept_tx_param_setup_req(&txParamSetupReq)) {
|
||||
// Accept command
|
||||
mac_sys_params.uplink_dwell_time =
|
||||
txParamSetupReq.ul_dwell_time;
|
||||
mac_sys_params.downlink_dwell_time =
|
||||
txParamSetupReq.dl_dwell_time;
|
||||
mac_sys_params.max_eirp =
|
||||
max_eirp_table[txParamSetupReq.max_eirp];
|
||||
// Add command response
|
||||
ret_value = add_mac_command(MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SRV_MAC_DL_CHANNEL_REQ: {
|
||||
dl_channel_req_params_t dlChannelReq;
|
||||
|
||||
dlChannelReq.channel_id = payload[mac_index++];
|
||||
dlChannelReq.rx1_frequency = (uint32_t) payload[mac_index++];
|
||||
dlChannelReq.rx1_frequency |= (uint32_t) payload[mac_index++] << 8;
|
||||
dlChannelReq.rx1_frequency |= (uint32_t) payload[mac_index++] << 16;
|
||||
dlChannelReq.rx1_frequency *= 100;
|
||||
|
||||
status = lora_phy.dl_channel_request(&dlChannelReq);
|
||||
|
||||
ret_value = add_mac_command(MOTE_MAC_DL_CHANNEL_ANS, status, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Unknown command. ABORT MAC commands processing
|
||||
|
@ -433,10 +414,9 @@ lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t ma
|
|||
return ret_value;
|
||||
}
|
||||
|
||||
bool LoRaMacCommand::IsStickyMacCommandPending()
|
||||
bool LoRaMacCommand::is_sticky_mac_command_pending()
|
||||
{
|
||||
if( MacCommandsBufferToRepeatIndex > 0 )
|
||||
{
|
||||
if (mac_cmd_buf_idx_to_repeat > 0) {
|
||||
// Sticky MAC commands pending
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -51,129 +51,130 @@
|
|||
|
||||
class LoRaMac;
|
||||
|
||||
class LoRaMacCommand
|
||||
{
|
||||
class LoRaMacCommand {
|
||||
|
||||
public:
|
||||
LoRaMacCommand(LoRaMac &lora_mac);
|
||||
~LoRaMacCommand();
|
||||
|
||||
/*!
|
||||
* \brief Adds a new MAC command to be sent.
|
||||
/**
|
||||
* @brief Adds a new MAC command to be sent.
|
||||
*
|
||||
* \remark MAC layer internal function
|
||||
* @remark MAC layer internal function
|
||||
*
|
||||
* \param [in] cmd MAC command to be added
|
||||
* [MOTE_MAC_LINK_CHECK_REQ,
|
||||
* MOTE_MAC_LINK_ADR_ANS,
|
||||
* MOTE_MAC_DUTY_CYCLE_ANS,
|
||||
* MOTE_MAC_RX2_PARAM_SET_ANS,
|
||||
* MOTE_MAC_DEV_STATUS_ANS
|
||||
* MOTE_MAC_NEW_CHANNEL_ANS]
|
||||
* \param [in] p1 1st parameter ( optional depends on the command )
|
||||
* \param [in] p2 2nd parameter ( optional depends on the command )
|
||||
* @param [in] cmd MAC command to be added
|
||||
* [MOTE_MAC_LINK_CHECK_REQ,
|
||||
* MOTE_MAC_LINK_ADR_ANS,
|
||||
* MOTE_MAC_DUTY_CYCLE_ANS,
|
||||
* MOTE_MAC_RX2_PARAM_SET_ANS,
|
||||
* MOTE_MAC_DEV_STATUS_ANS
|
||||
* MOTE_MAC_NEW_CHANNEL_ANS]
|
||||
* @param [in] p1 1st parameter (optional depends on the command)
|
||||
* @param [in] p2 2nd parameter (optional depends on the command)
|
||||
*
|
||||
* \retval status Function status [0: OK, 1: Unknown command, 2: Buffer full]
|
||||
* @return status Function status [0: OK, 1: Unknown command, 2: Buffer full]
|
||||
*/
|
||||
lorawan_status_t AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2);
|
||||
lorawan_status_t add_mac_command(uint8_t cmd, uint8_t p1, uint8_t p2);
|
||||
|
||||
/*!
|
||||
* \brief Clear MAC command buffer.
|
||||
/**
|
||||
* @brief Clear MAC command buffer.
|
||||
*/
|
||||
void ClearCommandBuffer();
|
||||
void clear_command_buffer(void);
|
||||
|
||||
/*!
|
||||
* \brief Get the length of MAC commands
|
||||
/**
|
||||
* @brief Get the length of MAC commands
|
||||
*
|
||||
* \retval status Length of used MAC buffer (bytes)
|
||||
* @return status Length of used MAC buffer (bytes)
|
||||
*/
|
||||
uint8_t GetLength() const;
|
||||
uint8_t get_mac_cmd_length() const;
|
||||
|
||||
/*!
|
||||
* \brief Get MAC command buffer
|
||||
/**
|
||||
* @brief Get MAC command buffer
|
||||
*
|
||||
* \retval Pointer to MAC command buffer
|
||||
* @return Pointer to MAC command buffer
|
||||
*/
|
||||
uint8_t *GetMacCommandsBuffer();
|
||||
uint8_t *get_mac_commands_buffer();
|
||||
|
||||
/*!
|
||||
* \brief Parses the MAC commands which must be resent.
|
||||
/**
|
||||
* @brief Parses the MAC commands which must be resent.
|
||||
*/
|
||||
void ParseMacCommandsToRepeat();
|
||||
void parse_mac_commands_to_repeat();
|
||||
|
||||
/*!
|
||||
* \brief Clear MAC command repeat buffer.
|
||||
/**
|
||||
* @brief Clear MAC command repeat buffer.
|
||||
*/
|
||||
void ClearRepeatBuffer();
|
||||
void clear_repeat_buffer();
|
||||
|
||||
/*!
|
||||
* \brief Copy MAC commands from repeat buffer to actual MAC command buffer.
|
||||
/**
|
||||
* @brief Copy MAC commands from repeat buffer to actual MAC command buffer.
|
||||
*/
|
||||
void CopyRepeatCommandsToBuffer();
|
||||
void copy_repeat_commands_to_buffer();
|
||||
|
||||
/*!
|
||||
* \brief Get the length of MAC commands in repeat buffer
|
||||
/**
|
||||
* @brief Get the length of MAC commands in repeat buffer
|
||||
*
|
||||
* \retval status Length of used MAC Repeat buffer (bytes)
|
||||
* @return status Length of used MAC Repeat buffer (bytes)
|
||||
*/
|
||||
uint8_t GetRepeatLength() const;
|
||||
uint8_t get_repeat_commands_length() const;
|
||||
|
||||
/*!
|
||||
* \brief Clear MAC commands in next TX.
|
||||
/**
|
||||
* @brief Clear MAC commands in next TX.
|
||||
*/
|
||||
void ClearMacCommandsInNextTx();
|
||||
void clear_mac_commands_in_next_tx();
|
||||
|
||||
/*!
|
||||
* \brief Check if MAC command buffer has commands to be sent in next TX
|
||||
/**
|
||||
* @brief Check if MAC command buffer has commands to be sent in next TX
|
||||
*
|
||||
* \retval status True: buffer has MAC commands to be sent, false: no commands in buffer]
|
||||
* @return status True: buffer has MAC commands to be sent, false: no commands in buffer]
|
||||
*/
|
||||
bool IsMacCommandsInNextTx() const;
|
||||
bool is_mac_command_in_next_tx() const;
|
||||
|
||||
/*!
|
||||
* \brief Decodes MAC commands in the fOpts field and in the payload
|
||||
|
||||
* \retval status Function status. LORAWAN_STATUS_OK if command successful.
|
||||
*/
|
||||
lorawan_status_t ProcessMacCommands(uint8_t *payload, uint8_t macIndex,
|
||||
uint8_t commandsSize, uint8_t snr,
|
||||
loramac_mlme_confirm_t& MlmeConfirm,
|
||||
lora_mac_system_params_t& LoRaMacParams,
|
||||
LoRaPHY& lora_phy);
|
||||
|
||||
/*!
|
||||
* \brief Verifies if sticky MAC commands are pending.
|
||||
/**
|
||||
* @brief Decodes MAC commands in the fOpts field and in the payload
|
||||
*
|
||||
* \retval [true: sticky MAC commands pending, false: No MAC commands pending]
|
||||
* @return status Function status. LORAWAN_STATUS_OK if command successful.
|
||||
*/
|
||||
bool IsStickyMacCommandPending();
|
||||
lorawan_status_t process_mac_commands(uint8_t *payload, uint8_t mac_index,
|
||||
uint8_t commands_size, uint8_t snr,
|
||||
loramac_mlme_confirm_t& mlme_conf,
|
||||
lora_mac_system_params_t& mac_params,
|
||||
LoRaPHY& lora_phy);
|
||||
|
||||
/**
|
||||
* @brief Verifies if sticky MAC commands are pending.
|
||||
*
|
||||
* @return [true: sticky MAC commands pending, false: No MAC commands pending]
|
||||
*/
|
||||
bool is_sticky_mac_command_pending();
|
||||
|
||||
private:
|
||||
LoRaMac& _lora_mac;
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Indicates if the MAC layer wants to send MAC commands
|
||||
*/
|
||||
bool MacCommandsInNextTx;
|
||||
bool mac_cmd_in_next_tx;
|
||||
|
||||
/*!
|
||||
* Contains the current MacCommandsBuffer index
|
||||
/**
|
||||
* Contains the current Mac command buffer index in 'mac_cmd_buffer'
|
||||
*/
|
||||
uint8_t MacCommandsBufferIndex;
|
||||
uint8_t mac_cmd_buf_idx;
|
||||
|
||||
/*!
|
||||
* Contains the current MacCommandsBuffer index for MAC commands to repeat
|
||||
/**
|
||||
* Contains the current Mac command buffer index for MAC commands to repeat in
|
||||
* 'mac_cmd_buffer_to_repeat'
|
||||
*/
|
||||
uint8_t MacCommandsBufferToRepeatIndex;
|
||||
uint8_t mac_cmd_buf_idx_to_repeat;
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Buffer containing the MAC layer commands
|
||||
*/
|
||||
uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH];
|
||||
uint8_t mac_cmd_buffer[LORA_MAC_COMMAND_MAX_LENGTH];
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Buffer containing the MAC layer commands which must be repeated
|
||||
*/
|
||||
uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH];
|
||||
uint8_t mac_cmd_buffer_to_repeat[LORA_MAC_COMMAND_MAX_LENGTH];
|
||||
};
|
||||
|
||||
#endif //__LORAMACCOMMAND_H__
|
||||
|
|
|
@ -41,251 +41,253 @@
|
|||
/**
|
||||
* MIC field computation initial data
|
||||
*/
|
||||
static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t mic_block_b0[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/**
|
||||
* Contains the computed MIC field.
|
||||
*
|
||||
* \remark Only the 4 first bytes are used
|
||||
*/
|
||||
static uint8_t Mic[16];
|
||||
static uint8_t computed_mic[16];
|
||||
|
||||
/**
|
||||
* Encryption aBlock and sBlock
|
||||
*/
|
||||
static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static uint8_t a_block[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static uint8_t s_block[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/**
|
||||
* AES computation context variable
|
||||
*/
|
||||
static mbedtls_aes_context AesContext;
|
||||
static mbedtls_aes_context aes_ctx;
|
||||
|
||||
/**
|
||||
* CMAC computation context variable
|
||||
*/
|
||||
static mbedtls_cipher_context_t AesCmacCtx[1];
|
||||
static mbedtls_cipher_context_t aes_cmac_ctx[1];
|
||||
|
||||
#define AES_CMAC_KEY_LENGTH 16
|
||||
|
||||
/**
|
||||
* \brief Computes the LoRaMAC frame MIC field
|
||||
*
|
||||
* \param [in] buffer Data buffer
|
||||
* \param [in] size Data buffer size
|
||||
* \param [in] key AES key to be used
|
||||
* \param [in] address Frame address
|
||||
* \param [in] dir Frame direction [0: uplink, 1: downlink]
|
||||
* \param [in] sequenceCounter Frame sequence counter
|
||||
* \param [out] mic Computed MIC field
|
||||
*/
|
||||
int LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic )
|
||||
int compute_mic(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint32_t *mic)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
|
||||
MicBlockB0[5] = dir;
|
||||
mic_block_b0[5] = dir;
|
||||
|
||||
MicBlockB0[6] = ( address ) & 0xFF;
|
||||
MicBlockB0[7] = ( address >> 8 ) & 0xFF;
|
||||
MicBlockB0[8] = ( address >> 16 ) & 0xFF;
|
||||
MicBlockB0[9] = ( address >> 24 ) & 0xFF;
|
||||
mic_block_b0[6] = (address) & 0xFF;
|
||||
mic_block_b0[7] = (address >> 8) & 0xFF;
|
||||
mic_block_b0[8] = (address >> 16) & 0xFF;
|
||||
mic_block_b0[9] = (address >> 24) & 0xFF;
|
||||
|
||||
MicBlockB0[10] = ( sequenceCounter ) & 0xFF;
|
||||
MicBlockB0[11] = ( sequenceCounter >> 8 ) & 0xFF;
|
||||
MicBlockB0[12] = ( sequenceCounter >> 16 ) & 0xFF;
|
||||
MicBlockB0[13] = ( sequenceCounter >> 24 ) & 0xFF;
|
||||
mic_block_b0[10] = (seq_counter) & 0xFF;
|
||||
mic_block_b0[11] = (seq_counter >> 8) & 0xFF;
|
||||
mic_block_b0[12] = (seq_counter >> 16) & 0xFF;
|
||||
mic_block_b0[13] = (seq_counter >> 24) & 0xFF;
|
||||
|
||||
MicBlockB0[15] = size & 0xFF;
|
||||
mic_block_b0[15] = size & 0xFF;
|
||||
|
||||
mbedtls_cipher_init(aes_cmac_ctx);
|
||||
|
||||
mbedtls_cipher_init(AesCmacCtx);
|
||||
const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
|
||||
|
||||
if (NULL != cipher_info) {
|
||||
ret = mbedtls_cipher_setup(AesCmacCtx, cipher_info);
|
||||
ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_starts(AesCmacCtx, key, AES_CMAC_KEY_LENGTH*8);
|
||||
ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key,
|
||||
AES_CMAC_KEY_LENGTH * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_update(AesCmacCtx, MicBlockB0, LORAMAC_MIC_BLOCK_B0_SIZE);
|
||||
ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, mic_block_b0,
|
||||
LORAMAC_MIC_BLOCK_B0_SIZE);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_update(AesCmacCtx, buffer, size & 0xFF);
|
||||
ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_finish(AesCmacCtx, Mic);
|
||||
ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
*mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
|
||||
*mic = (uint32_t) ((uint32_t) computed_mic[3] << 24
|
||||
| (uint32_t) computed_mic[2] << 16
|
||||
| (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]);
|
||||
} else {
|
||||
ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_cipher_free( AesCmacCtx );
|
||||
exit: mbedtls_cipher_free(aes_cmac_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer )
|
||||
int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *enc_buffer)
|
||||
{
|
||||
uint16_t i;
|
||||
uint8_t bufferIndex = 0;
|
||||
uint16_t ctr = 1;
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_aes_init(&AesContext);
|
||||
ret = mbedtls_aes_setkey_enc(&AesContext, key, 16*8);
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
aBlock[5] = dir;
|
||||
a_block[5] = dir;
|
||||
|
||||
aBlock[6] = ( address ) & 0xFF;
|
||||
aBlock[7] = ( address >> 8 ) & 0xFF;
|
||||
aBlock[8] = ( address >> 16 ) & 0xFF;
|
||||
aBlock[9] = ( address >> 24 ) & 0xFF;
|
||||
a_block[6] = (address) & 0xFF;
|
||||
a_block[7] = (address >> 8) & 0xFF;
|
||||
a_block[8] = (address >> 16) & 0xFF;
|
||||
a_block[9] = (address >> 24) & 0xFF;
|
||||
|
||||
aBlock[10] = ( sequenceCounter ) & 0xFF;
|
||||
aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF;
|
||||
aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF;
|
||||
aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF;
|
||||
a_block[10] = (seq_counter) & 0xFF;
|
||||
a_block[11] = (seq_counter >> 8) & 0xFF;
|
||||
a_block[12] = (seq_counter >> 16) & 0xFF;
|
||||
a_block[13] = (seq_counter >> 24) & 0xFF;
|
||||
|
||||
while( size >= 16 )
|
||||
{
|
||||
aBlock[15] = ( ( ctr ) & 0xFF );
|
||||
while (size >= 16) {
|
||||
a_block[15] = ((ctr) & 0xFF);
|
||||
ctr++;
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, aBlock, sBlock);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block,
|
||||
s_block);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
|
||||
for (i = 0; i < 16; i++) {
|
||||
enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i];
|
||||
}
|
||||
size -= 16;
|
||||
bufferIndex += 16;
|
||||
}
|
||||
|
||||
if( size > 0 )
|
||||
{
|
||||
aBlock[15] = ( ( ctr ) & 0xFF );
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, aBlock, sBlock);
|
||||
if (size > 0) {
|
||||
a_block[15] = ((ctr) & 0xFF);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block,
|
||||
s_block);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
for( i = 0; i < size; i++ )
|
||||
{
|
||||
encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
|
||||
for (i = 0; i < size; i++) {
|
||||
enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i];
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_aes_free(&AesContext);
|
||||
exit: mbedtls_aes_free(&aes_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer )
|
||||
int decrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *dec_buffer)
|
||||
{
|
||||
return LoRaMacPayloadEncrypt( buffer, size, key, address, dir, sequenceCounter, decBuffer );
|
||||
return encrypt_payload(buffer, size, key, address, dir, seq_counter,
|
||||
dec_buffer);
|
||||
}
|
||||
|
||||
int LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic )
|
||||
int compute_join_frame_mic(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t *mic)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_cipher_init(AesCmacCtx);
|
||||
mbedtls_cipher_init(aes_cmac_ctx);
|
||||
const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
|
||||
|
||||
if (NULL != cipher_info) {
|
||||
ret = mbedtls_cipher_setup(AesCmacCtx, cipher_info);
|
||||
ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_starts(AesCmacCtx, key, AES_CMAC_KEY_LENGTH*8);
|
||||
ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key,
|
||||
AES_CMAC_KEY_LENGTH * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_update(AesCmacCtx, buffer, size & 0xFF);
|
||||
ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_finish(AesCmacCtx, Mic);
|
||||
ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
*mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
|
||||
*mic = (uint32_t) ((uint32_t) computed_mic[3] << 24
|
||||
| (uint32_t) computed_mic[2] << 16
|
||||
| (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]);
|
||||
} else {
|
||||
ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_cipher_free(AesCmacCtx);
|
||||
exit: mbedtls_cipher_free(aes_cmac_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer )
|
||||
int decrypt_join_frame(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint8_t *dec_buffer)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_aes_init(&AesContext);
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
ret = mbedtls_aes_setkey_enc(&AesContext, key, 16*8);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, buffer, decBuffer);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer,
|
||||
dec_buffer);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
// Check if optional CFList is included
|
||||
if( size >= 16 )
|
||||
{
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, buffer + 16, decBuffer + 16);
|
||||
if (size >= 16) {
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer + 16,
|
||||
dec_buffer + 16);
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_aes_free(&AesContext);
|
||||
exit: mbedtls_aes_free(&aes_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey )
|
||||
int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce,
|
||||
uint16_t dev_nonce, uint8_t *nwk_skey,
|
||||
uint8_t *app_skey)
|
||||
{
|
||||
uint8_t nonce[16];
|
||||
uint8_t *pDevNonce = ( uint8_t * )&devNonce;
|
||||
uint8_t *p_dev_nonce = (uint8_t *) &dev_nonce;
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_aes_init(&AesContext);
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
ret = mbedtls_aes_setkey_enc(&AesContext, key, 16*8);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
memset( nonce, 0, sizeof( nonce ) );
|
||||
memset(nonce, 0, sizeof(nonce));
|
||||
nonce[0] = 0x01;
|
||||
memcpy( nonce + 1, appNonce, 6 );
|
||||
memcpy( nonce + 7, pDevNonce, 2 );
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, nonce, nwkSKey);
|
||||
memcpy(nonce + 1, app_nonce, 6);
|
||||
memcpy(nonce + 7, p_dev_nonce, 2);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, nwk_skey);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
memset( nonce, 0, sizeof( nonce ) );
|
||||
memset(nonce, 0, sizeof(nonce));
|
||||
nonce[0] = 0x02;
|
||||
memcpy( nonce + 1, appNonce, 6 );
|
||||
memcpy( nonce + 7, pDevNonce, 2 );
|
||||
ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, nonce, appSKey);
|
||||
memcpy(nonce + 1, app_nonce, 6);
|
||||
memcpy(nonce + 7, p_dev_nonce, 2);
|
||||
ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, app_skey);
|
||||
|
||||
exit:
|
||||
mbedtls_aes_free(&AesContext);
|
||||
exit: mbedtls_aes_free(&aes_ctx);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
|
@ -294,8 +296,8 @@ exit:
|
|||
// user knows what is wrong and in addition to that these ensure that
|
||||
// Mbed-OS compiles properly under normal conditions where LoRaWAN in conjunction
|
||||
// with mbedTLS is not being used.
|
||||
int LoRaMacComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t dir, uint32_t, uint32_t * )
|
||||
int compute_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t dir, uint32_t, uint32_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
@ -303,8 +305,8 @@ int LoRaMacComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
|||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int LoRaMacPayloadEncrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t * )
|
||||
int encrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
@ -312,15 +314,8 @@ int LoRaMacPayloadEncrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t
|
|||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int LoRaMacPayloadDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t * )
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
// Never actually reaches here
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
int LoRaMacJoinComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t * )
|
||||
int decrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
@ -328,7 +323,7 @@ int LoRaMacJoinComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t
|
|||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int LoRaMacJoinDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint8_t * )
|
||||
int compute_join_frame_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
@ -336,7 +331,16 @@ int LoRaMacJoinDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint8_t * )
|
|||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int LoRaMacJoinComputeSKeys( const uint8_t *, const uint8_t *, uint16_t , uint8_t *, uint8_t * )
|
||||
int decrypt_join_frame(const uint8_t *, uint16_t , const uint8_t *, uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
// Never actually reaches here
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int compute_skeys_for_join_frame(const uint8_t *, const uint8_t *, uint16_t ,
|
||||
uint8_t *, uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
|
|
@ -29,84 +29,94 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
/**
|
||||
* Computes the LoRaMAC frame MIC field
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [in] address - Frame address
|
||||
* \param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* \param [in] sequenceCounter - Frame sequence counter
|
||||
* \param [out] mic - Computed MIC field
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] mic - Computed MIC field
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic );
|
||||
int compute_mic(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint32_t *mic);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC payload encryption
|
||||
* Performs payload encryption
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [in] address - Frame address
|
||||
* \param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* \param [in] sequenceCounter - Frame sequence counter
|
||||
* \param [out] encBuffer - Encrypted buffer
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] enc_buffer - Encrypted buffer
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer );
|
||||
int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *enc_buffer);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC payload decryption
|
||||
* Performs payload decryption
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [in] address - Frame address
|
||||
* \param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* \param [in] sequenceCounter - Frame sequence counter
|
||||
* \param [out] decBuffer - Decrypted buffer
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] dec_buffer - Decrypted buffer
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer );
|
||||
int decrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *dec_buffer);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC Join Request frame MIC field
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [out] mic - Computed MIC field
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [out] mic - Computed MIC field
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*
|
||||
*/
|
||||
int LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic );
|
||||
int compute_join_frame_mic(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t *mic);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC join frame decryption
|
||||
*
|
||||
* \param [in] buffer - Data buffer
|
||||
* \param [in] size - Data buffer size
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [out] decBuffer - Decrypted buffer
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [out] dec_buffer - Decrypted buffer
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer );
|
||||
int decrypt_join_frame(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint8_t *dec_buffer);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC join frame decryption
|
||||
*
|
||||
* \param [in] key - AES key to be used
|
||||
* \param [in] appNonce - Application nonce
|
||||
* \param [in] devNonce - Device nonce
|
||||
* \param [out] nwkSKey - Network session key
|
||||
* \param [out] appSKey - Application session key
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] app_nonce - Application nonce
|
||||
* @param [in] dev_nonce - Device nonce
|
||||
* @param [out] nwk_skey - Network session key
|
||||
* @param [out] app_skey - Application session key
|
||||
*
|
||||
* \return 0 if successful, or a cipher specific error code
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey );
|
||||
int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce,
|
||||
uint16_t dev_nonce, uint8_t *nwk_skey,
|
||||
uint8_t *app_skey );
|
||||
|
||||
#endif // MBED_LORAWAN_MAC_LORAMAC_CRYPTO_H__
|
||||
|
|
|
@ -52,15 +52,15 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest,
|
|||
get_phy_params_t get_phy;
|
||||
phy_param_t phyParam;
|
||||
lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
loramac_mhdr_t macHdr;
|
||||
loramac_mhdr_t machdr;
|
||||
verification_params_t verify;
|
||||
uint8_t fPort = 0;
|
||||
void *fBuffer;
|
||||
uint16_t fBufferSize;
|
||||
uint8_t fport = 0;
|
||||
void *fbuffer;
|
||||
uint16_t fbuffer_size;
|
||||
int8_t datarate = DR_0;
|
||||
bool readyToSend = false;
|
||||
bool ready_to_send = false;
|
||||
|
||||
macHdr.value = 0;
|
||||
machdr.value = 0;
|
||||
|
||||
// Before performing any MCPS request, clear the confirmation structure
|
||||
memset((uint8_t*) &confirmation, 0, sizeof(confirmation));
|
||||
|
@ -72,34 +72,34 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest,
|
|||
|
||||
switch (mcpsRequest->type) {
|
||||
case MCPS_UNCONFIRMED: {
|
||||
readyToSend = true;
|
||||
ready_to_send = true;
|
||||
params->max_ack_timeout_retries = 1;
|
||||
|
||||
macHdr.bits.mtype = FRAME_TYPE_DATA_UNCONFIRMED_UP;
|
||||
fPort = mcpsRequest->req.unconfirmed.fport;
|
||||
fBuffer = mcpsRequest->f_buffer;
|
||||
fBufferSize = mcpsRequest->f_buffer_size;
|
||||
machdr.bits.mtype = FRAME_TYPE_DATA_UNCONFIRMED_UP;
|
||||
fport = mcpsRequest->req.unconfirmed.fport;
|
||||
fbuffer = mcpsRequest->f_buffer;
|
||||
fbuffer_size = mcpsRequest->f_buffer_size;
|
||||
datarate = mcpsRequest->req.unconfirmed.data_rate;
|
||||
break;
|
||||
}
|
||||
case MCPS_CONFIRMED: {
|
||||
readyToSend = true;
|
||||
ready_to_send = true;
|
||||
params->max_ack_timeout_retries = mcpsRequest->req.confirmed.nb_trials;
|
||||
|
||||
macHdr.bits.mtype = FRAME_TYPE_DATA_CONFIRMED_UP;
|
||||
fPort = mcpsRequest->req.confirmed.fport;
|
||||
fBuffer = mcpsRequest->f_buffer;
|
||||
fBufferSize = mcpsRequest->f_buffer_size;
|
||||
machdr.bits.mtype = FRAME_TYPE_DATA_CONFIRMED_UP;
|
||||
fport = mcpsRequest->req.confirmed.fport;
|
||||
fbuffer = mcpsRequest->f_buffer;
|
||||
fbuffer_size = mcpsRequest->f_buffer_size;
|
||||
datarate = mcpsRequest->req.confirmed.data_rate;
|
||||
break;
|
||||
}
|
||||
case MCPS_PROPRIETARY: {
|
||||
readyToSend = true;
|
||||
ready_to_send = true;
|
||||
params->max_ack_timeout_retries = 1;
|
||||
|
||||
macHdr.bits.mtype = FRAME_TYPE_PROPRIETARY;
|
||||
fBuffer = mcpsRequest->f_buffer;
|
||||
fBufferSize = mcpsRequest->f_buffer_size;
|
||||
machdr.bits.mtype = FRAME_TYPE_PROPRIETARY;
|
||||
fbuffer = mcpsRequest->f_buffer;
|
||||
fbuffer_size = mcpsRequest->f_buffer_size;
|
||||
datarate = mcpsRequest->req.proprietary.data_rate;
|
||||
break;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest,
|
|||
// Some regions have limitations for the minimum datarate.
|
||||
datarate = MAX(datarate, (int8_t)phyParam.value);
|
||||
|
||||
if (readyToSend == true) {
|
||||
if (ready_to_send == true) {
|
||||
if (params->sys_params.adr_on == false) {
|
||||
verify.datarate = datarate;
|
||||
|
||||
|
@ -133,7 +133,7 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest,
|
|||
}
|
||||
}
|
||||
|
||||
status = _lora_mac->Send(&macHdr, fPort, fBuffer, fBufferSize);
|
||||
status = _lora_mac->send(&machdr, fport, fbuffer, fbuffer_size);
|
||||
if (status == LORAWAN_STATUS_OK) {
|
||||
confirmation.req_type = mcpsRequest->type;
|
||||
params->flags.bits.mcps_req = 1;
|
||||
|
|
|
@ -75,7 +75,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet,
|
|||
params->sys_params.min_rx_symb,
|
||||
params->sys_params.max_sys_rx_error,
|
||||
¶ms->rx_window2_config);
|
||||
_lora_mac->OpenContinuousRx2Window();
|
||||
_lora_mac->open_continuous_rx2_window();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet,
|
|||
params->sys_params.max_sys_rx_error,
|
||||
¶ms->rx_window2_config);
|
||||
|
||||
_lora_mac->OpenContinuousRx2Window();
|
||||
_lora_mac->open_continuous_rx2_window();
|
||||
}
|
||||
} else {
|
||||
status = LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
|
@ -272,7 +272,7 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
|
|||
{
|
||||
lorawan_status_t status = LORAWAN_STATUS_OK;
|
||||
get_phy_params_t get_phy;
|
||||
phy_param_t phyParam;
|
||||
phy_param_t phy_param;
|
||||
rx2_channel_params rx2_channel;
|
||||
|
||||
if( mibGet == NULL )
|
||||
|
@ -330,9 +330,9 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
|
|||
case MIB_CHANNELS:
|
||||
{
|
||||
get_phy.attribute = PHY_CHANNELS;
|
||||
phyParam = _lora_phy->get_phy_params( &get_phy );
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
|
||||
mibGet->param.channel_list = phyParam.channel_params;
|
||||
mibGet->param.channel_list = phy_param.channel_params;
|
||||
break;
|
||||
}
|
||||
case MIB_RX2_CHANNEL:
|
||||
|
@ -343,12 +343,12 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
|
|||
case MIB_RX2_DEFAULT_CHANNEL:
|
||||
{
|
||||
get_phy.attribute = PHY_DEF_RX2_DR;
|
||||
phyParam = _lora_phy->get_phy_params( &get_phy );
|
||||
rx2_channel.datarate = phyParam.value;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
rx2_channel.datarate = phy_param.value;
|
||||
|
||||
get_phy.attribute = PHY_DEF_RX2_FREQUENCY;
|
||||
phyParam = _lora_phy->get_phy_params( &get_phy );
|
||||
rx2_channel.frequency = phyParam.value;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
rx2_channel.frequency = phy_param.value;
|
||||
|
||||
mibGet->param.rx2_channel = rx2_channel;
|
||||
break;
|
||||
|
@ -356,17 +356,17 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
|
|||
case MIB_CHANNELS_DEFAULT_MASK:
|
||||
{
|
||||
get_phy.attribute = PHY_CHANNELS_DEFAULT_MASK;
|
||||
phyParam = _lora_phy->get_phy_params( &get_phy );
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
|
||||
mibGet->param.default_channel_mask = phyParam.channel_mask;
|
||||
mibGet->param.default_channel_mask = phy_param.channel_mask;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_MASK:
|
||||
{
|
||||
get_phy.attribute = PHY_CHANNELS_MASK;
|
||||
phyParam = _lora_phy->get_phy_params( &get_phy );
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
|
||||
mibGet->param.channel_mask = phyParam.channel_mask;
|
||||
mibGet->param.channel_mask = phy_param.channel_mask;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_NB_REP:
|
||||
|
@ -402,8 +402,8 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
|
|||
case MIB_CHANNELS_DEFAULT_DATARATE:
|
||||
{
|
||||
get_phy.attribute = PHY_DEF_TX_DR;
|
||||
phyParam = _lora_phy->get_phy_params( &get_phy );
|
||||
mibGet->param.default_channel_data_rate = phyParam.value;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
mibGet->param.default_channel_data_rate = phy_param.value;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_DATARATE:
|
||||
|
@ -414,8 +414,8 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet,
|
|||
case MIB_CHANNELS_DEFAULT_TX_POWER:
|
||||
{
|
||||
get_phy.attribute = PHY_DEF_TX_POWER;
|
||||
phyParam = _lora_phy->get_phy_params( &get_phy );
|
||||
mibGet->param.default_channel_tx_pwr = phyParam.value;
|
||||
phy_param = _lora_phy->get_phy_params( &get_phy );
|
||||
mibGet->param.default_channel_tx_pwr = phy_param.value;
|
||||
break;
|
||||
}
|
||||
case MIB_CHANNELS_TX_POWER:
|
||||
|
|
|
@ -43,17 +43,17 @@ void LoRaMacMlme::activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy,
|
|||
_mac_cmd = cmd;
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *mlmeRequest,
|
||||
lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *request,
|
||||
loramac_protocol_params *params)
|
||||
{
|
||||
if (mlmeRequest && params && _lora_mac && _lora_phy && _mac_cmd) {
|
||||
if (request && params && _lora_mac && _lora_phy && _mac_cmd) {
|
||||
|
||||
lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN;
|
||||
loramac_mhdr_t macHdr;
|
||||
loramac_mhdr_t machdr;
|
||||
|
||||
verification_params_t verify;
|
||||
get_phy_params_t get_phy;
|
||||
phy_param_t phyParam;
|
||||
phy_param_t phy_param;
|
||||
|
||||
|
||||
if (params->mac_state != LORAMAC_IDLE) {
|
||||
|
@ -66,73 +66,73 @@ lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *mlmeRequest,
|
|||
|
||||
confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
|
||||
switch (mlmeRequest->type) {
|
||||
switch (request->type) {
|
||||
case MLME_JOIN: {
|
||||
if ((params->mac_state & LORAMAC_TX_DELAYED)
|
||||
== LORAMAC_TX_DELAYED) {
|
||||
return LORAWAN_STATUS_BUSY;
|
||||
}
|
||||
|
||||
if ((mlmeRequest->req.join.dev_eui == NULL)
|
||||
|| (mlmeRequest->req.join.app_eui == NULL)
|
||||
|| (mlmeRequest->req.join.app_key == NULL)
|
||||
|| (mlmeRequest->req.join.nb_trials == 0)) {
|
||||
if ((request->req.join.dev_eui == NULL)
|
||||
|| (request->req.join.app_eui == NULL)
|
||||
|| (request->req.join.app_key == NULL)
|
||||
|| (request->req.join.nb_trials == 0)) {
|
||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
// Verify the parameter NbTrials for the join procedure
|
||||
verify.nb_join_trials = mlmeRequest->req.join.nb_trials;
|
||||
verify.nb_join_trials = request->req.join.nb_trials;
|
||||
|
||||
if (_lora_phy->verify(&verify, PHY_NB_JOIN_TRIALS) == false) {
|
||||
// Value not supported, get default
|
||||
get_phy.attribute = PHY_DEF_NB_JOIN_TRIALS;
|
||||
phyParam = _lora_phy->get_phy_params(&get_phy);
|
||||
mlmeRequest->req.join.nb_trials = (uint8_t) phyParam.value;
|
||||
phy_param = _lora_phy->get_phy_params(&get_phy);
|
||||
request->req.join.nb_trials = (uint8_t) phy_param.value;
|
||||
}
|
||||
|
||||
params->flags.bits.mlme_req = 1;
|
||||
confirmation.req_type = mlmeRequest->type;
|
||||
confirmation.req_type = request->type;
|
||||
|
||||
params->keys.dev_eui = mlmeRequest->req.join.dev_eui;
|
||||
params->keys.app_eui = mlmeRequest->req.join.app_eui;
|
||||
params->keys.app_key = mlmeRequest->req.join.app_key;
|
||||
params->max_join_request_trials = mlmeRequest->req.join.nb_trials;
|
||||
params->keys.dev_eui = request->req.join.dev_eui;
|
||||
params->keys.app_eui = request->req.join.app_eui;
|
||||
params->keys.app_key = request->req.join.app_key;
|
||||
params->max_join_request_trials = request->req.join.nb_trials;
|
||||
|
||||
// Reset variable JoinRequestTrials
|
||||
params->join_request_trial_counter = 0;
|
||||
|
||||
// Setup header information
|
||||
macHdr.value = 0;
|
||||
macHdr.bits.mtype = FRAME_TYPE_JOIN_REQ;
|
||||
machdr.value = 0;
|
||||
machdr.bits.mtype = FRAME_TYPE_JOIN_REQ;
|
||||
|
||||
_lora_mac->ResetMacParameters();
|
||||
_lora_mac->reset_mac_parameters();
|
||||
|
||||
params->sys_params.channel_data_rate =
|
||||
_lora_phy->get_alternate_DR(params->join_request_trial_counter + 1);
|
||||
|
||||
status = _lora_mac->Send(&macHdr, 0, NULL, 0);
|
||||
status = _lora_mac->send(&machdr, 0, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case MLME_LINK_CHECK: {
|
||||
params->flags.bits.mlme_req = 1;
|
||||
// LoRaMac will send this command piggy-backed
|
||||
confirmation.req_type = mlmeRequest->type;
|
||||
confirmation.req_type = request->type;
|
||||
|
||||
status = _mac_cmd->AddMacCommand(MOTE_MAC_LINK_CHECK_REQ, 0, 0);
|
||||
status = _mac_cmd->add_mac_command(MOTE_MAC_LINK_CHECK_REQ, 0, 0);
|
||||
break;
|
||||
}
|
||||
case MLME_TXCW: {
|
||||
confirmation.req_type = mlmeRequest->type;
|
||||
confirmation.req_type = request->type;
|
||||
params->flags.bits.mlme_req = 1;
|
||||
status = _lora_mac->SetTxContinuousWave(mlmeRequest->req.cw_tx_mode.timeout);
|
||||
status = _lora_mac->set_tx_continuous_wave(request->req.cw_tx_mode.timeout);
|
||||
break;
|
||||
}
|
||||
case MLME_TXCW_1: {
|
||||
confirmation.req_type = mlmeRequest->type;
|
||||
confirmation.req_type = request->type;
|
||||
params->flags.bits.mlme_req = 1;
|
||||
status = _lora_mac->SetTxContinuousWave1(mlmeRequest->req.cw_tx_mode.timeout,
|
||||
mlmeRequest->req.cw_tx_mode.frequency,
|
||||
mlmeRequest->req.cw_tx_mode.power);
|
||||
status = _lora_mac->set_tx_continuous_wave1(request->req.cw_tx_mode.timeout,
|
||||
request->req.cw_tx_mode.frequency,
|
||||
request->req.cw_tx_mode.power);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -66,13 +66,13 @@ public:
|
|||
* to the central MAC control. It also modifies or uses protocol information
|
||||
* provided in the MAC protocol data structure.
|
||||
*
|
||||
* @param mlmeRequest pointer to MLME request structure
|
||||
* @param request pointer to MLME request structure
|
||||
* @param params pointer to MAC protocol parameters
|
||||
*
|
||||
* @return LORAWAN_STATUS_OK if everything goes well otherwise
|
||||
* a negative error code is returned.
|
||||
*/
|
||||
lorawan_status_t set_request(loramac_mlme_req_t *mlmeRequest, loramac_protocol_params *params);
|
||||
lorawan_status_t set_request(loramac_mlme_req_t *request, loramac_protocol_params *params);
|
||||
|
||||
/** Grants access to MLME confirmation data
|
||||
*
|
||||
|
|
|
@ -368,7 +368,7 @@ typedef struct multicast_params_s {
|
|||
/*!
|
||||
* A reference pointer to the next multicast channel parameters in the list.
|
||||
*/
|
||||
struct multicast_params_s *Next;
|
||||
struct multicast_params_s *next;
|
||||
} multicast_params_t;
|
||||
|
||||
/*!
|
||||
|
|
Loading…
Reference in New Issue