Gemtek Indoor Femto LoRaWAN Gateway - Anyone else using one?

I’m currently using a Gemtek Indoor Femto Gateway on TTN and so far, I like it. I think the best feature is that it’s powered via a 5V/2A Mini USB port, so perhaps, it can easily be powered in a car with a USB Car Charger.

I haven’t done any serious range testing with it, but it seems to work fine with our LT-100 GPS Trackers.

Anyone else use this Gateway? If so, what did you think?
What kind of range did you get?

Our friends at Embedded Works will be stocking them (US 915Mhz) soon:
http://www.sensorworks.net/sens322.html

1 Like

Hi, i use it in china, I found the range is no very good, it it near than node to node, and i cannot see the SF and RSSI of downlink.

What Network Server are you using it with?
TTN?

[quote=“usglobalsat, post:3, topic:11106”]
Network Server
[/quote]we don’t use network server, only connect it with PC.

Ah, I see.
I’m using it with TTN and so far, it is working well.

Hi, I have recently bought this Indoor Femto Gateway. I am struggling with the connection to TTN. Can you please let me know how you have registered it on TTN?

I have just received one purchased from eBay. I would like to use it on ttn but the first thing I need is a provisioning code. This sets up the Lora module for the correct frequency for use in the UK. If anyone has or knows how to get a provision code for the device that would be greatly appreciated.

Where can I buy this in the EU?

Unless you can get a provisioning code for use in your area don’t buy one of these. The LoRa radio is configured by entering a provision code into the web interface but there doesn’t seem to be a readily available tool for generating the required provisioning code for your local band plan.

I’ve been speaking to sensorworks.net and apparently the Provision Code in the web interface is only used for Gemtek’s own network. To configure this unit for TheThingsNetwork requires a change in the configuration file. Here is what sensorwork.net says;

all Gemtek Femto gateways run the same firmware. The only difference is a configuration file that is set through the Linux interface of the gateway. This Linux interface is reserved for the factory and OEM partners. The web interface, similar to what you might see on a router allows end users the ability to set Wi-Fi connectivity parameters in the case where you want to bridge the gateway to a Wi-Fi connection or use the gateway as an access point as well. As an OEM partner, we are able to make changes to the gateway to support a variety of different LoRaWAN networks and regions. Different OEMs have different configurations depending on their specific regional markets.

Sadly the required info/tool to make these changes is not readily availible from Gemtek or sensorworks.

What provision code are you referring to?

Are you able to SSH into the Gemtek Gateway? You’ll first need to connect to it via WiFi, the use 192.168.55.1 to SSH into the Gemtek Gateway…

Hi jessemydevices, when I try to ssh using the command

ssh admin@192.168.55.1

I get Connection to 192.168.55.1 closed. immediately after typing in password “admin”.

If it helps, the link is for the backup file downloaded from the Gemtek Gateway.
backup file

The provisioning code I was referring to is in the gateway web interface shown in the GioT menu. I originally thought it was for configuring the LoRa radio but apparently it is only used for the GioT network and the radio needs a configuration file. Maybe it is possible to modify my backup file with the correct configuration and then re-upload it through the web interface? I have had a poke around in the various file but without any documentation I am at a loss at the moment.

I’ve managed to gain ssh access with root privileges to the gateway. To do this I first logged in to the web interface on 192.168.55.1. Log in with user admin and password admin. Then go to system > backup and restore to download a backup to your pc. Ubuntu saves this in ~/Downloads. The backup file is simply a .tar.gz of the gateways /etc folder. Open the file /etc/shadow and copy the hash for the admin password (shown in bold) to all the other passwords. Save the changes and upload through the web interface.

root:$1$kISzvUen$KWbOWvwQwqDkLh0N4cX00/:16755:0:99999:7:::
daemon::0:0:99999:7:::
ftp:
:0:0:99999:7:::
network::0:0:99999:7:::
nobody:
:0:0:99999:7:::
admin:$1$kISzvUen$KWbOWvwQwqDkLh0N4cX00/:16755:0:99999:7:::
su:$1$kISzvUen$KWbOWvwQwqDkLh0N4cX00/:17441:0:99999:7:::
giot-admin:$1$kISzvUen$KWbOWvwQwqDkLh0N4cX00/:17441:0:99999:7:::
giot-user:$1$kISzvUen$KWbOWvwQwqDkLh0N4cX00/:17442:0:99999:7:::

The gateway will reboot with all passwords set to admin. Reconnect to the gateways wifi, open a terminal and run the command;
ssh giot-admin@192.168.55.1
enter password admin and you now have full root access to the gateway.

Next step, figure out how to configure the gateway for TTN. If anyone has one of these actually working on TTN can you share your backup file or compare your backup file to the one I posted a link to previously so that we can get an idea on how to set this up for TTN?

2 Likes

After a small delay I am back to trying to get this to work on TTN. The unit runs OpenWrt Barrier Breaker which is no longer getting security updates from OpenWrt. Midnight Commander plays well with this unit (sudo apt install mc to install on Ubuntu). Using mc connect to the unit using the Shell Link dialog, enter giot-admin@192.168.55.1 and type password admin when asked. Using mc I copied nearly all the directories from the root file system to a folder on my machine for ease of poking around. I have found a file /usr/bin/lora_sw_arch_check.sh that looks interesting, here is a copy of the file.

