summaryrefslogtreecommitdiff
path: root/include/usbg
diff options
context:
space:
mode:
authortaeyoung <ty317.kim@samsung.com>2016-09-23 20:36:42 +0900
committertaeyoung <ty317.kim@samsung.com>2016-09-23 20:37:16 +0900
commit175e5d7fcc47a6f7f480265edfff89e4ea1c6442 (patch)
tree2edbc50a8a91662cd022f9b5c5d0693f6a8b4071 /include/usbg
parent9ddeb24a02bff238a8c34688bd3e31e2a391c6f4 (diff)
downloadlibusbg-175e5d7fcc47a6f7f480265edfff89e4ea1c6442.tar.gz
libusbg-175e5d7fcc47a6f7f480265edfff89e4ea1c6442.tar.bz2
libusbg-175e5d7fcc47a6f7f480265edfff89e4ea1c6442.zip
Change-Id: I8c015fe84734a1020227040699dc4bbf9a081ccd
Diffstat (limited to 'include/usbg')
-rw-r--r--include/usbg/usbg.h612
-rw-r--r--include/usbg/usbg_internal.h174
2 files changed, 726 insertions, 60 deletions
diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index 1407f10..bcf221d 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -22,15 +22,20 @@
#include <netinet/ether.h>
#include <stdint.h>
#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h> /* For FILE * */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
/**
* @file include/usbg/usbg.h
- * @todo Add usbg_remove_[gadget|config|function|binding] APIs
* @todo Clean up static buffers in structures
*/
/**
- * @addtogroup libusbg
+ * @addtogroup libusbgx
* Public API for USB gadget-configfs library
* @{
*/
@@ -39,9 +44,21 @@
#define LANG_US_ENG 0x0409
#define DEFAULT_CONFIG_LABEL "config"
+/* This one has to be at least 18 bytes to hold network address */
#define USBG_MAX_STR_LENGTH 256
#define USBG_MAX_PATH_LENGTH PATH_MAX
#define USBG_MAX_NAME_LENGTH 40
+/* Dev name for ffs is a part of function name, we subtract 4 char for "ffs." */
+#define USBG_MAX_DEV_LENGTH (USBG_MAX_NAME_LENGTH - 4)
+/* ConfigFS just like SysFS uses page size as max size of file content */
+#define USBG_MAX_FILE_SIZE 4096
+
+/**
+ * @brief Additional option for usbg_rm_* functions.
+ * @details This option allows to remove all content
+ * of gadget/config/function recursively.
+ */
+#define USBG_RM_RECURSE 1
/*
* Internal structures
@@ -51,6 +68,7 @@ struct usbg_gadget;
struct usbg_config;
struct usbg_function;
struct usbg_binding;
+struct usbg_udc;
/**
* @brief State of the gadget devices in the system
@@ -78,6 +96,29 @@ typedef struct usbg_function usbg_function;
typedef struct usbg_binding usbg_binding;
/**
+ * @brief USB device controller
+ */
+typedef struct usbg_udc usbg_udc;
+
+/**
+ * @typedef usbg_gadget_attr
+ * @brief Gadget attributes which can be set using
+ * usbg_set_gadget_attr() function.
+ */
+typedef enum {
+ USBG_GADGET_ATTR_MIN = 0,
+ BCD_USB = USBG_GADGET_ATTR_MIN,
+ B_DEVICE_CLASS,
+ B_DEVICE_SUB_CLASS,
+ B_DEVICE_PROTOCOL,
+ B_MAX_PACKET_SIZE_0,
+ ID_VENDOR,
+ ID_PRODUCT,
+ BCD_DEVICE,
+ USBG_GADGET_ATTR_MAX,
+} usbg_gadget_attr;
+
+/**
* @typedef usbg_gadget_attrs
* @brief USB gadget device attributes
*/
@@ -93,6 +134,14 @@ typedef struct
uint16_t bcdDevice;
} usbg_gadget_attrs;
+typedef enum {
+ USBG_GADGET_STR_MIN = 0,
+ STR_PRODUCT = USBG_GADGET_STR_MIN,
+ STR_MANUFACTURER,
+ STR_SERIAL_NUMBER,
+ USBG_GADGET_STR_MAX,
+} usbg_gadget_str;
+
/**
* @typedef usbg_gadget_strs
* @brief USB gadget device strings
@@ -129,7 +178,8 @@ typedef struct
*/
typedef enum
{
- F_SERIAL,
+ USBG_FUNCTION_TYPE_MIN = 0,
+ F_SERIAL = USBG_FUNCTION_TYPE_MIN,
F_ACM,
F_OBEX,
F_ECM,
@@ -138,6 +188,11 @@ typedef enum
F_EEM,
F_RNDIS,
F_PHONET,
+ F_FFS,
+ F_MASS_STORAGE,
+ F_MIDI,
+ F_LOOPBACK,
+ USBG_FUNCTION_TYPE_MAX,
} usbg_function_type;
/**
@@ -155,7 +210,7 @@ typedef struct {
typedef struct {
struct ether_addr dev_addr;
struct ether_addr host_addr;
- char ifname[USBG_MAX_STR_LENGTH];
+ const char *ifname;
int qmult;
} usbg_f_net_attrs;
@@ -164,10 +219,66 @@ typedef struct {
* @brief Attributes for the phonet USB function
*/
typedef struct {
- char ifname[USBG_MAX_STR_LENGTH];
+ const char *ifname;
} usbg_f_phonet_attrs;
/**
+ * @typedef usbg_f_ffs_attrs
+ * @brief Attributes for function fs based functions
+ * @details This is read only and a virtual attribute, it is non present
+ * on config fs.
+ */
+typedef struct {
+ const char *dev_name;
+} usbg_f_ffs_attrs;
+
+/**
+ * @typedef usbg_f_ms_attrs
+ * @brief Attributes for mass storage functions
+ */
+typedef struct usbg_f_ms_lun_attrs {
+ int id;
+ bool cdrom;
+ bool ro;
+ bool nofua;
+ bool removable;
+ const char *filename;
+} usbg_f_ms_lun_attrs;
+
+/**
+ * @typedef usbg_f_ms_attrs
+ * @brief Attributes for mass storage functions
+ */
+typedef struct {
+ bool stall;
+ int nluns;
+ usbg_f_ms_lun_attrs **luns;
+} usbg_f_ms_attrs;
+
+/**
+ * @typedef usbg_f_midi_attrs
+ * @brief Attributes for the MIDI function
+ */
+typedef struct {
+ int index;
+ const char *id;
+ unsigned int in_ports;
+ unsigned int out_ports;
+ unsigned int buflen;
+ unsigned int qlen;
+} usbg_f_midi_attrs;
+
+
+/**
+ * @typedef usbg_f_loopback_attrs
+ * @brief Attributes for Loopback function
+ */
+typedef struct {
+ unsigned int buflen;
+ unsigned int qlen;
+} usbg_f_loopback_attrs;
+
+/**
* @typedef attrs
* @brief Attributes for a given function type
*/
@@ -175,6 +286,29 @@ typedef union {
usbg_f_serial_attrs serial;
usbg_f_net_attrs net;
usbg_f_phonet_attrs phonet;
+ usbg_f_ffs_attrs ffs;
+ usbg_f_ms_attrs ms;
+ usbg_f_midi_attrs midi;
+ usbg_f_loopback_attrs loopback;
+} usbg_f_attrs;
+
+typedef enum {
+ USBG_F_ATTRS_SERIAL = 1,
+ USBG_F_ATTRS_NET,
+ USBG_F_ATTRS_PHONET,
+ USBG_F_ATTRS_FFS,
+ USBG_F_ATTRS_MS,
+ USBG_F_ATTRS_MIDI,
+ USBG_F_ATTRS_LOOPBACK,
+} usbg_f_attrs_type;
+
+typedef struct {
+ int attrs_type;
+} usbg_f_attrs_header;
+
+typedef struct {
+ usbg_f_attrs_header header;
+ usbg_f_attrs attrs;
} usbg_function_attrs;
/* Error codes */
@@ -195,17 +329,22 @@ typedef enum {
USBG_ERROR_BUSY = -8,
USBG_ERROR_NOT_SUPPORTED = -9,
USBG_ERROR_PATH_TOO_LONG = -10,
+ USBG_ERROR_INVALID_FORMAT = -11,
+ USBG_ERROR_MISSING_TAG = -12,
+ USBG_ERROR_INVALID_TYPE = -13,
+ USBG_ERROR_INVALID_VALUE = -14,
+ USBG_ERROR_NOT_EMPTY = -15,
USBG_ERROR_OTHER_ERROR = -99
} usbg_error;
-/*
+/**
* @brief Get the error name as a constant string
* @param e error code
* @return Constant string with error name
*/
extern const char *usbg_error_name(usbg_error e);
-/*
+/**
* @brief Get the short description of error
* @param e error code
* @return Constant string with error description
@@ -215,20 +354,30 @@ extern const char *usbg_strerror(usbg_error e);
/* Library init and cleanup */
/**
- * @brief Initialize the libusbg library state
+ * @brief Initialize the libusbgx library state
* @param configfs_path Path to the mounted configfs filesystem
- * @param Pointer to be filled with pointer to usbg_state
+ * @param state Pointer to be filled with pointer to usbg_state
* @return 0 on success, usbg_error on error
*/
-extern int usbg_init(char *configfs_path, usbg_state **state);
+extern int usbg_init(const char *configfs_path, usbg_state **state);
/**
- * @brief Clean up the libusbg library state
+ * @brief Clean up the libusbgx library state
* @param s Pointer to state
*/
extern void usbg_cleanup(usbg_state *s);
/**
+ * @brief Get ConfigFS path
+ * @param s Pointer to state
+ * @return Path to configfs or NULL if error occurred
+ * @warning Returned buffer should not be edited!
+ * Returned string is valid as long as passed usbg_state is valid.
+ * For example path is valid until usbg_cleanup() call.
+ */
+extern const char *usbg_get_configfs_path(usbg_state *s);
+
+/**
* @brief Get ConfigFS path length
* @param s Pointer to state
* @return Length of path or usbg_error if error occurred.
@@ -236,13 +385,13 @@ extern void usbg_cleanup(usbg_state *s);
extern size_t usbg_get_configfs_path_len(usbg_state *s);
/**
- * @brieg Get ConfigFS path
+ * @brief Copy ConfigFS path to buffer
* @param s Pointer to state
* @param buf Buffer where path should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_get_configfs_path(usbg_state *s, char *buf, size_t len);
+extern int usbg_cpy_configfs_path(usbg_state *s, char *buf, size_t len);
/* USB gadget queries */
@@ -276,6 +425,67 @@ extern usbg_function *usbg_get_function(usbg_gadget *g,
*/
extern usbg_config *usbg_get_config(usbg_gadget *g, int id, const char *label);
+/**
+ * @brief Get a udc by name
+ * @param s Pointer to state
+ * @param name Name of the udc
+ * @return Pointer to udc or NULL if a matching udc isn't found
+ */
+extern usbg_udc *usbg_get_udc(usbg_state *s, const char *name);
+
+/* USB gadget/config/function/binding removal */
+
+/**
+ * @brief Remove binding between configuration and function
+ * @details This function frees also the memory allocated for binding
+ * @param b Binding to be removed
+ * @return 0 on success, usbg_error if error occurred
+ */
+extern int usbg_rm_binding(usbg_binding *b);
+
+/**
+ * @brief Remove configuration
+ * @details This function frees also the memory allocated for configuration
+ * @param c Configuration to be removed
+ * @param opts Additional options for configuration removal.
+ * @return 0 on success, usbg_error if error occurred
+ */
+extern int usbg_rm_config(usbg_config *c, int opts);
+
+/**
+ * @brief Remove existing USB function
+ * @details This function frees also the memory allocated for function
+ * @param f Function to be removed
+ * @param opts Additional options for configuration removal.
+ * @return 0 on success, usbg_error if error occurred
+ */
+extern int usbg_rm_function(usbg_function *f, int opts);
+
+/**
+ * @brief Remove existing USB gadget
+ * @details This function frees also the memory allocated for gadget
+ * @param g Gadget to be removed
+ * @param opts Additional options for configuration removal.
+ * @return 0 on success, usbg_error if error occurred
+ */
+extern int usbg_rm_gadget(usbg_gadget *g, int opts);
+
+/**
+ * @brief Remove configuration strings for given language
+ * @param c Pointer to configuration
+ * @param lang Language of strings which should be deleted
+ * @return 0 on success, usbg_error if error occurred
+ */
+extern int usbg_rm_config_strs(usbg_config *c, int lang);
+
+/**
+ * @brief Remove gadget strings for given language
+ * @param g Pointer to gadget
+ * @param lang Language of strings which should be deleted
+ * @return 0 on success, usbg_error if error occurred
+ */
+extern int usbg_rm_gadget_strs(usbg_gadget *g, int lang);
+
/* USB gadget allocation and configuration */
/**
@@ -287,7 +497,7 @@ extern usbg_config *usbg_get_config(usbg_gadget *g, int id, const char *label);
* @param g Pointer to be filled with pointer to gadget
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_create_gadget_vid_pid(usbg_state *s, char *name,
+extern int usbg_create_gadget_vid_pid(usbg_state *s, const char *name,
uint16_t idVendor, uint16_t idProduct, usbg_gadget **g);
/**
@@ -301,8 +511,60 @@ extern int usbg_create_gadget_vid_pid(usbg_state *s, char *name,
* @note Given strings are assumed to be in US English
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_create_gadget(usbg_state *s, char *name,
- usbg_gadget_attrs *g_attrs, usbg_gadget_strs *g_strs, usbg_gadget **g);
+extern int usbg_create_gadget(usbg_state *s, const char *name,
+ const usbg_gadget_attrs *g_attrs, const usbg_gadget_strs *g_strs,
+ usbg_gadget **g);
+
+/**
+ * @brief Get string representing selected gadget attribute
+ * @param attr code of selected attribute
+ * @return String suitable for given attribute or NULL if such
+ * string has not been found
+ */
+extern const char *usbg_get_gadget_attr_str(usbg_gadget_attr attr);
+
+/**
+ * @brief Lookup attr code based on its name
+ * @param name of attribute
+ * @return code of suitable attribute or usbg_error
+ */
+extern int usbg_lookup_gadget_attr(const char *name);
+
+/**
+ * @brief Lookup str code based on its name
+ * @param name of string
+ * @return code of suitable string or usbg_error
+ */
+extern int usbg_lookup_gadget_str(const char *name);
+
+/**
+ * @brief Get name of selected gadget string
+ * @param str Gadget string code
+ * @return Name of string associated with this code
+ */
+extern const char *usbg_get_gadget_str_name(usbg_gadget_str str);
+
+/**
+ * @brief Set selected attribute to value
+ * @param g Pointer to gadget
+ * @param attr Code of selected attribute
+ * @param val value to be set
+ * @return 0 on success, usbg_error otherwise
+ * @note val is of type int but value provided to this function should
+ * be suitable to place it in type dedicated for selected attr (uint16 or uint8)
+ */
+extern int usbg_set_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr, int val);
+
+/**
+ * @brief Get value of selected attribute
+ * @param g Pointer to gadget
+ * @param attr Code of selected attribute
+ * @return Value of selected attribute (always above zero) or
+ * usbg_error if error occurred.
+ * @note User should use only lowest one or two bytes as attribute value
+ * depending on attribute size (see usbg_gadget_attrs for details).
+ */
+extern int usbg_get_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr);
/**
* @brief Set the USB gadget attributes
@@ -311,7 +573,7 @@ extern int usbg_create_gadget(usbg_state *s, char *name,
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_set_gadget_attrs(usbg_gadget *g,
- usbg_gadget_attrs *g_attrs);
+ const usbg_gadget_attrs *g_attrs);
/**
* @brief Get the USB gadget strings
@@ -322,6 +584,16 @@ extern int usbg_set_gadget_attrs(usbg_gadget *g,
extern int usbg_get_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs);
/**
+ * @brief Get gadget name
+ * @param g Pointer to gadget
+ * @return Gadget name or NULL if error occurred.
+ * @warning Returned buffer should not be edited!
+ * Returned string is valid as long as passed usbg_gadget is valid.
+ * For example gadget name is valid until someone remove gadget.
+ */
+extern const char *usbg_get_gadget_name(usbg_gadget *g);
+
+/**
* @brief Get gadget name length
* @param g Gadget which name length should be returned
* @return Length of name string or usbg_error if error occurred.
@@ -329,13 +601,13 @@ extern int usbg_get_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs);
extern size_t usbg_get_gadget_name_len(usbg_gadget *g);
/**
- * @brieg Get gadget name
- * @param b Pointer to gadget
+ * @brief Copy gadget name
+ * @param g Pointer to gadget
* @param buf Buffer where name should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_get_gadget_name(usbg_gadget *g, char *buf, size_t len);
+extern int usbg_cpy_gadget_name(usbg_gadget *g, char *buf, size_t len);
/**
* @brief Set the USB gadget vendor id
@@ -410,21 +682,31 @@ extern int usbg_set_gadget_device_bcd_usb(usbg_gadget *g, uint16_t bcdUSB);
* @brief Get the USB gadget strings
* @param g Pointer to gadget
* @param lang Language of strings
- * @param g_sttrs Structure to be filled
+ * @param g_strs Structure to be filled
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_get_gadget_strs(usbg_gadget *g, int lang,
usbg_gadget_strs *g_strs);
/**
+ * @brief Set selected string
+ * @param g Pointer to gadget
+ * @param str Code of selected string
+ * @param val value to be set
+ * @return 0 on success, usbg_error otherwise
+ */
+extern int usbg_set_gadget_str(usbg_gadget *g, usbg_gadget_str str, int lang,
+ const char *val);
+
+/**
* @brief Set the USB gadget strings
* @param g Pointer to gadget
* @param lang USB language ID
- * @param g_sttrs Gadget attributes
+ * @param g_strs Gadget attributes
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_set_gadget_strs(usbg_gadget *g, int lang,
- usbg_gadget_strs *g_strs);
+ const usbg_gadget_strs *g_strs);
/**
* @brief Set the serial number for a gadget
@@ -433,7 +715,8 @@ extern int usbg_set_gadget_strs(usbg_gadget *g, int lang,
* @param ser Serial number
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_set_gadget_serial_number(usbg_gadget *g, int lang, char *ser);
+extern int usbg_set_gadget_serial_number(usbg_gadget *g, int lang,
+ const char *ser);
/**
* @brief Set the manufacturer name for a gadget
@@ -442,7 +725,8 @@ extern int usbg_set_gadget_serial_number(usbg_gadget *g, int lang, char *ser);
* @param mnf Manufacturer
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang, char *mnf);
+extern int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang,
+ const char *mnf);
/**
* @brief Set the product name for a gadget
@@ -451,7 +735,8 @@ extern int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang, char *mnf);
* @param prd Product
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd);
+extern int usbg_set_gadget_product(usbg_gadget *g, int lang,
+ const char *prd);
/* USB function allocation and configuration */
@@ -466,7 +751,18 @@ extern int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd);
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_create_function(usbg_gadget *g, usbg_function_type type,
- char *instance, usbg_function_attrs *f_attrs, usbg_function **f);
+ const char *instance, const usbg_function_attrs *f_attrs,
+ usbg_function **f);
+
+/**
+ * @brief Get function instance name
+ * @param f Pointer to function
+ * @return instance name or NULL if error occurred.
+ * @warning Returned buffer should not be edited!
+ * Returned string is valid as long as passed usbg_function is valid.
+ * For example instance name is valid until someone remove this function.
+ */
+extern const char *usbg_get_function_instance(usbg_function *f);
/**
* @brief Get function instance name length
@@ -476,13 +772,13 @@ extern int usbg_create_function(usbg_gadget *g, usbg_function_type type,
extern size_t usbg_get_function_instance_len(usbg_function *f);
/**
- * @brief Get function instance name
+ * @brief Copy function instance name
* @param f Pointer to function
* @param buf Buffer where instance name should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_get_function_instance(usbg_function *f, char *buf, size_t len);
+extern int usbg_cpy_function_instance(usbg_function *f, char *buf, size_t len);
/**
* @brief Get function type as a string
@@ -491,6 +787,30 @@ extern int usbg_get_function_instance(usbg_function *f, char *buf, size_t len);
*/
extern const char *usbg_get_function_type_str(usbg_function_type type);
+/**
+ * @brief Lookup function type suitable for given name
+ * @param name Name of function
+ * @return Function type enum or negative error code
+ */
+extern int usbg_lookup_function_type(const char *name);
+
+/**
+ * @brief Lookup attrs type for given type of function
+ * @param f_type type of functions
+ * @return Attributes type for this type of function
+ */
+extern int usbg_lookup_function_attrs_type(int f_type);
+
+/**
+ * @brief Cleanup content of function attributes
+ * @param f_attrs function attributes which should be cleaned up.
+ * @note This function should be called to free
+ * additional memory allocated by usbg_get_function_attrs().
+ * @warning None of attributes in passed structure should be
+ * accessed after returning from this function.
+ */
+extern void usbg_cleanup_function_attrs(usbg_function_attrs *f_attrs);
+
/* USB configurations allocation and configuration */
/**
@@ -505,7 +825,18 @@ extern const char *usbg_get_function_type_str(usbg_function_type type);
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_create_config(usbg_gadget *g, int id, const char *label,
- usbg_config_attrs *c_attrs, usbg_config_strs *c_strs, usbg_config **c);
+ const usbg_config_attrs *c_attrs, const usbg_config_strs *c_strs,
+ usbg_config **c);
+
+/**
+ * @brief Get config label
+ * @param c Pointer to config
+ * @return config label or NULL if error occurred.
+ * @warning Returned buffer should not be edited!
+ * Returned string is valid as long as passed usbg_config is valid.
+ * For example config label is valid until someone remove this function.
+ */
+extern const char *usbg_get_config_label(usbg_config *c);
/**
* @brief Get config label length
@@ -515,16 +846,16 @@ extern int usbg_create_config(usbg_gadget *g, int id, const char *label,
extern size_t usbg_get_config_label_len(usbg_config *c);
/**
- * @brieg Get config label
+ * @brief Copy config label
* @param c Pointer to config
* @param buf Buffer where label should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_get_config_label(usbg_config *c, char *buf, size_t len);
+extern int usbg_cpy_config_label(usbg_config *c, char *buf, size_t len);
/**
- * @brieg Get config id
+ * @brief Get config id
* @param c Pointer to config
* @return Configuration id or usbg_error if error occurred.
*/
@@ -537,7 +868,7 @@ extern int usbg_get_config_id(usbg_config *c);
* @return 0 on success or usbg_error if error occurred.
*/
extern int usbg_set_config_attrs(usbg_config *c,
- usbg_config_attrs *c_attrs);
+ const usbg_config_attrs *c_attrs);
/**
* @brief Get the USB configuration strings
@@ -567,7 +898,7 @@ extern int usbg_set_config_bm_attrs(usbg_config *c, int bmAttributes);
* @brief Get the USB configuration strings
* @param c Pointer to configuration
* @param lang Language of strings
- * @param c_sttrs Structure to be filled
+ * @param c_strs Structure to be filled
* @return 0 on success or usbg_error if error occurred.
*/
extern int usbg_get_config_strs(usbg_config *c, int lang,
@@ -577,11 +908,11 @@ extern int usbg_get_config_strs(usbg_config *c, int lang,
* @brief Set the USB configuration strings
* @param c Pointer to configuration
* @param lang USB language ID
- * @param c_sttrs Configuration strings
+ * @param c_strs Configuration strings
* @return 0 on success, usbg_error on failure.
*/
extern int usbg_set_config_strs(usbg_config *c, int lang,
- usbg_config_strs *c_strs);
+ const usbg_config_strs *c_strs);
/**
* @brief Set the configuration string
@@ -590,7 +921,7 @@ extern int usbg_set_config_strs(usbg_config *c, int lang,
* @param string Configuration description
* @return 0 on success, usbg_error on failure.
*/
-extern int usbg_set_config_string(usbg_config *c, int lang, char *string);
+extern int usbg_set_config_string(usbg_config *c, int lang, const char *string);
/**
* @brief Add a function to a configuration
@@ -599,7 +930,8 @@ extern int usbg_set_config_string(usbg_config *c, int lang, char *string);
* @param f Pointer to function
* @return 0 on success, usbg_error on failure.
*/
-extern int usbg_add_config_function(usbg_config *c, char *name, usbg_function *f);
+extern int usbg_add_config_function(usbg_config *c, const char *name,
+ usbg_function *f);
/**
* @brief Get target function of given binding
@@ -609,6 +941,16 @@ extern int usbg_add_config_function(usbg_config *c, char *name, usbg_function *f
extern usbg_function *usbg_get_binding_target(usbg_binding *b);
/**
+ * @brief Get binding name
+ * @param b Pointer to binding
+ * @return Binding name or NULL if error occurred.
+ * @warning Returned buffer should not be edited!
+ * Returned string is valid as long as passed usbg_binding is valid.
+ * For example binding name is valid until someone remove this binding.
+ */
+extern const char *usbg_get_binding_name(usbg_binding *b);
+
+/**
* @brief Get binding name length
* @param b Binding which name length should be returned
* @return Length of name string or usbg_error if error occurred.
@@ -616,30 +958,24 @@ extern usbg_function *usbg_get_binding_target(usbg_binding *b);
extern size_t usbg_get_binding_name_len(usbg_binding *b);
/**
- * @brief Get binding name
+ * @brief Copy binding name
* @param b Pointer to binding
* @param buf Buffer where name should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_get_binding_name(usbg_binding *b, char *buf, size_t len);
+extern int usbg_cpy_binding_name(usbg_binding *b, char *buf, size_t len);
/* USB gadget setup and teardown */
/**
- * @brief Get a list of UDC devices on the system
- * @param udc_list Pointer to pointer to dirent pointer
- * @return Number of UDC devices on success, usbg_error on failure
- */
-extern int usbg_get_udcs(struct dirent ***udc_list);
-
-/**
* @brief Enable a USB gadget device
* @param g Pointer to gadget
- * @param udc Name of UDC to enable gadget
+ * @param udc where gadget should be assigned.
+ * If NULL, default one (first) is used.
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_enable_gadget(usbg_gadget *g, char *udc);
+extern int usbg_enable_gadget(usbg_gadget *g, usbg_udc *udc);
/**
* @brief Disable a USB gadget device
@@ -649,6 +985,16 @@ extern int usbg_enable_gadget(usbg_gadget *g, char *udc);
extern int usbg_disable_gadget(usbg_gadget *g);
/**
+ * @brief Get name of udc
+ * @param u Pointer to udc
+ * @return UDC name or NULL if error occurred.
+ * @warning Returned buffer should not be edited!
+ * Returned string is valid as long as passed usbg_state is valid.
+ * For example UDC name is valid until usbg_cleanup().
+ */
+extern const char *usbg_get_udc_name(usbg_udc *u);
+
+/**
* @brief Get gadget name length
* @param g Gadget which name length should be returned
* @return Length of name string or usbg_error if error occurred.
@@ -657,14 +1003,27 @@ extern int usbg_disable_gadget(usbg_gadget *g);
extern size_t usbg_get_gadget_udc_len(usbg_gadget *g);
/**
- * @brieg Get name of udc to which gadget is binded
- * @param b Pointer to gadget
+ * @brief Copy name of udc
+ * @param u Pointer to udc
* @param buf Buffer where udc name should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
- * @note If gadget isn't enabled on any udc returned string is empty.
*/
-extern int usbg_get_gadget_udc(usbg_gadget *g, char *buf, size_t len);
+extern int usbg_cpy_udc_name(usbg_udc *u, char *buf, size_t len);
+
+/**
+ * @brief Get udc to which gadget is bound
+ * @param g Pointer to gadget
+ * @return Pointer to UDC or NULL if gadget is not enabled
+ */
+extern usbg_udc *usbg_get_gadget_udc(usbg_gadget *g);
+
+/**
+ * @brief Get gadget which is attached to this UDC
+ * @param u Pointer to udc
+ * @return Pointer to gadget or NULL if UDC is free
+ */
+extern usbg_gadget *usbg_get_udc_gadget(usbg_udc *u);
/*
* USB function-specific attribute configuration
@@ -693,7 +1052,8 @@ extern int usbg_get_function_attrs(usbg_function *f,
* @param f_attrs Attributes to be set
* @return 0 on success, usbg_error if error occurred
*/
-extern int usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs);
+extern int usbg_set_function_attrs(usbg_function *f,
+ const usbg_function_attrs *f_attrs);
/**
* @brief Set USB function network device address
@@ -756,6 +1116,15 @@ extern int usbg_set_net_qmult(usbg_function *f, int qmult);
b = usbg_get_next_binding(b))
/**
+ * @def usbg_for_each_udc(b, c)
+ * Iterates over each udc
+ */
+#define usbg_for_each_udc(u, s) \
+ for (u = usbg_get_first_udc(s); \
+ u != NULL; \
+ u = usbg_get_next_udc(u))
+
+/**
* @brief Get first gadget in gadget list
* @param s State of library
* @return Pointer to gadget or NULL if list is empty.
@@ -781,41 +1150,164 @@ extern usbg_config *usbg_get_first_config(usbg_gadget *g);
/**
* @brief Get first binding in binding list
- * @param C Pointer to configuration
+ * @param c Pointer to configuration
* @return Pointer to binding or NULL if list is empty.
* @note Bindings are sorted in strings (name) order
*/
extern usbg_binding *usbg_get_first_binding(usbg_config *c);
/**
+ * @brief Get first udc in udc list
+ * @param s State of library
+ * @return Pointer to udc or NULL if list is empty.
+ * @note UDCs are sorted in strings (name) order
+ */
+extern usbg_udc *usbg_get_first_udc(usbg_state *s);
+
+/**
* @brief Get the next gadget on a list.
- * @pram g Pointer to current gadget
+ * @param g Pointer to current gadget
* @return Next gadget or NULL if end of list.
*/
extern usbg_gadget *usbg_get_next_gadget(usbg_gadget *g);
/**
* @brief Get the next function on a list.
- * @pram g Pointer to current function
+ * @param f Pointer to current function
* @return Next function or NULL if end of list.
*/
extern usbg_function *usbg_get_next_function(usbg_function *f);
/**
* @brief Get the next config on a list.
- * @pram g Pointer to current config
+ * @param c Pointer to current config
* @return Next config or NULL if end of list.
*/
extern usbg_config *usbg_get_next_config(usbg_config *c);
/**
* @brief Get the next binding on a list.
- * @pram g Pointer to current binding
+ * @param b Pointer to current binding
* @return Next binding or NULL if end of list.
*/
extern usbg_binding *usbg_get_next_binding(usbg_binding *b);
/**
+ * @brief Get the next udc on a list.
+ * @param u Pointer to current udc
+ * @return Next udc or NULL if end of list.
+ */
+extern usbg_udc *usbg_get_next_udc(usbg_udc *u);
+
+/* Import / Export API */
+
+/**
+ * @brief Exports usb function to file
+ * @param f Pointer to function to be exported
+ * @param stream where function should be saved
+ * @return 0 on success, usbg_error otherwise
+ */
+extern int usbg_export_function(usbg_function *f, FILE *stream);
+
+/**
+ * @brief Exports configuration to file
+ * @param c Pointer to configuration to be exported
+ * @param stream where configuration should be saved
+ * @return 0 on success, usbg_error otherwise
+ */
+extern int usbg_export_config(usbg_config *c, FILE *stream);
+
+/**
+ * @brief Exports whole gadget to file
+ * @param g Pointer to gadget to be exported
+ * @param stream where gadget should be saved
+ * @return 0 on success, usbg_error otherwise
+ */
+extern int usbg_export_gadget(usbg_gadget *g, FILE *stream);
+
+/**
+ * @brief Imports usb function from file and adds it to given gadget
+ * @param g Gadget where function should be placed
+ * @param stream from which function should be imported
+ * @param instance name which should be used for new function
+ * @param f place for pointer to imported function
+ * if NULL this param will be ignored.
+ * @return 0 on success, usbg_error otherwise
+ */
+extern int usbg_import_function(usbg_gadget *g, FILE *stream,
+ const char *instance, usbg_function **f);
+
+/**
+ * @brief Imports usb configuration from file and adds it to given gadget
+ * @param g Gadget where configuration should be placed
+ * @param stream from which configuration should be imported
+ * @param id which should be used for new configuration
+ * @param c place for pointer to imported configuration
+ * if NULL this param will be ignored.
+ * @return 0 on success, usbg_error otherwise
+ */
+extern int usbg_import_config(usbg_gadget *g, FILE *stream, int id,
+ usbg_config **c);
+/**
+ * @brief Imports usb gadget from file
+ * @param s current state of library
+ * @param stream from which gadget should be imported
+ * @param name which should be used for new gadget
+ * @param g place for pointer to imported gadget
+ * if NULL this param will be ignored.
+ * @return 0 on success, usbg_error otherwise
+ */
+extern int usbg_import_gadget(usbg_state *s, FILE *stream,
+ const char *name, usbg_gadget **g);
+
+/**
+ * @brief Get text of error which occurred during last function import
+ * @param g gadget where function import error occurred
+ * @return Text of error or NULL if no error data
+ */
+extern const char *usbg_get_func_import_error_text(usbg_gadget *g);
+
+/**
+ * @brief Get line number where function import error occurred
+ * @param g gadget where function import error occurred
+ * @return line number or value below 0 if no error data
+ */
+extern int usbg_get_func_import_error_line(usbg_gadget *g);
+
+/**
+ * @brief Get text of error which occurred during last config import
+ * @param g gadget where config import error occurred
+ * @return Text of error or NULL if no error data
+ */
+extern const char *usbg_get_config_import_error_text(usbg_gadget *g);
+
+/**
+ * @brief Get line number where config import error occurred
+ * @param g gadget where config import error occurred
+ * @return line number or value below 0 if no error data
+ */
+extern int usbg_get_config_import_error_line(usbg_gadget *g);
+
+/**
+ * @brief Get text of error which occurred during last gadget import
+ * @param s where gadget import error occurred
+ * @return Text of error or NULL if no error data
+ */
+extern const char *usbg_get_gadget_import_error_text(usbg_state *s);
+
+/**
+ * @brief Get line number where gadget import error occurred
+ * @param s where gadget import error occurred
+ * @return line number or value below 0 if no error data
+ */
+extern int usbg_get_gadget_import_error_line(usbg_state *s);
+
+/**
* @}
*/
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __USBG_H__ */
diff --git a/include/usbg/usbg_internal.h b/include/usbg/usbg_internal.h
new file mode 100644
index 0000000..30d3fcf
--- /dev/null
+++ b/include/usbg/usbg_internal.h
@@ -0,0 +1,174 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ */
+
+#ifndef USBG_INTERNAL_H
+#define USBG_INTERNAL_H
+
+#include <sys/queue.h>
+#include <string.h>
+#include <usbg/usbg.h>
+
+#ifdef HAS_LIBCONFIG
+#include <libconfig.h>
+#else
+ typedef struct _should_not_be_used config_t;
+ void config_destroy(config_t *config);
+#endif
+
+/**
+ * @file include/usbg/usbg_internal.h
+ */
+
+#ifndef offsetof
+#define offsetof(type, member) __builtin_offsetof (type, member)
+#endif /* offsetof */
+
+#ifndef container_of
+#define container_of(ptr, type, field) ({ \
+ const typeof(((type *)0)->field) *member = (ptr); \
+ (type *)( (char *)member - offsetof(type, field) ); \
+ })
+#endif /* container_of */
+
+struct usbg_state
+{
+ char *path;
+ char *configfs_path;
+
+ TAILQ_HEAD(ghead, usbg_gadget) gadgets;
+ TAILQ_HEAD(uhead, usbg_udc) udcs;
+ config_t *last_failed_import;
+};
+
+struct usbg_gadget
+{
+ char *name;
+ char *path;
+
+ TAILQ_ENTRY(usbg_gadget) gnode;
+ TAILQ_HEAD(chead, usbg_config) configs;
+ TAILQ_HEAD(fhead, usbg_function) functions;
+ usbg_state *parent;
+ config_t *last_failed_import;
+ usbg_udc *udc;
+};
+
+struct usbg_config
+{
+ TAILQ_ENTRY(usbg_config) cnode;
+ TAILQ_HEAD(bhead, usbg_binding) bindings;
+ usbg_gadget *parent;
+
+ char *name;
+ char *path;
+ char *label;
+ int id;
+};
+
+typedef int (*usbg_rm_function_callback)(usbg_function *, int);
+
+struct usbg_function
+{
+ TAILQ_ENTRY(usbg_function) fnode;
+ usbg_gadget *parent;
+
+ char *name;
+ char *path;
+ char *instance;
+ /* Only for internal library usage */
+ char *label;
+ usbg_function_type type;
+ usbg_rm_function_callback rm_callback;
+};
+
+struct usbg_binding
+{
+ TAILQ_ENTRY(usbg_binding) bnode;
+ usbg_config *parent;
+ usbg_function *target;
+
+ char *name;
+ char *path;
+};
+
+struct usbg_udc
+{
+ TAILQ_ENTRY(usbg_udc) unode;
+ usbg_state *parent;
+ usbg_gadget *gadget;
+
+ char *name;
+};
+
+#define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
+
+#define ARRAY_SIZE_SENTINEL(array, size) \
+ static void __attribute__ ((unused)) array##_size_sentinel() \
+ { \
+ char array##_smaller_than_expected[ \
+ (int)(ARRAY_SIZE(array) - size)] \
+ __attribute__ ((unused)); \
+ \
+ char array##_larger_than_expected[ \
+ (int)(size - ARRAY_SIZE(array))] \
+ __attribute__ ((unused)); \
+ }
+
+#define ERROR(msg, ...) do {\
+ fprintf(stderr, "%s() "msg" \n", \
+ __func__, ##__VA_ARGS__);\
+ fflush(stderr);\
+ } while (0)
+
+#define ERRORNO(msg, ...) do {\
+ fprintf(stderr, "%s() %s: "msg" \n", \
+ __func__, strerror(errno), ##__VA_ARGS__);\
+ fflush(stderr);\
+ } while (0)
+
+/* Insert in string order */
+#define INSERT_TAILQ_STRING_ORDER(HeadPtr, HeadType, NameField, ToInsert, NodeField) \
+ do { \
+ if (TAILQ_EMPTY((HeadPtr)) || \
+ (strcmp((ToInsert)->NameField, TAILQ_FIRST((HeadPtr))->NameField) < 0)) \
+ TAILQ_INSERT_HEAD((HeadPtr), (ToInsert), NodeField); \
+ else if (strcmp((ToInsert)->NameField, TAILQ_LAST((HeadPtr), HeadType)->NameField) > 0) \
+ TAILQ_INSERT_TAIL((HeadPtr), (ToInsert), NodeField); \
+ else { \
+ typeof(ToInsert) _cur; \
+ TAILQ_FOREACH(_cur, (HeadPtr), NodeField) { \
+ if (strcmp((ToInsert)->NameField, _cur->NameField) > 0) \
+ continue; \
+ TAILQ_INSERT_BEFORE(_cur, (ToInsert), NodeField); \
+ } \
+ } \
+ } while (0)
+
+#define STRINGS_DIR "strings"
+#define CONFIGS_DIR "configs"
+#define FUNCTIONS_DIR "functions"
+#define GADGETS_DIR "usb_gadget"
+
+static inline int file_select(const struct dirent *dent)
+{
+ if ((strcmp(dent->d_name, ".") == 0) || (strcmp(dent->d_name, "..") == 0))
+ return 0;
+ else
+ return 1;
+}
+
+int usbg_translate_error(int error);
+
+char *usbg_ether_ntoa_r(const struct ether_addr *addr, char *buf);
+
+#endif /* USBG_INTERNAL_H */
+