

# Genere el archivo de actualización del firmware y la firma
<a name="lorawan-script-fwupdate-sigkey"></a>

Los pasos de este procedimiento son opcionales y dependen de la puerta de enlace que utilice. Los fabricantes de puertas de enlace proporcionan su propia actualización del firmware en forma de archivo de actualización o script, y Basics Station ejecuta este script en segundo plano. En este caso, lo más probable es que encuentre el archivo de actualización del firmware en las notas de la versión de la puerta de enlace que esté utilizando. A continuación, puede utilizar ese archivo o script de actualización en su lugar y continuar con [Suba el archivo de firmware en un bucket de S3 y agregue un rol de IAM](lorawan-upload-firmware-s3bucket.md).

Si no tiene este script, a continuación se muestran los comandos que debe ejecutar para generar el archivo de actualización del firmware. Las actualizaciones también se pueden firmar para garantizar que el código no se haya alterado ni dañado, y que los dispositivos ejecuten código publicado únicamente por autores de confianza.

**Topics**
+ [Generar el archivo de actualización del firmware](#lorawan-firmware-update-script)
+ [Generar la firma para la actualización del firmware](#lorawan-generate-signature-fwupdate)
+ [Revisar los siguientes pasos](#lorawan-fwupdate-sigkey-next-steps)

## Generar el archivo de actualización del firmware
<a name="lorawan-firmware-update-script"></a>

El software LoRa Basics Station que se ejecuta en la puerta de enlace es capaz de recibir actualizaciones de firmware en la respuesta de CUPS. Si no dispone de un script proporcionado por el fabricante, consulte el siguiente script de actualización del firmware escrito para la puerta de enlace RAKWireless basada en Raspberry Pi. Tenemos un script base y el archivo de versión binario de la nueva estación, y `station.conf` está asociado a este.

**nota**  
El script es específico de la puerta de enlace RAKWireless, por lo que tendrá que adaptarlo a su aplicación en función de la puerta de enlace que utilice.

**Script base**  
A continuación se muestra un ejemplo de script base para la puerta de enlace RAKWireless basada en Raspberry Pi. Puede guardar los siguientes comandos en un archivo `base.sh` y, a continuación, ejecutar el script en la terminal del navegador web de la 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
```

**Agregar un script de carga**  
Al script base, anexamos el binario de Basics Station, el archivo version.txt que identifica la versión a la que se debe actualizar y `station.conf` en un script denominado `addpayload.sh`. A continuación, ejecute este 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
```

Después de ejecutar estos scripts, puede ejecutar el siguiente comando en el terminal para generar el archivo de actualización del firmware, `fwstation`.

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

## Generar la firma para la actualización del firmware
<a name="lorawan-generate-signature-fwupdate"></a>

El software LoRa Basics Station proporciona actualizaciones de firmware firmadas con firmas ECDSA. Para permitir las actualizaciones firmadas, necesitará lo siguiente:
+ Una firma que deberá generarse mediante una clave privada de ECDSA y tener menos de 128 bytes. 
+ La clave privada que se usa para la firma y que debe almacenarse en la puerta de enlace con el nombre de archivo del formato `sig-%d.key`. Se recomienda utilizar el nombre del archivo `sig-0.key`.
+ Un CRC de 32 bits sobre la clave privada.

La firma y el CRC se pasarán a las API de AWS IoT Core para LoRaWAN. Para generar los archivos anteriores, puede usar el siguiente script `gen.sh` inspirado en el ejemplo de [basicstation](https://github.com/lorabasics/basicstation/blob/master/examples/cups/prep.sh) del repositorio de 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 clave privada generada por el script debe guardarse en la puerta de enlace. El archivo de clave se encuentra en 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
```

## Revisar los siguientes pasos
<a name="lorawan-fwupdate-sigkey-next-steps"></a>

Ahora que ha generado el firmware y la firma, vaya al tema siguiente para subir el archivo de firmware, `fwstation`, en un bucket de Amazon S3. El bucket es un contenedor que almacenará el archivo de actualización del firmware como un objeto. Puede agregar un rol de IAM que conceda permiso al servidor CUPS para leer el archivo de actualización del firmware en el bucket de S3. 