#!/bin/sh

#1.check real files
#2.move file
#3.create symbolic link

DATA_MNT="/mnt/data"
REAL_LORA_DIR="/mnt/data/lora"
REAL_LORA_LIB="/mnt/data/lora/usr/lib"
REAL_LORA_BIN="/mnt/data/lora/usr/bin"
SOUR_LIB_PATH="/usr/lib"
SOUR_BIN_PATH="/usr/bin"
CHK_LIB="liblgwinfo.so"

APP_MNT_DIR="/mnt/data/lora/app"
REAL_LORA_DIR_BOOT0="$APP_MNT_DIR/boot0"
REAL_LORA_LIB_BOOT0="$APP_MNT_DIR/boot0/usr/lib"
REAL_LORA_BIN_BOOT0="$APP_MNT_DIR/boot0/usr/bin"
REAL_LORA_DIR_BOOT1="$APP_MNT_DIR/boot1"
REAL_LORA_LIB_BOOT1="$APP_MNT_DIR/boot1/usr/lib"
REAL_LORA_BIN_BOOT1="$APP_MNT_DIR/boot1/usr/bin"
REAL_LORA_DB="$APP_MNT_DIR/db"
LORA_CFG_BK_DIR="$DATA_MNT/lora_cfg_bk"

CFG_NAME="lora_WLRGFM-100.ini"
CFG_NAME_BK="BK-lora_WLRGFM-100.ini"
CFG_NAME_BOOT0="boot0_lora_WLRGFM-100.ini"
CFG_NAME_BOOT1="boot1_lora_WLRGFM-100.ini"
GJSON_NAME="global_conf_0.json"
GJSON_CFG_NAME_BOOT0="boot0_global_conf_0.json"
GJSON_CFG_NAME_BOOT1="boot1_global_conf_0.json"
LORA_CFG_DIR="/app/cfg"
LORA_EXE_PATH="/app/lora_pkg"
LORA_DB_DIR="/app/db"
LORA_DB="lora.db"
MNT_CFG="/mnt/data/config"
ROM_CFG_DIR="/rom/app/cfg"
ROM_LORA_EXE_PATH="/rom/app/lora_pkg"
FIRST_EXE="cfg_cmd"
LAST_EXE="util_tx_test"
SW_ARCH_LOG="/tmp/lora_sw_arch_chk_log"
CUR_BOOT_LINK=""
AUTO_W_MAC="0"
AUTO_W_MAC_CMD="$LORA_EXE_PATH/lora_mac_rw.sh w"
CFG_CMD_EXE="/app/lora_pkg/cfg_cmd"
CFG_CMD_EXE_SYNC="$CFG_CMD_EXE sync"
LORA_GW_EXE="pkt_forwarder"
LORA_SVR_EXE="loraserver"
APP_PRODTEST="/app/prodtest"
PWR_TAB="pwr_tables.ini"

sync_lora_cfg(){
	$CFG_CMD_EXE_SYNC
	sleep 2
}

create_dual_boot_dir() 
{	
	mkdir -p $REAL_LORA_DIR_BOOT0
	mkdir -p $REAL_LORA_LIB_BOOT0	
	mkdir -p $REAL_LORA_BIN_BOOT0
	
	mkdir -p $REAL_LORA_DIR_BOOT1
	mkdir -p $REAL_LORA_LIB_BOOT1	
	mkdir -p $REAL_LORA_BIN_BOOT1
}

