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()
 | 
			
		||||
{
 | 
			
		||||
    // connection attempt without parameters.
 | 
			
		||||
    // System tries to look for configuration in mbed_lib.json that can be
 | 
			
		||||
    // overridden by mbed_app.json. However, if none of the json files are
 | 
			
		||||
    // available (highly unlikely), we still fallback to some default parameters.
 | 
			
		||||
    // Check lorawan_data_structure for fallback defaults.
 | 
			
		||||
    if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) {
 | 
			
		||||
        tr_error("Stack not initialized!");
 | 
			
		||||
        return LORAWAN_STATUS_NOT_INITIALIZED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 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;
 | 
			
		||||
    if (LORAWAN_STATUS_OK != status) {
 | 
			
		||||
        return status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    connection_params.connect_type = LORAWAN_CONNECTION_OTAA;
 | 
			
		||||
    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
 | 
			
		||||
    return handle_connect(MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
lorawan_status_t LoRaWANStack::connect(const lorawan_connect_t &connect)
 | 
			
		||||
{
 | 
			
		||||
    lorawan_status_t mac_status;
 | 
			
		||||
 | 
			
		||||
    if (connect.connect_type == LORAWAN_CONNECTION_OTAA) {
 | 
			
		||||
        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;
 | 
			
		||||
    if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) {
 | 
			
		||||
        tr_error("Stack not initialized!");
 | 
			
		||||
        return LORAWAN_STATUS_NOT_INITIALIZED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
| 
						 | 
				
			
			@ -315,61 +331,6 @@ lorawan_status_t LoRaWANStack::set_channel_data_rate(uint8_t 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,
 | 
			
		||||
                                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) {
 | 
			
		||||
        case MLME_JOIN:
 | 
			
		||||
            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) {
 | 
			
		||||
                    tr_error("Lora state machine did not return LORAWAN_STATUS_OK");
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // Join attempt failed.
 | 
			
		||||
                if (lora_state_machine(DEVICE_STATE_IDLE) != LORAWAN_STATUS_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;
 | 
			
		||||
        case MLME_LINK_CHECK:
 | 
			
		||||
            if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) {
 | 
			
		||||
                // Check DemodMargin
 | 
			
		||||
                // Check NbGateways
 | 
			
		||||
#if defined(LORAWAN_COMPLIANCE_TEST)
 | 
			
		||||
                if (_compliance_test.running == true) {
 | 
			
		||||
                    _compliance_test.link_check = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -541,7 +498,6 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
 | 
			
		|||
                } else
 | 
			
		||||
#endif
 | 
			
		||||
                {
 | 
			
		||||
                    // normal operation as oppose to compliance testing
 | 
			
		||||
                    if (_callbacks.link_check_resp) {
 | 
			
		||||
                        const int ret = _queue->call(_callbacks.link_check_resp,
 | 
			
		||||
                                                     mlme_confirm->demod_margin,
 | 
			
		||||
| 
						 | 
				
			
			@ -640,7 +596,10 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
 | 
			
		|||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (mcps_indication->is_data_recvd == true) {
 | 
			
		||||
    if (!mcps_indication->is_data_recvd) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (mcps_indication->port) {
 | 
			
		||||
        case 224: {
 | 
			
		||||
#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()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -774,10 +732,10 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
 | 
			
		|||
            status = LORAWAN_STATUS_OK;
 | 
			
		||||
            break;
 | 
			
		||||
        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..");
 | 
			
		||||
 | 
			
		||||
                status = _loramac.join_by_otaa(_lw_session.connection.connection_u.otaa);
 | 
			
		||||
                status = _loramac.join(true);
 | 
			
		||||
                if (status != LORAWAN_STATUS_OK) {
 | 
			
		||||
                    return status;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -801,7 +759,7 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
 | 
			
		|||
            break;
 | 
			
		||||
        case DEVICE_STATE_ABP_CONNECTING:
 | 
			
		||||
 | 
			
		||||
            _loramac.join_by_abp(_lw_session.connection.connection_u.abp);
 | 
			
		||||
            _loramac.join(false);
 | 
			
		||||
 | 
			
		||||
            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
 | 
			
		||||
            _loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON);
 | 
			
		||||
#endif
 | 
			
		||||
            _loramac.join_by_otaa(_lw_session.connection.connection_u.otaa);
 | 
			
		||||
            _loramac.join(true);
 | 
			
		||||
            break;
 | 
			
		||||
        case 7: // (x)
 | 
			
		||||
            if (mcps_indication->buffer_size == 3) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,26 +1,40 @@
 | 
			
		|||
/**
 | 
			
		||||
 / _____)             _              | |
 | 
			
		||||
( (____  _____ ____ _| |_ _____  ____| |__
 | 
			
		||||
 \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 | 
			
		||||
 _____) ) ____| | | || |_| ____( (___| | | |
 | 
			
		||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
 | 
			
		||||
    (C)2013 Semtech
 | 
			
		||||
 ___ _____ _   ___ _  _____ ___  ___  ___ ___
 | 
			
		||||
/ __|_   _/_\ / __| |/ / __/ _ \| _ \/ __| __|
 | 
			
		||||
\__ \ | |/ _ \ (__| ' <| _| (_) |   / (__| _|
 | 
			
		||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
 | 
			
		||||
embedded.connectivity.solutions===============
 | 
			
		||||
 | 
			
		||||
Description: LoRaWAN stack layer that controls both MAC and PHY underneath
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
SPDX-License-Identifier: BSD-3-Clause
 | 
			
		||||
 * \file      LoRaWANStack.h
 | 
			
		||||
 *
 | 
			
		||||
 * \brief     LoRaWAN stack layer implementation
 | 
			
		||||
 *
 | 
			
		||||
 * \copyright Revised BSD License, see LICENSE.TXT file include in the project
 | 
			
		||||
 *
 | 
			
		||||
 * \code
 | 
			
		||||
 *                ______                              _
 | 
			
		||||
 *               / _____)             _              | |
 | 
			
		||||
 *              ( (____  _____ ____ _| |_ _____  ____| |__
 | 
			
		||||
 *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 | 
			
		||||
 *               _____) ) ____| | | || |_| ____( (___| | | |
 | 
			
		||||
 *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
 | 
			
		||||
 *              (C)2013 Semtech
 | 
			
		||||
 *
 | 
			
		||||
 *               ___ _____ _   ___ _  _____ ___  ___  ___ ___
 | 
			
		||||
 *              / __|_   _/_\ / __| |/ / __/ _ \| _ \/ __| __|
 | 
			
		||||
 *              \__ \ | |/ _ \ (__| ' <| _| (_) |   / (__| _|
 | 
			
		||||
 *              |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
 | 
			
		||||
 *              embedded.connectivity.solutions===============
 | 
			
		||||
 *
 | 
			
		||||
 * \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_
 | 
			
		||||
| 
						 | 
				
			
			@ -35,11 +49,6 @@ SPDX-License-Identifier: BSD-3-Clause
 | 
			
		|||
#include "lorawan/system/lorawan_data_structures.h"
 | 
			
		||||
#include "LoRaRadio.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A mask for the network ID.
 | 
			
		||||
 */
 | 
			
		||||
#define LORAWAN_NETWORK_ID_MASK                          ( uint32_t )0xFE000000
 | 
			
		||||
 | 
			
		||||
class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
 | 
			
		||||
private:
 | 
			
		||||
    /** End-device states.
 | 
			
		||||
| 
						 | 
				
			
			@ -422,31 +431,10 @@ private:
 | 
			
		|||
     */
 | 
			
		||||
    lorawan_status_t set_application_port(uint8_t port);
 | 
			
		||||
 | 
			
		||||
    /** End device OTAA join.
 | 
			
		||||
     *
 | 
			
		||||
     * 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.
 | 
			
		||||
    /**
 | 
			
		||||
     * Handles connection internally
 | 
			
		||||
     */
 | 
			
		||||
    lorawan_status_t join_request_by_otaa(const lorawan_connect_t ¶ms);
 | 
			
		||||
 | 
			
		||||
    /** 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);
 | 
			
		||||
    lorawan_status_t handle_connect(bool is_otaa);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,11 @@ using namespace events;
 | 
			
		|||
 */
 | 
			
		||||
#define DOWN_LINK                                   1
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A mask for the network ID.
 | 
			
		||||
 */
 | 
			
		||||
#define LORAWAN_NETWORK_ID_MASK                     ( uint32_t )0xFE000000
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LoRaMac::LoRaMac()
 | 
			
		||||
    : _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,
 | 
			
		||||
                        (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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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.rx_slot = RX_SLOT_WIN_2;
 | 
			
		||||
 | 
			
		||||
    _params.rx_window2_config.is_rx_continuous = true;
 | 
			
		||||
 | 
			
		||||
    if (_device_class != CLASS_C) {
 | 
			
		||||
        _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,
 | 
			
		||||
                            (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.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,
 | 
			
		||||
                                      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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
        return LORAWAN_STATUS_BUSY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    reset_mlme_confirmation();
 | 
			
		||||
 | 
			
		||||
    _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)) {
 | 
			
		||||
    if (params) {
 | 
			
		||||
        if (is_otaa) {
 | 
			
		||||
            if ((params->connection_u.otaa.dev_eui == NULL) ||
 | 
			
		||||
                (params->connection_u.otaa.app_eui == NULL) ||
 | 
			
		||||
                (params->connection_u.otaa.app_key == NULL) ||
 | 
			
		||||
                (params->connection_u.otaa.nb_trials == 0)) {
 | 
			
		||||
                return LORAWAN_STATUS_PARAMETER_INVALID;
 | 
			
		||||
            }
 | 
			
		||||
    _params.keys.dev_eui = otaa_join.dev_eui;
 | 
			
		||||
    _params.keys.app_eui = otaa_join.app_eui;
 | 
			
		||||
    _params.keys.app_key = otaa_join.app_key;
 | 
			
		||||
    _params.max_join_request_trials = otaa_join.nb_trials;
 | 
			
		||||
            _params.keys.dev_eui = params->connection_u.otaa.dev_eui;
 | 
			
		||||
            _params.keys.app_eui = params->connection_u.otaa.app_eui;
 | 
			
		||||
            _params.keys.app_key = params->connection_u.otaa.app_key;
 | 
			
		||||
            _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
 | 
			
		||||
                _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 =
 | 
			
		||||
                    _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;
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
                                     uint16_t size)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -364,18 +364,20 @@ public:
 | 
			
		|||
    void setup_link_check_request();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief join_by_otaa Sends OTAA join message
 | 
			
		||||
     * @param otaa_join Joining parameters
 | 
			
		||||
     * @brief prepare_join prepares arguments to be ready for join() call.
 | 
			
		||||
     * @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.
 | 
			
		||||
     */
 | 
			
		||||
    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.
 | 
			
		||||
     * @param abp_join Connectivity parameters.
 | 
			
		||||
     * @brief join Joins the network.
 | 
			
		||||
     * @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:
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -452,11 +454,6 @@ private:
 | 
			
		|||
     */
 | 
			
		||||
    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
 | 
			
		||||
     * into account.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,36 +19,69 @@
 | 
			
		|||
#define LORAPHY_TARGET
 | 
			
		||||
 | 
			
		||||
#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"
 | 
			
		||||
  #define LoRaPHY_region LoRaPHYEU868
 | 
			
		||||
 #elif MBED_CONF_LORA_PHY    == 1
 | 
			
		||||
 #elif LORA_REGION    == LORA_REGION_AS923
 | 
			
		||||
  #include "lorawan/lorastack/phy/LoRaPHYAS923.h"
 | 
			
		||||
  #define LoRaPHY_region LoRaPHYAS923
 | 
			
		||||
 #elif MBED_CONF_LORA_PHY    == 2
 | 
			
		||||
 #elif LORA_REGION    == LORA_REGION_AU915
 | 
			
		||||
  #include "lorawan/lorastack/phy/LoRaPHYAU915.h"
 | 
			
		||||
 #define LoRaPHY_region LoRaPHYAU915;
 | 
			
		||||
 #elif MBED_CONF_LORA_PHY    == 3
 | 
			
		||||
 #elif LORA_REGION    == LORA_REGION_CN470
 | 
			
		||||
  #include "lorawan/lorastack/phy/LoRaPHYCN470.h"
 | 
			
		||||
  #define LoRaPHY_region LoRaPHYCN470
 | 
			
		||||
 #elif MBED_CONF_LORA_PHY    == 4
 | 
			
		||||
 #elif LORA_REGION    == LORA_REGION_CN779
 | 
			
		||||
  #include "lorawan/lorastack/phy/LoRaPHYCN779.h"
 | 
			
		||||
  #define LoRaPHY_region LoRaPHYCN779
 | 
			
		||||
 #elif MBED_CONF_LORA_PHY    == 5
 | 
			
		||||
 #elif LORA_REGION    == LORA_REGION_EU433
 | 
			
		||||
  #include "lorawan/lorastack/phy/LoRaPHYEU433.h"
 | 
			
		||||
  #define LoRaPHY_region LoRaPHYEU433
 | 
			
		||||
 #elif MBED_CONF_LORA_PHY    == 6
 | 
			
		||||
 #elif LORA_REGION    == LORA_REGION_IN865
 | 
			
		||||
  #include "lorawan/lorastack/phy/LoRaPHYIN865.h"
 | 
			
		||||
  #define LoRaPHY_region LoRaPHYIN865
 | 
			
		||||
 #elif MBED_CONF_LORA_PHY    == 7
 | 
			
		||||
 #elif LORA_REGION    == LORA_REGION_KR920
 | 
			
		||||
  #include "lorawan/lorastack/phy/LoRaPHYKR920.h"
 | 
			
		||||
  #define LoRaPHY_region LoRaPHYKR920
 | 
			
		||||
 #elif MBED_CONF_LORA_PHY    == 8
 | 
			
		||||
 #elif LORA_REGION    == LORA_REGION_US915
 | 
			
		||||
  #include "lorawan/lorastack/phy/LoRaPHYUS915.h"
 | 
			
		||||
  #define LoRaPHY_region LoRaPHYUS915
 | 
			
		||||
 #elif MBED_CONF_LORA_PHY    == 9
 | 
			
		||||
 #elif LORA_REGION    == LORA_REGION_US915_HYBRID
 | 
			
		||||
  #include "lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h"
 | 
			
		||||
  #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
 | 
			
		||||
#else
 | 
			
		||||
 #error "Must set LoRa PHY layer parameters."
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,8 @@
 | 
			
		|||
    "name": "lora",
 | 
			
		||||
    "config": {
 | 
			
		||||
        "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",
 | 
			
		||||
            "value": "0"
 | 
			
		||||
            "help": "LoRa PHY region: EU868, AS923, AU915, CN470, CN779, EU433, IN865, KR920, US915, US915_HYBRID",
 | 
			
		||||
            "value": "EU868"
 | 
			
		||||
        },
 | 
			
		||||
        "over-the-air-activation": {
 | 
			
		||||
            "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;
 | 
			
		||||
 | 
			
		||||
    lorawan_connect_t connection;
 | 
			
		||||
    /*!
 | 
			
		||||
     * Select the connection type, either LORAWAN_CONNECTION_OTAA
 | 
			
		||||
     * or LORAWAN_CONNECTION_ABP.
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t connect_type;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * LoRaWAN uplink counter
 | 
			
		||||
     */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue