mirror of https://github.com/ARMmbed/mbed-os.git
commit
5e62d17a9d
|
|
@ -122,56 +122,72 @@ void LoRaWANStack::bind_radio_driver(LoRaRadio& radio)
|
||||||
|
|
||||||
lorawan_status_t LoRaWANStack::connect()
|
lorawan_status_t LoRaWANStack::connect()
|
||||||
{
|
{
|
||||||
// connection attempt without parameters.
|
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) {
|
||||||
// System tries to look for configuration in mbed_lib.json that can be
|
tr_error("Stack not initialized!");
|
||||||
// overridden by mbed_app.json. However, if none of the json files are
|
return LORAWAN_STATUS_NOT_INITIALIZED;
|
||||||
// available (highly unlikely), we still fallback to some default parameters.
|
}
|
||||||
// Check lorawan_data_structure for fallback defaults.
|
|
||||||
|
|
||||||
lorawan_connect_t connection_params;
|
lorawan_status_t status = _loramac.prepare_join(NULL, MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION);
|
||||||
|
|
||||||
//TODO: LoRaWANStack don't need to know these values, move to LoRaMac (or below)
|
if (LORAWAN_STATUS_OK != status) {
|
||||||
#if MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION
|
return status;
|
||||||
const static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI;
|
}
|
||||||
const static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI;
|
|
||||||
const static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY;
|
|
||||||
|
|
||||||
connection_params.connect_type = LORAWAN_CONNECTION_OTAA;
|
return handle_connect(MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION);
|
||||||
connection_params.connection_u.otaa.app_eui = const_cast<uint8_t *>(app_eui);
|
|
||||||
connection_params.connection_u.otaa.dev_eui = const_cast<uint8_t *>(dev_eui);
|
|
||||||
connection_params.connection_u.otaa.app_key = const_cast<uint8_t *>(app_key);
|
|
||||||
connection_params.connection_u.otaa.nb_trials = MBED_CONF_LORA_NB_TRIALS;
|
|
||||||
|
|
||||||
return join_request_by_otaa(connection_params);
|
|
||||||
#else
|
|
||||||
const static uint8_t nwk_skey[] = MBED_CONF_LORA_NWKSKEY;
|
|
||||||
const static uint8_t app_skey[] = MBED_CONF_LORA_APPSKEY;
|
|
||||||
const static uint32_t dev_addr = MBED_CONF_LORA_DEVICE_ADDRESS;
|
|
||||||
const static uint32_t nwk_id = (MBED_CONF_LORA_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK);
|
|
||||||
|
|
||||||
connection_params.connect_type = LORAWAN_CONNECTION_ABP;
|
|
||||||
connection_params.connection_u.abp.nwk_id = const_cast<uint8_t *>(nwk_id);
|
|
||||||
connection_params.connection_u.abp.dev_addr = const_cast<uint8_t *>(dev_addr);
|
|
||||||
connection_params.connection_u.abp.nwk_skey = const_cast<uint8_t *>(nwk_skey);
|
|
||||||
connection_params.connection_u.abp.app_skey = const_cast<uint8_t *>(app_skey);
|
|
||||||
|
|
||||||
return activation_by_personalization(connection_params);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lorawan_status_t LoRaWANStack::connect(const lorawan_connect_t &connect)
|
lorawan_status_t LoRaWANStack::connect(const lorawan_connect_t &connect)
|
||||||
{
|
{
|
||||||
lorawan_status_t mac_status;
|
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) {
|
||||||
|
tr_error("Stack not initialized!");
|
||||||
if (connect.connect_type == LORAWAN_CONNECTION_OTAA) {
|
return LORAWAN_STATUS_NOT_INITIALIZED;
|
||||||
mac_status = join_request_by_otaa(connect);
|
|
||||||
} else if (connect.connect_type == LORAWAN_CONNECTION_ABP) {
|
|
||||||
mac_status = activation_by_personalization(connect);
|
|
||||||
} else {
|
|
||||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mac_status;
|
if (!(connect.connect_type == LORAWAN_CONNECTION_OTAA) &&
|
||||||
|
!(connect.connect_type == LORAWAN_CONNECTION_ABP)) {
|
||||||
|
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||||
|
}
|
||||||
|
bool is_otaa = (connect.connect_type == LORAWAN_CONNECTION_OTAA);
|
||||||
|
|
||||||
|
lorawan_status_t status = _loramac.prepare_join(&connect, is_otaa);
|
||||||
|
|
||||||
|
if (LORAWAN_STATUS_OK != status) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle_connect(is_otaa);
|
||||||
|
}
|
||||||
|
|
||||||
|
lorawan_status_t LoRaWANStack::handle_connect(bool is_otaa)
|
||||||
|
{
|
||||||
|
device_states_t new_state;
|
||||||
|
|
||||||
|
if (is_otaa) {
|
||||||
|
tr_debug("Initiating OTAA");
|
||||||
|
|
||||||
|
// As mentioned in the comment above, in 1.0.2 spec, counters are always set
|
||||||
|
// to zero for new connection. This section is common for both normal and
|
||||||
|
// connection restore at this moment. Will change in future with 1.1 support.
|
||||||
|
_lw_session.downlink_counter = 0;
|
||||||
|
_lw_session.uplink_counter = 0;
|
||||||
|
new_state = DEVICE_STATE_JOINING;
|
||||||
|
} else {
|
||||||
|
// If current state is SHUTDOWN, device may be trying to re-establish
|
||||||
|
// communication. In case of ABP specification is meddled about frame counters.
|
||||||
|
// It says to reset counters to zero but there is no mechanism to tell the
|
||||||
|
// network server that the device was disconnected or restarted.
|
||||||
|
// At the moment, this implementation does not support a non-volatile
|
||||||
|
// memory storage.
|
||||||
|
//_lw_session.downlink_counter; //Get from NVM
|
||||||
|
//_lw_session.uplink_counter; //Get from NVM
|
||||||
|
|
||||||
|
tr_debug("Initiating ABP");
|
||||||
|
tr_debug("Frame Counters. UpCnt=%lu, DownCnt=%lu",
|
||||||
|
_lw_session.uplink_counter, _lw_session.downlink_counter);
|
||||||
|
new_state = DEVICE_STATE_ABP_CONNECTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lora_state_machine(new_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue)
|
lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue)
|
||||||
|
|
@ -315,61 +331,6 @@ lorawan_status_t LoRaWANStack::set_channel_data_rate(uint8_t data_rate)
|
||||||
return _loramac.set_channel_data_rate(data_rate);
|
return _loramac.set_channel_data_rate(data_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
lorawan_status_t LoRaWANStack::join_request_by_otaa(const lorawan_connect_t ¶ms)
|
|
||||||
{
|
|
||||||
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state)
|
|
||||||
{
|
|
||||||
tr_error("Stack not initialized!");
|
|
||||||
return LORAWAN_STATUS_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr_debug("Initiating OTAA");
|
|
||||||
|
|
||||||
// As mentioned in the comment above, in 1.0.2 spec, counters are always set
|
|
||||||
// to zero for new connection. This section is common for both normal and
|
|
||||||
// connection restore at this moment. Will change in future with 1.1 support.
|
|
||||||
_lw_session.downlink_counter = 0;
|
|
||||||
_lw_session.uplink_counter = 0;
|
|
||||||
_lw_session.connection.connect_type = LORAWAN_CONNECTION_OTAA;
|
|
||||||
|
|
||||||
_lw_session.connection.connection_u.otaa.dev_eui = params.connection_u.otaa.dev_eui;
|
|
||||||
_lw_session.connection.connection_u.otaa.app_eui = params.connection_u.otaa.app_eui;
|
|
||||||
_lw_session.connection.connection_u.otaa.app_key = params.connection_u.otaa.app_key;
|
|
||||||
_lw_session.connection.connection_u.otaa.nb_trials = params.connection_u.otaa.nb_trials;
|
|
||||||
|
|
||||||
return lora_state_machine(DEVICE_STATE_JOINING);
|
|
||||||
}
|
|
||||||
|
|
||||||
lorawan_status_t LoRaWANStack::activation_by_personalization(const lorawan_connect_t ¶ms)
|
|
||||||
{
|
|
||||||
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) {
|
|
||||||
tr_error("Stack not initialized!");
|
|
||||||
return LORAWAN_STATUS_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr_debug("Initiating ABP");
|
|
||||||
|
|
||||||
_lw_session.connection.connect_type = LORAWAN_CONNECTION_ABP;
|
|
||||||
|
|
||||||
_lw_session.connection.connection_u.abp.dev_addr = params.connection_u.abp.dev_addr;
|
|
||||||
_lw_session.connection.connection_u.abp.nwk_skey = params.connection_u.abp.nwk_skey;
|
|
||||||
_lw_session.connection.connection_u.abp.app_skey = params.connection_u.abp.app_skey;
|
|
||||||
|
|
||||||
// If current state is SHUTDOWN, device may be trying to re-establish
|
|
||||||
// communication. In case of ABP specification is meddled about frame counters.
|
|
||||||
// It says to reset counters to zero but there is no mechanism to tell the
|
|
||||||
// network server that the device was disconnected or restarted.
|
|
||||||
// At the moment, this implementation does not support a non-volatile
|
|
||||||
// memory storage.
|
|
||||||
//_lw_session.downlink_counter; //Get from NVM
|
|
||||||
//_lw_session.uplink_counter; //Get from NVM
|
|
||||||
|
|
||||||
tr_debug("Frame Counters. UpCnt=%lu, DownCnt=%lu",
|
|
||||||
_lw_session.uplink_counter, _lw_session.downlink_counter);
|
|
||||||
|
|
||||||
return lora_state_machine(DEVICE_STATE_ABP_CONNECTING);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
|
int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
|
||||||
uint16_t length, uint8_t flags, bool null_allowed)
|
uint16_t length, uint8_t flags, bool null_allowed)
|
||||||
{
|
{
|
||||||
|
|
@ -512,12 +473,10 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
|
||||||
switch (mlme_confirm->req_type) {
|
switch (mlme_confirm->req_type) {
|
||||||
case MLME_JOIN:
|
case MLME_JOIN:
|
||||||
if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) {
|
if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) {
|
||||||
// Status is OK, node has joined the network
|
|
||||||
if (lora_state_machine(DEVICE_STATE_JOINED) != LORAWAN_STATUS_OK) {
|
if (lora_state_machine(DEVICE_STATE_JOINED) != LORAWAN_STATUS_OK) {
|
||||||
tr_error("Lora state machine did not return LORAWAN_STATUS_OK");
|
tr_error("Lora state machine did not return LORAWAN_STATUS_OK");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Join attempt failed.
|
|
||||||
if (lora_state_machine(DEVICE_STATE_IDLE) != LORAWAN_STATUS_IDLE) {
|
if (lora_state_machine(DEVICE_STATE_IDLE) != LORAWAN_STATUS_IDLE) {
|
||||||
tr_error("Lora state machine did not return DEVICE_STATE_IDLE !");
|
tr_error("Lora state machine did not return DEVICE_STATE_IDLE !");
|
||||||
}
|
}
|
||||||
|
|
@ -531,8 +490,6 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
|
||||||
break;
|
break;
|
||||||
case MLME_LINK_CHECK:
|
case MLME_LINK_CHECK:
|
||||||
if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) {
|
if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) {
|
||||||
// Check DemodMargin
|
|
||||||
// Check NbGateways
|
|
||||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||||
if (_compliance_test.running == true) {
|
if (_compliance_test.running == true) {
|
||||||
_compliance_test.link_check = true;
|
_compliance_test.link_check = true;
|
||||||
|
|
@ -541,7 +498,6 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// normal operation as oppose to compliance testing
|
|
||||||
if (_callbacks.link_check_resp) {
|
if (_callbacks.link_check_resp) {
|
||||||
const int ret = _queue->call(_callbacks.link_check_resp,
|
const int ret = _queue->call(_callbacks.link_check_resp,
|
||||||
mlme_confirm->demod_margin,
|
mlme_confirm->demod_margin,
|
||||||
|
|
@ -640,7 +596,10 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mcps_indication->is_data_recvd == true) {
|
if (!mcps_indication->is_data_recvd) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (mcps_indication->port) {
|
switch (mcps_indication->port) {
|
||||||
case 224: {
|
case 224: {
|
||||||
#if defined(LORAWAN_COMPLIANCE_TEST)
|
#if defined(LORAWAN_COMPLIANCE_TEST)
|
||||||
|
|
@ -697,7 +656,6 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
lorawan_status_t LoRaWANStack::set_link_check_request()
|
lorawan_status_t LoRaWANStack::set_link_check_request()
|
||||||
{
|
{
|
||||||
|
|
@ -774,10 +732,10 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
||||||
status = LORAWAN_STATUS_OK;
|
status = LORAWAN_STATUS_OK;
|
||||||
break;
|
break;
|
||||||
case DEVICE_STATE_JOINING:
|
case DEVICE_STATE_JOINING:
|
||||||
if (_lw_session.connection.connect_type == LORAWAN_CONNECTION_OTAA) {
|
if (_lw_session.connect_type == LORAWAN_CONNECTION_OTAA) {
|
||||||
tr_debug("Send Join-request..");
|
tr_debug("Send Join-request..");
|
||||||
|
|
||||||
status = _loramac.join_by_otaa(_lw_session.connection.connection_u.otaa);
|
status = _loramac.join(true);
|
||||||
if (status != LORAWAN_STATUS_OK) {
|
if (status != LORAWAN_STATUS_OK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -801,7 +759,7 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
|
||||||
break;
|
break;
|
||||||
case DEVICE_STATE_ABP_CONNECTING:
|
case DEVICE_STATE_ABP_CONNECTING:
|
||||||
|
|
||||||
_loramac.join_by_abp(_lw_session.connection.connection_u.abp);
|
_loramac.join(false);
|
||||||
|
|
||||||
tr_debug("ABP Connection OK!");
|
tr_debug("ABP Connection OK!");
|
||||||
|
|
||||||
|
|
@ -1028,7 +986,7 @@ void LoRaWANStack::compliance_test_handler(loramac_mcps_indication_t *mcps_indic
|
||||||
#if MBED_CONF_LORA_PHY == 0
|
#if MBED_CONF_LORA_PHY == 0
|
||||||
_loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON);
|
_loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON);
|
||||||
#endif
|
#endif
|
||||||
_loramac.join_by_otaa(_lw_session.connection.connection_u.otaa);
|
_loramac.join(true);
|
||||||
break;
|
break;
|
||||||
case 7: // (x)
|
case 7: // (x)
|
||||||
if (mcps_indication->buffer_size == 3) {
|
if (mcps_indication->buffer_size == 3) {
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,40 @@
|
||||||
/**
|
/**
|
||||||
/ _____) _ | |
|
* \file LoRaWANStack.h
|
||||||
( (____ _____ ____ _| |_ _____ ____| |__
|
*
|
||||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
* \brief LoRaWAN stack layer implementation
|
||||||
_____) ) ____| | | || |_| ____( (___| | | |
|
*
|
||||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
* \copyright Revised BSD License, see LICENSE.TXT file include in the project
|
||||||
(C)2013 Semtech
|
*
|
||||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
* \code
|
||||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
* ______ _
|
||||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
* / _____) _ | |
|
||||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||||
embedded.connectivity.solutions===============
|
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||||
|
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
|
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||||
|
* (C)2013 Semtech
|
||||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
*
|
||||||
|
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||||
|
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||||
|
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||||
Copyright (c) 2017, Arm Limited and affiliates.
|
* embedded.connectivity.solutions===============
|
||||||
|
*
|
||||||
SPDX-License-Identifier: BSD-3-Clause
|
* \endcode
|
||||||
|
*
|
||||||
|
* \author Miguel Luis ( Semtech )
|
||||||
|
*
|
||||||
|
* \author Gregory Cristian ( Semtech )
|
||||||
|
*
|
||||||
|
* \author Daniel Jaeckle ( STACKFORCE )
|
||||||
|
*
|
||||||
|
* \defgroup LoRaWAN stack layer that controls MAC layer underneath
|
||||||
|
*
|
||||||
|
* License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LORAWANSTACK_H_
|
#ifndef LORAWANSTACK_H_
|
||||||
|
|
@ -35,11 +49,6 @@ SPDX-License-Identifier: BSD-3-Clause
|
||||||
#include "lorawan/system/lorawan_data_structures.h"
|
#include "lorawan/system/lorawan_data_structures.h"
|
||||||
#include "LoRaRadio.h"
|
#include "LoRaRadio.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* A mask for the network ID.
|
|
||||||
*/
|
|
||||||
#define LORAWAN_NETWORK_ID_MASK ( uint32_t )0xFE000000
|
|
||||||
|
|
||||||
class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
|
class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
|
||||||
private:
|
private:
|
||||||
/** End-device states.
|
/** End-device states.
|
||||||
|
|
@ -422,31 +431,10 @@ private:
|
||||||
*/
|
*/
|
||||||
lorawan_status_t set_application_port(uint8_t port);
|
lorawan_status_t set_application_port(uint8_t port);
|
||||||
|
|
||||||
/** End device OTAA join.
|
/**
|
||||||
*
|
* Handles connection internally
|
||||||
* Based on the LoRaWAN standard 1.0.2.
|
|
||||||
* Join the network using the Over The Air Activation (OTAA) procedure.
|
|
||||||
*
|
|
||||||
* @param params The `lorawan_connect_t` type structure.
|
|
||||||
*
|
|
||||||
* @return LORAWAN_STATUS_OK or
|
|
||||||
* LORAWAN_STATUS_CONNECT_IN_PROGRESS on success,
|
|
||||||
* or a negative error code on failure.
|
|
||||||
*/
|
*/
|
||||||
lorawan_status_t join_request_by_otaa(const lorawan_connect_t ¶ms);
|
lorawan_status_t handle_connect(bool is_otaa);
|
||||||
|
|
||||||
/** End device ABP join.
|
|
||||||
*
|
|
||||||
* Based on the LoRaWAN standard 1.0.2.
|
|
||||||
* Join the network using the Activation By Personalization (ABP) procedure.
|
|
||||||
*
|
|
||||||
* @param params The `lorawan_connect_t` type structure.
|
|
||||||
*
|
|
||||||
* @return LORAWAN_STATUS_OK or
|
|
||||||
* LORAWAN_STATUS_CONNECT_IN_PROGRESS on success,
|
|
||||||
* or a negative error code on failure.
|
|
||||||
*/
|
|
||||||
lorawan_status_t activation_by_personalization(const lorawan_connect_t ¶ms);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,11 @@ using namespace events;
|
||||||
*/
|
*/
|
||||||
#define DOWN_LINK 1
|
#define DOWN_LINK 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mask for the network ID.
|
||||||
|
*/
|
||||||
|
#define LORAWAN_NETWORK_ID_MASK ( uint32_t )0xFE000000
|
||||||
|
|
||||||
|
|
||||||
LoRaMac::LoRaMac()
|
LoRaMac::LoRaMac()
|
||||||
: _lora_phy(_lora_time), mac_commands(), _is_nwk_joined(false)
|
: _lora_phy(_lora_time), mac_commands(), _is_nwk_joined(false)
|
||||||
|
|
@ -964,7 +969,7 @@ void LoRaMac::on_rx_window1_timer_event(void)
|
||||||
_lora_phy.rx_config(&_params.rx_window1_config,
|
_lora_phy.rx_config(&_params.rx_window1_config,
|
||||||
(int8_t*) &_mcps_indication.rx_datarate);
|
(int8_t*) &_mcps_indication.rx_datarate);
|
||||||
|
|
||||||
rx_window_setup(_params.rx_window1_config.is_rx_continuous,
|
_lora_phy.setup_rx_window(_params.rx_window1_config.is_rx_continuous,
|
||||||
_params.sys_params.max_rx_win_time);
|
_params.sys_params.max_rx_win_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -978,17 +983,16 @@ void LoRaMac::on_rx_window2_timer_event(void)
|
||||||
_params.rx_window2_config.is_repeater_supported = _params.is_repeater_supported;
|
_params.rx_window2_config.is_repeater_supported = _params.is_repeater_supported;
|
||||||
_params.rx_window2_config.rx_slot = RX_SLOT_WIN_2;
|
_params.rx_window2_config.rx_slot = RX_SLOT_WIN_2;
|
||||||
|
|
||||||
|
_params.rx_window2_config.is_rx_continuous = true;
|
||||||
|
|
||||||
if (_device_class != CLASS_C) {
|
if (_device_class != CLASS_C) {
|
||||||
_params.rx_window2_config.is_rx_continuous = false;
|
_params.rx_window2_config.is_rx_continuous = false;
|
||||||
} else {
|
|
||||||
// Setup continuous listening for class c
|
|
||||||
_params.rx_window2_config.is_rx_continuous = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_lora_phy.rx_config(&_params.rx_window2_config,
|
if (_lora_phy.rx_config(&_params.rx_window2_config,
|
||||||
(int8_t*) &_mcps_indication.rx_datarate) == true) {
|
(int8_t*) &_mcps_indication.rx_datarate) == true) {
|
||||||
|
|
||||||
rx_window_setup(_params.rx_window2_config.is_rx_continuous,
|
_lora_phy.setup_rx_window(_params.rx_window2_config.is_rx_continuous,
|
||||||
_params.sys_params.max_rx_win_time);
|
_params.sys_params.max_rx_win_time);
|
||||||
|
|
||||||
_params.rx_slot = RX_SLOT_WIN_2;
|
_params.rx_slot = RX_SLOT_WIN_2;
|
||||||
|
|
@ -1037,11 +1041,6 @@ void LoRaMac::on_ack_timeout_timer_event(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoRaMac::rx_window_setup(bool rx_continuous, uint32_t max_rx_window_time)
|
|
||||||
{
|
|
||||||
_lora_phy.setup_rx_window(rx_continuous, max_rx_window_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LoRaMac::validate_payload_length(uint8_t length, int8_t datarate,
|
bool LoRaMac::validate_payload_length(uint8_t length, int8_t datarate,
|
||||||
uint8_t fopts_len)
|
uint8_t fopts_len)
|
||||||
{
|
{
|
||||||
|
|
@ -1418,33 +1417,22 @@ void LoRaMac::setup_link_check_request()
|
||||||
mac_commands.add_mac_command(MOTE_MAC_LINK_CHECK_REQ, 0, 0);
|
mac_commands.add_mac_command(MOTE_MAC_LINK_CHECK_REQ, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
lorawan_status_t LoRaMac::join_by_otaa(const lorawan_connect_otaa_t& otaa_join)
|
lorawan_status_t LoRaMac::prepare_join(const lorawan_connect_t *params, bool is_otaa)
|
||||||
{
|
{
|
||||||
if (LORAMAC_IDLE != _params.mac_state) {
|
if (params) {
|
||||||
return LORAWAN_STATUS_BUSY;
|
if (is_otaa) {
|
||||||
}
|
if ((params->connection_u.otaa.dev_eui == NULL) ||
|
||||||
|
(params->connection_u.otaa.app_eui == NULL) ||
|
||||||
reset_mlme_confirmation();
|
(params->connection_u.otaa.app_key == NULL) ||
|
||||||
|
(params->connection_u.otaa.nb_trials == 0)) {
|
||||||
_mlme_confirmation.req_type = MLME_JOIN;
|
|
||||||
_params.flags.bits.mlme_req = 1;
|
|
||||||
|
|
||||||
// if ((_params.mac_state & LORAMAC_TX_DELAYED) == LORAMAC_TX_DELAYED) {
|
|
||||||
// return LORAWAN_STATUS_BUSY;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if ((otaa_join.dev_eui == NULL) ||
|
|
||||||
(otaa_join.app_eui == NULL) ||
|
|
||||||
(otaa_join.app_key == NULL) ||
|
|
||||||
(otaa_join.nb_trials == 0)) {
|
|
||||||
return LORAWAN_STATUS_PARAMETER_INVALID;
|
return LORAWAN_STATUS_PARAMETER_INVALID;
|
||||||
}
|
}
|
||||||
_params.keys.dev_eui = otaa_join.dev_eui;
|
_params.keys.dev_eui = params->connection_u.otaa.dev_eui;
|
||||||
_params.keys.app_eui = otaa_join.app_eui;
|
_params.keys.app_eui = params->connection_u.otaa.app_eui;
|
||||||
_params.keys.app_key = otaa_join.app_key;
|
_params.keys.app_key = params->connection_u.otaa.app_key;
|
||||||
_params.max_join_request_trials = otaa_join.nb_trials;
|
_params.max_join_request_trials = params->connection_u.otaa.nb_trials;
|
||||||
|
|
||||||
if (!_lora_phy.verify_nb_join_trials(otaa_join.nb_trials)) {
|
if (!_lora_phy.verify_nb_join_trials(params->connection_u.otaa.nb_trials)) {
|
||||||
// Value not supported, get default
|
// Value not supported, get default
|
||||||
_params.max_join_request_trials = MBED_CONF_LORA_NB_TRIALS;
|
_params.max_join_request_trials = MBED_CONF_LORA_NB_TRIALS;
|
||||||
}
|
}
|
||||||
|
|
@ -1455,6 +1443,67 @@ lorawan_status_t LoRaMac::join_by_otaa(const lorawan_connect_otaa_t& otaa_join)
|
||||||
|
|
||||||
_params.sys_params.channel_data_rate =
|
_params.sys_params.channel_data_rate =
|
||||||
_lora_phy.get_alternate_DR(_params.join_request_trial_counter + 1);
|
_lora_phy.get_alternate_DR(_params.join_request_trial_counter + 1);
|
||||||
|
} else {
|
||||||
|
_params.net_id = params->connection_u.abp.nwk_id;
|
||||||
|
_params.dev_addr = params->connection_u.abp.dev_addr;
|
||||||
|
|
||||||
|
memcpy(_params.keys.nwk_skey, params->connection_u.abp.nwk_skey,
|
||||||
|
sizeof(_params.keys.nwk_skey));
|
||||||
|
|
||||||
|
memcpy(_params.keys.app_skey, params->connection_u.abp.app_skey,
|
||||||
|
sizeof(_params.keys.app_skey));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#if MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION
|
||||||
|
const static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI;
|
||||||
|
const static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI;
|
||||||
|
const static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY;
|
||||||
|
|
||||||
|
_params.keys.app_eui = const_cast<uint8_t *>(app_eui);
|
||||||
|
_params.keys.dev_eui = const_cast<uint8_t *>(dev_eui);
|
||||||
|
_params.keys.app_key = const_cast<uint8_t *>(app_key);
|
||||||
|
_params.max_join_request_trials = MBED_CONF_LORA_NB_TRIALS;
|
||||||
|
|
||||||
|
// Reset variable JoinRequestTrials
|
||||||
|
_params.join_request_trial_counter = 0;
|
||||||
|
|
||||||
|
reset_mac_parameters();
|
||||||
|
|
||||||
|
_params.sys_params.channel_data_rate =
|
||||||
|
_lora_phy.get_alternate_DR(_params.join_request_trial_counter + 1);
|
||||||
|
|
||||||
|
#else
|
||||||
|
const static uint8_t nwk_skey[] = MBED_CONF_LORA_NWKSKEY;
|
||||||
|
const static uint8_t app_skey[] = MBED_CONF_LORA_APPSKEY;
|
||||||
|
|
||||||
|
_params.net_id = (MBED_CONF_LORA_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK);
|
||||||
|
_params.dev_addr = MBED_CONF_LORA_DEVICE_ADDRESS;
|
||||||
|
|
||||||
|
memcpy(_params.keys.nwk_skey, nwk_skey,
|
||||||
|
sizeof(_params.keys.nwk_skey));
|
||||||
|
|
||||||
|
memcpy(_params.keys.app_skey, app_skey,
|
||||||
|
sizeof(_params.keys.app_skey));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return LORAWAN_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
lorawan_status_t LoRaMac::join(bool is_otaa)
|
||||||
|
{
|
||||||
|
if (!is_otaa) {
|
||||||
|
set_nwk_joined(true);
|
||||||
|
return LORAWAN_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LORAMAC_IDLE != _params.mac_state) {
|
||||||
|
return LORAWAN_STATUS_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_mlme_confirmation();
|
||||||
|
|
||||||
|
_mlme_confirmation.req_type = MLME_JOIN;
|
||||||
|
_params.flags.bits.mlme_req = 1;
|
||||||
|
|
||||||
loramac_mhdr_t machdr;
|
loramac_mhdr_t machdr;
|
||||||
machdr.value = 0;
|
machdr.value = 0;
|
||||||
|
|
@ -1462,20 +1511,6 @@ lorawan_status_t LoRaMac::join_by_otaa(const lorawan_connect_otaa_t& otaa_join)
|
||||||
return send(&machdr, 0, NULL, 0);
|
return send(&machdr, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoRaMac::join_by_abp(const lorawan_connect_abp_t& abp_join)
|
|
||||||
{
|
|
||||||
_params.net_id = abp_join.nwk_id;
|
|
||||||
_params.dev_addr = abp_join.dev_addr;
|
|
||||||
|
|
||||||
memcpy(_params.keys.nwk_skey, abp_join.nwk_skey,
|
|
||||||
sizeof(_params.keys.nwk_skey));
|
|
||||||
|
|
||||||
memcpy(_params.keys.app_skey, abp_join.app_skey,
|
|
||||||
sizeof(_params.keys.app_skey));
|
|
||||||
|
|
||||||
set_nwk_joined(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void memcpy_convert_endianess(uint8_t *dst, const uint8_t *src,
|
static void memcpy_convert_endianess(uint8_t *dst, const uint8_t *src,
|
||||||
uint16_t size)
|
uint16_t size)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -364,18 +364,20 @@ public:
|
||||||
void setup_link_check_request();
|
void setup_link_check_request();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief join_by_otaa Sends OTAA join message
|
* @brief prepare_join prepares arguments to be ready for join() call.
|
||||||
* @param otaa_join Joining parameters
|
* @param params Join parameters to use, if NULL, the default will be used.
|
||||||
|
* @param is_otaa True if joining is to be done using OTAA, false for ABP.
|
||||||
*
|
*
|
||||||
* @return LORAWAN_STATUS_OK or a negative error code on failure.
|
* @return LORAWAN_STATUS_OK or a negative error code on failure.
|
||||||
*/
|
*/
|
||||||
lorawan_status_t join_by_otaa(const lorawan_connect_otaa_t& otaa_join);
|
lorawan_status_t prepare_join(const lorawan_connect_t *params, bool is_otaa);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief join_by_abp Sets up ABP connectivity parameters.
|
* @brief join Joins the network.
|
||||||
* @param abp_join Connectivity parameters.
|
* @param is_otaa True if joining is to be done using OTAA, false for ABP.
|
||||||
|
* @return LORAWAN_STATUS_OK or a negative error code on failure.
|
||||||
*/
|
*/
|
||||||
void join_by_abp(const lorawan_connect_abp_t& abp_join);
|
lorawan_status_t join(bool is_otaa);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
@ -452,11 +454,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void on_ack_timeout_timer_event(void);
|
void on_ack_timeout_timer_event(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes and opens the reception window
|
|
||||||
*/
|
|
||||||
void rx_window_setup(bool rx_continuous, uint32_t max_rx_window_time);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates if the payload fits into the frame, taking the datarate
|
* Validates if the payload fits into the frame, taking the datarate
|
||||||
* into account.
|
* into account.
|
||||||
|
|
|
||||||
|
|
@ -19,36 +19,69 @@
|
||||||
#define LORAPHY_TARGET
|
#define LORAPHY_TARGET
|
||||||
|
|
||||||
#ifdef MBED_CONF_LORA_PHY
|
#ifdef MBED_CONF_LORA_PHY
|
||||||
#if MBED_CONF_LORA_PHY == 0
|
|
||||||
|
#define LORA_REGION_EU868 0x10
|
||||||
|
#define LORA_REGION_AS923 0x11
|
||||||
|
#define LORA_REGION_AU915 0x12
|
||||||
|
#define LORA_REGION_CN470 0x13
|
||||||
|
#define LORA_REGION_CN779 0x14
|
||||||
|
#define LORA_REGION_EU433 0x15
|
||||||
|
#define LORA_REGION_IN865 0x16
|
||||||
|
#define LORA_REGION_KR920 0x17
|
||||||
|
#define LORA_REGION_US915 0x18
|
||||||
|
#define LORA_REGION_US915_HYBRID 0x19
|
||||||
|
|
||||||
|
//DO NOT USE integer values in mbed_app.json!
|
||||||
|
//These are defined for backward compatibility and
|
||||||
|
//Will be DEPRECATED in the future
|
||||||
|
#define LORA_REGION_0 0x10
|
||||||
|
#define LORA_REGION_1 0x11
|
||||||
|
#define LORA_REGION_2 0x12
|
||||||
|
#define LORA_REGION_3 0x13
|
||||||
|
#define LORA_REGION_4 0x14
|
||||||
|
#define LORA_REGION_5 0x15
|
||||||
|
#define LORA_REGION_6 0x16
|
||||||
|
#define LORA_REGION_7 0x17
|
||||||
|
#define LORA_REGION_8 0x18
|
||||||
|
#define LORA_REGION_9 0x19
|
||||||
|
|
||||||
|
//Since 0 would be equal to any undefined value we need to handle this in a other way
|
||||||
|
#define mbed_lora_concat_(x) LORA_REGION_##x
|
||||||
|
#define mbed_lora_concat(x) mbed_lora_concat_(x)
|
||||||
|
#define LORA_REGION mbed_lora_concat(MBED_CONF_LORA_PHY)
|
||||||
|
|
||||||
|
#if LORA_REGION == LORA_REGION_EU868
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYEU868.h"
|
#include "lorawan/lorastack/phy/LoRaPHYEU868.h"
|
||||||
#define LoRaPHY_region LoRaPHYEU868
|
#define LoRaPHY_region LoRaPHYEU868
|
||||||
#elif MBED_CONF_LORA_PHY == 1
|
#elif LORA_REGION == LORA_REGION_AS923
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYAS923.h"
|
#include "lorawan/lorastack/phy/LoRaPHYAS923.h"
|
||||||
#define LoRaPHY_region LoRaPHYAS923
|
#define LoRaPHY_region LoRaPHYAS923
|
||||||
#elif MBED_CONF_LORA_PHY == 2
|
#elif LORA_REGION == LORA_REGION_AU915
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYAU915.h"
|
#include "lorawan/lorastack/phy/LoRaPHYAU915.h"
|
||||||
#define LoRaPHY_region LoRaPHYAU915;
|
#define LoRaPHY_region LoRaPHYAU915;
|
||||||
#elif MBED_CONF_LORA_PHY == 3
|
#elif LORA_REGION == LORA_REGION_CN470
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYCN470.h"
|
#include "lorawan/lorastack/phy/LoRaPHYCN470.h"
|
||||||
#define LoRaPHY_region LoRaPHYCN470
|
#define LoRaPHY_region LoRaPHYCN470
|
||||||
#elif MBED_CONF_LORA_PHY == 4
|
#elif LORA_REGION == LORA_REGION_CN779
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYCN779.h"
|
#include "lorawan/lorastack/phy/LoRaPHYCN779.h"
|
||||||
#define LoRaPHY_region LoRaPHYCN779
|
#define LoRaPHY_region LoRaPHYCN779
|
||||||
#elif MBED_CONF_LORA_PHY == 5
|
#elif LORA_REGION == LORA_REGION_EU433
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYEU433.h"
|
#include "lorawan/lorastack/phy/LoRaPHYEU433.h"
|
||||||
#define LoRaPHY_region LoRaPHYEU433
|
#define LoRaPHY_region LoRaPHYEU433
|
||||||
#elif MBED_CONF_LORA_PHY == 6
|
#elif LORA_REGION == LORA_REGION_IN865
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYIN865.h"
|
#include "lorawan/lorastack/phy/LoRaPHYIN865.h"
|
||||||
#define LoRaPHY_region LoRaPHYIN865
|
#define LoRaPHY_region LoRaPHYIN865
|
||||||
#elif MBED_CONF_LORA_PHY == 7
|
#elif LORA_REGION == LORA_REGION_KR920
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYKR920.h"
|
#include "lorawan/lorastack/phy/LoRaPHYKR920.h"
|
||||||
#define LoRaPHY_region LoRaPHYKR920
|
#define LoRaPHY_region LoRaPHYKR920
|
||||||
#elif MBED_CONF_LORA_PHY == 8
|
#elif LORA_REGION == LORA_REGION_US915
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYUS915.h"
|
#include "lorawan/lorastack/phy/LoRaPHYUS915.h"
|
||||||
#define LoRaPHY_region LoRaPHYUS915
|
#define LoRaPHY_region LoRaPHYUS915
|
||||||
#elif MBED_CONF_LORA_PHY == 9
|
#elif LORA_REGION == LORA_REGION_US915_HYBRID
|
||||||
#include "lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h"
|
#include "lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h"
|
||||||
#define LoRaPHY_region LoRaPHYUS915Hybrid
|
#define LoRaPHY_region LoRaPHYUS915Hybrid
|
||||||
|
#else
|
||||||
|
#error "Invalid region configuration, update mbed_app.json with correct MBED_CONF_LORA_PHY value"
|
||||||
#endif //MBED_CONF_LORA_PHY == VALUE
|
#endif //MBED_CONF_LORA_PHY == VALUE
|
||||||
#else
|
#else
|
||||||
#error "Must set LoRa PHY layer parameters."
|
#error "Must set LoRa PHY layer parameters."
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
"name": "lora",
|
"name": "lora",
|
||||||
"config": {
|
"config": {
|
||||||
"phy": {
|
"phy": {
|
||||||
"help": "LoRa PHY region. 0 = EU868 (default), 1 = AS923, 2 = AU915, 3 = CN470, 4 = CN779, 5 = EU433, 6 = IN865, 7 = KR920, 8 = US915, 9 = US915_HYBRID",
|
"help": "LoRa PHY region: EU868, AS923, AU915, CN470, CN779, EU433, IN865, KR920, US915, US915_HYBRID",
|
||||||
"value": "0"
|
"value": "EU868"
|
||||||
},
|
},
|
||||||
"over-the-air-activation": {
|
"over-the-air-activation": {
|
||||||
"help": "When set to 1 the application uses the Over-the-Air activation procedure, default: true",
|
"help": "When set to 1 the application uses the Over-the-Air activation procedure, default: true",
|
||||||
|
|
|
||||||
|
|
@ -1277,7 +1277,12 @@ typedef struct lorawan_session {
|
||||||
*/
|
*/
|
||||||
bool active;
|
bool active;
|
||||||
|
|
||||||
lorawan_connect_t connection;
|
/*!
|
||||||
|
* Select the connection type, either LORAWAN_CONNECTION_OTAA
|
||||||
|
* or LORAWAN_CONNECTION_ABP.
|
||||||
|
*/
|
||||||
|
uint8_t connect_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LoRaWAN uplink counter
|
* LoRaWAN uplink counter
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue