---
title: Notecard API Requests for DFU
description: Notecard offers a set of APIs to help you monitor and manage both host MCU and Notecard firmware updates.
source_url: https://dev.blues.io/notehub/host-firmware-updates/notecard-api-requests-for-dfu/
canonical_url: https://dev.blues.io/notehub/host-firmware-updates/notecard-api-requests-for-dfu/
markdown_url: https://dev.blues.io/notehub/host-firmware-updates/notecard-api-requests-for-dfu.md
---

# Notecard API Requests for DFU

Notecard provides a set of APIs to help you monitor and manage both **host MCU** and **Notecard** firmware updates. Based on the Notecard's own firmware update protocols, these APIs offload a significant part of the burden of implementing over-the-air firmware updates.

> **Warning:**
>
> Certain API requests below are only available for [IAP host MCU firmware updates](https://dev.blues.io/notehub/host-firmware-updates/iap-firmware-update.md), [Notecard Outboard Firmware Update](https://dev.blues.io/notehub/host-firmware-updates/notecard-outboard-firmware-update.md), and/or [Notecard firmware updates](https://dev.blues.io/notecard/notecard-walkthrough/updating-notecard-firmware.md) and are identified on a per-API basis.

## NOFU Only: Enabling Notecard Outboard Firmware Update

> The `card.dfu` API is only relevant for [Notecard Outboard Firmware Update](https://dev.blues.io/notehub/host-firmware-updates/notecard-outboard-firmware-update.md).

The [card.dfu API](https://dev.blues.io/api-reference/notecard-api/card-requests/latest.md#card-dfu) is used to configure a Notecard to enable or disable [Notecard Outboard Firmware Update](https://dev.blues.io/notehub/host-firmware-updates/notecard-outboard-firmware-update.md).

For example, to allow the Notecard to flash the host MCU with a downloaded binary on an STM32-based host, set `"name"` to `"stm32"` and `"on"` to `true`:

**JSON**

```json
{
  "req": "card.dfu",
  "name": "stm32",
  "on": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("card.dfu");
JAddStringToObject(req, "name", "stm32");
JAddBoolToObject(req, "on", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "card.dfu"}
req["name"] = "stm32"
req["on"] = True
card.Transaction(req)
```

## Obtaining Firmware Download Status

> The `dfu.status` API works with all types of firmware updates.

The [dfu.status API](https://dev.blues.io/api-reference/notecard-api/dfu-requests/latest.md#dfu-status) is used to determine the status of the background download of firmware, and locally control whether the Notecard will allow a background firmware download.

When called with no arguments, a `dfu.status` request returns an object with two fields that answer two different questions:

- `mode` reports where the firmware download currently stands. On a Notecard that has never downloaded firmware this is `idle`, meaning no download is in progress and no data has been downloaded. The other possible values are covered in [DFU modes](#dfu-modes) below.
- `on` reports whether the Notecard is allowed to download firmware at all. This is `true` by default.

Use the `"name"` argument to specify the type of firmware update you want to check:

- `"user"` (the default) for IAP or Notecard Outboard Firmware Update host MCU updates.
- `"card"` for Notecard firmware updates.

**JSON**

```json
{
  "req":  "dfu.status",
  "name": "user"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("dfu.status");
JAddStringToObject(req, "name", "user");

NoteRequest(req);
```

**Python**

```python
req = {"req": "dfu.status"}
req["name"] = "user"

rsp = card.Transaction(req)
```

```json
{
 "mode": "idle",
 "on": true
}
```

To disable firmware downloads to the Notecard, set the `off` argument to `true`:

**JSON**

```json
{
  "req": "dfu.status",
  "off": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("dfu.status");
JAddBoolToObject(req, "off", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "dfu.status"}
req["off"] = True

rsp = card.Transaction(req)
```

To turn it back on, set the `on` argument to `true`:

**JSON**

```json
{
  "req": "dfu.status",
  "on": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("dfu.status");
JAddBoolToObject(req, "on", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "dfu.status"}
req["on"] = True

rsp = card.Transaction(req)
```

You can also use a voltage-variable value to control whether or not firmware updates are allowed, based on the battery level of the device, by using the `vvalue` argument. This argument expects a semicolon-delimited string of `<state>:<1|0>` pairs, where `1` allows firmware downloads in that state and `0` disallows them. The pre-defined Notecard battery states are:

- `usb`
- `high`
- `normal`
- `low`
- `dead`

When the Notecard's power source is in a given state, it will adjust whether a firmware download is allowed based on the values in that string. For instance, if you want to allow firmware updates when the battery is full or high, but NOT when the voltage is lower, send a request like this:

**JSON**

```json
{
  "req": "dfu.status",
  "vvalue": "usb:1;high:1;normal:0;low:0;dead:0"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("dfu.status");
JAddStringToObject(req, "vvalue", "usb:1;high:1;normal:0;low:0;dead:0");

NoteRequest(req);
```

**Python**

```python
req = {"req": "dfu.status"}
req["vvalue"] = "usb:1;high:1;normal:0;low:0;dead:0"

rsp = card.Transaction(req)
```

### DFU Modes

In addition to `idle` mode, `dfu.status` will return one of the following `mode` values after a device firmware update has been activated:

- `downloading`
- `ready`
- `outboard-ready`
- `error`
- `completed`

The `downloading` mode indicates that the Notecard detected the presence of new firmware on a previous sync and is in the process of downloading it. When in this mode, a `status` string is included in the response with additional details about download progress.

```json
{
 "mode": "downloading",
 "status": "downloaded 66% (28672/42892)",
 "on": true
}
```

Once the download is complete, the `mode` changes to `ready` to indicate that the firmware binary is fully downloaded and verified. When in this mode, a `status` string is included, as well as a `body` JSON object that includes essential details about the firmware binary, including the `length` of the binary, its `md5` hash, and more.

```json
{
 "mode": "ready",
 "status": "successfully downloaded",
 "on": true,
 "body": {
  "crc32": 2525287425,
  "created": 1599163431,
  "info": {},
  "length": 42892,
  "md5": "5a3f73a7f1b4bc8917b12b36c2532969",
  "modified": 1599163431,
  "name": "stm32-new-firmware$20200903200351.bin",
  "notes": "Latest prod firmware",
  "source": "stm32-new-firmware.bin",
  "type": "firmware"
 }
}
```

If the Notecard encounters an error during the download, the `mode` reports as `error` and the `status` field will provide a reason for the error.

```json
{
 "mode": "error",
 "status": "DFU did not complete",
 "on": true
}
```

## IAP Only: Entering Host DFU Mode on the Notecard

> The `hub.set` API's `"mode":"dfu"` argument is only relevant for [IAP host MCU](https://dev.blues.io/notehub/host-firmware-updates/iap-firmware-update.md) firmware updates.

Once the firmware binary is available, Notecard should be put into DFU mode by setting the [hub.set API's](https://dev.blues.io/api-reference/notecard-api/hub-requests/latest.md#hub-set) `mode` argument to `dfu`. This request halts all Notecard communications activity and allows the host to access downloaded host MCU firmware from internal storage.

**JSON**

```json
{
  "req": "hub.set",
  "mode": "dfu"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "mode", "dfu");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["mode"] = "dfu"

rsp = card.Transaction(req)
```

## IAP Only: Ensuring Host DFU Mode is Active

> The `dfu.get` API is only relevant for [IAP host MCU](https://dev.blues.io/notehub/host-firmware-updates/iap-firmware-update.md) firmware updates.

Setting the device to `"dfu"` mode does not make it ready to retrieve host MCU firmware immediately. The Notecard first has to wind down any in-progress communications and close its network connection, and how long that takes depends on what it was doing at the time. To check whether the Notecard is ready, use the [dfu.get API](https://dev.blues.io/api-reference/notecard-api/dfu-requests/latest.md#dfu-get) to set the `length` argument to `0`. This will verify that the device is in DFU mode without attempting to retrieve firmware.

**JSON**

```json
{
  "req": "dfu.get",
  "length": 0
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("dfu.get");
JAddNumberToObject(req, "length", 0);

NoteRequest(req);
```

**Python**

```python
req = {"req": "dfu.get"}
req["length"] = 0

rsp = card.Transaction(req)
```

> **Note:**
>
> This request returns a `{dfu-not-ready}` error if the Notecard is not ready yet.
>
> ```json
> {
>   "err": "disconnecting so that we can enter DFU mode {dfu-not-ready}"
> }
> ```

## IAP Only: Retrieving Host Firmware from the Notecard

> The `dfu.get` API is only relevant for [IAP host MCU](https://dev.blues.io/notehub/host-firmware-updates/iap-firmware-update.md) firmware updates.

Once the Notecard is in `dfu` mode, use the [dfu.get API](https://dev.blues.io/api-reference/notecard-api/dfu-requests/latest.md#dfu-get) to retrieve the downloaded host MCU firmware. This is typically done in successive chunks of length `n` until the entire binary has been delivered to the host. Use the `length` argument to provide a number of bytes to read for each request, and `offset` on each successive request to skip to the next available chunk.

For instance, if you wanted to read the binary 32 bytes at a time, the first request to `dfu.get` would look like this:

**JSON**

```json
{
  "req": "dfu.get",
  "length": 32
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("dfu.get");
JAddNumberToObject(req, "length", 32);

NoteRequest(req);
```

**Python**

```python
req = {"req": "dfu.get"}
req["length"] = 32

rsp = card.Transaction(req)
```

And each subsequent request would add an offset value that increments by the previously-requested length, each time:

**JSON**

```json
{
  "req": "dfu.get",
  "length": 32,
  "offset": 32
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("dfu.get");
JAddNumberToObject(req, "length", 32);
JAddNumberToObject(req, "offset", 32);

NoteRequest(req);
```

**Python**

```python
req = {"req": "dfu.get"}
req["length"] = 32
req["offset"] = 32

rsp = card.Transaction(req)
```

The first request to `dfu.get` returns the same `body` returned by `dfu.status` after a successful download. The first and subsequent requests also return a `payload` string containing the portion of the binary of the requested `length` and `offset`.

```json
{
  "payload": "AAAAAAAAAAAAAAAAcy8ACIEvAAgAAAAAjy8ACJ0vAAg="
}
```

## Clearing DFU State

> The `dfu.status` API works with all types of firmware updates.

After a host MCU or Notecard firmware update is complete, you can clear the Notecard's DFU state with a [dfu.status](https://dev.blues.io/api-reference/notecard-api/dfu-requests/latest.md#dfu-status) request and the `stop` argument. You can optionally supply a `status` message that will be sent to Notehub to indicate the final update status.

Use the `"name"` argument to specify the type of firmware update to clear:

- `"user"` for host MCU updates.
- `"card"` for Notecard updates.

**JSON**

```json
{
  "req": "dfu.status",
  "stop": true,
  "status": "firmware update successful",
  "name": "user"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("dfu.status");
JAddBoolToObject(req, "stop", true);
JAddStringToObject(req, "status", "firmware update successful");
JAddStringToObject(req, "name", "user");

NoteRequest(req);
```

**Python**

```python
req = {"req": "dfu.status"}
req["stop"] = True
req["status"] = "firmware update successful"
req["name"] = "user"

rsp = card.Transaction(req)
```

This request will set the `dfu.status` `mode` to `completed` and set the `status` field to the string value provided.

### Reporting a Failed Update

`status` is an informational string only, and it does not make a stop look like a failure. A `dfu.status` request with `stop` set to `true` always results in a `completed` mode unless you supply the `err` argument, which sets the mode to `error` instead and records your string as the reason.

**JSON**

```json
{
  "req": "dfu.status",
  "stop": true,
  "err": "CRC check failed",
  "name": "user"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("dfu.status");
JAddBoolToObject(req, "stop", true);
JAddStringToObject(req, "err", "CRC check failed");
JAddStringToObject(req, "name", "user");

NoteRequest(req);
```

**Python**

```python
req = {"req": "dfu.status"}
req["stop"] = True
req["err"] = "CRC check failed"
req["name"] = "user"

rsp = card.Transaction(req)
```

If both `err` and `status` are supplied, `err` takes precedence and `status` is ignored. Both arguments are ignored entirely unless `stop` is also `true`.

> **Warning:**
>
> **Don't forget to exit DFU mode if performing an IAP host MCU firmware update!**
>
> Once the IAP host DFU process is completed, take the Notecard out of `dfu` mode with another `hub.set` request. If you don't, the device remains in `dfu` mode, unable to sync with Notehub.
>
> Prefer `mode` set to `dfu-completed`, which exits DFU mode and resumes whatever synchronization mode the Notecard was using beforehand.
>
> **JSON**
>
> ```json
> {
>   "req": "hub.set",
>   "mode": "dfu-completed"
> }
> ```
>
> **C/C++**
>
> ```cpp
> J *req = NoteNewRequest("hub.set");
> JAddStringToObject(req, "mode", "dfu-completed");
>
> NoteRequest(req);
> ```
>
> **Python**
>
> ```python
> req = {"req": "hub.set"}
> req["mode"] = "dfu-completed"
>
> card.Transaction(req)
> ```

[Notehub API Requests for DFU](https://dev.blues.io/notehub/host-firmware-updates/notehub-api-requests-for-dfu.md "Notehub API Requests for DFU") [Environment Variables for DFU](https://dev.blues.io/notehub/host-firmware-updates/environment-variables-for-dfu.md "Environment Variables for DFU")
