usb_moded 0.86.0+mer58
usb_moded-dyn-config.c
Go to the documentation of this file.
1
29
31
32#include "usb_moded-log.h"
33
34#include <glob.h>
35
36/* ========================================================================= *
37 * Prototypes
38 * ========================================================================= */
39
40/* ------------------------------------------------------------------------- *
41 * MODEDATA
42 * ------------------------------------------------------------------------- */
43
44static void modedata_free_cb(gpointer self);
45void modedata_free (modedata_t *self);
47static gint modedata_sort_cb(gconstpointer a, gconstpointer b);
48static modedata_t *modedata_load (const gchar *filename);
49
50/* ------------------------------------------------------------------------- *
51 * MODELIST
52 * ------------------------------------------------------------------------- */
53
54void modelist_free(GList *modelist);
55GList *modelist_load(bool diag);
56
57/* ========================================================================= *
58 * MODEDATA
59 * ========================================================================= */
60
65static void
66modedata_free_cb(gpointer self)
67{
68 modedata_free(self);
69}
70
75void
77{
78 LOG_REGISTER_CONTEXT;
79
80 if( self ) {
81 g_free(self->mode_name);
82 g_free(self->mode_module);
83 g_free(self->network_interface);
84 g_free(self->sysfs_path);
85 g_free(self->sysfs_value);
86 g_free(self->sysfs_reset_value);
87 g_free(self->android_extra_sysfs_path);
88 g_free(self->android_extra_sysfs_value);
89 g_free(self->android_extra_sysfs_path2);
90 g_free(self->android_extra_sysfs_value2);
91 g_free(self->android_extra_sysfs_path3);
92 g_free(self->android_extra_sysfs_value3);
93 g_free(self->android_extra_sysfs_path4);
94 g_free(self->android_extra_sysfs_value4);
95 g_free(self->idProduct);
96 g_free(self->idVendorOverride);
97#ifdef CONNMAN
98 g_free(self->connman_tethering);
99#endif
100 free(self);
101 }
102}
103
112{
113 modedata_t *self = 0;
114
115 if( !that )
116 goto EXIT;
117
118 if( !(self = calloc(1, sizeof *self)) )
119 goto EXIT;
120
121 self->mode_name = g_strdup(that->mode_name);
122 self->mode_module = g_strdup(that->mode_module);
123 self->appsync = that->appsync;
124 self->network = that->network;
125 self->mass_storage = that->mass_storage;
126 self->network_interface = g_strdup(that->network_interface);
127 self->sysfs_path = g_strdup(that->sysfs_path);
128 self->sysfs_value = g_strdup(that->sysfs_value);
129 self->sysfs_reset_value = g_strdup(that->sysfs_reset_value);
138 self->idProduct = g_strdup(that->idProduct);
139 self->idVendorOverride = g_strdup(that->idVendorOverride);
140 self->nat = that->nat;
141 self->dhcp_server = that->dhcp_server;
142#ifdef CONNMAN
143 self->connman_tethering = g_strdup(that->connman_tethering);
144#endif
145
146EXIT:
147 return self;
148}
149
159static gint
160modedata_sort_cb(gconstpointer a, gconstpointer b)
161{
162 LOG_REGISTER_CONTEXT;
163
164 modedata_t *aa = (modedata_t *)a;
165 modedata_t *bb = (modedata_t *)b;
166
167 return g_strcmp0(aa->mode_name, bb->mode_name);
168}
169
176static modedata_t *
177modedata_load(const gchar *filename)
178{
179 LOG_REGISTER_CONTEXT;
180
181 modedata_t *self = NULL;
182 bool success = false;
183 GKeyFile *settingsfile = g_key_file_new();
184
185 if( !g_key_file_load_from_file(settingsfile, filename, G_KEY_FILE_NONE, NULL) ) {
186 log_err("%s: can't read mode configuration file", filename);
187 goto EXIT;
188 }
189
190 if( !(self = calloc(1, sizeof *self)) )
191 goto EXIT;
192
193 // [MODE_ENTRY = "mode"]
194 self->mode_name = g_key_file_get_string(settingsfile, MODE_ENTRY, MODE_NAME_KEY, NULL);
195 self->mode_module = g_key_file_get_string(settingsfile, MODE_ENTRY, MODE_MODULE_KEY, NULL);
196
197 log_debug("Dynamic mode name = %s\n", self->mode_name);
198 log_debug("Dynamic mode module = %s\n", self->mode_module);
199
200 self->appsync = g_key_file_get_integer(settingsfile, MODE_ENTRY, MODE_NEEDS_APPSYNC_KEY, NULL);
201 self->mass_storage = g_key_file_get_integer(settingsfile, MODE_ENTRY, MODE_MASS_STORAGE_KEY, NULL);
202 self->network = g_key_file_get_integer(settingsfile, MODE_ENTRY, MODE_NETWORK_KEY, NULL);
203 self->network_interface = g_key_file_get_string(settingsfile, MODE_ENTRY, MODE_NETWORK_INTERFACE_KEY, NULL);
204
205 // [MODE_OPTIONS_ENTRY = "options"]
206 self->sysfs_path = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_SYSFS_PATH, NULL);
207 self->sysfs_value = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_SYSFS_VALUE, NULL);
208 self->sysfs_reset_value = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_SYSFS_RESET_VALUE, NULL);
209
210 self->android_extra_sysfs_path = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_PATH, NULL);
211 self->android_extra_sysfs_path2 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_PATH2, NULL);
212 self->android_extra_sysfs_path3 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_PATH3, NULL);
213 self->android_extra_sysfs_path4 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_PATH4, NULL);
214 self->android_extra_sysfs_value = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_VALUE, NULL);
215 self->android_extra_sysfs_value2 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_VALUE2, NULL);
216 self->android_extra_sysfs_value3 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_VALUE3, NULL);
217 self->android_extra_sysfs_value4 = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_ANDROID_EXTRA_SYSFS_VALUE4, NULL);
218
219 self->idProduct = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_IDPRODUCT, NULL);
220 self->idVendorOverride = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_IDVENDOROVERRIDE, NULL);
221 self->nat = g_key_file_get_integer(settingsfile, MODE_OPTIONS_ENTRY, MODE_HAS_NAT, NULL);
222 self->dhcp_server = g_key_file_get_integer(settingsfile, MODE_OPTIONS_ENTRY, MODE_HAS_DHCP_SERVER, NULL);
223#ifdef CONNMAN
224 self->connman_tethering = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_CONNMAN_TETHERING, NULL);
225#endif
226
227 //log_debug("Dynamic mode sysfs path = %s\n", self->sysfs_path);
228 //log_debug("Dynamic mode sysfs value = %s\n", self->sysfs_value);
229 //log_debug("Android extra mode sysfs path2 = %s\n", self->android_extra_sysfs_path2);
230 //log_debug("Android extra value2 = %s\n", self->android_extra_sysfs_value2);
231
232 if( self->mode_name == NULL || self->mode_module == NULL ) {
233 log_err("%s: mode_name or mode_module not defined", filename);
234 goto EXIT;
235 }
236
237 if( self->network && self->network_interface == NULL) {
238 log_err("%s: network not fully defined", filename);
239 goto EXIT;
240 }
241
242 if( (self->sysfs_path && !self->sysfs_value) ||
243 (self->sysfs_reset_value && !self->sysfs_path) ) {
244 /* In theory all of this is optional.
245 *
246 * In most cases 'sysfs_value' holds a list of functions to enable,
247 * and 'sysfs_path' or 'sysfs_reset_value' values are simply ignored.
248 *
249 * However, for the benefit of existing special configuration files
250 * like the one for host mode:
251 * - having sysfs_path implies that sysfs_value should be set too
252 * - having sysfs_reset_value implies that sysfs_path should be set
253 */
254 log_err("%s: sysfs_value not fully defined", filename);
255 goto EXIT;
256 }
257
258 log_debug("%s: successfully loaded", filename);
259 success = true;
260
261EXIT:
262 g_key_file_free(settingsfile);
263
264 if( !success )
265 modedata_free(self), self = 0;
266
267 return self;
268}
269
270/* ========================================================================= *
271 * MODELIST
272 * ========================================================================= */
273
278void
279modelist_free(GList *modelist)
280{
281 LOG_REGISTER_CONTEXT;
282
283 g_list_free_full(modelist, modedata_free_cb);
284}
285
293GList *
295{
296 LOG_REGISTER_CONTEXT;
297
298 GList *modelist = 0;
299 const char *dirpath = diag ? DIAG_DIR_PATH : MODE_DIR_PATH;
300 gchar *pattern = g_strdup_printf("%s/*.ini", dirpath);
301 glob_t gb = {};
302
303 if( glob(pattern, 0, 0, &gb) != 0 )
304 log_debug("no mode configuration ini-files found");
305
306 for( size_t i = 0; i < gb.gl_pathc; ++i ) {
307 const char *filepath = gb.gl_pathv[i];
308 log_debug("Read file %s\n", filepath);
309 modedata_t *list_item = modedata_load(filepath);
310 if(list_item)
311 modelist = g_list_append(modelist, list_item);
312 }
313
314 globfree(&gb);
315 g_free(pattern);
316
317 return g_list_sort(modelist, modedata_sort_cb);
318}
gchar * android_extra_sysfs_value3
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
void modelist_free(GList *modelist)
void modedata_free(modedata_t *self)
modedata_t * modedata_copy(const modedata_t *that)
GList * modelist_load(bool diag)