Firmware over the air 💎

Sending firmware to your Devices is a premium feature in KPN Things. Are you interested in using this feature? Please contact our sales at

‘Firmware over the air’, known as FOTA, is used to remotely update device firmware. A GUI is available for suppliers and customers as well. With this tool it is possible to interact with the device using a desired state and reported state. The reported state is generated by the metadata send by the device. The desired state is the state that is desired by the user.

The GUI of our FOTA tool has been documented as well. The documentation is written in Dutch.

Solution architecture

When a firmware update is needed, and the customer does not yet have access to the FOTA tooling, a request should be done at the IoT Service Portal. With this request the file should be uploaded and the corresponding devices should be specified. The KPN onboarding team will make sure the update is carried out. They will change the desired state which initiates the updating process. When suppliers and customers have access to the FOTA tooling process, they can do this themselves by specifying the IMEI’s and the File which will be downloaded by the device.

For an update a specific range of devices can be specified (all devices of Client X or these 100 devices of type Y).

  1. The firmware file is placed on the M2M File server where it can be downloaded with a unique URL.

  2. This per device unique URL is fetched by the fota server and..

  3. ..send as downlink to the specific devices using the HTTP response on an uplink.

  4. The device receives the downlink containing the information to be able to download the firmware file.

  5. Fetching can be done in multiple messages using a range header. If the update was successful, the device reports the new firmware version via an uplink.

  6. The device reports progress on the firmware update using regular uplink communication.

  7. This will update the reported property of the device and hereby completing the update process.

Device implementation

The steps above that interface with the Device are explained in more detail below.

The command to download a new firmware is sent as a standard HTTP response from KPN Things.

  {"bn": "urn:dev:IMEI:0123456789abcdef:"},
  {"n": "url", "v": ""},
  {"n": "token", "v": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ....."}

Step 5. Fetch firmware file from M2M file server

The Device should use the url and token received from the downlink to fetch the firmware file from the file server.

GET /f/v1/c5801012-31c8-4346-9963-cf317f1b5aa3 HTTP/1.1
Host: m.m
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ....
Content-Type: application/json

Fetching your firmware part by part

Optionally, the Range header can be used to fetch the firmware file part by part:

GET /f/v1/c5801012-31c8-4346-9963-cf317f1b5aa3 HTTP/1.1
Host: m.m
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ....
Range: bytes={startByteIndex}-{endByteIndex}
Content-Type: application/json


  • {startByteIndex} should be the starting byte of the bytes you want to receive

  • {endByteIndex} should be the last byte you want to receive (so the byte at the position of endByteIndex will be returned as well.

So if you want to receive the first 100 bytes of your firmware, your Range header should have the value bytes=0-99.

The number of parts used by a device to download a firmware is limited to 19999. The range should be choosen carefully, so that the entire file can be downloaded within the maximum of 19999 requests.


The response of the fetch firmware file endpoint looks as following:

HTTP/1.1 200 OK
Content-Range: bytes {startByteIndex}-{endByteIndex}/{totalSize}
Digest: crc32={crc}
... (more headers) ...

5B X7r&|EǸUB`l!ϧRL:1dTА'{{hF{	5./8jut'ZWQF_o:P7yU/HOYZp{yE˦>!uÚXS^KDĠ7?qU>8S}3f	k{/mu]


  • {totalSize} is the total size of your firmware file in bytes.

  • {crc} is a CRC32 in HEX of the body in the current response.

  • The Content-Range header is not present when the request did not contain the Range header.

  • The body of the response is raw binary data.

Step 6. Report to KPN Things if succeeded

This is just like regular uplink message to KPN things, in this case showing the update firmware version in the payload if succeeded.

POST /ingestion/m2m/senml/v1 HTTP/1.1
Things-Message-Token: THINGS_MESSAGE_TOKEN
Content-Type: application/json

Device SDK

Our KPN Things Device SDK for C has support for M2M FOTA, making it easier for you to integrate it in your C-based Devices. Head on over to the Github documentation pages for more information.

Technical pointers

Furthermore, take into account the following aspects when implementing M2M FOTA on your Device:

  • You may reuse the TCP socket when fetching your firmware file partwise. However, the socket can only be used 100 times. The server will respond with Connection: close when the TCP socket is being used too often.

  • Make sure you have a mechanism in place to verify the integrity of the complete firmware file when downloading in parts. This way you can verify the file after concatenation all the parts together.

Last updated