

# Managing gateways with AWS IoT Wireless
<a name="lorawan-manage-gateways"></a>

Following are some important considerations when using your gateways with AWS IoT Core for LoRaWAN. For information about how to add your gateway to AWS IoT Core for LoRaWAN, see [Onboard your gateways to AWS IoT Core for LoRaWAN](lorawan-onboard-gateways.md). 

## LoRa Basics Station software requirement
<a name="lorawan-lora-basics-station"></a>

To connect to AWS IoT Core for LoRaWAN, your LoRaWAN gateway must have software called [LoRa Basics Station](https://doc.sm.tc/station/) running on it. LoRa Basics Station is an open source software that is maintained by Semtech Corporation and distributed by their [GitHub](https://github.com/lorabasics/basicstation) repository. AWS IoT Core for LoRaWAN supports LoRa Basics Station version 2.0.4 and later. The latest version is 2.0.6.

## Using qualified gateways from the AWS Partner Device Catalog
<a name="lorawan-qualified-gateways"></a>

The [AWS Partner Device Catalog](https://devices.amazonaws.com/search?page=1&sv=iotclorawan) contains gateways and developer kits that are qualified for use with AWS IoT Core for LoRaWAN. We recommend that you use these qualified gateways because you don't have to modify the embedding software for connecting the gateways to AWS IoT Core. These gateways already have a version of the BasicStation software compatible with AWS IoT Core for LoRaWAN.

**Note**  
If you have a gateway that is not listed in the Partner Catalog as a qualified gateway with AWS IoT Core for LoRaWAN, you might still be able to use it if the gateway is running LoRa Basics Station software with version 2.0.4 and later. Make sure that you use **TLS Server and Client Authentication** for authenticating your LoRaWAN gateway.

## Using CUPS and LNS protocols
<a name="lorawan-cups-lns-protocols"></a>

LoRa Basics Station software contains two sub protocols for connecting gateways to network servers, LoRaWAN Network Server (LNS) and Configuration and Update Server (CUPS) protocols.

The LNS protocol establishes a data connection between a LoRa Basics Station compatible gateway and a network server. LoRa uplink and downlink messages are exchanged through this data connection over secure WebSockets.

The CUPS protocol enables credentials management, and remote configuration and firmware update of gateways. AWS IoT Core for LoRaWAN provides both LNS and CUPS endpoints for LoRaWAN data ingestion and remote gateway management respectively.

For more information, see [LNS protocol](https://doc.sm.tc/station/tcproto.html) and [CUPS protocol](https://doc.sm.tc/station/cupsproto.html).

**Topics**
+ [LoRa Basics Station software requirement](#lorawan-lora-basics-station)
+ [Using qualified gateways from the AWS Partner Device Catalog](#lorawan-qualified-gateways)
+ [Using CUPS and LNS protocols](#lorawan-cups-lns-protocols)
+ [Configure beaconing for your LoRaWAN gateways](lorawan-gateway-beaconing.md)
+ [Configure subbands and filtering capabilities of your LoRaWAN gateways](lorawan-subband-filter-configuration.md)
+ [Choosing gateways to receive the LoRaWAN downlink data traffic](lorawan-gateway-participate.md)
+ [Update gateway firmware using CUPS service with AWS IoT Core for LoRaWAN](lorawan-update-firmware.md)

# Configure beaconing for your LoRaWAN gateways
<a name="lorawan-gateway-beaconing"></a>

If you onboard class B wireless devices to AWS IoT Core for LoRaWAN, the devices receive downlink messages in scheduled time slots. The devices open these slots based on time-synchronized beacons that are transmitted by the gateway. For your gateways to transmit these time-synchronous beacons, you can use AWS IoT Core for LoRaWAN to configure certain beaconing-related parameters for the gateways.

To configure these beaconing parameters, your gateway must be running LoRa Basics Station software version 2.0.6. See [Using qualified gateways from the AWS Partner Device Catalog](lorawan-manage-gateways.md#lorawan-qualified-gateways).

## How to configure the beaconing parameters
<a name="lorawan-beaconing-configure"></a>

**Note**  
You only need to configure the beaconing parameters for your gateway if it's communicating with a class B wireless device.

You configure the beaconing parameters when adding your gateway to AWS IoT Core for LoRaWAN using the [https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_CreateWirelessGateway.html](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_CreateWirelessGateway.html) API operation. When you invoke the API operation, specify the following parameters using the `Beaconing` object for your gateways. After you configure the parameters, the gateways will send the beacons to your devices at a 128-second interval.
+ `DataRate`: The data rate for the gateways that are transmitting the beacons.
+ `Frequencies`: The list of frequencies for the gateways to transmit the beacons.

The following example shows how you configure these parameters for the gateway. The `input.json` file will contain additional details, such as the gateway certificate and provisioning credentials. For more information about adding your gateway to AWS IoT Core for LoRaWAN using the `CreateWirelessGateway` API operation, see [Add a gateway by using the API](lorawan-onboard-gateway-add.md#lorawan-onboard-gateway-api).

**Note**  
The beaconing parameters aren't available when you add your gateway to AWS IoT Core for LoRaWAN using the AWS IoT console.

```
aws iotwireless create-wireless-gateway \
    --name "myLoRaWANGateway" \        
    --cli-input-json file://input.json
```

The following shows the contents of the `input.json` file.

**Contents of input.json**

```
{ 
    "Description": "My LoRaWAN gateway",
    "LoRaWAN": {
        "Beaconing": { 
          "DataRate": 8,
          "Frequencies": [923300000,923900000]
        },
        "GatewayEui": "a1b2c3d4567890ab",
        "RfRegion": US915, 
        "JoinEuiFilters": [ 
         ["0000000000000001", "00000000000000ff"], 
         ["000000000000ff00", "000000000000ffff"] 
         ], 
        "NetIdFilters": ["000000", "000001"], 
        "RfRegion": "US915", 
        "SubBands": [2] 
    }     
}
```

The following code shows a sample output of running this command.

```
{
    "Arn": "arn:aws:iotwireless:us-east-1:400232685877aa:WirelessGateway/a01b2c34-d44e-567f-abcd-0123e445663a",
    "Id": a01b2c34-d44e-567f-abcd-0123e445663a"
}
```

## Get information about the beaconing parameters
<a name="lorawan-beaconing-get"></a>

You can get information about the beaconing parameters for your gateway using the [https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_GetWirelessGateway.html](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_GetWirelessGateway.html) API operation.

**Note**  
If a gateway has already been onboarded, you can't use the `UpdateWirelessGateway` API operation to configure the beaconing parameters. To configure the parameters, you must delete the gateway and then specify the parameters when adding your gateway using the `CreateWirelessGateway` API operation.

```
aws iotwireless get-wireless-gateway \
    --identifier "12345678-a1b2-3c45-67d8-e90fa1b2c34d" \
    --identifier-type WirelessGatewayId
```

Running this command returns information about your gateway and the beaconing parameters.

# Configure subbands and filtering capabilities of your LoRaWAN gateways
<a name="lorawan-subband-filter-configuration"></a>

LoRaWAN gateways run a [LoRa Basics Station](https://doc.sm.tc/station/) software that enables the gateways to connect to AWS IoT Core for LoRaWAN. To connect to AWS IoT Core for LoRaWAN, your LoRa gateway first queries the CUPS server for the LNS endpoint, and then establishes a WebSockets data connection with that endpoint. After the connection is established, uplink and downlink frames can be exchanged through that connection.

## Filtering of LoRa data frames received by gateway
<a name="lorawan-frequency-channels-subbands"></a>

After your LoRaWAN gateway establishes a connection to the endpoint, AWS IoT Core for LoRaWAN responds with a `router_config` message that specifies a set of parameters for the LoRa gateway's configuration, including filtering parameters `NetID` and `JoinEui`. For more information about `router_config` and how a connection is established with the LoRaWAN Network Server (LNS), see [LNS protocol](https://doc.sm.tc/station/tcproto.html).

```
{
"msgtype"    : "router_config"
"NetID"      : [ INT, .. ]
"JoinEui"    : [ [INT,INT], .. ] // ranges: beg,end inclusive
"region"     : STRING             // e.g. "EU863", "US902", ..
"hwspec"     : STRING
"freq_range" : [ INT, INT ]       // min, max (hz)
"DRs"        : [ [INT,INT,INT], .. ]   // sf,bw,dnonly
"sx1301_conf": [ SX1301CONF, .. ]
"nocca"      : BOOL
"nodc"       : BOOL
"nodwell"    : BOOL
}
```

The gateways carry LoRaWAN device data to and from LNS usually over high-bandwidth networks like Wi-Fi, Ethernet, or Cellular. The gateways usually pick up all messages and pass through the traffic that comes to it to AWS IoT Core for LoRaWAN. However, you can configure the gateways to filter some of the device data traffic, which helps conserve bandwidth usage and reduces the traffic flow between the gateway and LNS.

To configure your LoRa gateway to filter the data frames, you can use the parameters `NetID` and `JoinEui` in the `router_config` message. `NetID` is a list of NetID values that are accepted. Any LoRa data frame carrying a data frame other than those listed will be dropped. `JoinEui` is a list of pairs of integer values encoding ranges of JoinEUI values. Join request frames will be dropped by the gateway unless the field `JoinEui` in the message is within the range [BegEui,EndEui].

## Frequency channels and subbands
<a name="lorawan-frequency-channels-subbands"></a>

For US915 and AU915 RF regions, wireless devices have choices of 64 125KHz and 8 500KHz uplink channels to access the LoRaWAN networks using the LoRa gateways. The uplink frequency channels are divided into 8 subbands, each with 8 125KHz channels and one 500KHz channel. For each regular gateway in AU915 region, one or more subbands will be supported.

Some wireless devices can't hop between subbands and use the frequency channels in only one subband when connected to AWS IoT Core for LoRaWAN. For the uplink packets from those devices to be transmitted, configure the LoRa gateways to use that particular subband. For gateways in other RF regions, such as EU868, this configuration is not required.

## Configure your gateway to use filtering and subbands using the console
<a name="lorawan-configure-gateway-channels-console"></a>

You can configure your gateway to use a particular subband and also enable the capability to filter the LoRa data frames. To specify these parameters using the console:

1. Navigate to the [AWS IoT Core for LoRaWAN](https://console.aws.amazon.com/iot/home#/wireless/gateways) **Gateways** page of the AWS IoT console and choose **Add gateway**.

1. Specify the gateway details such as the **Gateway's Eui**, **Frequency band (RFRegion)** and an optional **Name** and **Description**, and choose whether to associate an AWS IoT thing to your gateway. For more information about how to add a gateway, see [Add a gateway using the console](lorawan-onboard-gateway-add.md#lorawan-onboard-gateway-console).

1. In the **LoRaWAN configuration** section, you can specify the subbands and filtering information.
   + `SubBands`: To add a subband, choose **Add SubBand** and specify a list of integer values that indicate which subbands are supported by the gateway. The `SubBands` parameter can only be configured in the `RfRegion` US915 and AU915 and must have values in the range `[1,8]` within one of these supported regions.
   + `NetIdFilters`: To filter uplink frames, choose **Add NetId** and specify a list of string values that the gateway uses. The NetID of the incoming uplink frame from the wireless device must match at least one of the listed values, otherwise the frame is dropped.
   + `JoinEuiFilters`: Choose **Add JoinEui range** and specify a list of pairs of string values that a gateway uses to filter LoRa frames. The JoinEUI value specified as part of the join request from the wireless device must be within the range of at least one of the JoinEuiRange values, each listed as a pair of [BegEui, EndEui], otherwise the frame is dropped.

1. You can then continue to configure your gateway by following the instructions described in [Add a gateway using the console](lorawan-onboard-gateway-add.md#lorawan-onboard-gateway-console).

After you've added a gateway, in the [AWS IoT Core for LoRaWAN](https://console.aws.amazon.com/iot/home#/wireless/gateways) **Gateways** page of the AWS IoT console, if you select the gateway that you've added, you can see the `SubBands` and filters `NetIdFilters` and `JoinEuiFilters` in the **LoRaWAN specific details** section of the Gateway details page.

## Configure your gateway to use filtering and subbands using the API
<a name="lorawan-configure-gateway-channels-api"></a>

You can use the [CreateWirelessGateway](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_CreateWirelessGateway.html) API that you use to create a gateway to configure the subbands you want to use and enable the filtering capability. Using the `CreateWirelessGateway` API, you can specify the subbands and filters as part of the gateway configuration information that you provide using the `LoRaWAN` field. The following shows the request token that includes this information.

```
POST /wireless-gateways HTTP/1.1
Content-type: application/json

{
"Arn": "arn:aws:iotwireless:us-east-1:400232685877aa:WirelessGateway/
       a11e3d21-e44c-471c-afca-6716c228336a",
"Description": "Using my first LoRaWAN gateway",
   "LoRaWAN": { 
      "GatewayEui": "a1b2c3d4567890ab",
      "JoinEuiFilters": [
        ["0000000000000001", "00000000000000ff"],
        ["000000000000ff00", "000000000000ffff"]
      ],
      "NetIdFilters": ["000000", "000001"],
      "RfRegion": "US915",
      "SubBands": [2]
   },
   "Name": "myFirstLoRaWANGateway"  
   "ThingArn": null,
   "ThingName": null
}
```

You can also use the [UpdateWirelessGateway](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_UpdateWirelessGateway.html) API to update the filters but not the subbands. If the `JoinEuiFilters` and `NetIdfilters` values are null, it means there is no update for the fields. If the values aren't null and empty lists are included, then the update is applied. To get the values of the fields that you specified, use the [GetWirelessGateway](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_GetWirelessGateway.html) API.

# Choosing gateways to receive the LoRaWAN downlink data traffic
<a name="lorawan-gateway-participate"></a>

When you send a downlink message from AWS IoT Core for LoRaWAN to your device, you can choose the gateways you want to use for the downlink data traffic. You can specify an individual gateway or choose from a list of gateways to receive the downlink traffic.

**Note**  
This feature is different from the participating gateways feature that you can use for multicast downlink from AWS IoT Core for LoRaWAN to devices in your multicast group. For more information, see [Choose participating gateways to receive multicast downlink messages](lorawan-multicast-choose-gateways.md)

## How to specify the gateway list
<a name="lorawan-participate-how"></a>

You can specify an individual gateway or the list of gateways to use when sending a downlink message from AWS IoT Core for LoRaWAN to your device using the [https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_SendDataToWirelessDevice.html](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_SendDataToWirelessDevice.html) API operation. When you invoke the API operation, specify the following parameters using the `ParticipatingGateways` object for your gateways. 

**Note**  
The list of gateways you want to use isn't available in the AWS IoT console. You can specify this list of gateways to use only when using the `SendDataToWirelessDevice` API operation or the CLI.
+ `DownlinkMode`: Indicates whether to send the downlink message in sequential mode or concurrent mode. For class A devices, specify `UsingUplinkGateway` to use only the chosen gateways from the previous uplink message transmission.
+ `GatewayList`: The list of gateways that you want to use for sending the downlink data traffic. The downlink payload will be sent to the specified gateways with the specified frequency. This is indicated using a list of `GatewayListItem` objects, that consists of `GatewayId` and `DownlinkFrequency` pairs.
+ `TransmissionInterval`: The duration of time for which AWS IoT Core for LoRaWAN will wait before transmitting the payload to the next gateway.

**Note**  
You can specify this list of gateways to use only when sending the downlink message to a class B or a class C wireless device. If you use a class A device, the gateway that you chose when sending the uplink message will be used when a downlink message is sent to the device.

The following example shows how you specify these parameters for the gateway. The `input.json` file will contain additional details. For more information about sending a downlink message using the `SendDataToWirelessDevice` API operation, see [Perform downlink queue operations by using the API](lorawan-downlink-queue.md#lorawan-downlink-queue-api).

**Note**  
The parameters for specifying the list of participating gateways aren't available when you send a downlink message from AWS IoT Core for LoRaWAN using the AWS IoT console.

```
aws iotwireless send-data-to-wireless-device \
    --id "11aa5eae-2f56-4b8e-a023-b28d98494e49" \
    --transmit-mode "1" \
    --payload-data "SGVsbG8gVG8gRGV2c2lt" \
    --cli-input-json file://input.json
```

The following shows the contents of the `input.json` file.

**Contents of input.json**

```
{
    "WirelessMetadata": {
        "LoRaWAN": {
            "FPort": "1", 
            "ParticipatingGateways": {
                "DownlinkMode": "SEQUENTIAL", 
                "TransmissionInterval": 1200,
                "GatewayList": [
                    {
                        "DownlinkFrequency": 100000000,
                        "GatewayID": a01b2c34-d44e-567f-abcd-0123e445663a
                    },
                    {
                        "DownlinkFrequency": 100000101,
                        "GatewayID": 12345678-a1b2-3c45-67d8-e90fa1b2c34d
                    }
                ]
            }
        }
    }
}
```

The output of running this command generates a `MessageId` for the downlink message. In some cases, even if you receive the `MessageId`, packets can get dropped. For more information about how you can resolve the error, see [Troubleshoot downlink message queue errors](lorawan-downlink-queue.md#lorawan-downlink-queue-troubleshoot).

```
{
    MessageId: "6011dd36-0043d6eb-0072-0008"
}
```

## Get information about the list of participating gateways
<a name="lorawan-participate-get"></a>

You can get information about the list of gateways that are participating in receiving the downlink message by listing messages in the downlink queue. To list messages, use the [https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_ListQueuedMessages.html](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_ListQueuedMessages.html) API.

```
aws iotwireless list-queued-messages \
    --wireless-device-type "LoRaWAN"
```

Running this command returns information about the messages in the queue and their parameters.

# Update gateway firmware using CUPS service with AWS IoT Core for LoRaWAN
<a name="lorawan-update-firmware"></a>

The [LoRa Basics Station](https://doc.sm.tc/station/) software that runs on your gateway provides credential management and firmware update interface using the Configuration and Update Server (CUPS) protocol. The CUPS protocol is an efficient mechanism that provides secure firmware update delivery with ECDSA signatures. It enables over-the-air (OTA) firmware updates, allowing you to remotely manage and upgrade the software on your LoRaWAN gateways without physically accessing them.

You'll have to frequently update your gateway's firmware. You can use the CUPS service with AWS IoT Core for LoRaWAN to provide firmware updates to the gateway where the updates can also be signed. To update the gateway's firmware, you can use the SDK, CLI, or the console. With CUPS, you can upload the firmware file to an Amazon Simple Storage Service bucket, sign them with a private key, and schedule the updates to be delivered to your gateways with AWS IoT Core for LoRaWAN.

## Pre-requisites
<a name="lorawan-update-firmware-prereq"></a>

Before you can update the firmware of your LoRaWAN gateway, your gateway must have established a CUPS connection to the cloud. If you had previously connected your gateway, verify that your gateway is still connected before updating the gateway firmware. For information about onboarding and connecting your LoRaWAN gateway to AWS IoT Core for LoRaWAN, see [Onboard your gateways to AWS IoT Core for LoRaWAN](lorawan-onboard-gateways.md).

## Firmware update process
<a name="lorawan-update-firmware-process"></a>

The firmware update process involves the following steps.

1. Upload the firmware file to an Amazon Simple Storage Service (S3) bucket.

1. Generate a signature key pair and sign the firmware update file with the private key.
**Note**  
To perform this step, make sure that the private key is present in the gateway.

1. Schedule the firmware update job, specifying the signed firmware file, the devices to be updated, and other configuration options.

The firmware update is then securely delivered to the targeted gateways using the CUPS protocol. If the update was signed, the gateways can then verify the authenticity and integrity of the update using the provided signature, which ensures a secure and reliable firmware update process.

The update process takes about 45 minutes to complete. It can take longer if you're setting up your gateway for the first time to connect to AWS IoT Core for LoRaWAN.

Gateway manufacturers usually provide their own firmware update files and signatures so you can use that for the firmware update. If you don't have the firmware update files, see [(Optional) Generate the firmware update file and signature](lorawan-script-fwupdate-sigkey.md) for an example that you can use to adapt to your application.
+ If you're using the AWS Management Console to schedule and run the firmware update, proceed to [Schedule and run gateway firmware update task](lorawan-schedule-firmware-update.md).
+ If you're using the AWS CLI to schedule and run the firmware update, first proceed to [Upload the firmware file to an Amazon S3 bucket and add an IAM role](lorawan-upload-firmware-s3bucket.md) to upload your firmware file to Amazon S3 and grant AWS IoT Core for LoRaWAN permissions to access the file on your behalf.

**Topics**
+ [Pre-requisites](#lorawan-update-firmware-prereq)
+ [Firmware update process](#lorawan-update-firmware-process)
+ [(Optional) Generate the firmware update file and signature](lorawan-script-fwupdate-sigkey.md)
+ [Upload the firmware file to an Amazon S3 bucket and add an IAM role](lorawan-upload-firmware-s3bucket.md)
+ [Schedule and run gateway firmware update task](lorawan-schedule-firmware-update.md)

# (Optional) Generate the firmware update file and signature
<a name="lorawan-script-fwupdate-sigkey"></a>

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 Amazon S3 bucket and add an IAM role](lorawan-upload-firmware-s3bucket.md).

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 the devices run code that's published only by trusted authors.

**Topics**
+ [Generate the firmware update file](#lorawan-firmware-update-script)
+ [Generate signature for the firmware update](#lorawan-generate-signature-fwupdate)
+ [Review the next steps](#lorawan-fwupdate-sigkey-next-steps)

## Generate the firmware update file
<a name="lorawan-firmware-update-script"></a>

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
<a name="lorawan-generate-signature-fwupdate"></a>

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 name `sig-0.key`.
+ A 32-bit CRC over the private key.

The signature and CRC will be passed to the AWS IoT Core for LoRaWAN APIs. To generate the previous files, you can use the following script `gen.sh` that is inspired by the [ basicstation](https://github.com/lorabasics/basicstation/blob/master/examples/cups/prep.sh) example in the GitHub repository.

```
*#!/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
<a name="lorawan-fwupdate-sigkey-next-steps"></a>

Now that you have generated the firmware and signature. you can proceed to update the gateway firmware.
+ If you're using the AWS Management Console to schedule and run the firmware update, proceed to [Schedule and run gateway firmware update task](lorawan-schedule-firmware-update.md).
+ If you're using the AWS CLI to schedule and run the firmware update, first proceed to [Upload the firmware file to an Amazon S3 bucket and add an IAM role](lorawan-upload-firmware-s3bucket.md) to upload your firmware file, `fwstation`, to an Amazon S3 bucket. Then, grant AWS IoT Core for LoRaWAN permissions to access the file on your behalf.

# Upload the firmware file to an Amazon S3 bucket and add an IAM role
<a name="lorawan-upload-firmware-s3bucket"></a>

**Note**  
You'll need to perform these steps only if you're using the AWS CLI to create a wireless gateway task definition and perform the update. If you're using the AWS Management Console, you can skip these steps and proceed to [Schedule and run gateway firmware update task](lorawan-schedule-firmware-update.md).

You can use Amazon S3 to create a *bucket*, which is a container that can store your firmware update file. You can upload your file to the S3 bucket and add an IAM role that allows the CUPS server to read your update file from the bucket. For more information about Amazon S3, see [ Getting started with Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html). 

The firmware update file that you want to upload depends on the gateway you're using. If you followed a procedure similar to the one described in [(Optional) Generate the firmware update file and signature](lorawan-script-fwupdate-sigkey.md), you'll upload the `fwstation` file generated by running the scripts.

**Topics**
+ [Create an Amazon S3 bucket and upload the update file](#lorawan-create-s3-bucket)
+ [Create an IAM role with permissions to read the S3 bucket](#lorawan-s3-iam-permissions)
+ [Review the next steps](#lorawan-s3iam-next-steps)

## Create an Amazon S3 bucket and upload the update file
<a name="lorawan-create-s3-bucket"></a>

You'll create an Amazon S3 bucket by using the AWS Management Console and then upload your firmware update file into the bucket.

**Create an S3 bucket**  
To create an S3 bucket, sign in to the [Amazon S3 console](https://console.aws.amazon.com/s3/home#) and choose **Create bucket**. Then perform the following steps:

**Note**  
Make sure you selected the same AWS Region as the one you used to create your LoRaWAN gateway and device.

1. Enter a unique and meaningful name for the **Bucket name**, (for example, `iotwirelessfwupdate`). For recommended naming convention for your bucket, see [Bucket naming rules](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html).

1. Verify the following settings for your Amazon S3 bucket, and then choose **Create bucket**.
   + Make sure that the **Block all public access** setting is selected so that your bucket uses the default permissions.
   + Choose **Enable** for **Bucket versioning** which will help you keep multiple versions of the firmware update file in the same bucket.
   + Choose **Server-side encryption** and make sure that it is set to **Disable**.

**Upload your firmware update file**  
You can now see your bucket in the list of Buckets displayed in the AWS Management Console. Choose your bucket and then choose **Upload** to upload your file and complete the following steps.

1. Choose **Add file** and then upload the firmware update file. If you followed the procedure described in [(Optional) Generate the firmware update file and signature](lorawan-script-fwupdate-sigkey.md), you'll upload the `fwstation` file, otherwise upload the file provided by your gateway manufacturer.

1. Make sure all settings are set to their default. Make sure that **Predefined ACLs** is set to **private** and choose **Upload** to upload your file.

1. Copy the S3 URI of the file you uploaded. Choose your bucket and you'll see the file you uploaded displayed in the list of **Objects**. Choose your file and then choose **Copy S3 URI**. The URI will be something like: `s3://iotwirelessfwupdate/fwstation` if you named your bucket similar to the example described previously (`fwstation`). You'll use the S3 URI when creating the IAM role.

## Create an IAM role with permissions to read the S3 bucket
<a name="lorawan-s3-iam-permissions"></a>

You'll now create an IAM role and policy that will give CUPS the permission to read your firmware update file from the S3 bucket.

**Create an IAM policy for your role**  
To create an IAM policy for your AWS IoT Core for LoRaWAN destination role, open the [Policies hub of the IAM console](https://console.aws.amazon.com/iam/home#/policies) and then complete the following steps:

1. Choose **Create policy**, and choose the **JSON** tab.

1. Delete any content from the editor and paste this policy document. The policy provides permissions to access the `iotwireless` bucket and the firmware update file, `fwstation`, stored inside an object.  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "VisualEditor0",
               "Effect": "Allow",
               "Action": [
                   "s3:ListBucketVersions",
                   "s3:ListBucket",
                   "s3:GetObject"
               ],
               "Resource": [
                   "arn:aws:s3:::iotwirelessfwupdate/fwstation",
                   "arn:aws:s3:::iotwirelessfwupdate"
               ]
           }
       ]
   }
   ```

1. Choose **Review policy**, and in **Name**, enter a name for this policy (for example, `IoTWirelessFwUpdatePolicy`). You'll need this name to use in the next procedure.

1. Choose **Create policy**.

**Create an IAM role with the attached policy**  
You'll now create an IAM role and attach the policy created previously for accessing the S3 bucket. Open the [Roles hub of the IAM console](https://console.aws.amazon.com/iam/home#/roles) and choose **Create role**, and then complete the following steps:

1. In **Select type of trusted entity**, choose **Another AWS account**.

1. In **Account ID**, enter your AWS account ID, and then choose **Next: Permissions**.

1. In the search box, enter the name of the IAM policy that you created in the previous procedure. Check the IAM policy (for example, `IoTWirelessFwUpdatePolicy`) you created earlier in the search results and choose it.

1. Choose **Next: Tags**, and then choose **Next: Review**.

1. In **Role name**, enter the name of this role (for example, `IoTWirelessFwUpdateRole`), and then choose **Create role**.

**Edit trust relationship of the IAM role**  
In the confirmation message displayed after you ran the previous step, choose the name of the role you created to edit it. You'll edit the role to add the following trust relationship.

1. In the **Summary** section of the role you created, choose the **Trust relationships** tab, and then choose **Edit trust relationship**.

1. In **Policy Document**, change the `Principal` property to look like this example.

   ```
   "Principal": { 
       "Service": "iotwireless.amazonaws.com" 
   },
   ```

   After you change the `Principal` property, the complete policy document should look like this example.  
****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "iotwireless.amazonaws.com"
         },
         "Action": "sts:AssumeRole",
         "Condition": {}
       }
     ]
   }
   ```

1. To save your changes and exit, choose **Update Trust Policy**.

1. Obtain the ARN for your role. Choose your IAM role and in the Summary section, you'll see a **Role ARN**, such as `arn:aws:iam::123456789012:role/IoTWirelessFwUpdateRole`. Copy this **Role ARN**.

## Review the next steps
<a name="lorawan-s3iam-next-steps"></a>

Now that you have created the S3 bucket and an IAM role that allows the CUPS server to read the S3 bucket, go to the next topic to schedule and run the firmware update. Keep the **S3 URI** and **Role ARN** that you copied previously so that you can enter them to create a task definition that will be run to perform the firmware update.

# Schedule and run gateway firmware update task
<a name="lorawan-schedule-firmware-update"></a>

If you have the firmware update file and signature, you can schedule and run the task definition to update the gateway firmware, as described in this page. If you don't have the firmware update files, see [(Optional) Generate the firmware update file and signature](lorawan-script-fwupdate-sigkey.md) for an example that you can use to adapt to your application.

The following steps show you how to create a wireless gateway task definition to update the gateway firmware.

**Topics**
+ [What's a wireless gateway task definition?](#lorawan-firmware-task-definition)
+ [Get the current firmware version running on your gateway](#lorawan-gateway-current-version)
+ [Schedule gateway firmware update using a task definition](#lorawan-create-task-definition)
+ [Run the firmware update task and track progress](#lorawan-run-fwupdate-task)

## What's a wireless gateway task definition?
<a name="lorawan-firmware-task-definition"></a>

To update the gateway firmware, you create a task definition. You can use the task definition to include details about the firmware update and define the update. AWS IoT Core for LoRaWAN provides a firmware update based on information from the following three fields associated with the gateway.
+ 

**LoRa Basics Station**  
The version and build time of the Basics Station software. To identify this information, you can also generate it by using the Basics Station software that is being run by your gateway (for example, `2.0.5(rpi/std) 2021-03-09 03:45:09`).
+ 

**Package version**  
The firmware version, specified by the file `version.txt` in the gateway. While this information might not be present in the gateway, you must specify this field as it provides a way to define your firmware version (for example, `1.0.0`).
+ 

**Gateway platform model**  
The platform or model that is being used by the gateway (for example, Linux).

## Get the current firmware version running on your gateway
<a name="lorawan-gateway-current-version"></a>

To determine your gateway's eligibility for a firmware update, the CUPS server checks all three fields, **LoRa Basics Station**, **Package version**, and **Gateway platform model**, for a match when the gateway presents them during a CUPS request. These fields are stored as part of the current version of a wireless gateway task definition.

You can determine the current firmware version running on the gateway from the console or the CLI.

### Get the current firmware version (console)
<a name="lorawan-gateway-current-version-console"></a>

When you use the AWS Management Console, you can obtain the firmware version from the details page of the gateway for which you're retrieving this information.

1. Go to the [Gateways hub](https://console.aws.amazon.com/iot/home#/wireless/gateways) page of the AWS IoT console and choose the gateway for which you're retrieving this information.

1. Go to the **Firmware** tab in the details page of the gateway to see the current firmware version and the status information that indicates whether a firmware update is pending.

### Get the current firmware version (CLI)
<a name="lorawan-gateway-current-version-cli"></a>

When you use the AWS IoT Wireless API or the AWS CLI, you can obtain this information using the `CurrentVersion` field that's stored as part of the task definition. The following steps use the CLI to demonstrate how you can get this information.

1. 

**Obtain wireless gateway ID**

   First, obtain the unique identifier of the gateway for which you want to retrieve the current firmware version. If you've already provisioned a gateway, you can get information about the gateway using the [https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_GetWirelessGateway.html](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_GetWirelessGateway.html) API operation or the [https://docs.aws.amazon.com/cli/latest/reference/iotwireless/get-wireless-gateway.html](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/get-wireless-gateway.html) CLI command.

   ```
   aws iotwireless get-wireless-gateway \ 
       --identifier 5a11b0a85a11b0a8 \ 
           --identifier-type GatewayEui
   ```

   Following shows a sample output for the command.

   ```
   {
       "Name": "Raspberry pi",
       "Id": "1352172b-0602-4b40-896f-54da9ed16b57",
       "Description": "Raspberry pi",
       "LoRaWAN": {
           "GatewayEui": "5a11b0a85a11b0a8",
           "RfRegion": "US915"
       },
       "Arn": "arn:aws:iotwireless:us-east-1:231894231068:WirelessGateway/1352172b-0602-4b40-896f-54da9ed16b57"
   }
   ```

1. 

**Get gateway firmware version**

   Using the wireless gateway ID reported by the `get-wireless-gateway` command, you can use the [get-wireless-gateway-firmware-information](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/get-wireless-gateway-firmware-information.html) command to get the `CurrentVersion`. 

   ```
   aws iotwireless get-wireless-gateway-firmware-information \
       --id "3039b406-5cc9-4307-925b-9948c63da25b"
   ```

   Following shows a sample output for the command, with information from all three fields displayed by the `CurrentVersion`.

   ```
   {
       "LoRaWAN": {
           "CurrentVersion": {
               "PackageVersion": "1.0.0",
               "Model": "rpi",
               "Station": "2.0.5(rpi/std) 2021-03-09 03:45:09"
           }
       }
   }
   ```

## Schedule gateway firmware update using a task definition
<a name="lorawan-create-task-definition"></a>

Now that you've verified the eligibility of the firmware update, you can schedule a firmware update task using a wireless gateway task definition and then run the update.

To update the gateway firmware, you'll need a wireless gateway task definition. You can use the AWS IoT console or the AWS CLI to update the gateway firmware.

### Schedule gateway firmware update using a task definition (console)
<a name="lorawan-schedule-task-definition-console"></a>

To schedule a firmware update task from the console:

1. Go to the [Gateways hub](https://console.aws.amazon.com/iot/home#/wireless/gateways) page of the AWS IoT console and choose the gateway for which you're updating the firmware.

1. Go to the **Firmware** tab in the details page of the gateway and choose **Update firmware**.

1. Create a wireless gateway task, or choose an existing task definition if you have already created one.

   If you have already created a task definition, choose **Use an existing task**. Information about the task definition will appear here, such as the **Package version**, the location for the firmware file in Amazon S3, and the status of the update. You can review the information and then choose **Update firmware**.

#### Create a gateway task definition
<a name="lorawan-schedule-task-console-create"></a>

If you're creating a new task definition, you'll need to perform the steps described below to specify the location to your firmware file in Amazon S3, and the IAM role that grants AWS IoT Core for LoRaWAN permission to access the file and perform the update.

In the **Update firmware** page of the console, choose **Create a new task**, and then perform the following steps.

1. 

**Specify firmware file and location in Amazon S3**

   You can use an Amazon Simple Storage Service bucket to store the firmware update files. Specify the location to your firmware file in Amazon S3, and provide the IAM role that grants AWS IoT Core for LoRaWAN permission to access the file and perform the update.
   + If you have already uploaded the file to Amazon S3, choose **Select an existing firmware file**. You can then **Browse S3** and provide the S3 URI to the file.
   + If you haven't already uploaded the file to Amazon S3, choose **Upload a new firmware file**. You can then upload the firmware file and **Browse S3** to choose the Amazon S3 bucket where the file will be uploaded.

1. 

**(Optional) Provide additional firmware verification settings**

   Optionally, if your firmware update was signed, you can use the additional settings to specify the update signature and CRC. These settings can be used to verify the authenticity and integrity of the signed update. It also ensures that the code was not corrupted or altered, and the devices run code that's published only by trusted authors. The update signature and CRC will be passed to AWS IoT Core for LoRaWAN when updating the firmware using CUPS.

1. 

**(Optional) Provide additional setting to automatically create update tasks**

   Optionally, we recommend that you choose to specify automatic creation of tasks for all gateways by using the `Auto create tasks and update all like gateways` parameter. This parameter applies to any gateway that has a match for all three parameters mentioned previously in [What's a wireless gateway task definition?](#lorawan-firmware-task-definition). If this parameter is disabled, the parameters have to be manually assigned to the gateway.

1. 

**Permissions to access the bucket**

   You can either create a new service role or choose an existing role to allow AWS IoT Core for LoRaWAN to access the firmware update file in the Amazon S3 bucket on your behalf.

   To create a new role, you can enter a role name or leave it blank for a random name to be generated automatically. To view the policy permissions that grant access to the Amazon S3 bucket, choose **View policy permissions**. 

### Schedule gateway firmware update using a task definition (CLI)
<a name="lorawan-create-task-definition-cli"></a>

You can create the wireless gateway task definition by using the AWS IoT Wireless API or the AWS CLI. The following steps show how to create the task definition using the CLI.

**Note**  
When you create the task definition, we recommend that you specify automatic creation of tasks by using the `AutoCreateTasks` parameter. This parameter applies to any gateway that has a match for all three parameters mentioned previously in [What's a wireless gateway task definition?](#lorawan-firmware-task-definition). If this parameter is disabled, the parameters have to be manually assigned to the gateway.

#### Pre-requisites
<a name="lorawan-create-task-definition-cli-prereq"></a>

Before you use the AWS CLI to update the firmware, you must have uploaded the firmware file to an Amazon S3 bucket, and created an IAM role that grants AWS IoT Core for LoRaWAN permission to access the file in the Amazon S3 bucket for performing the update. If you've already uploaded the firmware file and the IAM role, proceed to [Run firmware update task](#lorawan-create-task-definition-cli-run) to run the firmware update task.

If you haven't already uploaded the firmware file and specified the IAM role, perform the steps described in [Upload the firmware file to an Amazon S3 bucket and add an IAM role](lorawan-upload-firmware-s3bucket.md)8 and then run the firmware update task.

#### Run firmware update task
<a name="lorawan-create-task-definition-cli-run"></a>

To run the firmware update task, perform the following steps.

1. 

**Specify the input parameters for the update task**

   Create a file, `input.json`, that'll contain the information to pass to the `CreateWirelessGatewayTaskDefinition` API. In the `input.json` file, provide the following information that you obtained earlier:
   + 

**UpdateDataSource**  
Provide the link to your object containing the firmware update file that you uploaded to the S3 bucket. (for example, `s3://iotwirelessfwupdate/fwstation`.
   + 

**UpdateDataRole**  
Provide the link to the Role ARN for the IAM role that you created, which provides permissions to read the S3 bucket. (for example, `arn:aws:iam::123456789012:role/IoTWirelessFwUpdateRole`.
   + 

**SigKeyCRC and UpdateSignature**  
This information might be provided by your gateway manufacturer, but if you followed the procedure described in [(Optional) Generate the firmware update file and signature](lorawan-script-fwupdate-sigkey.md), you'll find this information when generating the signature.
   + 

**CurrentVersion**  
Provide the `CurrentVersion` output that you obtained previously by running the `get-wireless-gateway-firmware-information ` command.

     ```
     cat input.json
     ```

     Following shows the contents of the `input.json` file.

     ```
     {
         "AutoCreateTasks": true,
         "Name": "FirmwareUpdate",
         "Update":
         {
             "UpdateDataSource" : "s3://iotwirelessfwupdate/fwstation",
             "UpdateDataRole" : "arn:aws:iam::123456789012:role/IoTWirelessFwUpdateRole",
             "LoRaWAN" :
             {
                 "SigKeyCrc": 3434210794,
                 "UpdateSignature": "MEQCIDPY/p2ssgXIPNCOgZr+NzeTLpX+WfBo5tYWbh5pQWN3AiBROen+XlIdMScvAsfVfU/ZScJCalkVNZh4esyS8mNIgA==",
                 "CurrentVersion" :
                 {
                 "PackageVersion": "1.0.0",
                 "Model": "rpi",
                 "Station": "2.0.5(rpi/std) 2021-03-09 03:45:09"
                 }
             }
         }
     }
     ```

1. 

**Create the gateway task definition**

   Pass the `input.json` file to the [create-wireless-gateway-task-definition](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/get-wireless-gateway-task-definition.html) command to create the task definition. 

   ```
   aws iotwireless create-wireless-gateway-task-definition \ 
       --cli-input-json file://input.json
   ```

   Following shows the output of the command.

   ```
   {
       "Id": "4ac46ff4-efc5-44fd-9def-e8517077bb12",
       "Arn": "arn:aws:iotwireless:us-east-1:231894231068:WirelessGatewayTaskDefinition/4ac46ff4-efc5-44fd-9def-e8517077bb12"
   }
   ```

## Run the firmware update task and track progress
<a name="lorawan-run-fwupdate-task"></a>

The gateway is ready to receive the firmware update and, once powered on, it connects to the CUPS server. When the CUPS server finds a match in the version of the gateway, it schedules a firmware update.

A task is a task definition in process. The firmware update task starts as soon as a matching gateway for the update is found by the CUPS server. You can track the progress of the update task on the gateway from the console or the CLI.

### Run update task and track progress (console)
<a name="lorawan-run-fwupdate-task-console"></a>

When you use the AWS Management Console, you can track the progress of the firmware update from the details page of the gateway for which you're retrieving this information. Go to the [Gateways hub](https://console.aws.amazon.com/iot/home#/wireless/gateways) page, choose the gateway for which you're tracking the update, and then go to the **Firmware** tab to see the update status.

If the firmware update fails the first time, you'll see a status of **Retrying**, and the gateway sends the same request. If the CUPS server is unable to connect to the gateway after a second retry, it will show a status of **FAILED**.

### Run update task and track progress (CLI)
<a name="lorawan-gateway-current-version-cli"></a>

You can track the progress of the task by using the `GetWirelessGatewayTask` API. When you run the [get-wireless-gateway-task](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/get-wireless-gateway-task.html) command the first time, it will show the task status as `IN_PROGRESS`.

```
aws iotwireless get-wireless-gateway-task \ 
    --id 1352172b-0602-4b40-896f-54da9ed16b57
```

Following shows the output of the command.

```
{
    "WirelessGatewayId": "1352172b-0602-4b40-896f-54da9ed16b57",
    "WirelessGatewayTaskDefinitionId": "ec11f9e7-b037-4fcc-aa60-a43b839f5de3",
    "LastUplinkReceivedAt": "2021-03-12T09:56:12.047Z",
    "TaskCreatedAt": "2021-03-12T09:56:12.047Z",
    "Status": "IN_PROGRESS"
}
```

When you run the command the next time, if the firmware update takes effect, it will show the updated fields, `Package`, `Version`, and `Model` and the task status changes to `COMPLETED`.

```
aws iotwireless get-wireless-gateway-task \ 
    --id 1352172b-0602-4b40-896f-54da9ed16b57
```

Following shows the output of the command.

```
{
    "WirelessGatewayId": "1352172b-0602-4b40-896f-54da9ed16b57",
    "WirelessGatewayTaskDefinitionId": "ec11f9e7-b037-4fcc-aa60-a43b839f5de3",
    "LastUplinkReceivedAt": "2021-03-12T09:56:12.047Z",
    "TaskCreatedAt": "2021-03-12T09:56:12.047Z",
    "Status": "COMPLETED"
}
```

In this example, we showed you the firmware update using the Raspberry Pi based RAKWireless gateway. The firmware update script stops the running BasicStation to store the updated `Package`, `Version`, and `Model` fields so BasicStation will have to be restarted.

```
2021-03-12 09:56:13.108 [CUP:INFO] CUPS provided update.bin
2021-03-12 09:56:13.108 [CUP:INFO] CUPS provided signature len=70 keycrc=37316C36
2021-03-12 09:56:13.148 [CUP:INFO] ECDSA key#0 -> VERIFIED
2021-03-12 09:56:13.148 [CUP:INFO] Running update.bin as background process
2021-03-12 09:56:13.149 [SYS:VERB] /tmp/update.bin: Forked, waiting...
2021-03-12 09:56:13.151 [SYS:INFO] Process /tmp/update.bin (pid=6873) completed
2021-03-12 09:56:13.152 [CUP:INFO] Interaction with CUPS done - next regular check in 10s
```

If the firmware update fails, you see a status of `FIRST_RETRY` from the CUPS server, and the gateway sends the same request. If the CUPS server is unable to connect to the gateway after a `SECOND_RETRY`, it will show a status of `FAILED`.

After the previous task was `COMPLETED` or `FAILED`, delete the old task by using the [delete-wireless-gateway-task](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/delete-wireless-gateway-task.html) command before starting a new one.

```
aws iotwireless delete-wireless-gateway-task \ 
    --id 1352172b-0602-4b40-896f-54da9ed16b57
```