Having specialized functions for each attribute may be sometime inconvenient to use. Provide also function whihc allows to set attribute selected by parameter.
Signed-off-by: Krzysztof Opasiak <k.opas...@samsung.com> --- include/usbg/usbg.h | 53 +++++++++++++++++++++++++++++++++++++ src/usbg.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h index 3f5d561..2c191eb 100644 --- a/include/usbg/usbg.h +++ b/include/usbg/usbg.h @@ -88,6 +88,22 @@ typedef struct usbg_function usbg_function; typedef struct usbg_binding usbg_binding; /** + * @typedef usbg_gadget_attr + * @brief Gadget attributes which can be set using + * usbg_set_gadget_attr() function. + */ +typedef enum { + BCD_USB = 0, + B_DEVICE_CLASS, + B_DEVICE_SUB_CLASS, + B_DEVICE_PROTOCOL, + B_MAX_PACKET_SIZE_0, + ID_VENDOR, + ID_PRODUCT, + BCD_DEVICE, +} usbg_gadget_attr; + +/** * @typedef usbg_gadget_attrs * @brief USB gadget device attributes */ @@ -395,6 +411,43 @@ extern int usbg_create_gadget(usbg_state *s, const char *name, usbg_gadget **g); /** + * @brief Get string representing selected gadget attribute + * @param attr code of selected attrobute + * @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 + */ +int usbg_lookup_gadget_attr(const char *name); + +/** + * @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 * @param g Pointer to gadget * @param g_attrs Gadget attributes diff --git a/src/usbg.c b/src/usbg.c index bd63790..cd2179e 100644 --- a/src/usbg.c +++ b/src/usbg.c @@ -111,6 +111,18 @@ const char *function_names[] = "ffs", }; +const char *gadget_attr_names[] = +{ + "bcdUSB", + "bDeviceClass", + "bDeviceSubClass", + "bDeviceProtocol", + "bMaxPacketSize0", + "idVendor", + "idProduct", + "bcdDevice" +}; + #define ERROR(msg, ...) do {\ fprintf(stderr, "%s() "msg" \n", \ __func__, ##__VA_ARGS__);\ @@ -158,6 +170,7 @@ static int usbg_translate_error(int error) case ENOTDIR: ret = USBG_ERROR_NOT_FOUND; break; + case ERANGE: case EINVAL: case USBG_ERROR_INVALID_PARAM: ret = USBG_ERROR_INVALID_PARAM; @@ -323,6 +336,29 @@ const const char *usbg_get_function_type_str(usbg_function_type type) function_names[type] : NULL; } +int usbg_lookup_gadget_attr(const char *name) +{ + int i = 0; + int max = sizeof(gadget_attr_names)/sizeof(char *); + + if (!name) + return USBG_ERROR_INVALID_PARAM; + + do { + if (!strcmp(name, gadget_attr_names[i])) + return i; + i++; + } while (i != max); + + return USBG_ERROR_NOT_FOUND; +} + +const const char *usbg_get_gadget_attr_str(usbg_gadget_attr attr) +{ + return attr >= 0 && attr < sizeof(gadget_attr_names)/sizeof(char *) ? + gadget_attr_names[attr] : NULL; +} + static usbg_error usbg_split_function_instance_type(const char *full_name, usbg_function_type *f_type, const char **instance) { @@ -519,6 +555,7 @@ static int usbg_write_int(const char *path, const char *name, const char *file, } #define usbg_write_dec(p, n, f, v) usbg_write_int(p, n, f, v, "%d\n") +#define usbg_write_hex(p, n, f, v) usbg_write_int(p, n, f, v, "0x%x\n") #define usbg_write_hex16(p, n, f, v) usbg_write_int(p, n, f, v, "0x%04x\n") #define usbg_write_hex8(p, n, f, v) usbg_write_int(p, n, f, v, "0x%02x\n") @@ -1746,6 +1783,42 @@ int usbg_get_gadget_udc(usbg_gadget *g, char *buf, size_t len) return USBG_SUCCESS; } +int usbg_set_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr, int val) +{ + const char *attr_name; + int ret = USBG_ERROR_INVALID_PARAM; + + if (!g) + goto out; + + attr_name = usbg_get_gadget_attr_str(attr); + if (!attr_name) + goto out; + + ret = usbg_write_hex(g->path, g->name, attr_name, val); + +out: + return ret; +} + +int usbg_get_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr) +{ + const char *attr_name; + int ret = USBG_ERROR_INVALID_PARAM; + + if (!g) + goto out; + + attr_name = usbg_get_gadget_attr_str(attr); + if (!attr_name) + goto out; + + usbg_read_hex(g->path, g->name, attr_name, &ret); + +out: + return ret; +} + int usbg_set_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs) { int ret; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html