# kdefs

kode_status_t, the one result type that every call able to fail returns in the Kode Dot SDK, with the meaning of each of its nine values.

## What it is

kdefs is the smallest layer of the SDK: one header, no source file and no dependency. The header declares `kode_status_t`, the type that most calls able to fail return. A call that can fail says how it went with one of nine values.

A few calls answer with something else: a `bool` (`khal_i2c_probe()` says whether a chip answers) or a pointer (`khal_alloc_psram()` returns `NULL` when PSRAM has no room).

No layer owns this type, and khal, kdrv, kaos and the public facade all use it. It lives here because it needs a home that belongs to none of them. The placement test in `sdk/overview` sends a type to the layer that owns it, and a type that no layer owns goes to kdefs.

## How it is connected

```mermaid
flowchart TB
  defs["kdefs: kode_defs.h"]
  khal["khal"] --> defs
  kdrv["kdrv"] --> defs
  kaos["kaos"] --> defs
  kode["kode: kode.h"] --> defs
  app["Your app"] --> kode
  class app app
```

*Who includes kode_defs.h*

The component registers one include folder and nothing else:

```cmake
idf_component_register(INCLUDE_DIRS "include")
```

Your app sees the type through `kode.h`, which includes `kode_defs.h`. The usual check reads `if (rc != KODE_OK)`: a call worked when it returned `KODE_OK`, which is 0.

**There is no BUSY value.** The public API never asks a caller to try again later. A driver that is busy either waits or refuses with `KODE_DENIED`, and the page of that driver says which. The same rule explains `khal_worker_submit()`, which answers `KODE_NO_RESOURCES` for a full queue.

## Specifications

### The values

The nine values of `kode_status_t`, in the order of the enum.

| Name | Value | Meaning |
| --- | --- | --- |
| `KODE_OK` | 0 | The call did what it says |
| `KODE_ERROR` | 1 | It failed, and no other code says more |
| `KODE_TIMEOUT` | 2 | The far end did not answer in time |
| `KODE_DENIED` | 3 | Refused: bad argument, wrong state, or no right to do it |
| `KODE_NO_RESOURCES` | 4 | No memory, slot or handle left |
| `KODE_IO_ERROR` | 5 | The request was correct and the device itself refused the operation |
| `KODE_EXISTS` | 6 | The name is already taken |
| `KODE_NOT_DIR` | 7 | A component of the path is not a directory |
| `KODE_IS_DIR` | 8 | The path is a directory and the call wanted a file |

The last three say why a call on files was refused. They are separate values because a layer above shows a status to a person as one word, and these cases need three different words. A failing medium is `KODE_IO_ERROR`.

### How the SDK uses them

Where each value shows up in the SDK and what it tells the caller.

| Value | Where it shows up | What it tells you |
| --- | --- | --- |
| `KODE_DENIED` | `khal_nvs_get_*()`, `kode_nvs_get()` | Nothing was stored under the key. This is an answer, and the default of the caller applies |
| `KODE_DENIED` | `khal_gpio_input()`, `khal_exp_*()` | A pin or position number that does not exist, or a position that is lent |
| `KODE_NO_RESOURCES` | `khal_worker_submit()`, `khal_pwm_open()`, `khal_exp_ctrl()` | A full queue, no free channel, every controller of that kind held |
| `KODE_TIMEOUT` | `khal_clk_measure()` | The source produced no edges: a missing or dead crystal. A reading, not a fault |
| `KODE_IO_ERROR` | `khal_identity_set_mac()` | The cache could not be written, and the name applies for this boot |
| `KODE_ERROR` | most calls | The bus refused the transaction, or the vendor driver refused the configuration |

### The files

The layer has two files.

| File | What it does |
| --- | --- |
| `include/kode_defs.h` | Declares `kode_status_t`. The only source file of the layer |
| `CMakeLists.txt` | Registers the include folder. The component requires nothing |

## Gotchas

> **WARNING**
>
> **`KODE_DENIED` is not always a refusal.** Every NVS getter returns it for "nothing was stored", which is the normal state of a board that nobody provisioned. Read the page of the call before you log it as a fault.

> **NOTE**
>
> **An event carries the status as a `uint8_t`.** The worker's hand-back event, for example, holds it in a one-byte field, and the Active Object casts it back with `(kode_status_t)job->status`. Compare it after the cast, not before.

> **NOTE**
>
> **Some calls do not return a status.** Read-only queries that cannot fail return the value, and probes return a `bool` or a pointer. Check the header before you wrap a call in an `if (rc != KODE_OK)`.

## Example code

Read a greeting from the flash of a Kode Dot and tell the three outcomes apart. On the first boot the log says nothing was stored and the app saves a greeting. On every later boot it logs the saved one.

```c
/*
 * status_check.c - 2026-10-28 - from Kode with love
 *
 * Reads a greeting stored in the flash of the Kode Dot and tells the three
 * outcomes of kode_status_t apart: found, never stored, or a real fault. The
 * first boot logs "nothing stored yet" and saves a greeting. Every later boot
 * logs "stored greeting: hello from Kode".
 */
#include "kode.h"

#define STATUS_TAG   "status"
#define GREETING_KEY "greeting"
#define GREETING_TEXT "hello from Kode"

/* Bring the system up, read the key, and branch on the status. */
void app_main(void)
{
    char greeting[KODE_NVS_VALUE_MAX];

    kode_init();

    kode_status_t status = kode_nvs_get(GREETING_KEY, greeting, sizeof(greeting));

    if (status == KODE_OK) {
        KLOG_N(STATUS_TAG, "stored greeting: %s", greeting);
    } else if (status == KODE_DENIED) {
        /* The key is not there: nothing was stored yet. */
        KLOG_N(STATUS_TAG, "nothing stored yet");
        status = kode_nvs_set(GREETING_KEY, GREETING_TEXT);
        if (status != KODE_OK) {
            KLOG_E(STATUS_TAG, "could not save the greeting: status %d", (int)status);
        }
    } else {
        KLOG_E(STATUS_TAG, "reading the greeting failed: status %d", (int)status);
    }
}
```

Compiled against the SDK with ESP-IDF v6.1 on 2026-10-28. **TBD**: a run on a Kode Dot.

## In the SDK

- [`components/kdefs`](https://github.com/kodediy/kode-sdk/tree/main/components/kdefs): the whole layer.
- [`kode_defs.h`](https://github.com/kodediy/kode-sdk/blob/main/components/kdefs/include/kode_defs.h): the enum, with a comment on every value.
