Loading...
Searching...
No Matches
settings.c File Reference

The persist API implementation. More...

#include "system/settings/settings.h"
#include "io/tuple_read.h"
#include "text/cstring_fit.h"
#include "text/number_format.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Functions

static void * field_ptr (const SettingsSchema *schema, const SettingField *field)
 A pointer to a field's storage inside its owning schema's blob.
static uint8_t get_version (const SettingsSchema *schema)
 The version byte lives at the head of every schema's struct.
static void set_version (const SettingsSchema *schema, uint8_t version)
 Set the version byte at the head of a schema's struct.
static void build_index (void)
 Index every schema's known fields by id, remembering the owning schema.
static uint8_t color_channel (uint32_t byte)
 One 0..255 colour byte down to the two bits a GColor channel holds.
static uint8_t color_from_hex (uint32_t hex)
 A 0xRRGGBB number as one opaque GColor byte.
static uint32_t color_to_hex (uint8_t argb)
 A GColor byte back to the 0xRRGGBB number the config page reads.
static void apply_defaults (const SettingsSchema *schema)
 Seed every field of one schema with its fresh-install default.
static bool sanitize_cstring (const SettingsSchema *schema, const SettingField *field)
 Clamp a damaged cstring back to its default.
static bool sanitize (const SettingsSchema *schema)
 Clamp every field of one schema to a legal value.
static void save_schema (const SettingsSchema *schema)
 Persist one schema's struct under its key, logging an error when the whole struct did not reach flash.
static void load_schema (const SettingsSchema *schema)
 Load one schema from its key, applying defaults first and re-saving when needed.
void settings_init (const SettingsSchema *head)
 Load a face's settings from their saved blobs, applying defaults first.
bool settings_was_fresh (void)
 Whether the watch booted with no saved settings, because storage was wiped by a fresh install or an update. Lets the phone know it should push its own config back rather than trust the watch's defaults.
void settings_save (void)
 Persist the active face's structs under their keys (the whole chain).
void settings_mark_restored (void)
 Clears settings_was_fresh once a save or restore from the settings page has been saved.
uint8_t settings_u8 (SettingId id)
 Read a known uint8/bool setting by id.
const char * settings_str (SettingId id)
 Read a known string setting by id.
void settings_set_u8 (SettingId id, uint8_t value)
 Write a known uint8 or enum setting by id. In memory only, does not persist.
uint8_t settings_enum_count (SettingId id)
 How many values an enum setting allows (its sanitize ceiling).
static void enum_text (uint8_t value, char *buf, size_t size)
 Writes an enum value as the text Clay reads a select back as.
static uint32_t field_value_size_max (const SettingField *field)
 The most bytes one field's value could take on the wire, written the way settings_serialize writes it.
uint32_t settings_serialized_size_max (void)
 The most outbox bytes every field of the active face could ever take once written.
bool settings_serialize (DictionaryIterator *iter)
 Write every field of the active face into an outbox iterator.
SettingsInbound settings_apply_inbox (DictionaryIterator *iter)
 Apply any settings present in an inbox message to the active face.

Variables

static const SettingsSchema * s_primary
 Head of the schema chain registered by settings_init, the primary plus any companions.
static bool s_was_fresh
 True when any schema in the chain had no saved blob at init, or one was reset for a blob it could not read, and no settings page message has landed since.
static const SettingField * s_by_id [SETTING_COUNT]
 Known fields indexed by id for typed reads, drawn from every schema in the chain.
static const SettingsSchema * s_owner_by_id [SETTING_COUNT]
 The schema that owns each indexed field, so a typed read hits the right blob.

Detailed Description

The persist API implementation.

Function Documentation

◆ apply_defaults()

void apply_defaults ( const SettingsSchema * schema)
static

Seed every field of one schema with its fresh-install default.

The whole blob is zeroed first, so a schema that declares no fields (one the face fills in itself rather than through the table) still resets to a known state instead of keeping whatever a rejected blob left behind. Zero is the empty string for a cstring and 0 for a number, which is what every field default then writes over.

Parameters
schemaThe schema to seed.