rm_ng_link_in_boot()
{
	for CHK_BOOT in $REAL_LORA_DIR_BOOT0/cfg $REAL_LORA_DIR_BOOT0/lora_pkg $REAL_LORA_DIR_BOOT0/usr/bin $REAL_LORA_DIR_BOOT0/usr/lib \
		$REAL_LORA_DIR_BOOT1/cfg $REAL_LORA_DIR_BOOT1/lora_pkg $REAL_LORA_DIR_BOOT1/usr/bin $REAL_LORA_DIR_BOOT1/usr/lib
	do 
		for FILE in $CHK_BOOT/*
		do
			file_name=`echo $FILE | awk -F "/app/" '{print$2}'`
			if [ -L "$FILE" ]; then
				echo "$FILE is link!"
				rm -f $FILE 
			fi
		done
	done
}

new_lib_chk(){
	#Add new lib here to make sure they are included
	for lib in libringbuf.so libmosquitto.a libmqttcli.so libcommon.so
	do
		if [ -f $SOUR_LIB_PATH/$lib ]; then
			if [[ ! -f $REAL_LORA_LIB_BOOT0/$lib || ! -f $REAL_LORA_LIB_BOOT1/$lib ]]; then
				cp $SOUR_LIB_PATH/$lib $REAL_LORA_LIB_BOOT0
				cp $SOUR_LIB_PATH/$lib $REAL_LORA_LIB_BOOT1
			fi
		fi
	done   
}

cp_and_chk_lora_lib() 
{	
	#Only when there is no lora lib in /mnt/data/lora/usr/lib
	if [[ -f $SOUR_LIB_PATH/$CHK_LIB && ! -f $REAL_LORA_LIB_BOOT0/$CHK_LIB || ! -f $REAL_LORA_LIB_BOOT1/$CHK_LIB ]]; then
		for lib in libcurls.so liblargedata.so liblgwinfo.so libringbuf.so liblorasql.so liblorautility.so libloglevel.so libmosquitto.a libmqttcli.so
		do
			cp $SOUR_LIB_PATH/$lib $REAL_LORA_LIB_BOOT0
			cp $SOUR_LIB_PATH/$lib $REAL_LORA_LIB_BOOT1
		done   
	fi
	
	#Exist both in /usr/lib and /mnt/data
	if [[ -f $REAL_LORA_LIB_BOOT0/$CHK_LIB && -f $REAL_LORA_LIB_BOOT1/$CHK_LIB ]]; then
		new_lib_chk
		echo "[cp_and_chk_lora_lib]:LoRa libraries copy to /mnt/data DONE!"
		return 0
	else
		echo "[cp_and_chk_lora_lib]:LoRa library copy to /mnt/data FAILED!"
		return 1
	fi
}		

get_lora_db(){
	mkdir -p $REAL_LORA_DB
	if [ ! -f $REAL_LORA_DB/$LORA_DB ] ; then
		if [ -f $ROM_LORA_EXE_PATH/$LORA_DB ]; then
			cp -f $ROM_LORA_EXE_PATH/* $REAL_LORA_DB
		else
			cp /rom/$LORA_DB_DIR/* $REAL_LORA_DB
		fi
	fi
}

create_lora_link()
{
	new_lib_chk
	get_lora_db
	if ls -al /app/lora_pkg | grep $LORA_SVR_EXE | grep boot1 > /dev/null; then
		LINK_BOOT="$REAL_LORA_DIR_BOOT1"
	else
		LINK_BOOT="$REAL_LORA_DIR_BOOT0"
	fi
	
	mkdir -p /app/lib /app/bin $LORA_DB_DIR
	#create symbolic link for /app/cfg
	for FILE in $LINK_BOOT/cfg/*
	do
		file_name=`echo $FILE| awk -F "cfg/" '{print$2}'`
		if [ ! -L "$FILE" ]; then
			ln -sf $FILE $LORA_CFG_DIR/$file_name
		fi
	done

	#create symbolic link for /app/lora_pkg
	for FILE in $LINK_BOOT/lora_pkg/*
	do
		file_name=`echo $FILE| awk -F "lora_pkg/" '{print$2}'`
		if [ ! -L "$FILE" ]; then
			ln -sf $FILE $LORA_EXE_PATH/$file_name
		fi
	done
	
	#create symbolic link for /app/usr/lib 
	for FILE in $LINK_BOOT/usr/lib/*
	do
		file_name=`echo $FILE| awk -F "usr/lib/" '{print$2}'`
		if [ ! -L "$FILE" ]; then
			ln -sf $FILE /app/lib/$file_name
		fi
	done
	
	#create symbolic link for /app/db
	for FILE in $REAL_LORA_DB/*
	do
		file_name=`echo $FILE| awk -F "db/" '{print$2}'`
		if [ ! -L "$FILE" ]; then
			ln -sf $FILE /app/db/$file_name
		fi
	done
	
	#create symbolic link for /app/usr/bin 
	chk_and_create_cwmpc_link
	
	
	if [[ ! -L $LORA_CFG_DIR/$CFG_NAME || ! -L $LORA_EXE_PATH/$FIRST_EXE || ! -L $LORA_EXE_PATH/$LAST_EXE ]]; then
		echo "[$0]:Create LoRa link fail!"
		return 1
	else
		echo "[$0]:LoRa link is ready!"
		return 0	
	fi	

}

#Supposed we only wanna dual images
mv_and_create_link() 
{
	create_dual_boot_dir
	#Keep LoRa CFG
	if [[ "$1" = "regen" || "$2" = "regen" ]];then
		mkdir -p $REAL_LORA_DIR_BOOT0/cfg
		mkdir -p $REAL_LORA_DIR_BOOT1/cfg
		cp -f $LORA_CFG_BK_DIR/$CFG_NAME_BOOT0 $REAL_LORA_DIR_BOOT0/cfg/$CFG_NAME
		cp -f $LORA_CFG_BK_DIR/$CFG_NAME_BOOT1 $REAL_LORA_DIR_BOOT1/cfg/$CFG_NAME
	fi
	#Actually, needless, since there is anothre check before this API...
	if [[ -L $LORA_EXE_PATH/$LORA_SVR_EXE && -L /app/lib/$CHK_LIB && -L $LORA_EXE_PATH/$FIRST_EXE \
		&& -L $LORA_CFG_DIR/$CFG_NAME && -L $LORA_EXE_PATH/$LAST_EXE && -L /app/bin/cwmpc \
		&& -f $REAL_LORA_DIR_BOOT0/lora_pkg/$FIRST_EXE && -f $REAL_LORA_DIR_BOOT1/lora_pkg/$FIRST_EXE \
		&& -f $REAL_LORA_DIR_BOOT0/cfg/$CFG_NAME && -f $REAL_LORA_DIR_BOOT1/cfg/$CFG_NAME \
		&& -f $REAL_LORA_BIN_BOOT0/cwmpc && -f $REAL_LORA_BIN_BOOT1/cwmpc ]]; then	
		
		echo "[mv_and_create_link]:No need to re-construct!"
		
		chmod -R 777 $REAL_LORA_DIR_BOOT0/*
		chmod -R 777 $REAL_LORA_DIR_BOOT1/*
		
		return 0
	fi

	#Initial status
	if [[ ! -L $LORA_CFG_DIR/$CFG_NAME && -f $LORA_CFG_DIR/$CFG_NAME \
		&& -f $LORA_EXE_PATH/$FIRST_EXE && -f $LORA_EXE_PATH/$LAST_EXE ]]; then

		#At this point, there is lora real package in /app, but not in /mnt/data/lora/app/boot0 and /mnt/data/lora/app/boot1!	
		if [[ ! -f $REAL_LORA_DIR_BOOT0/cfg/$CFG_NAME || ! -f $REAL_LORA_DIR_BOOT0/lora_pkg/$FIRST_EXE \
			|| ! -f $REAL_LORA_DIR_BOOT0/lora_pkg/$LAST_EXE || ! -f $REAL_LORA_DIR_BOOT1/cfg/$CFG_NAME \
			|| ! -f $REAL_LORA_DIR_BOOT1/lora_pkg/$FIRST_EXE || ! -f $REAL_LORA_DIR_BOOT1/lora_pkg/$LAST_EXE \
			|| ! -f $REAL_LORA_BIN_BOOT0/cwmpc || ! -f $REAL_LORA_BIN_BOOT1/cwmpc ]]; then
			
			cp -rf $LORA_CFG_DIR $REAL_LORA_DIR_BOOT0
			cp -rf $LORA_CFG_DIR $REAL_LORA_DIR_BOOT1
			
			#Keep LoRa CFG
			if [[ "$1" = "regen" || "$2" = "regen" ]];then   
				cp -f $LORA_CFG_BK_DIR/$CFG_NAME_BOOT0 $REAL_LORA_DIR_BOOT0/cfg/$CFG_NAME
		 		cp -f $LORA_CFG_BK_DIR/$CFG_NAME_BOOT1 $REAL_LORA_DIR_BOOT1/cfg/$CFG_NAME
			fi
			
			cp -rf $LORA_EXE_PATH $REAL_LORA_DIR_BOOT0
			cp -rf $LORA_EXE_PATH $REAL_LORA_DIR_BOOT1
		fi
		
		if [ "$1" = "recfg" ]; then
			cp $ROM_CFG_DIR/$CFG_NAME $REAL_LORA_DIR_BOOT0/cfg
			cp $ROM_CFG_DIR/$CFG_NAME $REAL_LORA_DIR_BOOT1/cfg
		fi
		cp_and_chk_lora_lib
		create_lora_link
		echo "[mv_and_create_link]:Creating and checking LoRa link done-01!"
	#Files in boot0, with no link(it could detect most links missing in /app/lora_pkg, /app/cfg, /app/bin, and /app/lib)
	elif [[ ! -L /app/bin/cwmpc || ! -L /app/lib/$CHK_LIB || ! -L $LORA_CFG_DIR/$CFG_NAME \
		|| ! -L $LORA_EXE_PATH/$FIRST_EXE || ! -L $LORA_EXE_PATH/$LAST_EXE ]] \
		&& [[ -f $REAL_LORA_DIR_BOOT0/cfg/$CFG_NAME && -f $REAL_LORA_DIR_BOOT0/lora_pkg/$LAST_EXE \
		&& -f $REAL_LORA_BIN_BOOT0/cwmpc && -f $REAL_LORA_LIB_BOOT0/$CHK_LIB ]]; then

		if [ "$1" = "recfg" ]; then
			cp $ROM_CFG_DIR/$CFG_NAME $REAL_LORA_DIR_BOOT0/cfg
			cp $ROM_CFG_DIR/$CFG_NAME $REAL_LORA_DIR_BOOT1/cfg
		fi
		
		create_lora_link
		echo "[mv_and_create_link]:Creating and checking LoRa link done-02!"
	#No link or file in /app/cfg and boot	
	elif [[ ! -f $LORA_CFG_DIR/$CFG_NAME && ! -L $LORA_CFG_DIR/$CFG_NAME \
		&& ! -f $LORA_EXE_PATH/$FIRST_EXE && ! -L $LORA_EXE_PATH/$FIRST_EXE \
		&& ! -f $LORA_EXE_PATH/$LAST_EXE && ! -L $LORA_EXE_PATH/$LAST_EXE \
		&& ! -f $REAL_LORA_DIR_BOOT0/cfg/$CFG_NAME && ! -f $REAL_LORA_DIR_BOOT1/cfg/$CFG_NAME ]]; then
		
		echo "[mv_and_create_link]:No good files or link found! Try to roll back from backup or default!"
		rm -rf $REAL_LORA_DIR_BOOT0/*
		rm -rf $REAL_LORA_DIR_BOOT1/*
		
		create_dual_boot_dir
		cp_and_chk_lora_lib
		
		if [[ ! -f $REAL_LORA_DIR_BOOT0/cfg/$CFG_NAME || ! -f $REAL_LORA_DIR_BOOT0/lora_pkg/$FIRST_EXE \
			|| ! -f $REAL_LORA_DIR_BOOT0/lora_pkg/$LAST_EXE || ! -f $REAL_LORA_BIN_BOOT0/cwmpc ]]; then
			
			cp -rf $ROM_CFG_DIR $REAL_LORA_DIR_BOOT0
			cp -rf $ROM_CFG_DIR $REAL_LORA_DIR_BOOT1
		
			cp -rf $ROM_LORA_EXE_PATH $REAL_LORA_DIR_BOOT0
			cp -rf $ROM_LORA_EXE_PATH $REAL_LORA_DIR_BOOT1
		fi
		#Try to find backup config, which may be povisioned
		if [[ -f "$MNT_CFG/$CFG_NAME" ]]; then
			cp -rf $MNT_CFG/$CFG_NAME $REAL_LORA_DIR_BOOT0/cfg
			cp -rf $MNT_CFG/$CFG_NAME $REAL_LORA_DIR_BOOT1/cfg	
		fi
		create_lora_link

		if [ -f $LORA_EXE_PATH/lora_mac_rw.sh ]; then
			AUTO_W_MAC="1"
			echo "[mv_and_create_link]:Auto writing MAC..."
			$AUTO_W_MAC_CMD
		fi 
		
		echo "[mv_and_create_link]:Creating and checking LoRa link done-3! You may have to re-provision!"
		echo "[mv_and_create_link]:Creating and checking LoRa link done-3! You may have to re-provision!" >> $SW_ARCH_LOG
	# No real files anywhere, but /rom	
	elif [[ ! -f $REAL_LORA_DIR_BOOT0/cfg/$CFG_NAME && ! -f $REAL_LORA_DIR_BOOT1/cfg/$CFG_NAME ]] \
		|| [[ ! -f $REAL_LORA_BIN_BOOT0/cwmpc && ! -f $REAL_LORA_BIN_BOOT1/cwmpc ]] \
		|| [[ ! -f $REAL_LORA_DIR_BOOT0/lora_pkg/$FIRST_EXE && ! -f $REAL_LORA_DIR_BOOT1/lora_pkg/$FIRST_EXE ]] \
		|| [[ ! -f $REAL_LORA_DIR_BOOT0/lora_pkg/$LAST_EXE && ! -f $REAL_LORA_DIR_BOOT1/lora_pkg/$LAST_EXE ]] \
		|| [[ ! -f $REAL_LORA_DIR_BOOT0/lora_pkg/$LORA_SVR_EXE && ! -f $REAL_LORA_DIR_BOOT1/lora_pkg/$LORA_SVR_EXE ]] \
		|| [[ ! -f $REAL_LORA_DIR_BOOT0/lora_pkg/$LORA_GW_EXE && ! -f $REAL_LORA_DIR_BOOT1/lora_pkg/$LORA_GW_EXE ]]; then		
			
			echo "[mv_and_create_link]:Wrong LoRa SW detected! Try to roll back from backup or default!"
			rm -rf $REAL_LORA_DIR_BOOT0/*
			rm -rf $REAL_LORA_DIR_BOOT1/*
			
			create_dual_boot_dir
			cp_and_chk_lora_lib
			
			cp -rf $ROM_CFG_DIR $REAL_LORA_DIR_BOOT0
			cp -rf $ROM_CFG_DIR $REAL_LORA_DIR_BOOT1
		
			cp -rf $ROM_LORA_EXE_PATH $REAL_LORA_DIR_BOOT0
			cp -rf $ROM_LORA_EXE_PATH $REAL_LORA_DIR_BOOT1
			
			#Try to find backup config
			if [[ -f "$MNT_CFG/$CFG_NAME" ]]; then
				cp -rf $MNT_CFG/$CFG_NAME $REAL_LORA_DIR_BOOT0/cfg
				cp -rf $MNT_CFG/$CFG_NAME $REAL_LORA_DIR_BOOT1/cfg	
			fi
			
			create_lora_link
			
			if [ -f $LORA_EXE_PATH/lora_mac_rw.sh ]; then
				AUTO_W_MAC="1"
				echo "[Urgent]: Auto writing MAC..."
				$AUTO_W_MAC_CMD
			fi 
			
			echo "[mv_and_create_link]:Creating and checking LoRa link done-4! You may have to re-provision!"
			echo "[mv_and_create_link]:Creating and checking LoRa link done-4! You may have to re-provision!" >> $SW_ARCH_LOG			
	else	
		echo "[mv_and_create_link]:Case not definded!"
		echo "[mv_and_create_link]:Case not definded!" >> $SW_ARCH_LOG
		return 1
	fi	
	
	chmod -R 777 $REAL_LORA_DIR_BOOT0/*
	chmod -R 777 $REAL_LORA_DIR_BOOT1/*
	
	return 0
}

chk_and_create_cwmpc_link() 
{
	if [[ ! -f $REAL_LORA_BIN_BOOT0/cwmpc || ! -f $REAL_LORA_BIN_BOOT1/cwmpc ]]; then
	    cp $SOUR_BIN_PATH/cwmpc $REAL_LORA_BIN_BOOT0/cwmpc
		cp $SOUR_BIN_PATH/cwmpc $REAL_LORA_BIN_BOOT1/cwmpc
	fi
	if [ ! -L /app/bin/cwmpc ]; then
		echo "[INFO]:cwmpc link is not ready!"  
		if ls -al /app/lora_pkg/$LORA_SVR_EXE | grep boot1 > /dev/null ; then
			ln -sf $REAL_LORA_BIN_BOOT1/cwmpc /app/bin/cwmpc
		else
			ln -sf $REAL_LORA_BIN_BOOT0/cwmpc /app/bin/cwmpc
		fi
		echo "[INFO]:Creating cwmpc link done!" 
	fi
}

check_cur_link() {
	echo "[INFO]:Check current link..."
	CHK_BOOT_LINK=`ls -al /app/lora_pkg | grep "$LORA_SVR_EXE" | grep boot0`
	if [ "$CHK_BOOT_LINK" = "" ]; then
		CHK_BOOT_LINK=`ls -al /app/lora_pkg | grep "$LORA_SVR_EXE" | grep boot1`
		if [ "$CHK_BOOT_LINK" = "" ]; then
			#echo "[INFO]:The dual LoRa boots are not ready!"
			return 2
		fi
		CUR_BOOT_LINK="boot1"
	else
		CUR_BOOT_LINK="boot0"
	fi
	echo "[INFO]:Check current link DONE!($CUR_BOOT_LINK)"
	if [ "$CUR_BOOT_LINK" = "boot1" ]; then
		return 1
	else
		return 0
	fi
}

chk_sw_status ()
{
	check_cur_link
	if [ "$?" = "2" ]; then
		if [[ -L "$LORA_EXE_PATH/$LORA_SVR_EXE" && -L "$LORA_EXE_PATH/$FIRST_EXE" && -L "$LORA_CFG_DIR/$CFG_NAME" \
		&& -L "$LORA_EXE_PATH/$LAST_EXE" && -f "$REAL_LORA_DIR/$LORA_EXE_PATH/$LORA_SVR_EXE" && ! -f "$REAL_LORA_DIR_BOOT0/lora_pkg/$LORA_SVR_EXE" ]]; then
		
			echo "[chk_sw_status]:The LoRa SW arch is the old style! LoRa link for single image!"
			return 1	
		else
			echo "[chk_sw_status]:The LoRa SW arch needs to re-construct! LoRa link not ready!"
			return 2
		fi
	fi
	
	#The SW arch is ready only when 1. lora link is ready. 2. the files in current boot are ready
	if [[ -L "/app/bin/cwmpc" && -L "/app/lib/$CHK_LIB" && -L "$LORA_EXE_PATH/$LORA_SVR_EXE" && -L "$LORA_EXE_PATH/$FIRST_EXE" \
		&& -L "$LORA_CFG_DIR/$CFG_NAME" && -L "$LORA_EXE_PATH/$LAST_EXE" && -f "$APP_MNT_DIR/$CUR_BOOT_LINK/lora_pkg/$FIRST_EXE" \
		&& -f "$APP_MNT_DIR/$CUR_BOOT_LINK/lora_pkg/$LAST_EXE" && -f "$APP_MNT_DIR/$CUR_BOOT_LINK/lora_pkg/$LORA_SVR_EXE" \
		&& -f "$APP_MNT_DIR/$CUR_BOOT_LINK/cfg/$CFG_NAME" && -f "$APP_MNT_DIR/$CUR_BOOT_LINK/usr/bin/cwmpc" ]]; then
		
		#in case, extra files from OTA 
		create_lora_link
		
		#echo "[chk_sw_status]:The LoRa SW arch is ready!"

		return 0
	#For single image, check if the link is old and no dual boots	
	elif [[ -L "$LORA_EXE_PATH/$LORA_SVR_EXE" && -L "$LORA_EXE_PATH/$FIRST_EXE" && -L "$LORA_CFG_DIR/$CFG_NAME" \
		&& -L "$LORA_EXE_PATH/$LAST_EXE" && -f "$REAL_LORA_DIR/$LORA_EXE_PATH/$LORA_SVR_EXE" \
		&& ! -f "$REAL_LORA_DIR_BOOT0/lora_pkg/$LORA_SVR_EXE" ]]; then
		
		echo "[chk_sw_status]:The LoRa SW arch is the old style!"
		return 1	
	else
		echo "[chk_sw_status]:The LoRa SW arch needs to re-construct!"
		return 2
	fi
}

#Only for the old LORA SW architecture(single image)
roll_back_lora_sw_arch()
{
	cp -rf $REAL_LORA_DIR/app/cfg/* $LORA_CFG_DIR
	cp -rf $REAL_LORA_DIR/app/lora_pkg/* $LORA_EXE_PATH
	
	cp -rf $REAL_LORA_DIR/usr/bin/* /usr/bin
	cp -rf $REAL_LORA_DIR/usr/lib/* /usr/lib
	rm -rf $REAL_LORA_DIR/usr
}

print_help(){
	echo "Usage:"
	echo "$0 (Check LoRa link and file)"
	echo "$0 reset [recfg](Backup and reset LoRa SW arch + reboot.  With 'recfg', the config will be set to default with auto writing MAC)"
	echo "$0 regen [recfg] [keep_db] (Backup and reset LoRa SW arch + re-generate. With 'recfg', the config will be set to default with auto writing MAC; with 'keep_db': keep the lora.db)"
	echo "$0 r2d [main_r2d](Without backup and remove LoRa link and files to default, with 'main_r2d', the DUT will r2d as well)"
}

restart_conf_manager(){
	echo "[INFO]:Restart conf_manager..."
	if [ "$(pidof conf_manager)" != "" ];then
		kill -9 $(pidof conf_manager)
	fi
	/usr/bin/conf_manager &
	sleep 5
}


main_do() 
{
	if [[ "$1" = "-h" || "$1" = "-help" ]]; then
		print_help
		return 1
	fi
	
	if [ "$(pidof lora_wdg.sh)" != "" ]; then
		/app/lora_pkg/loracmd.sh lora_wdg off
	fi
	if [[ "$(pidof $LORA_SVR_EXE)" != "" || "$(pidof $LORA_GW_EXE)" != "" ]]; then
		/app/lora_pkg/loracmd.sh lora_stop
	fi
	if [ "$(pidof cwmpc)" != "" ]; then
		killall cwmpc
	fi
	if [ "$(pidof mqtt_client_sub)" != "" ]; then
		killall mqtt_client_sub
	fi
	
	
	if [ "$1" = "r2d" ]; then
		echo "[INFO]:LoRa SW architecture is now r2d..."
		
		rm -rf /app
		rm -rf /mnt/data/lora
		cp -rf /rom/app /
		sync;sync
		if [ "$2" = "main_r2d" ]; then
			echo "[INFO]:You may have to re-bind LoRa MAC after rebooting..."
			sleep 2	
			restore_default	
		fi	
		echo "LoRa packages R2D Done! Run restore_default to re-new."
		return 0
	fi
	
	if [ "$1" = "reset" ]; then
		echo "[INFO]:LoRa SW architecture is now resetting..."
		
		if [[ -d $REAL_LORA_DIR_BOOT0 && -d $REAL_LORA_DIR_BOOT1 ]]; then
			cp -rf $REAL_LORA_DIR_BOOT0/cfg/* $LORA_CFG_DIR/
			cp -rf $ROM_LORA_EXE_PATH/* $LORA_EXE_PATH/	
		else
			cp -rf $REAL_LORA_DIR/cfg/* $LORA_CFG_DIR/
			cp -rf $ROM_LORA_EXE_PATH/* $LORA_EXE_PATH/	
		fi
		
		rm -rf /mnt/data/lora

		echo "[INFO]:LoRa SW architecture reset DONE! Reboot in 5 sec (Ctrl+C to quit)..."
		sleep 5

		reboot
	fi
	
	if [ "$1" = "regen" ]; then
		echo "[INFO]:LoRa SW architecture is now re-generating..."
		if [[ -d $REAL_LORA_DIR_BOOT0 && -d $REAL_LORA_DIR_BOOT1 ]]; then
			
			echo "[INFO]:Keep LoRa power table..."
			if [ -f "$REAL_LORA_DIR_BOOT0/cfg/$PWR_TAB" ]; then
				cp $REAL_LORA_DIR_BOOT0/cfg/$PWR_TAB $DATA_MNT
			elif [ -L "$LORA_CFG_DIR/$PWR_TAB" ] ; then
				cp $LORA_CFG_DIR/$PWR_TAB $DATA_MNT
			elif [ -f $APP_PRODTEST/$PWR_TAB ] ; then	
				cp $APP_PRODTEST/$PWR_TAB $DATA_MNT
			fi
			if [ ! -f "$DATA_MNT/$PWR_TAB" ]; then
				cp /rom/$LORA_CFG_DIR/$PWR_TAB $DATA_MNT
			fi
			
			cp -rf $ROM_CFG_DIR/* $LORA_CFG_DIR/
			cp -rf $ROM_LORA_EXE_PATH/* $LORA_EXE_PATH/	
			
			#keep lora.db
			if [[ -f $REAL_LORA_DB/$LORA_DB && "$2" = "keep_db" || "$3" = "keep_db" ]];then
				cp -f $REAL_LORA_DB/$LORA_DB $DATA_MNT  
				echo "[INFO]:Keep customized LoRa DB..."
			fi
			
			cp -rf /rom/$LORA_DB_DIR/* $LORA_DB_DIR/	
			rm -f $LORA_CFG_DIR/$CFG_NAME_BK
			
			#Keep LoRa CFG
			if [ "$2" != "recfg" ];then
			   mkdir -p $LORA_CFG_BK_DIR
			   cp /mnt/data/lora/app/boot0/cfg/$CFG_NAME $LORA_CFG_BK_DIR/$CFG_NAME_BOOT0
			   cp /mnt/data/lora/app/boot1/cfg/$CFG_NAME $LORA_CFG_BK_DIR/$CFG_NAME_BOOT1

			   cp /mnt/data/lora/app/boot0/cfg/$GJSON_NAME $LORA_CFG_BK_DIR/$GJSON_CFG_NAME_BOOT0
			   cp /mnt/data/lora/app/boot1/cfg/$GJSON_NAME $LORA_CFG_BK_DIR/$GJSON_CFG_NAME_BOOT1

			fi
		else
			cp -rf $ROM_CFG_DIR/* $LORA_CFG_DIR/
			cp -rf $ROM_LORA_EXE_PATH/* $LORA_EXE_PATH/	
		fi
		
		rm -rf /mnt/data/lora
		sync_lora_cfg
		echo "[INFO]:Remove old LoRa SW architecture DONE!"
	fi
		
	chk_sw_status
	rtn=$?
	if [ "$rtn" = "0" ]; then
		sync_lora_cfg
		return 0
	elif [ "$rtn" = "1" ]; then
		echo "[INFO]:Roll back LoRa SW architecture from old style to initial..."
		roll_back_lora_sw_arch		
	fi
	
	#For initial case, no lora package in /mnt/data and lora links are not ready.
	mv_and_create_link $2 $1
	if [ "$?" = "1" ]; then
		return 1
	fi
	
	if [ "$1" = "regen" ]; then
		if [[ "$2" = "keep_db" || "$3" = "keep_db" ]]; then
			mv $DATA_MNT/$LORA_DB $REAL_LORA_DB
			echo "[INFO]:Keep customized LoRa DB DONE."
		fi
		cp $DATA_MNT/$PWR_TAB $REAL_LORA_DIR_BOOT0/cfg
		cp $DATA_MNT/$PWR_TAB $REAL_LORA_DIR_BOOT1/cfg
		rm -f $DATA_MNT/$PWR_TAB
		echo "[INFO]:Keep LoRa power table DONE."
		
		#Keep LoRa CFG
		if [ "$2" != "recfg" ];then
			cp -f $LORA_CFG_BK_DIR/$CFG_NAME_BOOT0 $REAL_LORA_DIR_BOOT0/cfg/$CFG_NAME
			cp -f $LORA_CFG_BK_DIR/$CFG_NAME_BOOT1 $REAL_LORA_DIR_BOOT1/cfg/$CFG_NAME

			cp -f $LORA_CFG_BK_DIR/$GJSON_CFG_NAME_BOOT0 $REAL_LORA_DIR_BOOT0/cfg/$GJSON_NAME
			cp -f $LORA_CFG_BK_DIR/$GJSON_CFG_NAME_BOOT1 $REAL_LORA_DIR_BOOT1/cfg/$GJSON_NAME

			rm -rf $LORA_CFG_BK_DIR
		fi
	fi
	if [[ "$2" = "recfg" && -f $LORA_EXE_PATH/lora_mac_rw.sh && "$AUTO_W_MAC" != "1" ]]; then
		echo "[INFO]:Auto writing MAC..."
		$AUTO_W_MAC_CMD
	fi
	
	sync_lora_cfg
	restart_conf_manager
	sync;sync
	echo "[INFO]:LoRa program architecture is ready!"
	
	return 0
}

main_do $1 $2 $3

I tried running the file but get permision denied error. :frowning:

The FemtoGateway not opensource. When I try to modify some files to connect TTN server. I broke the firmwere of LoRaGateway. I hate this. I hope FemtoGateway push source and tool bootfirmware on Githup.

Can you document what you did to break it so we know what not to do? I will see if I can locate a backup file from my unit.

Maybe one day someone will figure out how to get one of these working on TTN, but for the moment DO NOT buy one of these!!!

1 Like

Hi everybody!
I have device IOT Femto Gateway WLRGFM-100
I have loged in to admin interface but i can not setup anything there
Only change admin password and reboot device
How to connect it to TTN ?

Alexey, until someone can find/post some documentation for this device I’m afraid it won’t work on TTN. The manufacturer and the one reseller I spoke with refuse to give me any information. Sadly for now, DO NOT BUY ONE OF THESE FOR TTN!

Is it using Semtech packet forwarder? can u please share the screen shot of device login? I am able to integrate the Gemtek Indoor LoRAWAN gateway with TTN

Hello madhuvarsha, can you share about how to integrate Gemtek Indoor LoRaWAN gateway with TTN Server step-by-step?

I very very need your help.

Thank you in advance