

# Genera il file di aggiornamento del firmware e la firma
<a name="lorawan-script-fwupdate-sigkey"></a>

I passaggi descritti in questa procedura sono facoltativi e dipendono dal gateway utilizzato. I produttori di gateway forniscono il proprio aggiornamento del firmware sotto forma di file di aggiornamento o script e Basics Station esegue questo script in background. In questo caso, molto probabilmente troverai il file di aggiornamento del firmware nelle note di rilascio del gateway che stai utilizzando. È quindi possibile utilizzare il file o lo script di aggiornamento e procedere a [Caricare il file del firmware in un bucket S3 e aggiungere un ruolo IAM](lorawan-upload-firmware-s3bucket.md).

Se non si dispone di questo script, di seguito vengono mostrati i comandi da eseguire per la generazione del file di aggiornamento del firmware. Gli aggiornamenti possono anche essere firmati per garantire che il codice non sia stato alterato o danneggiato e che i dispositivi eseguano codici pubblicati solo da autori attendibili.

**Topics**
+ [Generare il file di aggiornamento del firmware](#lorawan-firmware-update-script)
+ [Generare firma per l'aggiornamento del firmware](#lorawan-generate-signature-fwupdate)
+ [Esamina i passaggi successivi](#lorawan-fwupdate-sigkey-next-steps)

## Generare il file di aggiornamento del firmware
<a name="lorawan-firmware-update-script"></a>

Il software LoRa Basics Station in esecuzione sul gateway è in grado di ricevere aggiornamenti firmware nella risposta CUPS. Se non disponi di uno script fornito dal produttore, fai riferimento al seguente script di aggiornamento del firmware scritto per il gateway RAKWireless basato su Raspberry Pi. Abbiamo uno script di base e la nuova stazione binaria, il file di versione, e `station.conf` sono collegati ad esso.

**Nota**  
Lo script è specifico del gateway RAKWireless, quindi dovrai adattarlo alla tua applicazione in base al gateway che stai utilizzando.

**Script di base**  
Di seguito uno script di base di esempio per il gateway RAKWireless basato su Raspberry Pi. È possibile salvare i seguenti comandi in un file `base.sh` e quindi eseguire lo script nel terminale sul browser web di Raspberry Pi.

```
*#!/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
```

**Aggiungere script payload**  
Allo script di base, aggiungiamo il binario Basics Station, il version.txt che identifichi la versione a cui aggiornare, e `station.conf` in uno script chiamato `addpayload.sh`. Quindi, esegui questo 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
```

Dopo aver eseguito questi script, è possibile eseguire il seguente comando nel terminale per generare il file di aggiornamento del firmware, `fwstation`.

```
$ ./addpayload.sh station version.txt station.conf
```

## Generare firma per l'aggiornamento del firmware
<a name="lorawan-generate-signature-fwupdate"></a>

Il software LoRa Basics Station fornisce aggiornamenti firmware firmati con firme ECDSA. Per supportare gli aggiornamenti firmati, è necessario:
+ La firma che deve essere generata da una chiave privata ECDSA e meno di 128 byte. 
+ La chiave privata utilizzata per la firma e che deve essere memorizzata nel gateway con il nome file del formato `sig-%d.key`. Si consiglia di utilizzare il nome del file `sig-0.key`.
+ Un CRC a 32 bit sulla chiave privata.

La firma e il CRC saranno passati alle API AWS IoT Core per LoRaWAN. Per generare i file precedenti, è possibile utilizzare il seguente script `gen.sh` che si ispira all’esempio [ basicstation](https://github.com/lorabasics/basicstation/blob/master/examples/cups/prep.sh) nel repository GitHub.

```
*#!/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
```

La chiave privata generata dallo script dovrebbe essere salvata nel gateway. Il file chiave è in formato binario.

```
./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
```

## Esamina i passaggi successivi
<a name="lorawan-fwupdate-sigkey-next-steps"></a>

Ora che hai generato il firmware e la firma, vai all'argomento successivo per caricare il file del firmware `fwstation` per un bucket Amazon S3. Il bucket è un container che memorizza il file di aggiornamento del firmware come oggetto. È possibile aggiungere un ruolo IAM che consentirà al server CUPS l'autorizzazione per leggere il file di aggiornamento del firmware nel bucket S3. 