BA / SerialCom

Fork of OmniWheels by Gustav Atmel

mbed-os/features/lorawan/LoRaWANInterface.cpp

Committer:
gustavatmel
Date:
2018-05-01
Revision:
1:9c5af431a1f1

File content as of revision 1:9c5af431a1f1:

/**
 * @file
 *
 * @brief      Implementation of LoRaWANBase
 *
 * Copyright (c) 2017, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "lorawan/LoRaWANInterface.h"

using namespace events;

inline LoRaWANStack& stk_obj()
{
    return LoRaWANStack::get_lorawan_stack();
}

LoRaWANInterface::LoRaWANInterface(LoRaRadio& radio) : _link_check_requested(false)
{
    // Pass mac_handlers to radio to the radio driver after
    // binding radio driver to PHY layer
    radio_events_t *events = stk_obj().bind_radio_driver(radio);
    radio.lock();
    radio.init_radio(events);
    radio.unlock();
}

LoRaWANInterface::~LoRaWANInterface()
{
}

lorawan_status_t LoRaWANInterface::initialize(EventQueue *queue)
{
    if(!queue) {
        return LORAWAN_STATUS_PARAMETER_INVALID;
    }

    return stk_obj().initialize_mac_layer(queue);
}

lorawan_status_t LoRaWANInterface::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.

    lorawan_connect_t connection_params;

    if (MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION) {
        static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI;
        static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI;
        static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY;
        /**
         *
         * OTAA join
         */
        connection_params.connect_type = LORAWAN_CONNECTION_OTAA;
        connection_params.connection_u.otaa.app_eui = app_eui;
        connection_params.connection_u.otaa.dev_eui = dev_eui;
        connection_params.connection_u.otaa.app_key = app_key;
        connection_params.connection_u.otaa.nb_trials = MBED_CONF_LORA_NB_TRIALS;

        return connect(connection_params);
    } else {
        static uint8_t nwk_skey[] = MBED_CONF_LORA_NWKSKEY;
        static uint8_t app_skey[] = MBED_CONF_LORA_APPSKEY;
        static uint32_t dev_addr = MBED_CONF_LORA_DEVICE_ADDRESS;
        static uint32_t nwk_id = (MBED_CONF_LORA_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK);

        /**
         *
         * ABP connection
         */
        connection_params.connect_type = LORAWAN_CONNECTION_ABP;
        connection_params.connection_u.abp.nwk_id = nwk_id;
        connection_params.connection_u.abp.dev_addr = dev_addr;
        connection_params.connection_u.abp.nwk_skey = nwk_skey;
        connection_params.connection_u.abp.app_skey = app_skey;

        return connect(connection_params);
    }
}

lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect)
{
    lorawan_status_t mac_status;

    if (connect.connect_type == LORAWAN_CONNECTION_OTAA) {
        mac_status = stk_obj().join_request_by_otaa(connect);
    } else if (connect.connect_type == LORAWAN_CONNECTION_ABP) {
        mac_status = stk_obj().activation_by_personalization(connect);
    } else {
        return LORAWAN_STATUS_PARAMETER_INVALID;
    }

    return mac_status;
}

lorawan_status_t LoRaWANInterface::disconnect()
{
    return stk_obj().shutdown();
}

lorawan_status_t LoRaWANInterface::add_link_check_request()
{
    _link_check_requested = true;
    return stk_obj().set_link_check_request();
}

void LoRaWANInterface::remove_link_check_request()
{
    _link_check_requested = false;
}

lorawan_status_t LoRaWANInterface::set_datarate(uint8_t data_rate)
{
    return stk_obj().set_channel_data_rate(data_rate);
}

lorawan_status_t LoRaWANInterface::set_confirmed_msg_retries(uint8_t count)
{
    return stk_obj().set_confirmed_msg_retry(count);
}

lorawan_status_t LoRaWANInterface::enable_adaptive_datarate()
{
    return stk_obj().enable_adaptive_datarate(true);
}

lorawan_status_t LoRaWANInterface::disable_adaptive_datarate()
{
    return stk_obj().enable_adaptive_datarate(false);
}

lorawan_status_t LoRaWANInterface::set_channel_plan(const lorawan_channelplan_t &channel_plan)
{
    return stk_obj().add_channels(channel_plan);
}

lorawan_status_t LoRaWANInterface::get_channel_plan(lorawan_channelplan_t &channel_plan)
{
    return stk_obj().get_enabled_channels(channel_plan);
}

lorawan_status_t LoRaWANInterface::remove_channel(uint8_t id)
{
    return stk_obj().remove_a_channel(id);
}

lorawan_status_t LoRaWANInterface::remove_channel_plan()
{
    return stk_obj().drop_channel_list();
}

int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data,
                               uint16_t length, int flags)
{
    if (_link_check_requested) {
        // add a link check request with normal data, until the application
        // explicitly removes it.
        add_link_check_request();
    }

    if (data) {
        return stk_obj().handle_tx(port, data, length, flags);
    } else {
        return LORAWAN_STATUS_PARAMETER_INVALID;
    }
}

int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length,
                                  int flags)
{
    if (data && length > 0) {
        return stk_obj().handle_rx(port, data, length, flags);
    } else {
        return LORAWAN_STATUS_PARAMETER_INVALID;
    }
}

lorawan_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks)
  {

     if (!callbacks || !callbacks->events) {
         // Event Callback is mandatory
         return LORAWAN_STATUS_PARAMETER_INVALID;
     }

     stk_obj().set_lora_callbacks(callbacks);
     return LORAWAN_STATUS_OK;
  }