diff --git a/net/lora-packet-forwarder/Makefile b/net/lora-packet-forwarder/Makefile
new file mode 100644
index 00000000000000..7f257bbd359fdd
--- /dev/null
+++ b/net/lora-packet-forwarder/Makefile
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2019 Xue Liu <liuxuenetmail@gmail>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=lora-packet-forwarder
+PKG_VERSION:=4.0.1
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=https://codeload.github.com/Lora-net/packet_forwarder/tar.gz/v$(PKG_VERSION)?
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=e68fadf6f1d2e5e7b601e504d5efb48b0a8f374c2c29c0476ab2fe9db68d33ae
+PKG_MAINTAINER:=Xue Liu <liuxuenetmail@gmail.com>
+PKG_LICENSE_FILES:=LICENSE
+PKG_BUILD_DIR:=$(BUILD_DIR)/packet_forwarder-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/lora-packet-forwarder
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=LoRaWAN
+  TITLE:=Semtech packet-forwarder program
+  DEPENDS:=+libloragw +libubox-lua +libuci-lua +dkjson
+endef
+
+define Package/lora-packet-forwarder/description
+  A LoRa packet forwarder is a program running on the host of a LoRa gateway
+  that forwards RF packets receive by the concentrator to a server through a
+  IP/UDP link, and emits RF packets that are sent by the server.
+endef
+
+define Package/lora-packet-forwarder-utils
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=LoRaWAN
+  TITLE:=Utilities for lora pakcet forwarder
+  DEPENDS:=+libloragw
+endef
+
+define Package/lora-packet-forwarder/install
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/lora_pkt_fwd/lora_pkt_fwd $(1)/usr/sbin
+	$(INSTALL_BIN) ./files/gen_lora_global_conf $(1)/usr/sbin
+	$(INSTALL_DIR) $(1)/etc/init.d
+	$(INSTALL_BIN) ./files/lora_pkt_fwd.init $(1)/etc/init.d/lora_pkt_fwd
+	$(INSTALL_DIR) $(1)/etc/config
+	$(INSTALL_DATA) ./files/lora-global.config $(1)/etc/config/lora-global
+endef
+
+define Package/lora-packet-forwarder-utils/install
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_ack $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_sink $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_tx_test $(1)/usr/sbin
+endef
+
+$(eval $(call BuildPackage,lora-packet-forwarder))
+$(eval $(call BuildPackage,lora-packet-forwarder-utils))
diff --git a/net/lora-packet-forwarder/files/gen_lora_global_conf b/net/lora-packet-forwarder/files/gen_lora_global_conf
new file mode 100755
index 00000000000000..0654ea2bbce072
--- /dev/null
+++ b/net/lora-packet-forwarder/files/gen_lora_global_conf
@@ -0,0 +1,170 @@
+-- SPDX-License-Identifier: GPL-2.0
+--
+-- Copyright (c) 2019 Xue Liu <liuxuenetmail@gmail.com>
+--
+
+#!/usr/bin/env lua
+
+require("uloop")
+require("ubus")
+local json = require("dkjson")
+local uci = require("uci")
+
+x = uci.cursor()
+
+uloop.init()
+
+local conn = ubus.connect()
+if not conn then
+	error("Failed to connect to ubus")
+end
+
+local lora_global_ubus = conn:call("uci", "get", {config = "lora-global"})
+
+local lora_global_table = lora_global_ubus["values"]
+
+local lora_global = {}
+local gateway_conf = {}
+local sx1301_conf = {}
+local radio_0 = {}
+local radio_1 = {}
+
+--
+-- chan_x
+--
+for key, val in pairs(lora_global_table) do
+	if string.match(key, 'chan_[%a]*', 1) then
+    local chan = {}
+		for k, v in pairs(val) do
+			if string.match(k, '%.[%a]*', 1) == nil then
+        if tonumber(v) then
+          chan[k] = tonumber(v)
+        elseif v == "true" then
+          chan[k] = true
+        elseif v == "false" then
+          chan[k] = false
+        else
+          chan[k] = v
+        end
+			end
+		end
+    sx1301_conf[key] = chan
+	end
+end
+
+--
+-- tx_lut_x
+--
+for key, val in pairs(lora_global_table) do
+	if string.match(key, 'tx_lut_[%d]?', 1) then
+    	local tx_lut = {}
+		for k, v in pairs(val) do
+			if string.match(k, '%.[%a]*', 1) == nil then
+        if tonumber(v) then
+        	tx_lut[k] = tonumber(v)
+        elseif v == "true" then
+        	tx_lut[k] = true
+        elseif v == "false" then
+        	tx_lut[k] = false
+        else
+        	tx_lut[k] = v
+        end
+			end
+		end
+    	sx1301_conf[key] = tx_lut
+	end
+end
+
+--
+-- radio_0
+--
+if lora_global_table["radio_0"] then
+	for k, v in pairs(lora_global_table["radio_0"]) do
+		if string.match(k, '%.[%a]*', 1) == nil then
+    		if tonumber(v) then
+				radio_0[k] = tonumber(v)
+			elseif v == "true" then
+    			radio_0[k] = true
+    		elseif v == "false" then
+				radio_0[k] = false
+			else
+				radio_0[k] = v
+			end
+		end
+	end
+else
+	error("UCI configuration has no item radio_0, Please check your configuration")
+end
+
+--
+-- radio_1
+--
+if lora_global_table["radio_1"] then
+	for k, v in pairs(lora_global_table["radio_1"]) do
+		if string.match(k, '%.[%a]*', 1) == nil then
+    		if tonumber(v) then
+				radio_1[k] = tonumber(v)
+			elseif v == "true" then
+        		radio_1[k] = true
+    		elseif v == "false" then
+    			radio_1[k] = false
+    		else
+				radio_1[k] = v
+			end
+		end
+	end
+else
+	error("UCI configuration has no item radio_1, Please check your configuration")
+end
+
+--
+-- gateway_conf
+--
+if lora_global_table["gateway_conf"] then
+	for k, v in pairs(lora_global_table["gateway_conf"]) do
+		-- filter out internal uci options
+		if string.match(k, '%.[%a]*', 1) == nil then
+			if tonumber(v) then
+				gateway_conf[k] = tonumber(v)
+			elseif v == "true" then
+				gateway_conf[k] = true
+			elseif v == "false" then
+				gateway_conf[k] = false
+			else
+				gateway_conf[k] = v
+			end
+		end
+	end
+else
+	error("UCI configuration has no item gateway_conf, Please check your configuration")
+end
+
+--
+-- SX1301_conf
+--
+if lora_global_table["SX1301_conf"] then
+	for k, v in pairs(lora_global_table["SX1301_conf"]) do
+		if string.match(k, '%.[%a]*', 1) == nil then
+			if tonumber(v) then
+				sx1301_conf[k] = tonumber(v)
+			elseif v == "true" then
+				sx1301_conf[k] = true
+    		elseif v == "false" then
+    			sx1301_conf[k] = false
+			else
+				sx1301_conf[k] = v
+			end
+		end
+	end
+else
+	error("UCI configuration has no item SX1301_conf, Please check your configuration")
+end
+
+sx1301_conf["radio_0"] = radio_0
+sx1301_conf["radio_1"] = radio_1
+lora_global["gateway_conf"] = gateway_conf
+lora_global["SX1301_conf"] = sx1301_conf
+
+local lora_global_text = json.encode(lora_global, { indent = true })
+
+print(lora_global_text)
diff --git a/net/lora-packet-forwarder/files/lora-global.config b/net/lora-packet-forwarder/files/lora-global.config
new file mode 100644
index 00000000000000..1b5a53469d6899
--- /dev/null
+++ b/net/lora-packet-forwarder/files/lora-global.config
@@ -0,0 +1,198 @@
+
+config gateway 'gateway_conf'
+	option keepalive_interval '10'
+	option stat_interval '30'
+	option push_timeout_ms '100'
+	option forward_crc_valid 'true'
+	option forward_crc_error 'false'
+	option serv_port_up '1700'
+	option serv_port_down '1700'
+	option gateway_ID 'aabbccddeeffaabb'
+	option server_address 'router.eu.thethings.network'
+	option forward_crc_disabled 'false'
+	option gps_enable 'false'
+	option beacon_enable 'false'
+
+config sx1301 'SX1301_conf'
+	option clksrc '1'
+	option antenna_gain '0'
+	option enable_reset_pin '1'
+	option reset_pin '25'
+	option lorawan_public 'true'
+
+config radio 'radio_0'
+	option enable 'true'
+	option freq '867500000'
+	option rssi_offset '-166.0'
+	option tx_enable 'true'
+	option tx_freq_min '863000000'
+	option tx_freq_max '870000000'
+	option type 'SX1257'
+	option tx_notch_freq '129000'
+
+config radio 'radio_1'
+	option enable 'true'
+	option freq '868500000'
+	option rssi_offset '-166.0'
+	option type 'SX1257'
+	option tx_enable 'false'
+
+config chan 'chan_multiSF_0'
+	option enable 'true'
+	option radio '1'
+	option if '-400000'
+	option desc 'Lora MAC, 125kHz, all SF, 868.1 MHz'
+
+config chan 'chan_multiSF_1'
+	option enable 'true'
+	option radio '1'
+	option desc 'Lora MAC channel, 125kHz, all SF, 868.3 MHz'
+	option if '-200000'
+
+config chan 'chan_multiSF_2'
+	option enable 'true'
+	option radio '1'
+	option desc 'Lora MAC channel, 125kHz, all SF, 868.5 MHz'
+	option if '0'
+
+config chan 'chan_multiSF_3'
+	option enable 'true'
+	option radio '0'
+	option if '-400000'
+	option desc 'Lora MAC channel, 125kHz, all SF, 867.1 MHz'
+
+config chan 'chan_multiSF_4'
+	option enable 'true'
+	option radio '0'
+	option if '-200000'
+	option desc 'Lora MAC channel, 125kHz, all SF, 867.3 MHz'
+
+config chan 'chan_multiSF_5'
+	option enable 'true'
+	option radio '0'
+	option if '0'
+	option desc 'Lora MAC channel, 125kHz, all SF, 867.5 MHz'
+
+config chan 'chan_multiSF_6'
+	option enable 'true'
+	option radio '0'
+	option if '200000'
+	option desc 'Lora MAC channel, 125kHz, all SF, 867.7 MHz'
+
+config chan 'chan_multiSF_7'
+	option enable 'true'
+	option radio '0'
+	option if '400000'
+	option desc 'Lora MAC channel, 125kHz, all SF, 867.9 MHz'
+
+config chan 'chan_Lora_std'
+	option enable 'true'
+	option radio '1'
+	option if '-200000'
+	option desc 'Lora MAC channel, 250kHz, SF7, 868.3 MHz'
+	option bandwidth '250000'
+	option spread_factor '7'
+
+config chan 'chan_FSK'
+	option enable 'true'
+	option radio '1'
+	option if '300000'
+	option desc 'FSK 50kbps channel, 868.8 MHz'
+	option bandwidth '125000'
+	option datarate '50000'
+
+config lut 'tx_lut_0'
+	option pa_gain '0'
+	option mix_gain '8'
+	option rf_power '-6'
+	option dig_gain '0'
+
+config lut 'tx_lut_1'
+	option pa_gain '0'
+	option mix_gain '10'
+	option rf_power '-3'
+	option dig_gain '0'
+
+config lut 'tx_lut_2'
+	option pa_gain '0'
+	option mix_gain '12'
+	option rf_power '0'
+	option dig_gain '0'
+
+config lut 'tx_lut_3'
+	option pa_gain '1'
+	option mix_gain '8'
+	option rf_power '3'
+	option dig_gain '0'
+
+config lut 'tx_lut_4'
+	option pa_gain '1'
+	option mix_gain '10'
+	option rf_power '6'
+	option dig_gain '0'
+
+config lut 'tx_lut_5'
+	option pa_gain '1'
+	option mix_gain '12'
+	option rf_power '10'
+	option dig_gain '0'
+
+config lut 'tx_lut_6'
+	option pa_gain '1'
+	option mix_gain '13'
+	option rf_power '11'
+	option dig_gain '0'
+
+config lut 'tx_lut_7'
+	option pa_gain '2'
+	option mix_gain '9'
+	option rf_power '12'
+	option dig_gain '0'
+
+config lut 'tx_lut_8'
+	option pa_gain '1'
+	option mix_gain '15'
+	option rf_power '13'
+	option dig_gain '0'
+
+config lut 'tx_lut_9'
+	option pa_gain '2'
+	option mix_gain '10'
+	option rf_power '14'
+	option dig_gain '0'
+
+config lut 'tx_lut_10'
+	option pa_gain '2'
+	option mix_gain '11'
+	option rf_power '16'
+	option dig_gain '0'
+
+config lut 'tx_lut_11'
+	option pa_gain '3'
+	option mix_gain '9'
+	option rf_power '20'
+	option dig_gain '0'
+
+config lut 'tx_lut_12'
+	option pa_gain '3'
+	option mix_gain '10'
+	option rf_power '23'
+	option dig_gain '0'
+
+config lut 'tx_lut_13'
+	option pa_gain '3'
+	option mix_gain '11'
+	option rf_power '25'
+	option dig_gain '0'
+
+config lut 'tx_lut_14'
+	option pa_gain '3'
+	option mix_gain '12'
+	option rf_power '26'
+	option dig_gain '0'
+
+config lut 'tx_lut_15'
+	option pa_gain '3'
+	option mix_gain '14'
+	option rf_power '27'
+	option dig_gain '0'
diff --git a/net/lora-packet-forwarder/files/lora_pkt_fwd.init b/net/lora-packet-forwarder/files/lora_pkt_fwd.init
new file mode 100755
index 00000000000000..3da0d5a5fbfbe4
--- /dev/null
+++ b/net/lora-packet-forwarder/files/lora_pkt_fwd.init
@@ -0,0 +1,70 @@
+#!/bin/sh /etc/rc.common
+START=99
+STOP=10
+
+USE_PROCD=1
+
+PROG=/usr/sbin/lora_pkt_fwd
+CONFIGFILE=/etc/global_conf.json
+
+reset_sx1301_board ()
+{
+	local pin=$1
+
+	logger "lora_pkt_fwd: Reset SX1301 with pin ${pin}"
+
+	if [ -d "/sys/class/gpio/gpio${pin}" ]
+	then
+		echo 1 > /dev/null
+	else
+		echo ${pin} > /sys/class/gpio/export
+		echo "out" > /sys/class/gpio/gpio${pin}/direction
+	fi
+
+	echo "1" > /sys/class/gpio/gpio${pin}/value
+	sleep 5
+	echo "0" > /sys/class/gpio/gpio${pin}/value
+	sleep 1
+	echo "0" > /sys/class/gpio/gpio${pin}/value
+
+	logger "lora_pkt_fwd: SX1301 reset completed"
+}
+
+generate_global_conf()
+{
+	logger "lora_pkt_fwd: Generate ${CONFIGFILE}"
+	gen_lora_global_conf > ${CONFIGFILE}
+}
+
+start_service()
+{
+	include /lib/functions
+
+	logger "lora_pkt_fwd: Start"
+
+	config_load lora_pkt_fwd
+
+	generate_global_conf
+
+	local reset_enable=$(uci get lora-global.SX1301_conf.enable_reset_pin)
+	
+	if [ ${reset_enable} = 1 ]; then
+		reset_sx1301_board $(uci get lora-global.SX1301_conf.reset_pin)
+	fi
+
+	procd_open_instance
+	procd_set_param command $PROG
+	procd_set_param file ${CONFIGFILE}
+	procd_set_param file /etc/config/lora-global
+	procd_set_param respawn
+
+	procd_set_param stdout 1
+	procd_set_param stderr 1
+
+	procd_close_instance
+}
+
+stop_service() {
+    logger "lora_pkt_fwd: Stop"
+    killall lora_pkt_fwd 
+}
diff --git a/net/lora-packet-forwarder/patches/001-relocate_config_files_into_etc.patch b/net/lora-packet-forwarder/patches/001-relocate_config_files_into_etc.patch
new file mode 100644
index 00000000000000..0793f9b7a4f371
--- /dev/null
+++ b/net/lora-packet-forwarder/patches/001-relocate_config_files_into_etc.patch
@@ -0,0 +1,15 @@
+--- a/lora_pkt_fwd/src/lora_pkt_fwd.c
++++ b/lora_pkt_fwd/src/lora_pkt_fwd.c
+@@ -980,9 +980,9 @@ int main(void)
+     int x;
+ 
+     /* 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_path= "/etc/global_conf.json"; /* contain global (typ. network-wide) configuration */
++    char *local_cfg_path = "/etc/local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */
++    char *debug_cfg_path = "/etc/debug_conf.json"; /* if present, all other configuration files are ignored */
+ 
+     /* threads */
+     pthread_t thrid_up;
diff --git a/net/lora-packet-forwarder/patches/002-using_qsort.patch b/net/lora-packet-forwarder/patches/002-using_qsort.patch
new file mode 100644
index 00000000000000..9918f9cb39cd14
--- /dev/null
+++ b/net/lora-packet-forwarder/patches/002-using_qsort.patch
@@ -0,0 +1,50 @@
+Index: packet_forwarder-4.0.1/lora_pkt_fwd/src/jitqueue.c
+===================================================================
+--- packet_forwarder-4.0.1.orig/lora_pkt_fwd/src/jitqueue.c
++++ packet_forwarder-4.0.1/lora_pkt_fwd/src/jitqueue.c
+@@ -16,8 +16,7 @@ Maintainer: Michael Coracin
+ /* -------------------------------------------------------------------------- */
+ /* --- DEPENDANCIES --------------------------------------------------------- */
+ 
+-#define _GNU_SOURCE     /* needed for qsort_r to be defined */
+-#include <stdlib.h>     /* qsort_r */
++#include <stdlib.h>
+ #include <stdio.h>      /* printf, fprintf, snprintf, fopen, fputs */
+ #include <string.h>     /* memset, memcpy */
+ #include <pthread.h>
+@@ -91,32 +90,27 @@ void jit_queue_init(struct jit_queue_s *
+     pthread_mutex_unlock(&mx_jit_queue);
+ }
+ 
+-int compare(const void *a, const void *b, void *arg)
++int compare(const void *a, const void *b)
+ {
+     struct jit_node_s *p = (struct jit_node_s *)a;
+     struct jit_node_s *q = (struct jit_node_s *)b;
+-    int *counter = (int *)arg;
+     int p_count, q_count;
+ 
+     p_count = p->pkt.count_us;
+     q_count = q->pkt.count_us;
+ 
+-    if (p_count > q_count)
+-        *counter = *counter + 1;
+-
+     return p_count - q_count;
+ }
+ 
+ void jit_sort_queue(struct jit_queue_s *queue) {
+-    int counter = 0;
+ 
+     if (queue->num_pkt == 0) {
+         return;
+     }
+ 
+     MSG_DEBUG(DEBUG_JIT, "sorting queue in ascending order packet timestamp - queue size:%u\n", queue->num_pkt);
+-    qsort_r(queue->nodes, queue->num_pkt, sizeof(queue->nodes[0]), compare, &counter);
+-    MSG_DEBUG(DEBUG_JIT, "sorting queue done - swapped:%d\n", counter);
++    qsort(queue->nodes, queue->num_pkt, sizeof(queue->nodes[0]), compare);
++    MSG_DEBUG(DEBUG_JIT, "sorting queue done - swapped\n");
+ }
+ 
+ bool jit_collision_test(uint32_t p1_count_us, uint32_t p1_pre_delay, uint32_t p1_post_delay, uint32_t p2_count_us, uint32_t p2_pre_delay, uint32_t p2_post_delay) {
diff --git a/net/lora-packet-forwarder/patches/003-add-CMake-support.patch b/net/lora-packet-forwarder/patches/003-add-CMake-support.patch
new file mode 100644
index 00000000000000..865c76f686ebbb
--- /dev/null
+++ b/net/lora-packet-forwarder/patches/003-add-CMake-support.patch
@@ -0,0 +1,308 @@
+From d4088124704f458f31b3b10768c8f3f50eb9886e Mon Sep 17 00:00:00 2001
+From: Xue Liu <liuxuenetmail@gmail.com>
+Date: Thu, 21 Feb 2019 15:06:52 +0100
+Subject: [PATCH 1/1] - add CMake support
+
+Signed-off-by: Xue Liu <liuxuenetmail@gmail.com>
+---
+ CMakeLists.txt              | 72 +++++++++++++++++++++++++++++++++++++
+ lora_pkt_fwd/CMakeLists.txt | 68 +++++++++++++++++++++++++++++++++++
+ util_ack/CMakeLists.txt     | 36 +++++++++++++++++++
+ util_sink/CMakeLists.txt    | 37 +++++++++++++++++++
+ util_tx_test/CMakeLists.txt | 43 ++++++++++++++++++++++
+ 5 files changed, 256 insertions(+)
+ create mode 100644 CMakeLists.txt
+ create mode 100644 lora_pkt_fwd/CMakeLists.txt
+ create mode 100644 util_ack/CMakeLists.txt
+ create mode 100644 util_sink/CMakeLists.txt
+ create mode 100644 util_tx_test/CMakeLists.txt
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+new file mode 100644
+index 0000000..7e6c18b
+--- /dev/null
++++ b/CMakeLists.txt
+@@ -0,0 +1,72 @@
++# -- Minimum required version
++cmake_minimum_required (VERSION 3.2)
++
++# -- Project name
++project (packet_forwarder)
++
++# -- Various includes
++include (CMakePackageConfigHelpers)
++include (GNUInstallDirs)
++include (CheckFunctionExists)
++
++# -- set c99 standard default
++set(CMAKE_C_STANDARD 99)
++
++# -- Required to build
++set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
++set(THREADS_PREFER_PTHREAD_FLAG TRUE)
++find_package(Threads REQUIRED)
++
++# -- Versioning with git tag
++if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
++	execute_process(
++		COMMAND git describe --tags --always
++		WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
++		OUTPUT_VARIABLE "packet_forwarder_VERSION"
++		ERROR_QUIET
++		OUTPUT_STRIP_TRAILING_WHITESPACE)
++		if(packet_forwarder_VERSION STREQUAL "")
++			set(packet_forwarder_VERSION 0)
++		endif(packet_forwarder_VERSION STREQUAL "")
++		message( STATUS "Git full version: ${packet_forwarder_VERSION}" )
++	execute_process(
++		COMMAND /bin/bash -c "git describe --tags --abbrev=0 | cut --delimiter='v' --fields=2"
++		WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
++		OUTPUT_VARIABLE "packet_forwarder_VERSION_SHORT"
++		ERROR_QUIET
++		OUTPUT_STRIP_TRAILING_WHITESPACE)
++		if(packet_forwarder_VERSION_SHORT STREQUAL "")
++			set(packet_forwarder_VERSION_SHORT 0)
++		endif(packet_forwarder_VERSION_SHORT STREQUAL "")
++		message( STATUS "Git version: ${packet_forwarder_VERSION_SHORT}" )
++else(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
++	set(packet_forwarder_VERSION_SHORT 0)
++	set(packet_forwarder_VERSION 0)
++endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
++
++# -- find packages
++find_package(loragw QUIET)
++if(NOT loragw_FOUND)
++	find_package(PkgConfig)
++	pkg_search_module(LORAGW loragw)
++
++	if(LORAGW_FOUND)
++		message("-- pkg_config: libloragw is found")
++		message("-- libloragw include: ${LORAGW_INCLUDE_DIRS}")
++		message("-- libloragw library: ${LORAGW_LINK_LIBRARIES}")
++	endif()
++else()
++	message("-- CMake: libloragw is found")
++endif()
++
++# -- add the lora_pkt_fwd
++add_subdirectory(lora_pkt_fwd)
++
++# -- add the util_ack
++add_subdirectory(util_ack)
++
++# -- add the util_sink
++add_subdirectory(util_sink)
++
++# -- add the util_tx_test
++add_subdirectory(util_tx_test)
+diff --git a/lora_pkt_fwd/CMakeLists.txt b/lora_pkt_fwd/CMakeLists.txt
+new file mode 100644
+index 0000000..4d61fdd
+--- /dev/null
++++ b/lora_pkt_fwd/CMakeLists.txt
+@@ -0,0 +1,68 @@
++set(TARGET lora_pkt_fwd)
++
++add_executable(${TARGET} "")
++
++# --  add the compile options
++target_compile_options(
++	${TARGET}
++	PRIVATE
++	-Wall
++	-Wextra
++)
++
++target_compile_definitions(
++	${TARGET}
++	PRIVATE
++	VERSION_STRING="${packet_forwarder_VERSION_SHORT}"
++)
++
++target_sources(${TARGET}
++	PRIVATE
++		${CMAKE_CURRENT_LIST_DIR}/src/base64.c
++		${CMAKE_CURRENT_LIST_DIR}/src/jitqueue.c
++		${CMAKE_CURRENT_LIST_DIR}/src/lora_pkt_fwd.c
++		${CMAKE_CURRENT_LIST_DIR}/src/parson.c
++		${CMAKE_CURRENT_LIST_DIR}/src/timersync.c
++)
++
++target_include_directories(${TARGET}
++	PRIVATE
++		${CMAKE_CURRENT_LIST_DIR}
++		${CMAKE_CURRENT_LIST_DIR}/inc
++)
++
++target_link_libraries(${TARGET}
++	PUBLIC
++		Threads::Threads
++		m
++)
++
++if(LORAGW_FOUND)
++target_include_directories(${TARGET}
++	PRIVATE
++		${LORAGW_INCLUDE_DIRS}
++)
++
++target_link_libraries(${TARGET}
++	PRIVATE
++		${LORAGW_LINK_LIBRARIES}
++)
++endif()
++
++if(loragw_FOUND)
++target_link_libraries(${TARGET}
++	PRIVATE
++		Semtech::loragw
++)
++endif()
++
++set_target_properties(${TARGET} PROPERTIES VERSION ${packet_forwarder_VERSION})
++set_target_properties(${TARGET} PROPERTIES SOVERSION ${packet_forwarder_VERSION_SHORT})
++
++# add the install targets
++install (
++	TARGETS ${TARGET}
++	LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib
++	ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
++	RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
++)
+diff --git a/util_ack/CMakeLists.txt b/util_ack/CMakeLists.txt
+new file mode 100644
+index 0000000..b2d776d
+--- /dev/null
++++ b/util_ack/CMakeLists.txt
+@@ -0,0 +1,36 @@
++
++add_executable(util_ack "")
++target_sources(util_ack
++        PRIVATE
++        ${CMAKE_CURRENT_LIST_DIR}/src/util_ack.c
++)
++
++if(LORAGW_FOUND)
++target_include_directories(util_ack
++	PRIVATE
++		${LORAGW_INCLUDE_DIRS}
++)
++
++target_link_libraries(util_ack
++	PRIVATE
++		${LORAGW_LINK_LIBRARIES}
++)
++endif()
++
++if(loragw_FOUND)
++target_link_libraries(util_ack
++	PRIVATE
++		Semtech::loragw
++)
++endif()
++set_target_properties(util_ack PROPERTIES
++        RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
++)
++
++# add the install targets
++install (
++        TARGETS util_ack
++  	LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib
++	ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
++	RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
++)
+diff --git a/util_sink/CMakeLists.txt b/util_sink/CMakeLists.txt
+new file mode 100644
+index 0000000..c006fa7
+--- /dev/null
++++ b/util_sink/CMakeLists.txt
+@@ -0,0 +1,37 @@
++
++add_executable(util_sink "")
++target_sources(util_sink
++        PRIVATE
++	${CMAKE_CURRENT_LIST_DIR}/src/util_sink.c
++)
++
++if(LORAGW_FOUND)
++target_include_directories(util_sink
++	PRIVATE
++		${LORAGW_INCLUDE_DIRS}
++)
++
++target_link_libraries(util_sink
++	PRIVATE
++		${LORAGW_LINK_LIBRARIES}
++)
++endif()
++
++if(loragw_FOUND)
++target_link_libraries(util_sink
++	PRIVATE
++		Semtech::loragw
++)
++endif()
++
++set_target_properties(util_sink PROPERTIES
++        RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
++)
++
++# add the install targets
++install (
++        TARGETS util_sink
++  	LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib
++	ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
++	RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
++)
+diff --git a/util_tx_test/CMakeLists.txt b/util_tx_test/CMakeLists.txt
+new file mode 100644
+index 0000000..2207cac
+--- /dev/null
++++ b/util_tx_test/CMakeLists.txt
+@@ -0,0 +1,43 @@
++
++add_executable(util_tx_test "")
++target_sources(util_tx_test
++        PRIVATE
++	${CMAKE_CURRENT_LIST_DIR}/src/util_tx_test.c
++	${CMAKE_CURRENT_LIST_DIR}/src/base64.c
++)
++
++target_include_directories(util_tx_test
++	PRIVATE
++        ${CMAKE_CURRENT_LIST_DIR}/inc
++)
++
++if(LORAGW_FOUND)
++target_include_directories(util_tx_test
++	PRIVATE
++		${LORAGW_INCLUDE_DIRS}
++)
++
++target_link_libraries(util_tx_test
++	PRIVATE
++		${LORAGW_LINK_LIBRARIES}
++)
++endif()
++
++if(loragw_FOUND)
++target_link_libraries(util_tx_test
++	PRIVATE
++		Semtech::loragw
++)
++endif()
++
++set_target_properties(util_tx_test PROPERTIES
++        RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
++)
++
++# add the install targets
++install (
++        TARGETS util_tx_test
++  	LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib
++	ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
++	RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
++)
+-- 
+2.20.1
+