upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/main/beacon_price.c
blob: b87e289a6dc2ba6cb291c3bf41649fad04bb445a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "beacon_price.h"
#include "config.h"
#include "identity.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "mbedtls/sha256.h"
#include <string.h>

static const char *TAG = "beacon_price";
static bool s_active = false;

void beacon_price_hash_mint(const char *mint_url, uint8_t hash_out[4])
{
    uint8_t full_hash[32];
    mbedtls_sha256((const unsigned char *)mint_url, strlen(mint_url), full_hash, 0);
    memcpy(hash_out, full_hash, 4);
}

void beacon_price_hash_npub(const char *npub_hex, uint8_t hash_out[4])
{
    uint8_t full_hash[32];
    mbedtls_sha256((const unsigned char *)npub_hex, strlen(npub_hex), full_hash, 0);
    memcpy(hash_out, full_hash, 4);
}

void beacon_price_build_ie(tollgate_price_ie_t *ie)
{
    const tollgate_config_t *cfg = tollgate_config_get();
    const tollgate_identity_t *id = identity_get();

    memset(ie, 0, sizeof(*ie));
    ie->element_id = WIFI_VENDOR_IE_ELEMENT_ID;
    ie->length = 4 + TOLLGATE_IE_PAYLOAD_SIZE;
    ie->vendor_oui[0] = TOLLGATE_OUI_0;
    ie->vendor_oui[1] = TOLLGATE_OUI_1;
    ie->vendor_oui[2] = TOLLGATE_OUI_2;
    ie->vendor_oui_type = TOLLGATE_IE_TYPE;

    tollgate_price_payload_t *p = &ie->payload;
    p->version = TOLLGATE_IE_VERSION;
    p->metric = (strcmp(cfg->metric, "bytes") == 0) ? 1 : 0;
    p->price_per_step = (uint16_t)cfg->price_per_step;

    bool is_bytes = (strcmp(cfg->metric, "bytes") == 0);
    p->step_size = is_bytes ? (uint32_t)cfg->step_size_bytes : (uint32_t)cfg->step_size_ms;

    beacon_price_hash_mint(cfg->mint_url, p->mint_hash);

    p->geohash_len = (uint8_t)strnlen(cfg->nostr_geohash, TOLLGATE_IE_GEOHASH_MAX);
    memcpy(p->geohash, cfg->nostr_geohash, p->geohash_len);
    if (p->geohash_len < TOLLGATE_IE_GEOHASH_MAX) {
        memset(p->geohash + p->geohash_len, 0, TOLLGATE_IE_GEOHASH_MAX - p->geohash_len);
    }

    if (id && id->initialized) {
        beacon_price_hash_npub(id->npub_hex, p->npub_hash);
    }

    ESP_LOGI(TAG, "Built IE: price=%lu sats, step=%lu, metric=%s, geohash=%.*s",
             (unsigned long)p->price_per_step, (unsigned long)p->step_size,
             p->metric ? "bytes" : "milliseconds",
             p->geohash_len, p->geohash);
}

esp_err_t beacon_price_start(void)
{
    if (s_active) {
        ESP_LOGW(TAG, "Already active");
        return ESP_OK;
    }

    static tollgate_price_ie_t s_ie;
    beacon_price_build_ie(&s_ie);

    esp_err_t ret = esp_wifi_set_vendor_ie(true, WIFI_VND_IE_TYPE_BEACON,
                                            WIFI_VND_IE_ID_0, &s_ie);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to set beacon vendor IE: %s", esp_err_to_name(ret));
        return ret;
    }

    ret = esp_wifi_set_vendor_ie(true, WIFI_VND_IE_TYPE_PROBE_RESP,
                                  WIFI_VND_IE_ID_1, &s_ie);
    if (ret != ESP_OK) {
        ESP_LOGW(TAG, "Failed to set probe resp vendor IE: %s", esp_err_to_name(ret));
    }

    s_active = true;
    ESP_LOGI(TAG, "Price advertising started (beacon + probe response)");
    return ESP_OK;
}

esp_err_t beacon_price_stop(void)
{
    if (!s_active) return ESP_OK;

    esp_wifi_set_vendor_ie(false, WIFI_VND_IE_TYPE_BEACON, WIFI_VND_IE_ID_0, NULL);
    esp_wifi_set_vendor_ie(false, WIFI_VND_IE_TYPE_PROBE_RESP, WIFI_VND_IE_ID_1, NULL);

    s_active = false;
    ESP_LOGI(TAG, "Price advertising stopped");
    return ESP_OK;
}