usb_moded  0.86.0+mer57
usb_moded-dyn-config.c
Go to the documentation of this file.
1 
30 #include "usb_moded-dyn-config.h"
31 
32 #include "usb_moded-log.h"
33 
34 #include <glob.h>
35 
36 /* ========================================================================= *
37  * Prototypes
38  * ========================================================================= */
39 
40 /* ------------------------------------------------------------------------- *
41  * MODEDATA
42  * ------------------------------------------------------------------------- */
43 
44 static void modedata_free_cb(gpointer self);
45 void modedata_free (modedata_t *self);
46 modedata_t *modedata_copy (const modedata_t *that);
47 static gint modedata_sort_cb(gconstpointer a, gconstpointer b);
48 static modedata_t *modedata_load (const gchar *filename);
49 
50 /* ------------------------------------------------------------------------- *
51  * MODELIST
52  * ------------------------------------------------------------------------- */
53 
54 void modelist_free(GList *modelist);
55 GList *modelist_load(bool diag);
56 
57 /* ========================================================================= *
58  * MODEDATA
59  * ========================================================================= */
60 
65 static void
66 modedata_free_cb(gpointer self)
67 {
68  modedata_free(self);
69 }
70 
75 void
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 
110 modedata_t *
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);
130  self->android_extra_sysfs_path = g_strdup(that->android_extra_sysfs_path);
131  self->android_extra_sysfs_value = g_strdup(that->android_extra_sysfs_value);
132  self->android_extra_sysfs_path2 = g_strdup(that->android_extra_sysfs_path2);
133  self->android_extra_sysfs_value2 = g_strdup(that->android_extra_sysfs_value2);
134  self->android_extra_sysfs_path3 = g_strdup(that->android_extra_sysfs_path3);
135  self->android_extra_sysfs_value3 = g_strdup(that->android_extra_sysfs_value3);
136  self->android_extra_sysfs_path4 = g_strdup(that->android_extra_sysfs_path4);
137  self->android_extra_sysfs_value4 = g_strdup(that->android_extra_sysfs_value4);
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 
146 EXIT:
147  return self;
148 }
149 
159 static gint
160 modedata_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 
176 static modedata_t *
177 modedata_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 
261 EXIT:
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 
278 void
279 modelist_free(GList *modelist)
280 {
281  LOG_REGISTER_CONTEXT;
282 
283  g_list_free_full(modelist, modedata_free_cb);
284 }
285 
293 GList *
294 modelist_load(bool diag)
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 }
modedata_free
void modedata_free(modedata_t *self)
Definition: usb_moded-dyn-config.c:76
modedata_t::mode_name
gchar * mode_name
Definition: usb_moded-dyn-config.h:102
modelist_free
void modelist_free(GList *modelist)
Definition: usb_moded-dyn-config.c:279
modedata_t::nat
int nat
Definition: usb_moded-dyn-config.h:121
modedata_t::network_interface
gchar * network_interface
Definition: usb_moded-dyn-config.h:107
modedata_t::network
int network
Definition: usb_moded-dyn-config.h:105
modelist_load
GList * modelist_load(bool diag)
Definition: usb_moded-dyn-config.c:294
modedata_t::android_extra_sysfs_value3
gchar * android_extra_sysfs_value3
Definition: usb_moded-dyn-config.h:116
modedata_t::android_extra_sysfs_value4
gchar * android_extra_sysfs_value4
Definition: usb_moded-dyn-config.h:118
modedata_t::mass_storage
int mass_storage
Definition: usb_moded-dyn-config.h:106
modedata_t::appsync
int appsync
Definition: usb_moded-dyn-config.h:104
modedata_t::android_extra_sysfs_path4
gchar * android_extra_sysfs_path4
Definition: usb_moded-dyn-config.h:117
modedata_t::mode_module
gchar * mode_module
Definition: usb_moded-dyn-config.h:103
modedata_t::android_extra_sysfs_path
gchar * android_extra_sysfs_path
Definition: usb_moded-dyn-config.h:111
modedata_t::dhcp_server
int dhcp_server
Definition: usb_moded-dyn-config.h:122
modedata_t::android_extra_sysfs_value
gchar * android_extra_sysfs_value
Definition: usb_moded-dyn-config.h:112
usb_moded-dyn-config.h
modedata_t::android_extra_sysfs_path2
gchar * android_extra_sysfs_path2
Definition: usb_moded-dyn-config.h:113
modedata_t::android_extra_sysfs_path3
gchar * android_extra_sysfs_path3
Definition: usb_moded-dyn-config.h:115
modedata_t::idProduct
gchar * idProduct
Definition: usb_moded-dyn-config.h:119
modedata_copy
modedata_t * modedata_copy(const modedata_t *that)
Definition: usb_moded-dyn-config.c:111
modedata_t::sysfs_value
gchar * sysfs_value
Definition: usb_moded-dyn-config.h:109
modedata_t::idVendorOverride
gchar * idVendorOverride
Definition: usb_moded-dyn-config.h:120
usb_moded-log.h
modedata_t
Definition: usb_moded-dyn-config.h:100
modedata_t::sysfs_reset_value
gchar * sysfs_reset_value
Definition: usb_moded-dyn-config.h:110
modedata_t::sysfs_path
gchar * sysfs_path
Definition: usb_moded-dyn-config.h:108
modedata_t::android_extra_sysfs_value2
gchar * android_extra_sysfs_value2
Definition: usb_moded-dyn-config.h:114