You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2017/04/29 00:28:42 UTC

[04/19] incubator-mynewt-core git commit: MYNEWT-741 Port of LoRaMac-node library

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/include/node/radio.h
----------------------------------------------------------------------
diff --git a/net/lora/node/include/node/radio.h b/net/lora/node/include/node/radio.h
new file mode 100644
index 0000000..6923ec9
--- /dev/null
+++ b/net/lora/node/include/node/radio.h
@@ -0,0 +1,337 @@
+/*
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2013 Semtech
+
+Description: Generic radio driver definition
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __RADIO_H__
+#define __RADIO_H__
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+/*!
+ * Radio driver supported modems
+ */
+typedef enum
+{
+    MODEM_FSK = 0,
+    MODEM_LORA,
+}RadioModems_t;
+
+/*!
+ * Radio driver internal state machine states definition
+ */
+typedef enum
+{
+    RF_IDLE = 0,
+    RF_RX_RUNNING,
+    RF_TX_RUNNING,
+    RF_CAD,
+}RadioState_t;
+
+/*!
+ * \brief Radio driver callback functions
+ */
+typedef struct
+{
+    /*!
+     * \brief  Tx Done callback prototype.
+     */
+    void    ( *TxDone )( void );
+    /*!
+     * \brief  Tx Timeout callback prototype.
+     */
+    void    ( *TxTimeout )( void );
+    /*!
+     * \brief Rx Done callback prototype.
+     *
+     * \param [IN] payload Received buffer pointer
+     * \param [IN] size    Received buffer size
+     * \param [IN] rssi    RSSI value computed while receiving the frame [dBm]
+     * \param [IN] snr     Raw SNR value given by the radio hardware
+     *                     FSK : N/A ( set to 0 )
+     *                     LoRa: SNR value in dB
+     */
+    void    ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
+    /*!
+     * \brief  Rx Timeout callback prototype.
+     */
+    void    ( *RxTimeout )( void );
+    /*!
+     * \brief Rx Error callback prototype.
+     */
+    void    ( *RxError )( void );
+    /*!
+     * \brief  FHSS Change Channel callback prototype.
+     *
+     * \param [IN] currentChannel   Index number of the current channel
+     */
+    void ( *FhssChangeChannel )( uint8_t currentChannel );
+
+    /*!
+     * \brief CAD Done callback prototype.
+     *
+     * \param [IN] channelDetected    Channel Activity detected during the CAD
+     */
+    void ( *CadDone ) ( bool channelActivityDetected );
+}RadioEvents_t;
+
+/*!
+ * \brief Radio driver definition
+ */
+struct Radio_s
+{
+    /*!
+     * \brief Initializes the radio
+     *
+     * \param [IN] events Structure containing the driver callback functions
+     */
+    void    ( *Init )( RadioEvents_t *events );
+    /*!
+     * Return current radio status
+     *
+     * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING]
+     */
+    RadioState_t ( *GetStatus )( void );
+    /*!
+     * \brief Configures the radio with the given modem
+     *
+     * \param [IN] modem Modem to be used [0: FSK, 1: LoRa] 
+     */
+    void    ( *SetModem )( RadioModems_t modem );
+    /*!
+     * \brief Sets the channel frequency
+     *
+     * \param [IN] freq         Channel RF frequency
+     */
+    void    ( *SetChannel )( uint32_t freq );
+    /*!
+     * \brief Sets the channels configuration
+     *
+     * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
+     * \param [IN] freq       Channel RF frequency
+     * \param [IN] rssiThresh RSSI threshold
+     *
+     * \retval isFree         [true: Channel is free, false: Channel is not free]
+     */
+    bool    ( *IsChannelFree )( RadioModems_t modem, uint32_t freq, int16_t rssiThresh );
+    /*!
+     * \brief Generates a 32 bits random value based on the RSSI readings
+     *
+     * \remark This function sets the radio in LoRa modem mode and disables 
+     *         all interrupts.
+     *         After calling this function either Radio.SetRxConfig or
+     *         Radio.SetTxConfig functions must be called.
+     *
+     * \retval randomValue    32 bits random value
+     */
+    uint32_t ( *Random )( void );
+    /*!
+     * \brief Sets the reception parameters
+     *
+     * \param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa]
+     * \param [IN] bandwidth    Sets the bandwidth
+     *                          FSK : >= 2600 and <= 250000 Hz
+     *                          LoRa: [0: 125 kHz, 1: 250 kHz,
+     *                                 2: 500 kHz, 3: Reserved] 
+     * \param [IN] datarate     Sets the Datarate
+     *                          FSK : 600..300000 bits/s
+     *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
+     *                                10: 1024, 11: 2048, 12: 4096  chips]
+     * \param [IN] coderate     Sets the coding rate (LoRa only)
+     *                          FSK : N/A ( set to 0 )
+     *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] 
+     * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) 
+     *                          FSK : >= 2600 and <= 250000 Hz
+     *                          LoRa: N/A ( set to 0 ) 
+     * \param [IN] preambleLen  Sets the Preamble length
+     *                          FSK : Number of bytes 
+     *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
+     * \param [IN] symbTimeout  Sets the RxSingle timeout value (LoRa only) 
+     *                          FSK : N/A ( set to 0 ) 
+     *                          LoRa: timeout in symbols
+     * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
+     * \param [IN] payloadLen   Sets payload length when fixed length is used
+     * \param [IN] crcOn        Enables/Disables the CRC [0: OFF, 1: ON]
+     * \param [IN] FreqHopOn    Enables disables the intra-packet frequency hopping
+     *                          FSK : N/A ( set to 0 )
+     *                          LoRa: [0: OFF, 1: ON]
+     * \param [IN] HopPeriod    Number of symbols between each hop
+     *                          FSK : N/A ( set to 0 )
+     *                          LoRa: Number of symbols
+     * \param [IN] iqInverted   Inverts IQ signals (LoRa only)
+     *                          FSK : N/A ( set to 0 )
+     *                          LoRa: [0: not inverted, 1: inverted]
+     * \param [IN] rxContinuous Sets the reception in continuous mode
+     *                          [false: single mode, true: continuous mode]
+     */
+    void    ( *SetRxConfig )( RadioModems_t modem, uint32_t bandwidth,
+                              uint32_t datarate, uint8_t coderate,
+                              uint32_t bandwidthAfc, uint16_t preambleLen,
+                              uint16_t symbTimeout, bool fixLen,
+                              uint8_t payloadLen,
+                              bool crcOn, bool FreqHopOn, uint8_t HopPeriod,
+                              bool iqInverted, bool rxContinuous );
+    /*!
+     * \brief Sets the transmission parameters
+     *
+     * \param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa] 
+     * \param [IN] power        Sets the output power [dBm]
+     * \param [IN] fdev         Sets the frequency deviation (FSK only)
+     *                          FSK : [Hz]
+     *                          LoRa: 0
+     * \param [IN] bandwidth    Sets the bandwidth (LoRa only)
+     *                          FSK : 0
+     *                          LoRa: [0: 125 kHz, 1: 250 kHz,
+     *                                 2: 500 kHz, 3: Reserved] 
+     * \param [IN] datarate     Sets the Datarate
+     *                          FSK : 600..300000 bits/s
+     *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
+     *                                10: 1024, 11: 2048, 12: 4096  chips]
+     * \param [IN] coderate     Sets the coding rate (LoRa only)
+     *                          FSK : N/A ( set to 0 )
+     *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] 
+     * \param [IN] preambleLen  Sets the preamble length
+     *                          FSK : Number of bytes 
+     *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
+     * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
+     * \param [IN] crcOn        Enables disables the CRC [0: OFF, 1: ON]
+     * \param [IN] FreqHopOn    Enables disables the intra-packet frequency hopping
+     *                          FSK : N/A ( set to 0 )
+     *                          LoRa: [0: OFF, 1: ON]
+     * \param [IN] HopPeriod    Number of symbols between each hop
+     *                          FSK : N/A ( set to 0 )
+     *                          LoRa: Number of symbols
+     * \param [IN] iqInverted   Inverts IQ signals (LoRa only)
+     *                          FSK : N/A ( set to 0 )
+     *                          LoRa: [0: not inverted, 1: inverted]
+     * \param [IN] timeout      Transmission timeout [ms]
+     */
+    void    ( *SetTxConfig )( RadioModems_t modem, int8_t power, uint32_t fdev, 
+                              uint32_t bandwidth, uint32_t datarate,
+                              uint8_t coderate, uint16_t preambleLen,
+                              bool fixLen, bool crcOn, bool FreqHopOn,
+                              uint8_t HopPeriod, bool iqInverted, uint32_t timeout );
+    /*!
+     * \brief Checks if the given RF frequency is supported by the hardware
+     *
+     * \param [IN] frequency RF frequency to be checked
+     * \retval isSupported [true: supported, false: unsupported]
+     */
+    bool    ( *CheckRfFrequency )( uint32_t frequency );
+    /*!
+     * \brief Computes the packet time on air in ms for the given payload
+     *
+     * \Remark Can only be called once SetRxConfig or SetTxConfig have been called
+     *
+     * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
+     * \param [IN] pktLen     Packet payload length
+     *
+     * \retval airTime        Computed airTime (ms) for the given packet payload length
+     */
+    uint32_t  ( *TimeOnAir )( RadioModems_t modem, uint8_t pktLen );
+    /*!
+     * \brief Sends the buffer of size. Prepares the packet to be sent and sets
+     *        the radio in transmission
+     *
+     * \param [IN]: buffer     Buffer pointer
+     * \param [IN]: size       Buffer size
+     */
+    void    ( *Send )( uint8_t *buffer, uint8_t size );
+    /*!
+     * \brief Sets the radio in sleep mode
+     */
+    void    ( *Sleep )( void );
+    /*!
+     * \brief Sets the radio in standby mode
+     */
+    void    ( *Standby )( void );
+    /*!
+     * \brief Sets the radio in reception mode for the given time
+     * \param [IN] timeout Reception timeout [ms]
+     *                     [0: continuous, others timeout]
+     */
+    void    ( *Rx )( uint32_t timeout );
+    /*!
+     * \brief Start a Channel Activity Detection
+     */
+    void    ( *StartCad )( void );
+    /*!
+     * \brief Sets the radio in continuous wave transmission mode
+     *
+     * \param [IN]: freq       Channel RF frequency
+     * \param [IN]: power      Sets the output power [dBm]
+     * \param [IN]: time       Transmission mode timeout [s]
+     */
+    void    ( *SetTxContinuousWave )( uint32_t freq, int8_t power, uint16_t time );
+    /*!
+     * \brief Reads the current RSSI value
+     *
+     * \retval rssiValue Current RSSI value in [dBm]
+     */
+    int16_t ( *Rssi )( RadioModems_t modem );
+    /*!
+     * \brief Writes the radio register at the specified address
+     *
+     * \param [IN]: addr Register address
+     * \param [IN]: data New register value
+     */
+    void    ( *Write )( uint8_t addr, uint8_t data );
+    /*!
+     * \brief Reads the radio register at the specified address
+     *
+     * \param [IN]: addr Register address
+     * \retval data Register value
+     */
+    uint8_t ( *Read )( uint8_t addr );
+    /*!
+     * \brief Writes multiple radio registers starting at address
+     *
+     * \param [IN] addr   First Radio register address
+     * \param [IN] buffer Buffer containing the new register's values
+     * \param [IN] size   Number of registers to be written
+     */
+    void    ( *WriteBuffer )( uint8_t addr, uint8_t *buffer, uint8_t size );
+    /*!
+     * \brief Reads multiple radio registers starting at address
+     *
+     * \param [IN] addr First Radio register address
+     * \param [OUT] buffer Buffer where to copy the registers data
+     * \param [IN] size Number of registers to be read
+     */
+    void    ( *ReadBuffer )( uint8_t addr, uint8_t *buffer, uint8_t size );
+    /*!
+     * \brief Sets the maximum payload length.
+     *
+     * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
+     * \param [IN] max        Maximum payload length in bytes
+     */
+    void    ( *SetMaxPayloadLength )( RadioModems_t modem, uint8_t max );
+    /*!
+     * \brief Sets the network to public or private. Updates the sync byte.
+     *
+     * \remark Applies to LoRa modem only
+     *
+     * \param [IN] enable if true, it enables a public network
+     */
+    void    ( *SetPublicNetwork )( bool enable );
+};
+
+/*!
+ * \brief Radio driver
+ *
+ * \remark This variable is defined and initialized in the specific radio
+ *         board implementation
+ */
+extern const struct Radio_s Radio;
+
+#endif // __RADIO_H__

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/include/node/timer.h
----------------------------------------------------------------------
diff --git a/net/lora/node/include/node/timer.h b/net/lora/node/include/node/timer.h
new file mode 100644
index 0000000..424dc32
--- /dev/null
+++ b/net/lora/node/include/node/timer.h
@@ -0,0 +1,38 @@
+/*
+ / _____)             _              | |
+((____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____)) ____| | | || |_| ____((___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2013 Semtech
+
+Description: Timer objects and scheduling management
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __TIMER_H__
+#define __TIMER_H__
+
+#include <inttypes.h>
+#include <stdbool.h>
+struct hal_timer;
+
+/*!
+ * \brief Return the Time elapsed since a fix moment in Time
+ *
+ * \param [IN] savedTime    fix moment in Time
+ * \retval time             returns elapsed time
+ */
+uint32_t TimerGetElapsedTime(uint32_t savedTime);
+
+/*!
+ * \brief Return the Time elapsed since a fix moment in Time
+ *
+ * \param [IN] eventInFuture    fix moment in the future
+ * \retval time             returns difference between now and future event
+ */
+uint32_t TimerGetFutureTime(uint32_t eventInFuture);
+
+#endif  // __TIMER_H__

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/include/node/utilities.h
----------------------------------------------------------------------
diff --git a/net/lora/node/include/node/utilities.h b/net/lora/node/include/node/utilities.h
new file mode 100644
index 0000000..8816351
--- /dev/null
+++ b/net/lora/node/include/node/utilities.h
@@ -0,0 +1,72 @@
+/*
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2013 Semtech
+
+Description: Helper functions implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __UTILITIES_H__
+#define __UTILITIES_H__
+
+#include <inttypes.h>
+
+/*!
+ * \brief Returns the minimum value between a and b
+ *
+ * \param [IN] a 1st value
+ * \param [IN] b 2nd value
+ * \retval minValue Minimum value
+ */
+#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
+
+/*!
+ * \brief Returns the maximum value between a and b
+ *
+ * \param [IN] a 1st value
+ * \param [IN] b 2nd value
+ * \retval maxValue Maximum value
+ */
+#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
+
+/*!
+ * \brief Returns 2 raised to the power of n
+ *
+ * \param [IN] n power value
+ * \retval result of raising 2 to the power n
+ */
+#define POW2( n ) ( 1 << n )
+
+/*!
+ * \brief Computes a random number between min and max
+ *
+ * \param [IN] min range minimum value
+ * \param [IN] max range maximum value
+ * \retval random random value in range min..max
+ */
+int32_t randr( int32_t min, int32_t max );
+
+/*!
+ * \brief Copies size elements of src array to dst array reversing the byte order
+ *
+ * \param [OUT] dst  Destination array
+ * \param [IN]  src  Source array
+ * \param [IN]  size Number of bytes to be copied
+ */
+void memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size );
+
+/*!
+ * \brief Converts a nibble to an hexadecimal character
+ *
+ * \param [IN] a   Nibble to be converted
+ * \retval hexChar Converted hexadecimal character
+ */
+int8_t Nibble2HexChar( uint8_t a );
+
+#endif // __UTILITIES_H__

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/pkg.yml
----------------------------------------------------------------------
diff --git a/net/lora/node/pkg.yml b/net/lora/node/pkg.yml
new file mode 100644
index 0000000..694bc01
--- /dev/null
+++ b/net/lora/node/pkg.yml
@@ -0,0 +1,42 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+pkg.name: net/lora/node
+pkg.description: Mynewt port of the Semtech LoRaWAN endpoint stack.
+pkg.author: "Semtech"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - lora
+
+pkg.cflags:
+    # Allow declarations inside for loops.
+    - "-std=c99"
+
+pkg.deps:
+
+pkg.deps.LORA_NODE_CLI:
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/util/parse"
+
+pkg.req_apis:
+    - lora_node_board
+    - lora_node_radio
+
+pkg.init:
+    lora_node_init: 200

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/src/lora_cli.c
----------------------------------------------------------------------
diff --git a/net/lora/node/src/lora_cli.c b/net/lora/node/src/lora_cli.c
new file mode 100644
index 0000000..99156fb
--- /dev/null
+++ b/net/lora/node/src/lora_cli.c
@@ -0,0 +1,569 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "syscfg/syscfg.h"
+
+#if MYNEWT_VAL(LORA_NODE_CLI)
+
+#include <inttypes.h>
+#include <string.h>
+
+#include "sysinit/sysinit.h"
+#include "shell/shell.h"
+#include "console/console.h"
+#include "node/radio.h"
+#include "parse/parse.h"
+
+static int lora_cli_cmd_fn(int argc, char **argv);
+static int lora_cli_set_freq(int argc, char **argv);
+static int lora_cli_tx_cfg(int argc, char **argv);
+static int lora_cli_rx_cfg(int argc, char **argv);
+static int lora_cli_tx(int argc, char **argv);
+static int lora_cli_rx(int argc, char **argv);
+static int lora_cli_max_payload_len(int argc, char **argv);
+
+static struct shell_cmd lora_cli_cmd = {
+    .sc_cmd = "lora",
+    .sc_cmd_func = lora_cli_cmd_fn,
+};
+
+static struct shell_cmd lora_cli_subcmds[] = {
+    {
+        .sc_cmd = "set_freq",
+        .sc_cmd_func = lora_cli_set_freq,
+    },
+    {
+        .sc_cmd = "tx_cfg",
+        .sc_cmd_func = lora_cli_tx_cfg,
+    },
+    {
+        .sc_cmd = "rx_cfg",
+        .sc_cmd_func = lora_cli_rx_cfg,
+    },
+    {
+        .sc_cmd = "tx",
+        .sc_cmd_func = lora_cli_tx,
+    },
+    {
+        .sc_cmd = "rx",
+        .sc_cmd_func = lora_cli_rx,
+    },
+    {
+        .sc_cmd = "max_payload_len",
+        .sc_cmd_func = lora_cli_max_payload_len,
+    },
+};
+
+static int
+lora_cli_cmd_fn(int argc, char **argv)
+{
+    const struct shell_cmd *subcmd;
+    const char *err;
+    int rc;
+    int i;
+
+    if (argc <= 1) {
+        rc = 1;
+        err = NULL;
+        goto err;
+    }
+
+    for (i = 0;
+         i < sizeof lora_cli_subcmds / sizeof lora_cli_subcmds[0];
+         i++) {
+
+        subcmd = lora_cli_subcmds + i;
+        if (strcmp(argv[1], subcmd->sc_cmd) == 0) {
+            rc = subcmd->sc_cmd_func(argc - 1, argv + 1);
+            return rc;
+        }
+    }
+
+    rc = 1;
+    err = "invalid lora command";
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora set_freq\n"
+"    lora tx_cfg\n"
+"    lora rx_cfg\n"
+"    lora tx\n"
+"    lora rx\n"
+"    lora max_payload_len\n");
+
+    return rc;
+}
+
+static int
+lora_cli_set_freq(int argc, char **argv)
+{
+    const char *err;
+    uint32_t freq;
+    int rc;
+
+    if (argc <= 1) {
+        rc = 1;
+        err = NULL;
+        goto err;
+    }
+
+    freq = parse_ull(argv[1], &rc);
+    if (rc != 0) {
+        err = "invalid frequency";
+        goto err;
+    }
+
+    Radio.SetChannel(freq);
+    return 0;
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora set_freq <hz>\n");
+
+    return rc;
+}
+
+static int
+lora_cli_tx_cfg(int argc, char **argv)
+{
+    RadioModems_t modem;
+    const char *err;
+    char **arg;
+    uint32_t bandwidth;
+    uint32_t datarate;
+    uint32_t timeout;
+    uint32_t fdev;
+    uint16_t preamble_len;
+    uint8_t hop_period;
+    uint8_t coderate;
+    int8_t power;
+    int freq_hop_on;
+    int iq_inverted;
+    int fix_len;
+    int crc_on;
+    int rc;
+
+    if (argc <= 13) {
+        rc = 1;
+        err = NULL;
+        goto err;
+    }
+
+    arg = argv + 1;
+
+    modem = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    power = parse_ll_bounds(*arg, INT8_MIN, INT8_MAX, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    fdev = parse_ull_bounds(*arg, 0, UINT32_MAX, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    bandwidth = parse_ull_bounds(*arg, 0, UINT32_MAX, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    datarate = parse_ull_bounds(*arg, 0, UINT32_MAX, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    coderate = parse_ull_bounds(*arg, 0, UINT8_MAX, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    preamble_len = parse_ull_bounds(*arg, 0, UINT16_MAX, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    fix_len = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    crc_on = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    freq_hop_on = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    hop_period = parse_ull_bounds(*arg, 0, UINT8_MAX, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    iq_inverted = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    timeout = parse_ull_bounds(*arg, 0, UINT32_MAX, &rc);
+    if (rc != 0) {
+        goto err;
+    }
+    arg++;
+
+    Radio.SetTxConfig(modem,
+                      power,
+                      fdev,
+                      bandwidth,
+                      datarate,
+                      coderate,
+                      preamble_len,
+                      fix_len,
+                      crc_on,
+                      freq_hop_on,
+                      hop_period,
+                      iq_inverted,
+                      timeout);
+
+    return 0;
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora tx_cfg <modem-type (0/1)> <power> <frequency-deviation>\n"
+"                <bandwidth> <data-rate> <code-rate> <preamble-length>\n"
+"                <fixed-length (0/1)> <crc-on (0/1)>\n"
+"                <frequency-hopping (0/1)> <hop-period> <iq-inverted (0/1)>\n"
+"                <timeout>\n");
+
+    return rc;
+}
+
+static int
+lora_cli_rx_cfg(int argc, char **argv)
+{
+    RadioModems_t modem;
+    const char *err;
+    char **arg;
+    uint32_t bandwidth_afc;
+    uint32_t bandwidth;
+    uint32_t datarate;
+    uint16_t preamble_len;
+    uint16_t symb_timeout;
+    uint8_t payload_len;
+    uint8_t hop_period;
+    uint8_t coderate;
+    int rx_continuous;
+    int freq_hop_on;
+    int iq_inverted;
+    int fix_len;
+    int crc_on;
+    int rc;
+
+    if (argc <= 14) {
+        rc = 1;
+        err = NULL;
+        goto err;
+    }
+
+    arg = argv + 1;
+
+    modem = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        err = "invalid modem type";
+        goto err;
+    }
+    arg++;
+
+    bandwidth = parse_ull_bounds(*arg, 0, UINT32_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid bandwidth";
+        goto err;
+    }
+    arg++;
+
+    datarate = parse_ull_bounds(*arg, 0, UINT32_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid data rate";
+        goto err;
+    }
+    arg++;
+
+    coderate = parse_ull_bounds(*arg, 0, UINT8_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid code rate";
+        goto err;
+    }
+    arg++;
+
+    bandwidth_afc = parse_ull_bounds(*arg, 0, UINT32_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid bandwidtch_afc";
+        goto err;
+    }
+    arg++;
+
+    preamble_len = parse_ull_bounds(*arg, 0, UINT16_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid preamble length";
+        goto err;
+    }
+    arg++;
+
+    symb_timeout = parse_ull_bounds(*arg, 0, UINT16_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid symbol timeout";
+        goto err;
+    }
+    arg++;
+
+    fix_len = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        err = "invalid fixed length value";
+        goto err;
+    }
+    arg++;
+
+    payload_len = parse_ull_bounds(*arg, 0, UINT8_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid payload length";
+        goto err;
+    }
+    arg++;
+
+    crc_on = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        err = "invalid crc on value";
+        goto err;
+    }
+    arg++;
+
+    freq_hop_on = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        err = "invalid frequency hopping value";
+        goto err;
+    }
+    arg++;
+
+    hop_period = parse_ull_bounds(*arg, 0, UINT8_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid hop period";
+        goto err;
+    }
+    arg++;
+
+    iq_inverted = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        err = "invalid iq inverted value";
+        goto err;
+    }
+    arg++;
+
+    rx_continuous = parse_ull_bounds(*arg, 0, 1, &rc);
+    if (rc != 0) {
+        err = "invalid rx continuous value";
+        goto err;
+    }
+    arg++;
+
+    Radio.SetRxConfig(modem,
+                      bandwidth,
+                      datarate,
+                      coderate,
+                      bandwidth_afc,
+                      preamble_len,
+                      symb_timeout,
+                      fix_len,
+                      payload_len,
+                      crc_on,
+                      freq_hop_on,
+                      hop_period,
+                      iq_inverted,
+                      rx_continuous);
+
+    return 0;
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora rx_cfg <modem-type (0/1)> <bandwidth> <data-rate> <code-rate>\n"
+"                <bandwidtch-afc> <preamble-length> <symbol-timeout>\n"
+"                <fixed-length (0/1)> <payload-length> <crc-on (0/1)>\n"
+"                <frequency-hopping (0/1)> <hop-period> <iq-inverted (0/1)>\n"
+"                <rx-continuous (0/1)>\n");
+
+    return rc;
+}
+
+static int
+lora_cli_tx(int argc, char **argv)
+{
+    uint8_t buf[UINT8_MAX];
+    const char *err;
+    int buf_sz;
+    int rc;
+
+    if (argc <= 1) {
+        rc = 1;
+        err = NULL;
+        goto err;
+    }
+
+    rc = parse_byte_stream(argv[1], sizeof buf, buf, &buf_sz);
+    if (rc != 0) {
+        err = "invalid payload";
+        goto err;
+    }
+
+    Radio.Send(buf, buf_sz);
+    return 0;
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora tx <0xXX:0xXX:...>\n");
+
+    return rc;
+}
+
+static int
+lora_cli_rx(int argc, char **argv)
+{
+    const char *err;
+    uint32_t timeout;
+    int rc;
+
+    if (argc <= 1) {
+        rc = 1;
+        err = NULL;
+        goto err;
+    }
+
+    timeout = parse_ull_bounds(argv[1], 0, UINT32_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid timeout";
+        goto err;
+    }
+
+    Radio.Rx(timeout);
+    return 0;
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora rx <timeout>\n");
+
+    return rc;
+}
+
+static int
+lora_cli_max_payload_len(int argc, char **argv)
+{
+    RadioModems_t modem;
+    const char *err;
+    uint8_t len;
+    int rc;
+
+    if (argc <= 2) {
+        rc = 1;
+        err = NULL;
+        goto err;
+    }
+
+    modem = parse_ull_bounds(argv[1], 0, 1, &rc);
+    if (rc != 0) {
+        err = "invalid modem type";
+        goto err;
+    }
+
+    len = parse_ull_bounds(argv[2], 0, UINT8_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid length";
+        goto err;
+    }
+
+    Radio.SetMaxPayloadLength(modem, len);
+    return 0;
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora max_payload_len <length>\n");
+
+    return rc;
+}
+
+void
+lora_cli_init(void)
+{
+    int rc;
+
+    rc = shell_cmd_register(&lora_cli_cmd);
+    SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register lora CLI command");
+}
+
+#endif /* MYNEWT_VAL(LORA_NODE_CLI) */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/src/lora_node.c
----------------------------------------------------------------------
diff --git a/net/lora/node/src/lora_node.c b/net/lora/node/src/lora_node.c
new file mode 100644
index 0000000..57a2b1f
--- /dev/null
+++ b/net/lora/node/src/lora_node.c
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "sysinit/sysinit.h"
+#include "syscfg/syscfg.h"
+#include "node/lora.h"
+#include "lora_priv.h"
+
+STATS_SECT_DECL(lora_stats) lora_stats;
+STATS_NAME_START(lora_stats)
+    STATS_NAME(lora_stats, rx_error)
+    STATS_NAME(lora_stats, rx_success)
+    STATS_NAME(lora_stats, rx_timeout)
+    STATS_NAME(lora_stats, tx_success)
+    STATS_NAME(lora_stats, tx_timeout)
+STATS_NAME_END(lora_stats)
+
+void
+lora_node_init(void)
+{
+    int rc;
+
+    rc = stats_init_and_reg(
+        STATS_HDR(lora_stats),
+        STATS_SIZE_INIT_PARMS(lora_stats, STATS_SIZE_32),
+        STATS_NAME_INIT_PARMS(lora_stats), "lora");
+    SYSINIT_PANIC_ASSERT(rc == 0);
+
+#if MYNEWT_VAL(LORA_NODE_CLI)
+    lora_cli_init();
+#endif
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/net/lora/node/src/lora_priv.h
----------------------------------------------------------------------
diff --git a/net/lora/node/src/lora_priv.h b/net/lora/node/src/lora_priv.h
new file mode 100644
index 0000000..bf0dd28
--- /dev/null
+++ b/net/lora/node/src/lora_priv.h
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+#ifndef H_LORA_PRIV_
+#define H_LORA_PRIV_
+
+#include "syscfg/syscfg.h"
+
+#if   MYNEWT_VAL(LORA_NODE_FREQ_BAND) == 433
+#define USE_BAND_433
+
+#elif MYNEWT_VAL(LORA_NODE_FREQ_BAND) == 470
+#define USE_BAND_470
+
+#elif MYNEWT_VAL(LORA_NODE_FREQ_BAND) == 780
+#define USE_BAND_780
+
+#elif MYNEWT_VAL(LORA_NODE_FREQ_BAND) == 868
+#define USE_BAND_868
+
+#elif MYNEWT_VAL(LORA_NODE_FREQ_BAND) == 915
+#define USE_BAND_915
+
+#endif
+
+void lora_cli_init(void);
+
+#endif