libusbgx-0.2.0
Loading...
Searching...
No Matches
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
28extern "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
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;
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
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
212static 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
220int usbg_translate_error(int error);
221
222char *usbg_ether_ntoa_r(const struct ether_addr *addr, char *buf);
223
224
225
226int usbg_read_buf(const char *path, const char *name,
227 const char *file, char *buf);
228
229int usbg_read_buf_limited(const char *path, const char *name,
230 const char *file, char *buf, int len);
231
232int 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
238int usbg_read_bool(const char *path, const char *name,
239 const char *file, bool *dest);
240
241int usbg_read_string(const char *path, const char *name,
242 const char *file, char *buf);
243
244int usbg_read_string_limited(const char *path, const char *name,
245 const char *file, char *buf, int len);
246
247int usbg_read_string_alloc(const char *path, const char *name,
248 const char *file, char **dest);
249
250int usbg_write_buf(const char *path, const char *name,
251 const char *file, const char *buf, int len);
252
253int 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
262int usbg_write_string(const char *path, const char *name,
263 const char *file, const char *buf);
264
265int usbg_rm_file(const char *path, const char *name);
266
267int usbg_rm_dir(const char *path, const char *name);
268
269int usbg_rm_all_dirs(const char *path);
270
271int 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
276int usbg_init_function(struct usbg_function *f,
277 struct usbg_function_type *ops,
279 const char *type_name,
280 const char *instance,
281 const char *path,
282 struct usbg_gadget *parent);
283
284void 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
324typedef int (*usbg_attr_get_func)(const char *, const char *, const char *, void *);
325typedef int (*usbg_attr_set_func)(const char *, const char *, const char *, void *);
326
327static 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
333static 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
339static 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
345static 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
351static 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
357static 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
363int usbg_get_ether_addr(const char *path, const char *name, const char *attr,
364 void *val);
365
366int usbg_set_ether_addr(const char *path, const char *name, const char *attr,
367 void *val);
368
369int 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 */
378typedef 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 */
382typedef 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 */
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