◆ build_index()

void build_index ( void )
static

Index every schema's known fields by id, remembering the owning schema.

So a shared read is a direct lookup. Face-only fields (id >= SETTING_COUNT) are skipped. The face reads those off its own struct. The whole chain is indexed, so a shared field may live in any schema (primary or companion) and the owner table keeps the typed read pointed at the right blob.

◆ color_channel()

uint8_t color_channel ( uint32_t byte)
static

One 0..255 colour byte down to the two bits a GColor channel holds.

The phone picks from the watch's own palette, so the byte is already one of 0, 85, 170 or 255. Rounding rather than dividing keeps anything slightly off landing on the nearest.

Parameters
byteThe channel byte.
Returns
0 to 3.

◆ color_from_hex()

uint8_t color_from_hex ( uint32_t hex)
static

A 0xRRGGBB number as one opaque GColor byte.

Parameters
hexThe colour the phone sent.
Returns
The argb byte.

◆ color_to_hex()

uint32_t color_to_hex ( uint8_t argb)
static

A GColor byte back to the 0xRRGGBB number the config page reads.

Parameters
argbThe stored byte.
Returns
The colour as 0xRRGGBB.

◆ enum_text()

void enum_text ( uint8_t value,
char * buf,
size_t size )
static

Writes an enum value as the text Clay reads a select back as.

Parameters
valueThe enum value.
bufWhere the text goes. Four bytes holds any uint8_t and its terminator.
sizeThe size of buf.

◆ field_ptr()

void * field_ptr ( const SettingsSchema * schema,
const SettingField * field )
static

A pointer to a field's storage inside its owning schema's blob.

Parameters
schemaThe schema that owns the field.
fieldThe setting field to get the pointer for.
Returns
A pointer to the field's storage.

◆ field_value_size_max()

uint32_t field_value_size_max ( const SettingField * field)
static

The most bytes one field's value could take on the wire, written the way settings_serialize writes it.

A string counts as filling its whole buffer, and an enum as the three digits plus terminator any uint8_t fits in.

Parameters
fieldThe field to measure.
Returns
The value's size, without its tuple header.

◆ get_version()

uint8_t get_version ( const SettingsSchema * schema)
static

The version byte lives at the head of every schema's struct.

Parameters
schemaThe schema to read the version from.
Returns
The version byte from the schema's struct.

◆ load_schema()

void load_schema ( const SettingsSchema * schema)
static

Load one schema from its key, applying defaults first and re-saving when needed.

Parameters
schemaThe schema to load.

◆ sanitize()

bool sanitize ( const SettingsSchema * schema)
static

Clamp every field of one schema to a legal value.

Ensures a damaged blob never renders as garbage.

Parameters
schemaThe schema to sanitize.
Returns
true if anything was corrected so the caller can re-save.

◆ sanitize_cstring()

bool sanitize_cstring ( const SettingsSchema * schema,
const SettingField * field )
static

Clamp a damaged cstring back to its default.

Valid means NUL-terminated within the buffer, free of control bytes, and non-empty unless the field's own default is empty. A place name can arrive as UTF-8, so anything from 0x20 up counts as text and is left alone.

Parameters
schemaThe schema that owns the field.
fieldThe setting field to sanitize.
Returns
true if the string was corrected, false otherwise.

◆ save_schema()

void save_schema ( const SettingsSchema * schema)
static

Persist one schema's struct under its key, logging an error when the whole struct did not reach flash.

Parameters
schemaThe schema to save.

◆ set_version()

void set_version ( const SettingsSchema * schema,
uint8_t version )
static

Set the version byte at the head of a schema's struct.

Parameters
schemaThe schema to write the version into.
versionThe version byte to set.

Variable Documentation

◆ s_was_fresh

bool s_was_fresh
static

True when any schema in the chain had no saved blob at init, or one was reset for a blob it could not read, and no settings page message has landed since.

Either way some settings are on their defaults, after a fresh install, an update, or a blob this build cannot read. It tells the phone to push its own config back rather than the watch seeding from defaults. It clears once the settings page's save or restore has landed and been saved.