summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Gilles <jgilles@multitech.com>2015-05-22 14:47:15 -0500
committerJesse Gilles <jgilles@multitech.com>2015-05-22 14:47:15 -0500
commitbfd5846c53d528c16a875f5b2469e1d29381763e (patch)
tree8182631bb580d0a05c05624b7e8a736f4ec983c6
parent2fe4b3bfcaef7164f8890d4eec58450e7271b639 (diff)
downloadmeta-mlinux-bfd5846c53d528c16a875f5b2469e1d29381763e.tar.gz
meta-mlinux-bfd5846c53d528c16a875f5b2469e1d29381763e.tar.bz2
meta-mlinux-bfd5846c53d528c16a875f5b2469e1d29381763e.zip
add recipes for initial LoRa support for MTAC-LORA
-rw-r--r--recipes-connectivity/lora/lora-gateway.inc55
-rw-r--r--recipes-connectivity/lora/lora-gateway/library.cfg73
-rw-r--r--recipes-connectivity/lora/lora-gateway/lora-gateway-debug.patch13
-rw-r--r--recipes-connectivity/lora/lora-gateway_1.7.0mts.bb7
-rw-r--r--recipes-connectivity/lora/lora-network-server/lora-network-server.default2
-rwxr-xr-xrecipes-connectivity/lora/lora-network-server/lora-network-server.init101
-rw-r--r--recipes-connectivity/lora/lora-network-server/lora-network-server.logrotate.conf7
-rw-r--r--recipes-connectivity/lora/lora-network-server_0.0.2-11-g82ab10d.bb49
-rw-r--r--recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-fixb64.patch66
-rw-r--r--recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-mts-enhancements.patch265
-rw-r--r--recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-set-spi-path.patch111
-rw-r--r--recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-skip-bad-packets.patch54
-rw-r--r--recipes-connectivity/lora/lora-packet-forwarder_1.4.1.bb52
-rw-r--r--recipes-connectivity/lora/lora-query_0.0.1.bb21
14 files changed, 876 insertions, 0 deletions
diff --git a/recipes-connectivity/lora/lora-gateway.inc b/recipes-connectivity/lora/lora-gateway.inc
new file mode 100644
index 0000000..afd68e0
--- /dev/null
+++ b/recipes-connectivity/lora/lora-gateway.inc
@@ -0,0 +1,55 @@
+DESCRIPTION = "LoRa Gateway library"
+HOMEPAGE = "https://www.semtech.com/"
+PRIORITY = "optional"
+SECTION = "console/utils"
+# Semtech license is a modified BSD-style license
+LICENSE = "SEMTECH"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=a2bdef95625509f821ba00460e3ae0eb"
+DEPENDS = "libftdi libmpsse libusb1"
+INC_PR = "r8"
+BRANCH ?= "master"
+
+SRC_URI = "git://git.multitech.net/lora_gateway;protocol=git;branch=${BRANCH} \
+ file://lora-gateway-debug.patch \
+ file://library.cfg \
+ "
+
+S = "${WORKDIR}/git"
+
+CFLAGS += "-Iinc -I. -DLIBFTDI1=1"
+
+do_configure_append() {
+ # copy over custom library.cfg
+ cp ${WORKDIR}/library.cfg ${S}/libloragw/
+}
+
+do_compile() {
+ oe_runmake
+}
+
+do_install() {
+ install -d ${D}${includedir}/lora
+ install -d ${D}${libdir}/lora
+ install -m 0644 libloragw/libloragw.a ${D}${libdir}/lora
+ install -m 0644 libloragw/library.cfg ${D}${libdir}/lora
+ install -m 0644 libloragw/inc/* ${D}${includedir}/lora
+
+ install -d ${D}/opt/lora
+ install -m 0755 libloragw/test_* ${D}/opt/lora/
+ install -m 0755 util_pkt_logger/util_pkt_logger ${D}/opt/lora/
+ install -m 0755 util_band_survey/util_band_survey ${D}/opt/lora/
+ install -m 0755 util_spi_stress/util_spi_stress ${D}/opt/lora/
+ install -m 0755 util_tx_test/util_tx_test ${D}/opt/lora/
+}
+
+PACKAGES += "${PN}-utils ${PN}-utils-dbg"
+
+FILES_${PN}-utils = "/opt/lora/*"
+FILES_${PN}-utils-dbg = "/opt/lora/.debug"
+FILES_${PN}-dev = "${includedir}/lora ${libdir}/lora/library.cfg"
+FILES_${PN}-staticdev = "${libdir}/lora/libloragw.a"
+
+# disable this on purpose for dev purposes
+do_rm_work() {
+ echo "skipping"
+}
diff --git a/recipes-connectivity/lora/lora-gateway/library.cfg b/recipes-connectivity/lora/lora-gateway/library.cfg
new file mode 100644
index 0000000..01b066d
--- /dev/null
+++ b/recipes-connectivity/lora/lora-gateway/library.cfg
@@ -0,0 +1,73 @@
+# That file will be included in the Makefile files that have hardware dependencies
+
+### SPI interface to the concentrator ###
+# Accepted values:
+# native Linux native SPI driver (/dev/spidev32766.0)
+# ftdi FTDI SPI-over-USB bridge using libmpsse/libftdi/libusb
+
+CFG_SPI= ftdi
+CFG_SPI_DEV = "/dev/spidev32766.2"
+
+### Concentrator chip ###
+# Accepted values:
+# sx1301 Semtech SX1301 production chip
+# fpga1301 FPGA containing the SX1301 IP
+
+CFG_CHIP= sx1301
+
+### Radio chip(s) ###
+# Accepted values:
+# sx1257 Dual SX1257 transceivers, covering 860-1000 MHz
+# sx1255 Dual SX1255 transceivers, covering 400-510 MHz
+
+CFG_RADIO= sx1257
+
+### RF band configuration ###
+# Used to configured frequency restrictions (eg. if a SAW filter is installed)
+# Accepted values:
+# full Full range supported by the radio(s)
+# eu868 ETSI 868 (866) MHz band
+# us915 FCC 915 MHz band
+# cn470 China 470 MHz band
+# eu433 ETSI 433 MHz band
+# cn780 China 780 MHz band
+
+CFG_BAND= full
+
+### Board misc parameters & calibration ###
+# Used to configure misc board options.
+# RX RSSI indication and TX power are highly dependant on radio, band, filter
+# and RF front-ends, and must be calibrated for each new board design.
+# Available calibration parameters:
+# dev_nano_868 FPGA-based nano-concentrator, with 868 MHz SAW filter
+# ref_1301_868 SX1301 reference board with SX1257 radios, 868 MHz filters
+# ref_1301_433 SX1301 reference board with SX1255 radios, 433 MHz filters
+# kerlink_868 Kerlink LoRa 868MHz gateway
+# kerlink_433 Kerlink LoRa 433MHz gateway
+# cisco_433 Cisco LoRa 433MHz gateway
+# cisco_470 Cisco LoRa 470MHz gateway
+# cisco_780 Cisco LoRa 780MHz gateway
+# Keep empty for no calibration parameters (neutral values will be used).
+
+# MTAC-LORA 900MHz
+CFG_BRD= mtaclora
+
+### Network Type ###
+# Accepted values:
+# private Default
+# lora_mac Only compliant with devices running LoRa MAC
+
+CFG_NET= private
+
+### Debug options ###
+# Set the DEBUG_* to 1 to activate debug mode in individual modules.
+# Warning: that makes the module *very verbose*, do not use for production
+
+DEBUG_AUX= 0
+DEBUG_SPI= 0
+DEBUG_REG= 0
+# jjg - turning this on is useful to get HAL-related error messages that
+# don't print out otherwise. It doesn't seem to add that much printing
+# under normal operation.
+DEBUG_HAL= 1
+DEBUG_GPS= 0
diff --git a/recipes-connectivity/lora/lora-gateway/lora-gateway-debug.patch b/recipes-connectivity/lora/lora-gateway/lora-gateway-debug.patch
new file mode 100644
index 0000000..dba4392
--- /dev/null
+++ b/recipes-connectivity/lora/lora-gateway/lora-gateway-debug.patch
@@ -0,0 +1,13 @@
+Index: git/libloragw/src/loragw_hal.c
+===================================================================
+--- git.orig/libloragw/src/loragw_hal.c 2014-12-16 16:07:20.812506157 -0600
++++ git/libloragw/src/loragw_hal.c 2014-12-16 16:18:34.427454833 -0600
+@@ -1626,6 +1626,8 @@
+ break;
+ }
+ }
++
++ DEBUG_PRINTF("DEBUG: Tx pow_index %d, rf_power %d\n", pow_index, tx_pow_table[pow_index].rf_power);
+
+ /* loading TX imbalance correction */
+ target_mix_gain = tx_pow_table[pow_index].mix_gain;
diff --git a/recipes-connectivity/lora/lora-gateway_1.7.0mts.bb b/recipes-connectivity/lora/lora-gateway_1.7.0mts.bb
new file mode 100644
index 0000000..87b48b2
--- /dev/null
+++ b/recipes-connectivity/lora/lora-gateway_1.7.0mts.bb
@@ -0,0 +1,7 @@
+require lora-gateway.inc
+
+PR = "${INC_PR}.0"
+
+SRCREV = "d6e01b5a566c08c89f17ae4a26d4ef003e39167c"
+BRANCH = "1.7.0-mts"
+
diff --git a/recipes-connectivity/lora/lora-network-server/lora-network-server.default b/recipes-connectivity/lora/lora-network-server/lora-network-server.default
new file mode 100644
index 0000000..be7dcd5
--- /dev/null
+++ b/recipes-connectivity/lora/lora-network-server/lora-network-server.default
@@ -0,0 +1,2 @@
+# set to "yes" or "no" to control starting on boot
+ENABLED="yes"
diff --git a/recipes-connectivity/lora/lora-network-server/lora-network-server.init b/recipes-connectivity/lora/lora-network-server/lora-network-server.init
new file mode 100755
index 0000000..099da38
--- /dev/null
+++ b/recipes-connectivity/lora/lora-network-server/lora-network-server.init
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+NAME="lora-network-server"
+ENABLED="yes"
+
+[ -f /etc/default/$NAME ] && source /etc/default/$NAME
+
+run_dir=/var/run/lora
+conf_dir=/var/config/lora
+conf_file=$conf_dir/lora-network-server.conf
+conf_db=$conf_dir/lora-network-server.db
+
+net_server=/opt/lora/lora-network-server
+net_server_log=/var/log/lora-network-server.log
+net_server_pidfile=$run_dir/$NAME.pid
+
+pkt_fwd=/opt/lora/basic_pkt_fwd
+pkt_fwd_log=/var/log/lora-pkt-fwd.log
+pkt_fwd_pidfile=$run_dir/lora-pkt-fwd.pid
+
+lora_us_id="MTAC-LORA-915"
+lora_eu_id="MTAC-LORA-868"
+
+read_card_info() {
+ # product-id of first lora card
+ lora_id=$(mts-io-sysfs show lora/product-id 2> /dev/null)
+ lora_eui=$(mts-io-sysfs show lora/eui 2> /dev/null)
+ # remove all colons
+ lora_eui_raw=${lora_eui//:/}
+}
+
+card_found() {
+ if [ "$lora_id" = "$lora_us_id" ] || [ "$lora_id" = "$lora_eu_id" ]; then
+ echo "Found lora card $lora_id"
+ return 0
+ else
+ return 1
+ fi
+}
+
+do_start() {
+ read_card_info
+
+ if ! [ -f $conf_file ]; then
+ echo "$0: $conf_file missing"
+ exit 1
+ fi
+
+ if ! card_found; then
+ echo "$0: MTAC-LORA not detected"
+ exit 1
+ fi
+
+ echo -n "Starting $NAME: "
+ mkdir -p $run_dir
+ # start network server
+ start-stop-daemon --start --background --make-pidfile \
+ --pidfile $net_server_pidfile --exec $net_server -- \
+ -c $conf_file --lora-eui $lora_eui --lora-path $run_dir --db $conf_db \
+ --noconsole -l $net_server_log
+ sleep 1
+ # start packet forwarder
+ start-stop-daemon --start --background --make-pidfile \
+ --pidfile $pkt_fwd_pidfile --exec $pkt_fwd -- \
+ -c $run_dir -l $pkt_fwd_log
+ echo "OK"
+}
+
+do_stop() {
+ echo -n "Stopping $NAME: "
+ start-stop-daemon --stop --quiet --oknodo --pidfile $net_server_pidfile --retry 15
+ start-stop-daemon --stop --quiet --oknodo --pidfile $pkt_fwd_pidfile --retry 5
+ rm -f $net_server_pidfile $pkt_fwd_pidfile
+ echo "OK"
+}
+
+if [ "$ENABLED" != "yes" ]; then
+ echo "$NAME: disabled in /etc/default"
+ exit
+fi
+
+case "$1" in
+ "start")
+ do_start
+ ;;
+ "stop")
+ do_stop
+ ;;
+ "restart")
+ ## Stop the service and regardless of whether it was
+ ## running or not, start it again.
+ do_stop
+ do_start
+ ;;
+ *)
+ ## If no parameters are given, print which are avaiable.
+ echo "Usage: $0 {start|stop|restart}"
+ exit 1
+ ;;
+esac
+
diff --git a/recipes-connectivity/lora/lora-network-server/lora-network-server.logrotate.conf b/recipes-connectivity/lora/lora-network-server/lora-network-server.logrotate.conf
new file mode 100644
index 0000000..67616a0
--- /dev/null
+++ b/recipes-connectivity/lora/lora-network-server/lora-network-server.logrotate.conf
@@ -0,0 +1,7 @@
+/var/log/lora-pkt-fwd.log /var/log/lora-network-server.log {
+ size 512k
+ rotate 4
+ compress
+ copytruncate
+ missingok
+}
diff --git a/recipes-connectivity/lora/lora-network-server_0.0.2-11-g82ab10d.bb b/recipes-connectivity/lora/lora-network-server_0.0.2-11-g82ab10d.bb
new file mode 100644
index 0000000..e64e482
--- /dev/null
+++ b/recipes-connectivity/lora/lora-network-server_0.0.2-11-g82ab10d.bb
@@ -0,0 +1,49 @@
+DESCRIPTION = "MultiTech LoRa Network Server"
+PRIORITY = "optional"
+SECTION = "console/utils"
+LICENSE = "Proprietary"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=7ffae4666a986c4ccf45e99e464f8402"
+DEPENDS = "jsoncpp libmts mosquitto sqlite3"
+RDEPENDS_${PN} += "lora-packet-forwarder logrotate"
+PR = "r0"
+
+SRC_URI = "http://multitech.net/downloads/lora-network-server_${TUNE_PKGARCH}_${PV}.tar.gz \
+ file://lora-network-server.init \
+ file://lora-network-server.default \
+ file://lora-network-server.logrotate.conf \
+ "
+
+SRC_URI[md5sum] = "139a4f82af1ea3afcbe0f4924aedcc0d"
+SRC_URI[sha256sum] = "9639ea5ff8cdd6d9979dae010aef8c6011607fb1c0e2e4083d94e405e40ac8cb"
+
+# binaries are already stripped, so suppress warning
+INSANE_SKIP_${PN} = "already-stripped"
+
+S = "${WORKDIR}"
+
+LORA_DIR = "/opt/lora"
+
+do_compile() {
+}
+
+inherit update-rc.d
+
+INITSCRIPT_NAME = "lora-network-server"
+INITSCRIPT_PARAMS = "defaults 80 30"
+
+do_install() {
+ install -d ${D}${LORA_DIR}
+ install -m 0755 lora-network-server ${D}${LORA_DIR}/
+ install -m 0644 lora-network-server.conf.sample ${D}${LORA_DIR}/lora-network-server.conf.sample
+
+ install -d ${D}${sysconfdir}/default
+ install -m 0644 ${WORKDIR}/lora-network-server.default ${D}${sysconfdir}/default/lora-network-server
+ install -d ${D}${sysconfdir}/init.d
+ install -m 0755 ${WORKDIR}/lora-network-server.init ${D}${sysconfdir}/init.d/lora-network-server
+ install -d ${D}${sysconfdir}/logrotate.d
+ install -m 0644 ${WORKDIR}/lora-network-server.logrotate.conf ${D}${sysconfdir}/logrotate.d/lora-network-server.conf
+}
+
+CONFFILES_${PN} = "${sysconfdir}/default/lora-network-server"
+FILES_${PN} += "${LORA_DIR}"
+FILES_${PN}-dbg += "${LORA_DIR}/.debug"
diff --git a/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-fixb64.patch b/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-fixb64.patch
new file mode 100644
index 0000000..dc0df42
--- /dev/null
+++ b/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-fixb64.patch
@@ -0,0 +1,66 @@
+Index: git/basic_pkt_fwd/src/base64.c
+===================================================================
+--- git.orig/basic_pkt_fwd/src/base64.c 2015-03-31 16:00:39.479058735 -0500
++++ git/basic_pkt_fwd/src/base64.c 2015-03-31 16:02:18.529580540 -0500
+@@ -263,7 +263,7 @@
+ DEBUG("ERROR: INVALID UNPADDED BASE64 STRING\n");
+ return -1;
+ case 2: /* 2 chars in last block, must add 2 padding char */
+- if (max_len > (ret + 2 + 1)) {
++ if (max_len >= (ret + 2 + 1)) {
+ out[ret] = code_pad;
+ out[ret+1] = code_pad;
+ out[ret+2] = 0;
+@@ -273,7 +273,7 @@
+ return -1;
+ }
+ case 3: /* 3 chars in last block, must add 1 padding char */
+- if (max_len > (ret + 1 + 1)) {
++ if (max_len >= (ret + 1 + 1)) {
+ out[ret] = code_pad;
+ out[ret+1] = 0;
+ return ret+1;
+Index: git/beacon_pkt_fwd/src/base64.c
+===================================================================
+--- git.orig/beacon_pkt_fwd/src/base64.c 2015-03-31 16:00:39.479058735 -0500
++++ git/beacon_pkt_fwd/src/base64.c 2015-03-31 16:03:26.040561508 -0500
+@@ -263,7 +263,7 @@
+ DEBUG("ERROR: INVALID UNPADDED BASE64 STRING\n");
+ return -1;
+ case 2: /* 2 chars in last block, must add 2 padding char */
+- if (max_len > (ret + 2 + 1)) {
++ if (max_len >= (ret + 2 + 1)) {
+ out[ret] = code_pad;
+ out[ret+1] = code_pad;
+ out[ret+2] = 0;
+@@ -273,7 +273,7 @@
+ return -1;
+ }
+ case 3: /* 3 chars in last block, must add 1 padding char */
+- if (max_len > (ret + 1 + 1)) {
++ if (max_len >= (ret + 1 + 1)) {
+ out[ret] = code_pad;
+ out[ret+1] = 0;
+ return ret+1;
+Index: git/gps_pkt_fwd/src/base64.c
+===================================================================
+--- git.orig/gps_pkt_fwd/src/base64.c 2015-03-31 16:02:59.344965478 -0500
++++ git/gps_pkt_fwd/src/base64.c 2015-03-31 16:03:13.208755845 -0500
+@@ -263,7 +263,7 @@
+ DEBUG("ERROR: INVALID UNPADDED BASE64 STRING\n");
+ return -1;
+ case 2: /* 2 chars in last block, must add 2 padding char */
+- if (max_len > (ret + 2 + 1)) {
++ if (max_len >= (ret + 2 + 1)) {
+ out[ret] = code_pad;
+ out[ret+1] = code_pad;
+ out[ret+2] = 0;
+@@ -273,7 +273,7 @@
+ return -1;
+ }
+ case 3: /* 3 chars in last block, must add 1 padding char */
+- if (max_len > (ret + 1 + 1)) {
++ if (max_len >= (ret + 1 + 1)) {
+ out[ret] = code_pad;
+ out[ret+1] = 0;
+ return ret+1;
diff --git a/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-mts-enhancements.patch b/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-mts-enhancements.patch
new file mode 100644
index 0000000..2bf82ff
--- /dev/null
+++ b/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-mts-enhancements.patch
@@ -0,0 +1,265 @@
+Index: git/basic_pkt_fwd/src/basic_pkt_fwd.c
+===================================================================
+--- git.orig/basic_pkt_fwd/src/basic_pkt_fwd.c 2015-04-01 15:14:12.192933389 -0500
++++ git/basic_pkt_fwd/src/basic_pkt_fwd.c 2015-04-01 15:36:38.731731561 -0500
+@@ -42,6 +42,8 @@
+ #include <netdb.h> /* gai_strerror */
+
+ #include <pthread.h>
++#include <getopt.h>
++#include <linux/limits.h>
+
+ #include "parson.h"
+ #include "base64.h"
+@@ -472,19 +474,65 @@
+ return x;
+ }
+
++void usage(char *proc_name) {
++ fprintf(stderr, "Usage: %s [-c config_dir] [-l logfile]\n", proc_name);
++ exit(1);
++}
++
++
++static char *short_options = "c:l:h";
++static struct option long_options[] = {
++ {"config-dir", 1, 0, 'c'},
++ {"logfile", 1, 0, 'l'},
++ {"help", 0, 0, 'h'},
++ {0, 0, 0, 0},
++};
++
+ /* -------------------------------------------------------------------------- */
+ /* --- MAIN FUNCTION -------------------------------------------------------- */
+
+-int main(void)
++int main(int argc, char *argv[])
+ {
+ struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
+ int i; /* loop variable and temporary variable for return value */
+
+ /* configuration file related */
+- char *global_cfg_path= "global_conf.json"; /* contain global (typ. network-wide) configuration */
+- char *local_cfg_path = "local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */
+- char *debug_cfg_path = "debug_conf.json"; /* if present, all other configuration files are ignored */
+-
++ char *global_cfg_name = "global_conf.json"; /* contain global (typ. network-wide) configuration */
++ char *local_cfg_name = "local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */
++ char *debug_cfg_name = "debug_conf.json"; /* if present, all other configuration files are ignored */
++
++ int opt_ind = 0;
++ char cfg_dir[PATH_MAX] = {0};
++ char global_cfg_path[PATH_MAX] = {0};
++ char local_cfg_path[PATH_MAX] = {0};
++ char debug_cfg_path[PATH_MAX] = {0};
++ char *logfile_path = NULL;
++ char *proc_name = argv[0];
++
++ while((i = getopt_long(argc, argv, short_options, long_options, &opt_ind)) >= 0) {
++ switch(i) {
++ case 0:
++ break;
++ case 'c':
++ strncpy(cfg_dir, optarg, sizeof(cfg_dir)-2);
++ strcat(cfg_dir, "/");
++ break;
++ case 'l':
++ logfile_path = optarg;
++ break;
++ case 'h':
++ usage(proc_name);
++ break;
++ default:
++ usage(proc_name);
++ break;
++ }
++ }
++
++ snprintf(global_cfg_path, sizeof(global_cfg_path), "%s%s", cfg_dir, global_cfg_name);
++ snprintf(local_cfg_path, sizeof(local_cfg_path), "%s%s", cfg_dir, local_cfg_name);
++ snprintf(debug_cfg_path, sizeof(debug_cfg_path), "%s%s", cfg_dir, debug_cfg_name);
++
+ /* threads */
+ pthread_t thrid_up;
+ pthread_t thrid_down;
+@@ -522,6 +570,22 @@
+ float rx_nocrc_ratio;
+ float up_ack_ratio;
+ float dw_ack_ratio;
++
++ /* redirect stdout, stderr to logfile if specified */
++ int logfile_fd;
++ FILE *logfile = NULL;
++ if (logfile_path) {
++ logfile = fopen(logfile_path, "w");
++ if (logfile) {
++ logfile_fd = fileno(logfile);
++ dup2(logfile_fd, STDOUT_FILENO);
++ dup2(logfile_fd, STDERR_FILENO);
++ }
++ else {
++ printf("Error opening log file %s\n", logfile_path);
++ exit(1);
++ }
++ }
+
+ /* display version informations */
+ MSG("*** Basic Packet Forwarder for Lora Gateway ***\nVersion: " VERSION_STRING "\n");
+Index: git/gps_pkt_fwd/src/gps_pkt_fwd.c
+===================================================================
+--- git.orig/gps_pkt_fwd/src/gps_pkt_fwd.c 2015-04-01 15:14:12.160933893 -0500
++++ git/gps_pkt_fwd/src/gps_pkt_fwd.c 2015-04-01 15:14:12.280932001 -0500
+@@ -44,6 +44,8 @@
+ #include <netdb.h> /* gai_strerror */
+
+ #include <pthread.h>
++#include <getopt.h>
++#include <linux/limits.h>
+
+ #include "parson.h"
+ #include "base64.h"
+@@ -539,19 +541,60 @@
+ return x;
+ }
+
++void usage(char *proc_name) {
++ fprintf(stderr, "Usage: %s [-c config_dir]\n", proc_name);
++ exit(1);
++}
++
++
++static char *short_options = "c:h";
++static struct option long_options[] = {
++ {"config-dir", 1, 0, 'c'},
++ {"help", 0, 0, 'h'},
++ {0, 0, 0, 0},
++};
++
+ /* -------------------------------------------------------------------------- */
+ /* --- MAIN FUNCTION -------------------------------------------------------- */
+
+-int main(void)
++int main(int argc, char *argv[])
+ {
+ struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
+ int i; /* loop variable and temporary variable for return value */
+
+ /* configuration file related */
+- char *global_cfg_path= "global_conf.json"; /* contain global (typ. network-wide) configuration */
+- char *local_cfg_path = "local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */
+- char *debug_cfg_path = "debug_conf.json"; /* if present, all other configuration files are ignored */
+-
++ char *global_cfg_name = "global_conf.json"; /* contain global (typ. network-wide) configuration */
++ char *local_cfg_name = "local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */
++ char *debug_cfg_name = "debug_conf.json"; /* if present, all other configuration files are ignored */
++
++ int opt_ind = 0;
++ char cfg_dir[PATH_MAX] = {0};
++ char global_cfg_path[PATH_MAX] = {0};
++ char local_cfg_path[PATH_MAX] = {0};
++ char debug_cfg_path[PATH_MAX] = {0};
++ char *proc_name = argv[0];
++
++ while((i = getopt_long(argc, argv, short_options, long_options, &opt_ind)) >= 0) {
++ switch(i) {
++ case 0:
++ break;
++ case 'c':
++ strncpy(cfg_dir, optarg, sizeof(cfg_dir)-2);
++ strcat(cfg_dir, "/");
++ break;
++ case 'h':
++ usage(proc_name);
++ break;
++ default:
++ usage(proc_name);
++ break;
++ }
++ }
++
++ snprintf(global_cfg_path, sizeof(global_cfg_path), "%s%s", cfg_dir, global_cfg_name);
++ snprintf(local_cfg_path, sizeof(local_cfg_path), "%s%s", cfg_dir, local_cfg_name);
++ snprintf(debug_cfg_path, sizeof(debug_cfg_path), "%s%s", cfg_dir, debug_cfg_name);
++
+ /* threads */
+ pthread_t thrid_up;
+ pthread_t thrid_down;
+Index: git/beacon_pkt_fwd/src/beacon_pkt_fwd.c
+===================================================================
+--- git.orig/beacon_pkt_fwd/src/beacon_pkt_fwd.c 2015-04-01 15:14:12.156933956 -0500
++++ git/beacon_pkt_fwd/src/beacon_pkt_fwd.c 2015-04-01 15:14:12.284931938 -0500
+@@ -45,6 +45,8 @@
+ #include <netdb.h> /* gai_strerror */
+
+ #include <pthread.h>
++#include <getopt.h>
++#include <linux/limits.h>
+
+ #include "parson.h"
+ #include "base64.h"
+@@ -618,19 +620,60 @@
+ return x;
+ }
+
++void usage(char *proc_name) {
++ fprintf(stderr, "Usage: %s [-c config_dir]\n", proc_name);
++ exit(1);
++}
++
++
++static char *short_options = "c:h";
++static struct option long_options[] = {
++ {"config-dir", 1, 0, 'c'},
++ {"help", 0, 0, 'h'},
++ {0, 0, 0, 0},
++};
++
+ /* -------------------------------------------------------------------------- */
+ /* --- MAIN FUNCTION -------------------------------------------------------- */
+
+-int main(void)
++int main(int argc, char *argv[])
+ {
+ struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
+ int i; /* loop variable and temporary variable for return value */
+
+ /* configuration file related */
+- char *global_cfg_path= "global_conf.json"; /* contain global (typ. network-wide) configuration */
+- char *local_cfg_path = "local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */
+- char *debug_cfg_path = "debug_conf.json"; /* if present, all other configuration files are ignored */
+-
++ char *global_cfg_name = "global_conf.json"; /* contain global (typ. network-wide) configuration */
++ char *local_cfg_name = "local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */
++ char *debug_cfg_name = "debug_conf.json"; /* if present, all other configuration files are ignored */
++
++ int opt_ind = 0;
++ char cfg_dir[PATH_MAX] = {0};
++ char global_cfg_path[PATH_MAX] = {0};
++ char local_cfg_path[PATH_MAX] = {0};
++ char debug_cfg_path[PATH_MAX] = {0};
++ char *proc_name = argv[0];
++
++ while((i = getopt_long(argc, argv, short_options, long_options, &opt_ind)) >= 0) {
++ switch(i) {
++ case 0:
++ break;
++ case 'c':
++ strncpy(cfg_dir, optarg, sizeof(cfg_dir)-2);
++ strcat(cfg_dir, "/");
++ break;
++ case 'h':
++ usage(proc_name);
++ break;
++ default:
++ usage(proc_name);
++ break;
++ }
++ }
++
++ snprintf(global_cfg_path, sizeof(global_cfg_path), "%s%s", cfg_dir, global_cfg_name);
++ snprintf(local_cfg_path, sizeof(local_cfg_path), "%s%s", cfg_dir, local_cfg_name);
++ snprintf(debug_cfg_path, sizeof(debug_cfg_path), "%s%s", cfg_dir, debug_cfg_name);
++
+ /* threads */
+ pthread_t thrid_up;
+ pthread_t thrid_down;
diff --git a/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-set-spi-path.patch b/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-set-spi-path.patch
new file mode 100644
index 0000000..01ce509
--- /dev/null
+++ b/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-set-spi-path.patch
@@ -0,0 +1,111 @@
+Index: git/basic_pkt_fwd/src/basic_pkt_fwd.c
+===================================================================
+--- git.orig/basic_pkt_fwd/src/basic_pkt_fwd.c 2015-01-07 14:38:10.016886785 -0600
++++ git/basic_pkt_fwd/src/basic_pkt_fwd.c 2015-01-07 14:49:57.823412026 -0600
+@@ -106,6 +106,7 @@
+ /* network configuration variables */
+ static uint64_t lgwm = 0; /* Lora gateway MAC address */
+ static char serv_addr[64] = STR(DEFAULT_SERVER); /* address of the server (host name or IPv4/IPv6) */
++static char spi_device_path[64] = {0} ; /* custom SPI device path */
+ static char serv_port_up[8] = STR(DEFAULT_PORT_UP); /* server port for upstream traffic */
+ static char serv_port_down[8] = STR(DEFAULT_PORT_DW); /* server port for downstream traffic */
+ static int keepalive_time = DEFAULT_KEEPALIVE; /* send a PULL_DATA request every X seconds, negative = disabled */
+@@ -393,6 +394,13 @@
+ strncpy(serv_addr, str, sizeof serv_addr);
+ MSG("INFO: server hostname or IP address is configured to \"%s\"\n", serv_addr);
+ }
++
++ /* spi device path (optional) */
++ str = json_object_get_string(conf_obj, "spi_device");
++ if (str != NULL) {
++ strncpy(spi_device_path, str, sizeof(spi_device_path)-1);
++ MSG("INFO: SPI device is configured to \"%s\"\n", spi_device_path);
++ }
+
+ /* get up and down ports (optional) */
+ val = json_object_get_value(conf_obj, "serv_port_up");
+@@ -629,6 +637,10 @@
+ exit(EXIT_FAILURE);
+ }
+ freeaddrinfo(result);
++
++ /* set custom SPI device path if configured */
++ if (strlen(spi_device_path) > 0)
++ lgw_spi_set_path(spi_device_path);
+
+ /* starting the concentrator */
+ i = lgw_start();
+Index: git/beacon_pkt_fwd/src/beacon_pkt_fwd.c
+===================================================================
+--- git.orig/beacon_pkt_fwd/src/beacon_pkt_fwd.c 2015-01-05 11:29:12.946020392 -0600
++++ git/beacon_pkt_fwd/src/beacon_pkt_fwd.c 2015-01-07 14:57:00.338533303 -0600
+@@ -115,6 +115,7 @@
+ /* network configuration variables */
+ static uint64_t lgwm = 0; /* Lora gateway MAC address */
+ static char serv_addr[64] = STR(DEFAULT_SERVER); /* address of the server (host name or IPv4/IPv6) */
++static char spi_device_path[64] = {0} ; /* custom SPI device path */
+ static char serv_port_up[8] = STR(DEFAULT_PORT_UP); /* server port for upstream traffic */
+ static char serv_port_down[8] = STR(DEFAULT_PORT_DW); /* server port for downstream traffic */
+ static int keepalive_time = DEFAULT_KEEPALIVE; /* send a PULL_DATA request every X seconds, negative = disabled */
+@@ -440,6 +441,13 @@
+ strncpy(serv_addr, str, sizeof serv_addr);
+ MSG("INFO: server hostname or IP address is configured to \"%s\"\n", serv_addr);
+ }
++
++ /* spi device path (optional) */
++ str = json_object_get_string(conf_obj, "spi_device");
++ if (str != NULL) {
++ strncpy(spi_device_path, str, sizeof(spi_device_path)-1);
++ MSG("INFO: SPI device is configured to \"%s\"\n", spi_device_path);
++ }
+
+ /* get up and down ports (optional) */
+ val = json_object_get_value(conf_obj, "serv_port_up");
+@@ -774,6 +782,10 @@
+ exit(EXIT_FAILURE);
+ }
+ freeaddrinfo(result);
++
++ /* set custom SPI device path if configured */
++ if (strlen(spi_device_path) > 0)
++ lgw_spi_set_path(spi_device_path);
+
+ /* starting the concentrator */
+ i = lgw_start();
+Index: git/gps_pkt_fwd/src/gps_pkt_fwd.c
+===================================================================
+--- git.orig/gps_pkt_fwd/src/gps_pkt_fwd.c 2015-01-05 11:29:12.946020392 -0600
++++ git/gps_pkt_fwd/src/gps_pkt_fwd.c 2015-01-07 14:56:03.320278543 -0600
+@@ -110,6 +110,7 @@
+ /* network configuration variables */
+ static uint64_t lgwm = 0; /* Lora gateway MAC address */
+ static char serv_addr[64] = STR(DEFAULT_SERVER); /* address of the server (host name or IPv4/IPv6) */
++static char spi_device_path[64] = {0} ; /* custom SPI device path */
+ static char serv_port_up[8] = STR(DEFAULT_PORT_UP); /* server port for upstream traffic */
+ static char serv_port_down[8] = STR(DEFAULT_PORT_DW); /* server port for downstream traffic */
+ static int keepalive_time = DEFAULT_KEEPALIVE; /* send a PULL_DATA request every X seconds, negative = disabled */
+@@ -424,6 +425,13 @@
+ strncpy(serv_addr, str, sizeof serv_addr);
+ MSG("INFO: server hostname or IP address is configured to \"%s\"\n", serv_addr);
+ }
++
++ /* spi device path (optional) */
++ str = json_object_get_string(conf_obj, "spi_device");
++ if (str != NULL) {
++ strncpy(spi_device_path, str, sizeof(spi_device_path)-1);
++ MSG("INFO: SPI device is configured to \"%s\"\n", spi_device_path);
++ }
+
+ /* get up and down ports (optional) */
+ val = json_object_get_value(conf_obj, "serv_port_up");
+@@ -717,6 +725,10 @@
+ exit(EXIT_FAILURE);
+ }
+ freeaddrinfo(result);
++
++ /* set custom SPI device path if configured */
++ if (strlen(spi_device_path) > 0)
++ lgw_spi_set_path(spi_device_path);
+
+ /* starting the concentrator */
+ i = lgw_start();
diff --git a/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-skip-bad-packets.patch b/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-skip-bad-packets.patch
new file mode 100644
index 0000000..cb12a97
--- /dev/null
+++ b/recipes-connectivity/lora/lora-packet-forwarder/lora-packet-forwarder-skip-bad-packets.patch
@@ -0,0 +1,54 @@
+Index: git/basic_pkt_fwd/src/basic_pkt_fwd.c
+===================================================================
+--- git.orig/basic_pkt_fwd/src/basic_pkt_fwd.c 2014-12-16 17:03:32.891297739 -0600
++++ git/basic_pkt_fwd/src/basic_pkt_fwd.c 2014-12-18 10:49:22.379916372 -0600
+@@ -928,7 +928,8 @@
+ MSG("ERROR: [up] received packet with unknown status\n");
+ memcpy((void *)(buff_up + buff_index), (void *)",\"stat\":?", 9);
+ buff_index += 9;
+- exit(EXIT_FAILURE);
++ continue; // skip packet
++ //exit(EXIT_FAILURE);
+ }
+
+ /* Packet modulation, 13-14 useful chars */
+@@ -966,7 +967,8 @@
+ MSG("ERROR: [up] lora packet with unknown datarate\n");
+ memcpy((void *)(buff_up + buff_index), (void *)",\"datr\":\"SF?", 12);
+ buff_index += 12;
+- exit(EXIT_FAILURE);
++ continue; // skip packet
++ //exit(EXIT_FAILURE);
+ }
+ switch (p->bandwidth) {
+ case BW_125KHZ:
+@@ -985,7 +987,8 @@
+ MSG("ERROR: [up] lora packet with unknown bandwidth\n");
+ memcpy((void *)(buff_up + buff_index), (void *)"BW?\"", 4);
+ buff_index += 4;
+- exit(EXIT_FAILURE);
++ continue; // skip packet
++ //exit(EXIT_FAILURE);
+ }
+
+ /* Packet ECC coding rate, 11-13 useful chars */
+@@ -1014,7 +1017,8 @@
+ MSG("ERROR: [up] lora packet with unknown coderate\n");
+ memcpy((void *)(buff_up + buff_index), (void *)",\"codr\":\"?\"", 11);
+ buff_index += 11;
+- exit(EXIT_FAILURE);
++ continue; // skip packet
++ //exit(EXIT_FAILURE);
+ }
+
+ /* Lora SNR, 11-13 useful chars */
+@@ -1039,7 +1043,8 @@
+ }
+ } else {
+ MSG("ERROR: [up] received packet with unknown modulation\n");
+- exit(EXIT_FAILURE);
++ continue; // skip packet
++ //exit(EXIT_FAILURE);
+ }
+
+ /* Packet RSSI, payload size, 18-23 useful chars */
diff --git a/recipes-connectivity/lora/lora-packet-forwarder_1.4.1.bb b/recipes-connectivity/lora/lora-packet-forwarder_1.4.1.bb
new file mode 100644
index 0000000..56fdbe6
--- /dev/null
+++ b/recipes-connectivity/lora/lora-packet-forwarder_1.4.1.bb
@@ -0,0 +1,52 @@
+DESCRIPTION = "LoRa Packet Forwarder"
+HOMEPAGE = "https://github.com/Lora-net"
+PRIORITY = "optional"
+SECTION = "console/utils"
+# Semtech license is a modified BSD-style license
+LICENSE = "SEMTECH"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=22af7693d7b76ef0fc76161c4be76c45"
+DEPENDS = "lora-gateway"
+PR = "r7"
+
+# tag v1.4.1
+SRCREV = "0011a60759a7d81656a5393e97089daab1ff1a81"
+
+SRC_URI = "git://github.com/Lora-net/packet_forwarder.git;protocol=git \
+ file://lora-packet-forwarder-set-spi-path.patch \
+ file://lora-packet-forwarder-skip-bad-packets.patch \
+ file://lora-packet-forwarder-fixb64.patch \
+ file://lora-packet-forwarder-mts-enhancements.patch \
+"
+
+S = "${WORKDIR}/git"
+
+LORA_DIR = "/opt/lora"
+
+export LGW_PATH = "${STAGING_LIBDIR}/lora"
+export LGW_INC = "${STAGING_INCDIR}/lora"
+
+CFLAGS += "-I${LGW_INC} -Iinc -I."
+
+do_compile() {
+ oe_runmake
+}
+
+do_install() {
+ install -d ${D}${LORA_DIR}
+ install -m 755 gps_pkt_fwd/gps_pkt_fwd ${D}${LORA_DIR}/
+ install -m 755 basic_pkt_fwd/basic_pkt_fwd ${D}${LORA_DIR}/
+ install -m 755 beacon_pkt_fwd/beacon_pkt_fwd ${D}${LORA_DIR}/
+ install -m 755 util_sink/util_sink ${D}${LORA_DIR}/
+ install -m 755 util_ack/util_ack ${D}${LORA_DIR}/
+
+# skip util_tx_test since it conflicts with one in lora-gateway
+# install -m 755 util_tx_test/util_tx_test ${D}${LORA_DIR}/
+}
+
+FILES_${PN} += "${LORA_DIR}"
+FILES_${PN}-dbg += "${LORA_DIR}/.debug"
+
+# disable this on purpose for dev purposes
+do_rm_work() {
+ echo "skipping"
+}
diff --git a/recipes-connectivity/lora/lora-query_0.0.1.bb b/recipes-connectivity/lora/lora-query_0.0.1.bb
new file mode 100644
index 0000000..d21d6e6
--- /dev/null
+++ b/recipes-connectivity/lora/lora-query_0.0.1.bb
@@ -0,0 +1,21 @@
+DESCRIPTION = "LoRa network server query tool"
+HOMEPAGE = "http://www.multitech.net/"
+LICENSE = "GPL-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=94d55d512a9ba36caa9b7df079bae19f"
+DEPENDS = "jsoncpp libmts"
+PR = "r0"
+
+SRCREV = "${PV}"
+
+SRC_URI = "git://git.multitech.net/lora-query;branch=master"
+
+S = "${WORKDIR}/git"
+
+do_compile() {
+ oe_runmake
+}
+
+do_install() {
+ oe_runmake install DESTDIR=${D}
+}
+