libusbgx-0.3.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_read_buf_alloc(const char *path, const char *name,
251 const char *file, char **dest, int len);
252
253int usbg_write_buf(const char *path, const char *name,
254 const char *file, const char *buf, int len);
255
256int usbg_write_int(const char *path, const char *name, const char *file,
257 int value, const char *str);
258
259#define usbg_write_dec(p, n, f, v) usbg_write_int(p, n, f, v, "%d\n")
260#define usbg_write_hex(p, n, f, v) usbg_write_int(p, n, f, v, "0x%x\n")
261#define usbg_write_hex16(p, n, f, v) usbg_write_int(p, n, f, v, "0x%04x\n")
262#define usbg_write_hex8(p, n, f, v) usbg_write_int(p, n, f, v, "0x%02x\n")
263#define usbg_write_bool(p, n, f, v) usbg_write_dec(p, n, f, !!v)
264
265int usbg_write_string(const char *path, const char *name,
266 const char *file, const char *buf);
267
268int usbg_rm_file(const char *path, const char *name);
269
270int usbg_rm_dir(const char *path, const char *name);
271
272int usbg_rm_all_dirs(const char *path);
273
274int usbg_check_dir(const char *path);
275#define usbg_config_is_int(node) (config_setting_type(node) == CONFIG_TYPE_INT)
276#define usbg_config_is_string(node) \
277 (config_setting_type(node) == CONFIG_TYPE_STRING)
278
279int usbg_init_function(struct usbg_function *f,
280 struct usbg_function_type *ops,
282 const char *type_name,
283 const char *instance,
284 const char *path,
285 struct usbg_gadget *parent);
286
287void usbg_cleanup_function(struct usbg_function *f);
288
289#define GENERIC_ALLOC_INST(prefix, _type, _member) \
290 static int prefix##_alloc_inst(struct usbg_function_type *type, \
291 usbg_function_type type_code, \
292 const char *instance, const char *path, \
293 struct usbg_gadget *parent, \
294 struct usbg_function **f) \
295 { \
296 _type *ff; \
297 int ret; \
298 \
299 ff = malloc(sizeof(*ff)); \
300 if (!ff) \
301 return USBG_ERROR_NO_MEM; \
302 \
303 ret = usbg_init_function(&ff->_member, type, type_code, \
304 type->name, instance, path, parent); \
305 if (ret != USBG_SUCCESS) \
306 goto free_func; \
307 \
308 *f = &ff->_member; \
309 \
310 return ret; \
311 \
312 free_func: \
313 free(ff); \
314 return ret; \
315 }
316
317#define GENERIC_FREE_INST(prefix, _type, _member) \
318 static void prefix##_free_inst(struct usbg_function_type *type, \
319 struct usbg_function *f) \
320 { \
321 _type *ff = container_of(f, _type, _member); \
322 \
323 usbg_cleanup_function(&ff->_member); \
324 free(ff); \
325 }
326
327typedef int (*usbg_attr_get_func)(const char *, const char *, const char *, void *);
328typedef int (*usbg_attr_set_func)(const char *, const char *, const char *, void *);
329
330static inline int usbg_get_dec(const char *path, const char *name,
331 const char *attr, void *val)
332{
333 return usbg_read_dec(path, name, attr, (int *)val);
334}
335
336static inline int usbg_set_dec(const char *path, const char *name,
337 const char *attr, void *val)
338{
339 return usbg_write_dec(path, name, attr, *((int *)val));
340}
341
342static inline int usbg_get_bool(const char *path, const char *name,
343 const char *attr, void *val)
344{
345 return usbg_read_bool(path, name, attr, (bool *)val);
346}
347
348static inline int usbg_set_bool(const char *path, const char *name,
349 const char *attr, void *val)
350{
351 return usbg_write_bool(path, name, attr, *((bool *)val));
352}
353
354static inline int usbg_get_string(const char *path, const char *name,
355 const char *attr, void *val)
356{
357 return usbg_read_string_alloc(path, name, attr, (char **)val);
358}
359
360static inline int usbg_set_string(const char *path, const char *name,
361 const char *attr, void *val)
362{
363 return usbg_write_string(path, name, attr, *(char **)val);
364}
365
366int usbg_get_ether_addr(const char *path, const char *name, const char *attr,
367 void *val);
368
369int usbg_set_ether_addr(const char *path, const char *name, const char *attr,
370 void *val);
371
372int usbg_get_dev(const char *path, const char *name, const char *attr,
373 void *val);
374
375int usbg_write_guid(const char *path, const char *name,
376 const char *file, const char *buf);
377
378/*
379 * return:
380 * 0 - if not found
381 * usbg_error on error (less than 0)
382 * above 0 when found suitable value
383 */
384typedef int (*usbg_import_node_func)(config_setting_t *root,
385 const char *node_name, void *val);
386
387/* return 0 on success, usbg_error otherwise */
388typedef int (*usbg_export_node_func)(config_setting_t *root,
389 const char *node_name, void *val);
390
391#ifdef __cplusplus
392}
393#endif
394
395#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