usb_moded 0.86.0+mer64
usb_moded-dyn-config.c
Go to the documentation of this file.
1
29
31
33#include "usb_moded-log.h"
34
35#include <glob.h>
36
37/* ========================================================================= *
38 * Prototypes
39 * ========================================================================= */
40
41/* ------------------------------------------------------------------------- *
42 * MODEDATA
43 * ------------------------------------------------------------------------- */
44
45static void modedata_free_cb (gpointer self);
46void modedata_free (modedata_t *self);
48static void modedata_flush_settings(modedata_t *self);
49void modedata_cache_settings(modedata_t *self);
50static gint modedata_sort_cb (gconstpointer a, gconstpointer b);
51static modedata_t *modedata_load (const gchar *filename);
52
53/* ------------------------------------------------------------------------- *
54 * MODELIST
55 * ------------------------------------------------------------------------- */
56
57void modelist_free(GList *modelist);
58GList *modelist_load(bool diag);
59
60/* ========================================================================= *
61 * MODEDATA
62 * ========================================================================= */
63
68static void
69modedata_free_cb(gpointer self)
70{
71 modedata_free(self);
72}
73
78void
80{
81 LOG_REGISTER_CONTEXT;
82
83 if( self ) {
84 g_free(self->mode_name);
85 g_free(self->mode_module);
86 g_free(self->network_interface);
87 g_free(self->sysfs_path);
88 g_free(self->sysfs_value);
89 g_free(self->sysfs_reset_value);
90 g_free(self->android_extra_sysfs_path);
91 g_free(self->android_extra_sysfs_value);
92 g_free(self->android_extra_sysfs_path2);
93 g_free(self->android_extra_sysfs_value2);
94 g_free(self->android_extra_sysfs_path3);
95 g_free(self->android_extra_sysfs_value3);
96 g_free(self->android_extra_sysfs_path4);
97 g_free(self->android_extra_sysfs_value4);
98 g_free(self->idProduct);
99 g_free(self->idVendorOverride);
100#ifdef CONNMAN
101 g_free(self->connman_tethering);
102#endif
103 modedata_flush_settings(self);
104 free(self);
105 }
106}
107
116{
117 modedata_t *self = 0;
118
119 if( !that )
120 goto EXIT;
121
122 if( !(self = calloc(1, sizeof *self)) )
123 goto EXIT;
124
125 self->mode_name = g_strdup(that->mode_name);
126 self->mode_module = g_strdup(that->mode_module);
127 self->appsync = that->appsync;
128 self->network = that->network;
129 self->mass_storage = that->mass_storage;
130 self->network_interface = g_strdup(that->network_interface);
131 self->sysfs_path = g_strdup(that->sysfs_path);
132 self->sysfs_value = g_strdup(that->sysfs_value);
133 self->sysfs_reset_value = g_strdup(that->sysfs_reset_value);
142 self->idProduct = g_strdup(that->idProduct);
143 self->idVendorOverride = g_strdup(that->idVendorOverride);
144 self->nat = that->nat;
145 self->dhcp_server = that->dhcp_server;
146#ifdef CONNMAN
147 self->connman_tethering = g_strdup(that->connman_tethering);
148#endif
149 self->cached_ip = g_strdup(that->cached_ip);
150 self->cached_interface = g_strdup(that->cached_interface);
151 self->cached_gateway = g_strdup(that->cached_gateway);
152 self->cached_nat_interface = g_strdup(that->cached_nat_interface);
153 self->cached_netmask = g_strdup(that->cached_netmask);
154
155EXIT:
156 return self;
157}
158
159static void
160modedata_flush_settings(modedata_t *self)
161{
162 g_free(self->cached_ip),
163 self->cached_ip = NULL;
164 g_free(self->cached_interface),
165 self->cached_interface = NULL;
166 g_free(self->cached_gateway),
167 self->cached_gateway = NULL;
168 g_free(self->cached_nat_interface),
169 self->cached_nat_interface = NULL;
170 g_free(self->cached_netmask),
171 self->cached_netmask = NULL;
172}
173
174void
175modedata_cache_settings(modedata_t *self)
176{
177 modedata_flush_settings(self);
178
179 if( !(self->cached_ip = config_get_network_setting(NETWORK_IP_KEY)) )
180 self->cached_ip = config_get_network_fallback(NETWORK_IP_KEY);
181
182 if( !(self->cached_interface = config_get_network_setting(NETWORK_INTERFACE_KEY)) )
183 if( !(self->cached_interface = g_strdup(self->network_interface)) )
184 self->cached_interface = config_get_network_fallback(NETWORK_INTERFACE_KEY);
185
186 if( !(self->cached_gateway = config_get_network_setting(NETWORK_GATEWAY_KEY)) )
187 self->cached_gateway = config_get_network_fallback(NETWORK_GATEWAY_KEY);
188
189 if( !(self->cached_nat_interface = config_get_network_setting(NETWORK_NAT_INTERFACE_KEY)) )
190 self->cached_nat_interface = config_get_network_fallback(NETWORK_NAT_INTERFACE_KEY);
191
192 if( !(self->cached_netmask = config_get_network_setting(NETWORK_NETMASK_KEY)) )
193 self->cached_netmask = config_get_network_fallback(NETWORK_NETMASK_KEY);
194
195 log_debug("%s: %s = %s", self->mode_name, "cached_ip", self->cached_ip);
196 log_debug("%s: %s = %s", self->mode_name, "cached_interface", self->cached_interface);
197 log_debug("%s: %s = %s", self->mode_name, "cached_gateway", self->cached_gateway);
198 log_debug("%s: %s = %s", self->mode_name, "cached_nat_interface", self->cached_nat_interface);
199 log_debug("%s: %s = %s", self->mode_name, "cached_netmask", self->cached_netmask);
200}
201
211static gint
212modedata_sort_cb(gconstpointer a, gconstpointer b)
213{
214 LOG_REGISTER_CONTEXT;
215
216 modedata_t *aa = (modedata_t *)a;
217 modedata_t *bb = (modedata_t *)b;
218
219 return g_strcmp0(aa->mode_name, bb->mode_name);
220}
221
228static modedata_t *
229modedata_load(const gchar *filename)
230{
231 LOG_REGISTER_CONTEXT;
232
233 modedata_t *self = NULL;
234 bool success = false;
235 GKeyFile *settingsfile = g_key_file_new();
236
237 if( !g_key_file_load_from_file(settingsfile, filename, G_KEY_FILE_NONE, NULL) ) {
238 log_err("%s: can't read mode configuration file", filename);
239 goto EXIT;
240 }
241
242 if( !(self = calloc(1, sizeof *self)) )
243 goto EXIT;
244
245 // [MODE_ENTRY = "mode"]
246 self->mode_name = g_key_file_get_string(settingsfile, MODE_ENTRY, MODE_NAME_KEY, NULL);
247 self->mode_module = g_key_file_get_string(settingsfile, MODE_ENTRY, MODE_MODULE_KEY, NULL);
248
249 log_debug("Dynamic mode name = %s\n", self->mode_name);
250 log_debug("Dynamic mode module = %s\n", self->mode_module);
251
252 self->appsync = g_key_file_get_integer(settingsfile, MODE_ENTRY, MODE_NEEDS_APPSYNC_KEY, NULL);
253 self->mass_storage = g_key_file_get_integer(settingsfile, MODE_ENTRY, MODE_MASS_STORAGE_KEY, NULL);
254 self->network = g_key_file_get_integer(settingsfile, MODE_ENTRY, MODE_NETWORK_KEY, NULL);
255 self->network_interface = g_key_file_get_string(settingsfile, MODE_ENTRY, MODE_NETWORK_INTERFACE_KEY, NULL);
256
257 // [MODE_OPTIONS_ENTRY = "options"]
258 self->sysfs_path = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_SYSFS_PATH, NULL);
259 self->sysfs_value = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_SYSFS_VALUE, NULL);
260 self->sysfs_reset_value = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_SYSFS_RESET_VALUE, NULL);
261
262 self->android_extra_sysfs_path = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_PATH, NULL);
263 self->android_extra_sysfs_path2 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_PATH2, NULL);
264 self->android_extra_sysfs_path3 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_PATH3, NULL);
265 self->android_extra_sysfs_path4 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_PATH4, NULL);
266 self->android_extra_sysfs_value = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_VALUE, NULL);
267 self->android_extra_sysfs_value2 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_VALUE2, NULL);
268 self->android_extra_sysfs_value3 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_VALUE3, NULL);
269 self->android_extra_sysfs_value4 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_VALUE4, NULL);
270
271 self->idProduct = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_IDPRODUCT, NULL);
272 self->idVendorOverride = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_IDVENDOROVERRIDE, NULL);
273 self->nat = g_key_file_get_integer(settingsfile, MODE_OPTIONS_ENTRY, MODE_HAS_NAT, NULL);
274 self->dhcp_server = g_key_file_get_integer(settingsfile, MODE_OPTIONS_ENTRY, MODE_HAS_DHCP_SERVER, NULL);
275#ifdef CONNMAN
276 self->connman_tethering = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_CONNMAN_TETHERING, NULL);
277#endif
278
279 //log_debug("Dynamic mode sysfs path = %s\n", self->sysfs_path);
280 //log_debug("Dynamic mode sysfs value = %s\n", self->sysfs_value);
281 //log_debug("Android extra mode sysfs path2 = %s\n", self->android_extra_sysfs_path2);
282 //log_debug("Android extra value2 = %s\n", self->android_extra_sysfs_value2);
283
284 if( self->mode_name == NULL || self->mode_module == NULL ) {
285 log_err("%s: mode_name or mode_module not defined", filename);
286 goto EXIT;
287 }
288
289 if( self->network && self->network_interface == NULL) {
290 /* Original behavior was such that mode configuration files that
291 * declare network=1 without also defining network_interface were
292 * rejected. This makes little sense as:
293 * - the interface value is very likely to get overridden by
294 * kernel command line / usb-moded settings
295 * - there is fallback strategy in case no explicit value is set
296 * - one could argue that all this requirement manages to do is
297 * that mode configuration files have a meaningless, confusing
298 * line present
299 *
300 * Ignoring the value altogether could cause problems with some
301 * existing configurations out in the wild. But at least we can
302 * relax future requirements and demote diagnostic logging to
303 * debug level.
304 */
305 log_debug("%s: network_interface not defined", filename);
306 }
307
308 if( (self->sysfs_path && !self->sysfs_value) ||
309 (self->sysfs_reset_value && !self->sysfs_path) ) {
310 /* In theory all of this is optional.
311 *
312 * In most cases 'sysfs_value' holds a list of functions to enable,
313 * and 'sysfs_path' or 'sysfs_reset_value' values are simply ignored.
314 *
315 * However, for the benefit of existing special configuration files
316 * like the one for host mode:
317 * - having sysfs_path implies that sysfs_value should be set too
318 * - having sysfs_reset_value implies that sysfs_path should be set
319 */
320 log_err("%s: sysfs_value not fully defined", filename);
321 goto EXIT;
322 }
323
324 log_debug("%s: successfully loaded", filename);
325 success = true;
326
327EXIT:
328 g_key_file_free(settingsfile);
329
330 if( !success )
331 modedata_free(self), self = 0;
332
333 return self;
334}
335
336/* ========================================================================= *
337 * MODELIST
338 * ========================================================================= */
339
344void
345modelist_free(GList *modelist)
346{
347 LOG_REGISTER_CONTEXT;
348
349 g_list_free_full(modelist, modedata_free_cb);
350}
351
359GList *
361{
362 LOG_REGISTER_CONTEXT;
363
364 GList *modelist = 0;
365 const char *dirpath = diag ? DIAG_DIR_PATH : MODE_DIR_PATH;
366 gchar *pattern = g_strdup_printf("%s/*.ini", dirpath);
367 glob_t gb = {};
368
369 if( glob(pattern, 0, 0, &gb) != 0 )
370 log_debug("no mode configuration ini-files found");
371
372 for( size_t i = 0; i < gb.gl_pathc; ++i ) {
373 const char *filepath = gb.gl_pathv[i];
374 log_debug("Read file %s\n", filepath);
375 modedata_t *list_item = modedata_load(filepath);
376 if(list_item)
377 modelist = g_list_append(modelist, list_item);
378 }
379
380 globfree(&gb);
381 g_free(pattern);
382
383 return g_list_sort(modelist, modedata_sort_cb);
384}
gchar * android_extra_sysfs_value3
gchar * cached_nat_interface
gchar * android_extra_sysfs_path3
gchar * android_extra_sysfs_path
gchar * android_extra_sysfs_path4
gchar * android_extra_sysfs_value4
gchar * android_extra_sysfs_value2
gchar * android_extra_sysfs_value
gchar * android_extra_sysfs_path2
char * config_get_network_fallback(const char *config)
char * config_get_network_setting(const char *config)
void modelist_free(GList *modelist)
void modedata_free(modedata_t *self)
modedata_t * modedata_copy(const modedata_t *that)
GList * modelist_load(bool diag)