11// Copyright 2020 <Zach Whitehead>
22// OpenPPG
33
4+ /* *
5+ * WebUSB Protocol Documentation
6+ *
7+ * Available Commands:
8+ * - "rbl": Reboot to bootloader for firmware updates
9+ * - "sync": Request current device settings and state
10+ *
11+ * Response Format:
12+ * {
13+ * "mj_v": number, // Major version
14+ * "mi_v": number, // Minor version
15+ * "arch": string, // Architecture ("SAMD21" or "RP2040")
16+ * "scr_rt": number, // Screen rotation
17+ * "ar_tme": number, // Armed time in minutes
18+ * "m_tmp": bool, // Metric temperature
19+ * "m_alt": bool, // Metric altitude
20+ * "prf": number, // Performance mode
21+ * "sea_p": float, // Sea pressure
22+ * "thm": number // Theme
23+ * }
24+ */
25+
426// ** Logic for EEPROM **
527# define EEPROM_OFFSET 0 // Address of first byte of EEPROM
628
@@ -80,27 +102,48 @@ void resetDeviceData() {
80102 writeDeviceData ();
81103}
82104
83- // ** Logic for WebUSB **
84- // Callback for when the USB connection state changes
105+ /* *
106+ * WebUSB connection state change callback.
107+ * Updates LED indicators to show connection status.
108+ *
109+ * @param connected True if WebUSB connection established, false if disconnected
110+ */
85111void line_state_callback (bool connected) {
86112 setLEDColor (connected ? LED_BLUE : LED_GREEN);
87113 setLEDs (connected);
88-
89- if ( connected ) send_usb_serial ();
90114}
91115
92- // customized for sp140
116+ /* *
117+ * Parses and handles incoming WebUSB JSON messages.
118+ * Messages can either be commands or settings updates.
119+ *
120+ * Command messages are processed immediately and return.
121+ * Settings messages must have major_v >= 5 and contain valid settings values.
122+ *
123+ * All settings changes are validated, sanitized, and saved to EEPROM.
124+ * Current device state is sent back after successful settings changes.
125+ *
126+ * Error Handling:
127+ * - Invalid JSON: Silently ignored
128+ * - Invalid version: Silently ignored
129+ * - Invalid settings: Sanitized to default values
130+ */
93131void parse_usb_serial () {
94132#ifdef USE_TINYUSB
95- const size_t capacity = JSON_OBJECT_SIZE (13 ) + 90 ;
133+ const size_t capacity = JSON_OBJECT_SIZE (13 ) + 90 ; // Size for max message
96134 DynamicJsonDocument doc (capacity);
97135 deserializeJson (doc, usb_web);
98136
99- if (doc[" command" ] && doc[" command" ] == " rbl" ) {
100- // display.fillScreen(DEFAULT_BG_COLOR);
101- // TODO display ("BL - UF2");
102- rebootBootloader ();
103- return ; // run only the command
137+ if (doc[" command" ]) {
138+ if (doc[" command" ] == " rbl" ) {
139+ // display.fillScreen(DEFAULT_BG_COLOR);
140+ // TODO display ("BL - UF2");
141+ rebootBootloader ();
142+ return ; // run only the command
143+ } else if (doc[" command" ] == " sync" ) {
144+ send_usb_serial ();
145+ return ; // run only the command
146+ }
104147 }
105148
106149 if (doc[" major_v" ] < 5 ) return ; // ignore old versions
@@ -121,10 +164,16 @@ void parse_usb_serial() {
121164
122165 vTaskResume (updateDisplayTaskHandle);
123166
124- send_usb_serial ();
167+ send_usb_serial (); // Send back updated data after settings change
125168#endif
126169}
127170
171+ /* *
172+ * Validates and sanitizes device settings to ensure they are within acceptable ranges.
173+ * Each setting is checked against its valid range and set to a default if invalid.
174+ *
175+ * @return true if any values were changed during sanitization, false if all valid
176+ */
128177bool sanitizeDeviceData () {
129178 bool changed = false ;
130179 // Ensure screen rotation is either 1 or 3, default to 3
0 commit comments