ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
settings.c
Go to the documentation of this file.
1
13#include <ascii-chat/session/settings.h>
14#include <ascii-chat/common.h>
15#include <ascii-chat/options/options.h>
16#include <ascii-chat/asciichat_errno.h>
17#include <ascii-chat/platform/network.h>
18
19#include <string.h>
20#include <time.h>
21
22/* ============================================================================
23 * Session Settings Functions
24 * ============================================================================ */
25
26void session_settings_init(session_settings_t *settings) {
27 if (!settings) {
28 return;
29 }
30
31 memset(settings, 0, sizeof(session_settings_t));
32
33 // Read all defaults from the RCU options system
34 settings->version = 0;
35 settings->width = (int16_t)GET_OPTION(width);
36 settings->height = (int16_t)GET_OPTION(height);
37 settings->color_mode = (uint8_t)GET_OPTION(color_mode);
38 settings->render_mode = (uint8_t)GET_OPTION(render_mode);
39 settings->palette_type = (uint8_t)GET_OPTION(palette_type);
40
41 // Custom palette
42 const char *palette = GET_OPTION(palette_custom);
43 if (palette && palette[0] != '\0') {
44 SAFE_STRNCPY(settings->palette_custom, palette, sizeof(settings->palette_custom));
45 }
46
47 settings->audio_enabled = (uint8_t)GET_OPTION(audio_enabled);
48 settings->encryption_required = GET_OPTION(no_encrypt) ? 0 : 1;
49}
50
51asciichat_error_t session_settings_serialize(const session_settings_t *settings, uint8_t *buffer, size_t *len) {
52 if (!settings || !buffer || !len) {
53 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_serialize: NULL parameter");
54 }
55
56 // Fixed-size serialization format
57 size_t offset = 0;
58
59 // Version (4 bytes, network byte order)
60 uint32_t version_net = htonl(settings->version);
61 memcpy(buffer + offset, &version_net, sizeof(version_net));
62 offset += sizeof(version_net);
63
64 // Width (2 bytes, network byte order)
65 uint16_t width_net = htons((uint16_t)(settings->width & 0xFFFF));
66 memcpy(buffer + offset, &width_net, sizeof(width_net));
67 offset += sizeof(width_net);
68
69 // Height (2 bytes, network byte order)
70 uint16_t height_net = htons((uint16_t)(settings->height & 0xFFFF));
71 memcpy(buffer + offset, &height_net, sizeof(height_net));
72 offset += sizeof(height_net);
73
74 // Color mode (1 byte)
75 buffer[offset++] = settings->color_mode;
76
77 // Render mode (1 byte)
78 buffer[offset++] = settings->render_mode;
79
80 // Palette type (1 byte)
81 buffer[offset++] = settings->palette_type;
82
83 // Custom palette (32 bytes, null-padded)
84 memcpy(buffer + offset, settings->palette_custom, 32);
85 offset += 32;
86
87 // Audio enabled (1 byte)
88 buffer[offset++] = settings->audio_enabled;
89
90 // Encryption required (1 byte)
91 buffer[offset++] = settings->encryption_required;
92
93 // Reserved (16 bytes)
94 memcpy(buffer + offset, settings->reserved, 16);
95 offset += 16;
96
97 *len = offset;
98 return ASCIICHAT_OK;
99}
100
101asciichat_error_t session_settings_deserialize(const uint8_t *buffer, size_t len, session_settings_t *settings) {
102 if (!buffer || !settings) {
103 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_deserialize: NULL parameter");
104 }
105
106 // Check minimum buffer size
107 if (len < SESSION_SETTINGS_SERIALIZED_SIZE) {
108 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_deserialize: buffer too small (%zu < %d)", len,
109 SESSION_SETTINGS_SERIALIZED_SIZE);
110 }
111
112 memset(settings, 0, sizeof(session_settings_t));
113 size_t offset = 0;
114
115 // Version (4 bytes, network byte order)
116 uint32_t version_net;
117 memcpy(&version_net, buffer + offset, sizeof(version_net));
118 settings->version = ntohl(version_net);
119 offset += sizeof(version_net);
120
121 // Width (2 bytes, network byte order)
122 uint16_t width_net;
123 memcpy(&width_net, buffer + offset, sizeof(width_net));
124 settings->width = (int16_t)ntohs(width_net);
125 offset += sizeof(width_net);
126
127 // Height (2 bytes, network byte order)
128 uint16_t height_net;
129 memcpy(&height_net, buffer + offset, sizeof(height_net));
130 settings->height = (int16_t)ntohs(height_net);
131 offset += sizeof(height_net);
132
133 // Color mode (1 byte)
134 settings->color_mode = buffer[offset++];
135
136 // Render mode (1 byte)
137 settings->render_mode = buffer[offset++];
138
139 // Palette type (1 byte)
140 settings->palette_type = buffer[offset++];
141
142 // Custom palette (32 bytes)
143 memcpy(settings->palette_custom, buffer + offset, 32);
144 settings->palette_custom[31] = '\0'; // Ensure null termination
145 offset += 32;
146
147 // Audio enabled (1 byte)
148 settings->audio_enabled = buffer[offset++];
149
150 // Encryption required (1 byte)
151 settings->encryption_required = buffer[offset++];
152
153 // Reserved (16 bytes)
154 memcpy(settings->reserved, buffer + offset, 16);
155 // offset += 16; // Unused, commented to avoid warning
156
157 return ASCIICHAT_OK;
158}
159
160asciichat_error_t session_settings_from_options(session_settings_t *settings) {
161 if (!settings) {
162 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_from_options: NULL settings");
163 }
164
165 // Initialize to defaults
166 session_settings_init(settings);
167
168 // Get current options
169 const options_t *opts = options_get();
170 if (!opts) {
171 return SET_ERRNO(ERROR_CONFIG, "Options not initialized");
172 }
173
174 // Set version to current time for ordering
175 settings->version = (uint32_t)time(NULL);
176
177 // Copy dimension settings
178 settings->width = (int16_t)opts->width;
179 settings->height = (int16_t)opts->height;
180
181 // Copy display settings
182 settings->color_mode = (uint8_t)opts->color_mode;
183 settings->render_mode = (uint8_t)opts->render_mode;
184 settings->palette_type = (uint8_t)opts->palette_type;
185
186 // Copy custom palette if set
187 if (opts->palette_custom_set && opts->palette_custom[0] != '\0') {
188 SAFE_STRNCPY(settings->palette_custom, opts->palette_custom, sizeof(settings->palette_custom));
189 }
190
191 // Copy audio/encryption settings
192 settings->audio_enabled = (uint8_t)opts->audio_enabled;
193 settings->encryption_required = opts->no_encrypt ? 0 : 1;
194
195 return ASCIICHAT_OK;
196}
197
198asciichat_error_t session_settings_apply_to_options(const session_settings_t *settings) {
199 if (!settings) {
200 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_apply_to_options: NULL settings");
201 }
202
203 // Update dimensions if specified
204 if (settings->width > 0 && settings->height > 0) {
205 asciichat_error_t width_result = options_set_int("width", (int)settings->width);
206 asciichat_error_t height_result = options_set_int("height", (int)settings->height);
207 if (width_result != ASCIICHAT_OK || height_result != ASCIICHAT_OK) {
208 log_warn("Failed to apply dimension settings: width=%d, height=%d", width_result, height_result);
209 }
210 }
211
212 // Note: Other options would require additional RCU update functions
213 // For now, dimensions are the primary use case for runtime updates
214 // Color mode, render mode, and palette typically don't change mid-session
215
216 return ASCIICHAT_OK;
217}
218
219bool session_settings_needs_update(uint32_t local_version, uint32_t remote_version) {
220 // Higher version wins (newer settings)
221 return remote_version > local_version;
222}
223
224bool session_settings_equal(const session_settings_t *a, const session_settings_t *b) {
225 if (!a || !b) {
226 return false;
227 }
228
229 // Compare all fields except version
230 return a->width == b->width && a->height == b->height && a->color_mode == b->color_mode &&
231 a->render_mode == b->render_mode && a->palette_type == b->palette_type &&
232 strncmp(a->palette_custom, b->palette_custom, sizeof(a->palette_custom)) == 0 &&
233 a->audio_enabled == b->audio_enabled && a->encryption_required == b->encryption_required;
234}
asciichat_error_t options_set_int(const char *field_name, int value)
Definition rcu.c:449
const options_t * options_get(void)
Definition rcu.c:347
bool session_settings_equal(const session_settings_t *a, const session_settings_t *b)
Definition settings.c:224
asciichat_error_t session_settings_deserialize(const uint8_t *buffer, size_t len, session_settings_t *settings)
Definition settings.c:101
asciichat_error_t session_settings_apply_to_options(const session_settings_t *settings)
Definition settings.c:198
bool session_settings_needs_update(uint32_t local_version, uint32_t remote_version)
Definition settings.c:219
asciichat_error_t session_settings_from_options(session_settings_t *settings)
Definition settings.c:160
asciichat_error_t session_settings_serialize(const session_settings_t *settings, uint8_t *buffer, size_t *len)
Definition settings.c:51
void session_settings_init(session_settings_t *settings)
Definition settings.c:26