Style Changes in MAC layer

Style changed according to Mbed-OS guidelines.
pull/6059/head
Hasnain Virk 2018-02-09 16:23:33 +02:00
parent 20bce2f21c
commit 7224fbae1c
12 changed files with 1594 additions and 1721 deletions

View File

@ -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

View File

@ -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__

View File

@ -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;
}

View File

@ -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__

View File

@ -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");

View File

@ -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__

View File

@ -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;

View File

@ -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,
&params->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,
&params->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:

View File

@ -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:

View File

@ -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
*

View File

@ -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;
/*!