Generate the firmware update file and signature
The steps in this procedure are optional and depend on the gateway you're using. Gateway manufacturers provide their own firmware update in the form of an update file or a script and Basics Station runs this script in the background. In this case, you'll most likely find the firmware update file in the release notes of the gateway you're using. You can then use that update file or script instead and proceed to Upload the firmware file to an S3 bucket and add an IAM role.
If you don't have this script, following shows the commands to run for generating the firmware update file. The updates can also be signed to ensure that the code was not altered or corrupted and devices run code published only by trusted authors.
In this procedure, you'll:
Generate the firmware update file
The LoRa Basics Station software running on the gateway is capable of
receiving firmware updates in the CUPS response. If you don't have a script
provided by the manufacturer, refer to the following firmware update script
that is written for the Raspberry Pi based RAKWireless Gateway. We have a
base script and the new station binary, version file, and
station.conf
are attached to it.
Note
The script is specific to the RAKWireless Gateway, so you'll have to adapt it to your application depending on the gateway you're using.
Base script
Following shows a sample base script for the Raspberry Pi based
RAKWireless Gateway. You can save the following commands in a file
base.sh
and then run the script in the terminal on the
Raspberry Pi's web browser.
*#!/bin/bash* execution_folder=/home/pi/Documents/basicstation/examples/aws_lorawan station_path="$execution_folder/station" version_path="$execution_folder/version.txt" station_conf_path="$execution_folder/station_conf" # Function to find the Basics Station binary at the end of this script # and store it in the station path function prepare_station() { match=$(grep --text --line-number '^STATION:$' $0 | cut -d ':' -f 1) payload_start=$((match + 1)) match_end=$(grep --text --line-number '^END_STATION:$' $0 | cut -d ':' -f 1) payload_end=$((match_end - 1)) lines=$(($payload_end-$payload_start+1)) head -n $payload_end $0 | tail -n $lines > $station_path } # Function to find the version.txt at the end of this script # and store it in the location for version.txt function prepare_version() { match=$(grep --text --line-number '^VERSION:$' $0 | cut -d ':' -f 1) payload_start=$((match + 1)) match_end=$(grep --text --line-number '^END_VERSION:$' $0 | cut -d ':' -f 1) payload_end=$((match_end - 1)) lines=$(($payload_end-$payload_start+1)) head -n $payload_end $0 | tail -n $lines > $version_path } # Function to find the version.txt at the end of this script # and store it in the location for version.txt function prepare_station_conf() { match=$(grep --text --line-number '^CONF:$' $0 | cut -d ':' -f 1) payload_start=$((match + 1)) match_end=$(grep --text --line-number '^END_CONF:$' $0 | cut -d ':' -f 1) payload_end=$((match_end - 1)) lines=$(($payload_end-$payload_start+1)) head -n $payload_end $0 | tail -n $lines > $station_conf_path } # Stop the currently running Basics station so that it can be overwritten # by the new one killall station # Store the different files prepare_station prepare_versionp prepare_station_conf # Provide execute permission for Basics station binary chmod +x $station_path # Remove update.bin so that it is not read again next time Basics station starts rm -f /tmp/update.bin # Exit so that rest of this script which has binaries attached does not get executed exit 0
Add payload script
To the base script, we append the Basics Station binary, the
version.txt that identifies the version to update to, and
station.conf
in a script called
addpayload.sh
. Then, run this script.
*#!/bin/bash * base.sh > fwstation # Add station echo "STATION:" >> fwstation cat $1 >> fwstation echo "" >> fwstation echo "END_STATION:" >> fwstation # Add version.txt echo "VERSION:" >> fwstation cat $2 >> fwstation echo "" >> fwstation echo "END_VERSION:" >> fwstation # Add station.conf echo "CONF:" >> fwstation cat $3 >> fwstation echo "END_CONF:" >> fwstation # executable chmod +x fwstation
After you've run these scripts, you can run the following command in the
terminal to generate the firmware update file, fwstation
.
$ ./addpayload.sh station version.txt station.conf
Generate signature for the firmware update
The LoRa Basics Station software provides signed firmware updates with ECDSA signatures. To support signed updates, you'll need:
-
A signature that must be generated by an ECDSA private key and less than 128 bytes.
-
The private key that is used for the signature and must be stored in the gateway with file name of the format
sig-%d.key
. We recommend using the file namesig-0.key
. -
A 32-bit CRC over the private key.
The signature and CRC will be passed to the Amazon IoT Core for LoRaWAN APIs. To
generate the previous files, you can use the following script
gen.sh
that is inspired by the basicstation
*#!/bin/bash *function ecdsaKey() { # Key not password protected for simplicity openssl ecparam -name prime256v1 -genkey | openssl ec -out $1 } # Generate ECDSA key ecdsaKey sig-0.prime256v1.pem # Generate public key openssl ec -in sig-0.prime256v1.pem -pubout -out sig-0.prime256v1.pub # Generate signature private key openssl ec -in sig-0.prime256v1.pub -inform PEM -outform DER -pubin | tail -c 64 > sig-0.key # Generate signature openssl dgst -sha512 -sign sig-0.prime256v1.pem $1 > sig-0.signature # Convert signature to base64 openssl enc -base64 -in sig-0.signature -out sig-0.signature.base64 # Print the crc crc_res=$(crc32 sig-0.key)printf "The crc for the private key=%d\n" $((16#$crc_res)) # Remove the generated files which won't be needed later rm -rf sig-0.prime256v1.pem sig-0.signature sig-0.prime256v1.pub
The private key generated by the script should be saved into the gateway. The key file is in binary format.
./gen_sig.sh fwstation read EC key writing EC key read EC key writing EC key read EC key writing EC key The crc for the private key=3434210794 $ cat sig-0.signature.base64 MEQCIDPY/p2ssgXIPNCOgZr+NzeTLpX+WfBo5tYWbh5pQWN3AiBROen+XlIdMScv AsfVfU/ZScJCalkVNZh4esyS8mNIgA== $ ls sig-0.key sig-0.key $ scp sig-0.key pi@192.168.1.11:/home/pi/Documents/basicstation/examples/iotwireless
Review the next steps
Now that you have generated the firmware and signature, go to the next
topic to upload the firmware file, fwstation
, to an Amazon S3
bucket. The bucket is a container that will store the firmware update file
as an object. You can add an IAM role that will give the CUPS server
permission to read the firmware update file in the S3 bucket.