

# 펌웨어 업데이트 파일 및 서명 생성
<a name="lorawan-script-fwupdate-sigkey"></a>

이 절차의 단계는 선택 사항이며 사용 중인 게이트웨이에 따라 다릅니다. 게이트웨이 제조업체는 업데이트 파일 또는 스크립트 형태로 자체 펌웨어 업데이트를 제공하며 Basic Station은 백그라운드에서 이 스크립트를 실행합니다. 이 경우 사용 중인 게이트웨이의 릴리스 정보에서 펌웨어 업데이트 파일을 찾을 수 있습니다. 그런 다음 해당 업데이트 파일이나 스크립트를 대신 사용하고 [S3 버킷에 펌웨어 파일 업로드 및 IAM 역할 추가](lorawan-upload-firmware-s3bucket.md)(으)로 진행할 수 있습니다.

이 스크립트가 없는 경우 다음은 펌웨어 업데이트 파일을 생성하기 위해 실행하는 명령을 보여 줍니다. 또한 코드가 변경되거나 손상되지 않았으며 신뢰할 수 있는 작성자에 의해 게시된 코드만 디바이스에서 실행된다는 것을 증명하기 위해 업데이트에 서명을 할 수도 있습니다.

**Topics**
+ [펌웨어 업데이트 파일 생성](#lorawan-firmware-update-script)
+ [펌웨어 업데이트에 대한 서명 생성](#lorawan-generate-signature-fwupdate)
+ [다음 단계 검토](#lorawan-fwupdate-sigkey-next-steps)

## 펌웨어 업데이트 파일 생성
<a name="lorawan-firmware-update-script"></a>

게이트웨이에서 실행되는 LoRa Basic Station 소프트웨어는 CUPS 응답에서 펌웨어 업데이트를 수신할 수 있습니다. 제조업체에서 제공한 스크립트가 없는 경우 Raspberry Pi 기반 RakWireless 게이트웨이에 대해 작성된 다음 펌웨어 업데이트 스크립트를 참조하세요. 기본 스크립트가 있으며 새로운 스테이션 이진, 버전 파일 및 `station.conf`이(가) 여기에 연결됩니다.

**참고**  
스크립트는 RAKWireless 게이트웨이에 고유하므로 사용 중인 게이트웨이에 따라 애플리케이션에 맞게 조정해야 합니다.

**기본 스크립트**  
다음은 Raspberry Pi 기반 RAKWireless 게이트웨이에 대한 기본 스크립트 샘플을 보여줍니다. 다음 명령을 `base.sh` 파일에 저장한 다음 터미널의 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
```

**페이로드 스크립트 추가**  
기본 스크립트에 Basics Station 이진, 업데이트 버전을 식별하는 version.txt, `addpayload.sh`라는 스크립트의 `station.conf`를 추가합니다. 그런 다음 이 스크립트를 실행합니다.

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

이러한 스크립트를 실행한 후 터미널에서 다음 명령을 실행하여 펌웨어 업데이트 파일 `fwstation`을 생성할 수 있습니다.

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

## 펌웨어 업데이트에 대한 서명 생성
<a name="lorawan-generate-signature-fwupdate"></a>

LoRa Basic Station 소프트웨어는 ECDSA 서명과 함께 서명된 펌웨어 업데이트를 제공합니다. 서명된 업데이트를 지원하려면 다음이 필요합니다.
+ ECDSA 프라이빗 키에 의해 생성되고 128바이트 미만이어야 하는 서명.
+ 서명에 사용되고 `sig-%d.key` 형식의 파일 이름으로 게이트웨이에 저장되어야 하는 프라이빗 키. `sig-0.key` 파일 이름을 사용하는 것이 좋습니다.
+ 프라이빗 키를 통한 32 비트 CRC.

서명과 CRC는 AWS IoT Core for LoRaWAN API에 전달됩니다. 이전 파일을 생성하려면 GitHub 리포지토리에 있는 [basicstation](https://github.com/lorabasics/basicstation/blob/master/examples/cups/prep.sh) 예제를 활용하는 다음 스크립트 `gen.sh`를 사용할 수 있습니다.

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

스크립트에 의해 생성된 프라이빗 키는 게이트웨이에 저장되어야 합니다. 키 파일은 이진 형식입니다.

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

## 다음 단계 검토
<a name="lorawan-fwupdate-sigkey-next-steps"></a>

이제 펌웨어와 서명을 생성했으니 다음 주제로 이동하여 펌웨어 파일 `fwstation`을 Amazon S3 버킷에 업로드하세요. 버킷은 펌웨어 업데이트 파일을 객체로 저장하는 컨테이너입니다. S3 버킷의 펌웨어 업데이트 파일을 읽을 수 있는 권한을 CUPS 서버에 부여하는 IAM 역할을 추가할 수 있습니다.