libusbgx-0.2.0
usbg_internal.h
Go to the documentation of this file.
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  */
12 
13 #ifndef USBG_INTERNAL_H
14 #define USBG_INTERNAL_H
15 
16 #include <sys/queue.h>
17 #include <string.h>
18 #include <usbg/usbg.h>
19 #include <malloc.h>
20 #include <sys/types.h>
21 #ifdef HAS_GADGET_SCHEMES
22 #include "usbg_internal_libconfig.h"
23 #else
24 #include "usbg_internal_none.h"
25 #endif
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
35 #ifndef offsetof
36 #define offsetof(type, member) __builtin_offsetof (type, member)
37 #endif /* offsetof */
38 
39 #ifndef container_of
40 #define container_of(ptr, type, field) ({ \
41  const typeof(((type *)0)->field) *member = (ptr); \
42  (type *)( (char *)member - offsetof(type, field) ); \
43  })
44 #endif /* container_of */
45 
46 #define USBG_MAX_PATH_LENGTH PATH_MAX
47 /* ConfigFS just like SysFS uses page size as max size of file content */
48 #define USBG_MAX_FILE_SIZE 4096
49 
51 {
52  /* Name of this function type */
53  char *name;
54 
55  /* OS Descriptor interface name */
56  char **os_desc_iname;
57 
58  /* Called to allocate instance of function */
59  int (*alloc_inst)(struct usbg_function_type *, usbg_function_type,
60  const char *, const char *, usbg_gadget *,
61  struct usbg_function **);
62 
63  /* Called to free memory used by function */
64  void (*free_inst)(struct usbg_function_type *, struct usbg_function *);
65 
66  /*
67  * Called when user would like to remove this function.
68  * If this callback is provided it will be always called
69  * before rmdir on function directory. This function
70  * should check received flags and remove composed function
71  * attributes (directories) only if USBG_RM_RECURSE flag
72  * has been passed.
73  */
74  int (*remove)(struct usbg_function *, int);
75 
76  /* Set the value of all given attributes */
77  int (*set_attrs)(struct usbg_function *, void *);
78 
79  /* Get the value of all function attributes */
80  int (*get_attrs)(struct usbg_function *, void *);
81 
82  /* Free the additional memory allocated for function attributes */
83  void (*cleanup_attrs)(struct usbg_function *, void *);
84 
85  /* Should import all function attributes from libconfig format */
86  int (*import)(struct usbg_function *, config_setting_t *);
87 
88  /* Should export all functions attributes to libconfig format */
89  int (*export)(struct usbg_function *, config_setting_t *);
90 };
91 
92 struct usbg_state
93 {
94  char *path;
95  char *configfs_path;
96 
97  TAILQ_HEAD(ghead, usbg_gadget) gadgets;
98  TAILQ_HEAD(uhead, usbg_udc) udcs;
99  config_t *last_failed_import;
100 };
101 
103 {
104  char *name;
105  char *path;
106 
107  TAILQ_ENTRY(usbg_gadget) gnode;
108  TAILQ_HEAD(chead, usbg_config) configs;
109  TAILQ_HEAD(fhead, usbg_function) functions;
110  usbg_state *parent;
111  config_t *last_failed_import;
112  usbg_udc *udc;
113  usbg_config *os_desc_binding;
114 };
115 
117 {
118  TAILQ_ENTRY(usbg_config) cnode;
119  TAILQ_HEAD(bhead, usbg_binding) bindings;
120  usbg_gadget *parent;
121 
122  char *name;
123  char *path;
124  char *label;
125  int id;
126 };
127 
129 {
130  TAILQ_ENTRY(usbg_function) fnode;
131  usbg_gadget *parent;
132 
133  char *name;
134  char *path;
135  char *instance;
136  /* Only for internal library usage */
137  char *label;
138  usbg_function_type type;
139  struct usbg_function_type *ops;
140 };
141 
143 {
144  TAILQ_ENTRY(usbg_binding) bnode;
145  usbg_config *parent;
146  usbg_function *target;
147 
148  char *name;
149  char *path;
150 };
151 
152 struct usbg_udc
153 {
154  TAILQ_ENTRY(usbg_udc) unode;
155  usbg_state *parent;
156  usbg_gadget *gadget;
157 
158  char *name;
159 };
160 
161 #define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
162 
163 #define ARRAY_SIZE_SENTINEL(array, size) \
164  static void __attribute__ ((unused)) array##_size_sentinel() \
165  { \
166  char array##_smaller_than_expected[ \
167  (int)(ARRAY_SIZE(array) - size)] \
168  __attribute__ ((unused)); \
169  \
170  char array##_larger_than_expected[ \
171  (int)(size - ARRAY_SIZE(array))] \
172  __attribute__ ((unused)); \
173  }
174 
175 #define ERROR(msg, ...) do {\
176  fprintf(stderr, "%s() "msg" \n", \
177  __func__, ##__VA_ARGS__);\
178  fflush(stderr);\
179  } while (0)
180 
181 #define ERRORNO(msg, ...) do {\
182  fprintf(stderr, "%s() %s: "msg" \n", \
183  __func__, strerror(errno), ##__VA_ARGS__);\
184  fflush(stderr);\
185  } while (0)
186 
187 /* Insert in string order */
188 #define INSERT_TAILQ_STRING_ORDER(HeadPtr, HeadType, NameField, ToInsert, NodeField) \
189  do { \
190  if (TAILQ_EMPTY((HeadPtr)) || \
191  (strcmp((ToInsert)->NameField, TAILQ_FIRST((HeadPtr))->NameField) < 0)) \
192  TAILQ_INSERT_HEAD((HeadPtr), (ToInsert), NodeField); \
193  else if (strcmp((ToInsert)->NameField, TAILQ_LAST((HeadPtr), HeadType)->NameField) > 0) \
194  TAILQ_INSERT_TAIL((HeadPtr), (ToInsert), NodeField); \
195  else { \
196  typeof(ToInsert) _cur; \
197  TAILQ_FOREACH(_cur, (HeadPtr), NodeField) { \
198  if (strcmp((ToInsert)->NameField, _cur->NameField) > 0) \
199  continue; \
200  TAILQ_INSERT_BEFORE(_cur, (ToInsert), NodeField); \
201  break; \
202  } \
203  } \
204  } while (0)
205 
206 #define STRINGS_DIR "strings"
207 #define CONFIGS_DIR "configs"
208 #define FUNCTIONS_DIR "functions"
209 #define GADGETS_DIR "usb_gadget"
210 #define OS_DESC_DIR "os_desc"
211 
212 static inline int file_select(const struct dirent *dent)
213 {
214  if ((strcmp(dent->d_name, ".") == 0) || (strcmp(dent->d_name, "..") == 0))
215  return 0;
216  else
217  return 1;
218 }
219 
220 int usbg_translate_error(int error);
221 
222 char *usbg_ether_ntoa_r(const struct ether_addr *addr, char *buf);
223 
224 
225 
226 int usbg_read_buf(const char *path, const char *name,
227  const char *file, char *buf);
228 
229 int usbg_read_buf_limited(const char *path, const char *name,
230  const char *file, char *buf, int len);
231 
232 int usbg_read_int(const char *path, const char *name, const char *file,
233  int base, int *dest);
234 
235 #define usbg_read_dec(p, n, f, d) usbg_read_int(p, n, f, 10, d)
236 #define usbg_read_hex(p, n, f, d) usbg_read_int(p, n, f, 16, d)
237 
238 int usbg_read_bool(const char *path, const char *name,
239  const char *file, bool *dest);
240 
241 int usbg_read_string(const char *path, const char *name,
242  const char *file, char *buf);
243 
244 int usbg_read_string_limited(const char *path, const char *name,
245  const char *file, char *buf, int len);
246 
247 int usbg_read_string_alloc(const char *path, const char *name,
248  const char *file, char **dest);
249 
250 int usbg_write_buf(const char *path, const char *name,
251  const char *file, const char *buf, int len);
252 
253 int usbg_write_int(const char *path, const char *name, const char *file,
254  int value, const char *str);
255 
256 #define usbg_write_dec(p, n, f, v) usbg_write_int(p, n, f, v, "%d\n")
257 #define usbg_write_hex(p, n, f, v) usbg_write_int(p, n, f, v, "0x%x\n")
258 #define usbg_write_hex16(p, n, f, v) usbg_write_int(p, n, f, v, "0x%04x\n")
259 #define usbg_write_hex8(p, n, f, v) usbg_write_int(p, n, f, v, "0x%02x\n")
260 #define usbg_write_bool(p, n, f, v) usbg_write_dec(p, n, f, !!v)
261 
262 int usbg_write_string(const char *path, const char *name,
263  const char *file, const char *buf);
264 
265 int usbg_rm_file(const char *path, const char *name);
266 
267 int usbg_rm_dir(const char *path, const char *name);
268 
269 int usbg_rm_all_dirs(const char *path);
270 
271 int usbg_check_dir(const char *path);
272 #define usbg_config_is_int(node) (config_setting_type(node) == CONFIG_TYPE_INT)
273 #define usbg_config_is_string(node) \
274  (config_setting_type(node) == CONFIG_TYPE_STRING)
275 
276 int usbg_init_function(struct usbg_function *f,
277  struct usbg_function_type *ops,
278  usbg_function_type type,
279  const char *type_name,
280  const char *instance,
281  const char *path,
282  struct usbg_gadget *parent);
283 
284 void usbg_cleanup_function(struct usbg_function *f);
285 
286 #define GENERIC_ALLOC_INST(prefix, _type, _member) \
287  static int prefix##_alloc_inst(struct usbg_function_type *type, \
288  usbg_function_type type_code, \
289  const char *instance, const char *path, \
290  struct usbg_gadget *parent, \
291  struct usbg_function **f) \
292  { \
293  _type *ff; \
294  int ret; \
295  \
296  ff = malloc(sizeof(*ff)); \
297  if (!ff) \
298  return USBG_ERROR_NO_MEM; \
299  \
300  ret = usbg_init_function(&ff->_member, type, type_code, \
301  type->name, instance, path, parent); \
302  if (ret != USBG_SUCCESS) \
303  goto free_func; \
304  \
305  *f = &ff->_member; \
306  \
307  return ret; \
308  \
309  free_func: \
310  free(ff); \
311  return ret; \
312  }
313 
314 #define GENERIC_FREE_INST(prefix, _type, _member) \
315  static void prefix##_free_inst(struct usbg_function_type *type, \
316  struct usbg_function *f) \
317  { \
318  _type *ff = container_of(f, _type, _member); \
319  \
320  usbg_cleanup_function(&ff->_member); \
321  free(ff); \
322  }
323 
324 typedef int (*usbg_attr_get_func)(const char *, const char *, const char *, void *);
325 typedef int (*usbg_attr_set_func)(const char *, const char *, const char *, void *);
326 
327 static inline int usbg_get_dec(const char *path, const char *name,
328  const char *attr, void *val)
329 {
330  return usbg_read_dec(path, name, attr, (int *)val);
331 }
332 
333 static inline int usbg_set_dec(const char *path, const char *name,
334  const char *attr, void *val)
335 {
336  return usbg_write_dec(path, name, attr, *((int *)val));
337 }
338 
339 static inline int usbg_get_bool(const char *path, const char *name,
340  const char *attr, void *val)
341 {
342  return usbg_read_bool(path, name, attr, (bool *)val);
343 }
344 
345 static inline int usbg_set_bool(const char *path, const char *name,
346  const char *attr, void *val)
347 {
348  return usbg_write_bool(path, name, attr, *((bool *)val));
349 }
350 
351 static inline int usbg_get_string(const char *path, const char *name,
352  const char *attr, void *val)
353 {
354  return usbg_read_string_alloc(path, name, attr, (char **)val);
355 }
356 
357 static inline int usbg_set_string(const char *path, const char *name,
358  const char *attr, void *val)
359 {
360  return usbg_write_string(path, name, attr, *(char **)val);
361 }
362 
363 int usbg_get_ether_addr(const char *path, const char *name, const char *attr,
364  void *val);
365 
366 int usbg_set_ether_addr(const char *path, const char *name, const char *attr,
367  void *val);
368 
369 int usbg_get_dev(const char *path, const char *name, const char *attr,
370  void *val);
371 
372 /*
373  * return:
374  * 0 - if not found
375  * usbg_error on error (less than 0)
376  * above 0 when found suitable value
377  */
378 typedef int (*usbg_import_node_func)(config_setting_t *root,
379  const char *node_name, void *val);
380 
381 /* return 0 on success, usbg_error otherwise */
382 typedef int (*usbg_export_node_func)(config_setting_t *root,
383  const char *node_name, void *val);
384 
385 #ifdef __cplusplus
386 }
387 #endif
388 
389 #endif /* USBG_INTERNAL_H */
usbg_function_type
Supported USB function types.
Definition: usbg.h:205
Definition: usbg_internal.h:143
Definition: usbg_internal.h:117
Definition: usbg_internal.h:51
Definition: usbg_internal.h:129
Definition: usbg_internal.h:103
Definition: usbg_internal.h:93
Definition: usbg_internal.h:153