diff options
author | taeyoung <ty317.kim@samsung.com> | 2016-09-23 19:09:36 +0900 |
---|---|---|
committer | taeyoung <ty317.kim@samsung.com> | 2016-09-23 19:10:56 +0900 |
commit | 1521b31edc929f9b2d2551d2548765fa953f357d (patch) | |
tree | 2edbc50a8a91662cd022f9b5c5d0693f6a8b4071 /include | |
parent | a826d136e0e8fa53815f1ba05893e6dd74208c15 (diff) | |
download | libusbg-1521b31edc929f9b2d2551d2548765fa953f357d.tar.gz libusbg-1521b31edc929f9b2d2551d2548765fa953f357d.tar.bz2 libusbg-1521b31edc929f9b2d2551d2548765fa953f357d.zip |
Imported Upstream version 0.0.1
Change-Id: I3ef3d374cc9e58ac062a426b9113a2f90d46e60f
Diffstat (limited to 'include')
-rw-r--r-- | include/usbg/usbg.h | 612 | ||||
-rw-r--r-- | include/usbg/usbg_internal.h | 174 |
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 */ + |