CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
sao.cpp
Go to the documentation of this file.
1
4
5#include "mod_sao/sao.h"
6#include "cdc_hal/II2cBus.h"
7#include "cdc_log.h"
8#include <cstring>
9
10static const char* TAG = "SAO";
11
12static sao_descriptor_t g_sao_descriptor;
13static bool g_sao_detected = false;
14static bool g_sao_initialized = false;
15static cdc::hal::II2cBus* g_sao_bus = nullptr;
17
25static esp_err_t sao_read_eeprom(uint8_t mem_addr, uint8_t* data, size_t len) {
26 if (!g_sao_bus || !g_sao_dev) return ESP_FAIL;
27 return g_sao_bus->readReg(g_sao_dev, mem_addr, data, len);
28}
29
35static bool sao_parse_descriptor(sao_descriptor_t* desc) {
36 if (!desc) return false;
37 memset(desc, 0, sizeof(sao_descriptor_t));
38
39 // 1. Read magic bytes
40 uint8_t buf[4] = {0};
41 if (sao_read_eeprom(0x00, buf, 4) != ESP_OK) {
42 LOG_D(TAG, "Failed to read magic bytes");
43 return false;
44 }
45
46 if (buf[0] != 0x53 || buf[1] != 0x41 || buf[2] != 0x4F || buf[3] != 0x31) {
47 LOG_D(TAG, "Invalid magic: %02X %02X %02X %02X", buf[0], buf[1], buf[2], buf[3]);
48 return false;
49 }
50
51 // 2. Read SAO name length and name
52 uint8_t offset = 4;
53 uint8_t name_len = 0;
54 if (sao_read_eeprom(offset, &name_len, 1) != ESP_OK) return false;
55 offset += 1;
56 if (name_len > SAO_MAX_NAME_LEN) name_len = SAO_MAX_NAME_LEN;
57 if (name_len > 0) {
58 if (sao_read_eeprom(offset, reinterpret_cast<uint8_t*>(desc->name), name_len) != ESP_OK) return false;
59 desc->name[name_len] = '\0';
60 offset += name_len;
61 }
62
63 // 3. Primary driver name
64 uint8_t drv_name_len = 0;
65 if (sao_read_eeprom(offset, &drv_name_len, 1) != ESP_OK) return false;
66 offset += 1;
67 if (drv_name_len > SAO_MAX_DRIVER_NAME_LEN) drv_name_len = SAO_MAX_DRIVER_NAME_LEN;
68 if (drv_name_len > 0) {
69 if (sao_read_eeprom(offset, reinterpret_cast<uint8_t*>(desc->primary_driver.name), drv_name_len) != ESP_OK) {
70 return false;
71 }
72 desc->primary_driver.name[drv_name_len] = '\0';
73 offset += drv_name_len;
74 }
75
76 // 4. Primary driver data
77 uint8_t drv_data_len = 0;
78 if (sao_read_eeprom(offset, &drv_data_len, 1) != ESP_OK) return false;
79 offset += 1;
80 desc->primary_driver.data_len = (drv_data_len > SAO_MAX_DRIVER_DATA_LEN) ? SAO_MAX_DRIVER_DATA_LEN : drv_data_len;
81 if (desc->primary_driver.data_len > 0) {
82 if (sao_read_eeprom(offset, desc->primary_driver.data, desc->primary_driver.data_len) != ESP_OK) {
83 return false;
84 }
85 offset += desc->primary_driver.data_len;
86 }
87
88 // 5. Extra drivers
89 uint8_t extra_count = 0;
90 if (sao_read_eeprom(offset, &extra_count, 1) != ESP_OK) return false;
91 offset += 1;
92 desc->extra_driver_count = (extra_count > SAO_MAX_EXTRA_DRIVERS) ? SAO_MAX_EXTRA_DRIVERS : extra_count;
93
94 for (uint8_t i = 0; i < desc->extra_driver_count; i++) {
95 if (sao_read_eeprom(offset, &drv_name_len, 1) != ESP_OK) break;
96 offset += 1;
97 if (drv_name_len > SAO_MAX_DRIVER_NAME_LEN) drv_name_len = SAO_MAX_DRIVER_NAME_LEN;
98 if (drv_name_len > 0) {
99 if (sao_read_eeprom(offset,
100 reinterpret_cast<uint8_t*>(desc->extra_drivers[i].name),
101 drv_name_len) != ESP_OK) {
102 break;
103 }
104 desc->extra_drivers[i].name[drv_name_len] = '\0';
105 offset += drv_name_len;
106 }
107
108 if (sao_read_eeprom(offset, &drv_data_len, 1) != ESP_OK) break;
109 offset += 1;
110 desc->extra_drivers[i].data_len =
111 (drv_data_len > SAO_MAX_DRIVER_DATA_LEN) ? SAO_MAX_DRIVER_DATA_LEN : drv_data_len;
112 if (desc->extra_drivers[i].data_len > 0) {
113 if (sao_read_eeprom(offset, desc->extra_drivers[i].data,
114 desc->extra_drivers[i].data_len) != ESP_OK) {
115 break;
116 }
117 offset += desc->extra_drivers[i].data_len;
118 }
119 }
120
121 return true;
122}
123
124bool sao_init(void) {
125 if (g_sao_initialized) return true;
126
128 if (!g_sao_bus) {
129 LOG_E(TAG, "I2C1 bus not available");
130 return false;
131 }
132
134 if (!g_sao_bus->init()) {
135 LOG_E(TAG, "I2C1 init failed");
136 return false;
137 }
138 }
140 g_sao_bus->start();
141 }
142
143 if (g_sao_bus->addDevice(SAO_EEPROM_ADDR, &g_sao_dev) != ESP_OK) {
144 LOG_E(TAG, "Failed to add SAO EEPROM device");
145 return false;
146 }
147
148 memset(&g_sao_descriptor, 0, sizeof(g_sao_descriptor));
149 g_sao_detected = false;
150 g_sao_initialized = true;
151 LOG_I(TAG, "SAO module initialized");
152 return true;
153}
154
155bool sao_scan(void) {
156 if (!g_sao_initialized) {
157 if (!sao_init()) return false;
158 }
159
160 g_sao_detected = false;
161 memset(&g_sao_descriptor, 0, sizeof(g_sao_descriptor));
162
164 g_sao_detected = true;
165 LOG_I(TAG, "SAO detected: %s (driver: %s)",
166 g_sao_descriptor.name,
167 g_sao_descriptor.primary_driver.name);
168 return true;
169 }
170
171 LOG_D(TAG, "No SAO detected");
172 return false;
173}
174
175bool sao_read_descriptor(sao_descriptor_t* desc) {
176 if (!desc) return false;
177 if (!g_sao_detected) {
178 memset(desc, 0, sizeof(sao_descriptor_t));
179 return false;
180 }
181 memcpy(desc, &g_sao_descriptor, sizeof(sao_descriptor_t));
182 return true;
183}
184
185bool sao_is_detected(void) {
186 return g_sao_detected;
187}
188
189const char* sao_get_name(void) {
190 if (!g_sao_detected) return "";
191 return g_sao_descriptor.name;
192}
193
194const char* sao_get_driver_name(void) {
195 if (!g_sao_detected) return "";
196 return g_sao_descriptor.primary_driver.name;
197}
198
199void sao_get_info_string(char* buf, size_t len) {
200 if (!buf || len == 0) return;
201 buf[0] = '\0';
202
203 if (!g_sao_detected) {
204 snprintf(buf, len,
205 "No SAO detected\n\nConnect an SAO module\nto the SAO port and\nunlock to detect it.");
206 return;
207 }
208
209 int pos = 0;
210 pos += snprintf(buf + pos, len - pos, "SAO: %s\n", g_sao_descriptor.name[0] ? g_sao_descriptor.name : "(none)");
211 pos += snprintf(buf + pos, len - pos, "Driver: %s\n",
212 g_sao_descriptor.primary_driver.name[0]
213 ? g_sao_descriptor.primary_driver.name : "(none)");
214
215 if (pos < static_cast<int>(len) && g_sao_descriptor.primary_driver.data_len > 0) {
216 pos += snprintf(buf + pos, len - pos, "Driver Data:");
217 for (int i = 0; i < g_sao_descriptor.primary_driver.data_len && pos < static_cast<int>(len) - 3; i++) {
218 pos += snprintf(buf + pos, len - pos, " %02X", g_sao_descriptor.primary_driver.data[i]);
219 }
220 pos += snprintf(buf + pos, len - pos, "\n");
221 }
222
223 if (pos < static_cast<int>(len) && g_sao_descriptor.extra_driver_count > 0) {
224 pos += snprintf(buf + pos, len - pos, "Extra Drivers: %d\n", g_sao_descriptor.extra_driver_count);
225 for (int i = 0; i < g_sao_descriptor.extra_driver_count && pos < static_cast<int>(len); i++) {
226 pos += snprintf(buf + pos, len - pos, " - %s\n", g_sao_descriptor.extra_drivers[i].name);
227 }
228 }
229}
static const char * TAG
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_D(tag, fmt,...)
Definition cdc_log.h:148
#define LOG_I(tag, fmt,...)
Definition cdc_log.h:147
#define LOG_E(tag, fmt,...)
Definition cdc_log.h:145
#define SAO_EEPROM_ADDR
Definition hw_config.h:49
II2cBus * getI2cBus1()
Returns singleton instance of I2C bus 1.
Definition I2cBus.cpp:280
void * I2cDeviceHandle
Definition II2cBus.h:10
static sao_descriptor_t g_sao_descriptor
Definition sao.cpp:12
bool sao_read_descriptor(sao_descriptor_t *desc)
Definition sao.cpp:175
bool sao_scan(void)
Definition sao.cpp:155
void sao_get_info_string(char *buf, size_t len)
Definition sao.cpp:199
const char * sao_get_driver_name(void)
Definition sao.cpp:194
const char * sao_get_name(void)
Definition sao.cpp:189
static esp_err_t sao_read_eeprom(uint8_t mem_addr, uint8_t *data, size_t len)
Reads bytes from SAO EEPROM at a given memory address.
Definition sao.cpp:25
static bool g_sao_detected
Definition sao.cpp:13
static bool sao_parse_descriptor(sao_descriptor_t *desc)
Parses the SAO binary descriptor from EEPROM content.
Definition sao.cpp:35
bool sao_init(void)
Definition sao.cpp:124
static cdc::hal::I2cDeviceHandle g_sao_dev
Definition sao.cpp:16
static cdc::hal::II2cBus * g_sao_bus
Definition sao.cpp:15
static bool g_sao_initialized
Definition sao.cpp:14
bool sao_is_detected(void)
Definition sao.cpp:185
#define SAO_MAX_EXTRA_DRIVERS
Definition sao.h:15
#define SAO_MAX_NAME_LEN
Definition sao.h:12
#define SAO_MAX_DRIVER_DATA_LEN
Definition sao.h:14
#define SAO_MAX_DRIVER_NAME_LEN
Definition sao.h:13