diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2017-01-24 14:22:19 -0800 |
---|---|---|
committer | Krzysztof Opasiak <k.opasiak@samsung.com> | 2017-12-12 14:06:36 +0100 |
commit | 0bc519f2f27703689c7436ce86b506c3cbd02463 (patch) | |
tree | 57ec447f86b41f0ad22bf7f7f36470e92e0a1531 | |
parent | abf422bffca4a4767e7e242c44910dbf5ef7094f (diff) | |
download | libusbg-0bc519f2f27703689c7436ce86b506c3cbd02463.tar.gz libusbg-0bc519f2f27703689c7436ce86b506c3cbd02463.tar.bz2 libusbg-0bc519f2f27703689c7436ce86b506c3cbd02463.zip |
libusbgx: Add function level OS Descriptor support
This adds support for OS Descriptors available on function level,
called "Feature Descriptors".
Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
[Fix mem leak in error path, allow multiple ifaces per funciton]
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
-rw-r--r-- | include/usbg/usbg.h | 45 | ||||
-rw-r--r-- | src/usbg.c | 64 |
2 files changed, 109 insertions, 0 deletions
diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h index e5de7af..4b67f4e 100644 --- a/include/usbg/usbg.h +++ b/include/usbg/usbg.h @@ -216,6 +216,15 @@ typedef enum USBG_FUNCTION_TYPE_MAX, } usbg_function_type; +/** + * @brief USB OS Descriptor function attributes + */ +struct usbg_function_os_desc +{ + char *compatible_id; + char *sub_compatible_id; +}; + /* Error codes */ /** @@ -790,6 +799,42 @@ extern int usbg_get_function_attrs(usbg_function *f, void *f_attrs); */ extern int usbg_set_function_attrs(usbg_function *f, void *f_attrs); +/** + * @brief Get OS Descriptor compatibility of given function + * @param f Pointer to function + * @param iname Interface name + * @param f_os_desc OS Descriptor compatibility to be filled + * @return 0 on success, usbg_error if error occurred + */ +extern int usbg_get_interf_os_desc(usbg_function *f, const char *iname, + struct usbg_function_os_desc *f_os_desc); + +/** + * @brief Free OS Descriptor function attributes + * @details This function releases the memory allocated for function + * atrributes for struct usbg_function_os_desc. + * @param f_os_desc OS Descriptor function attributes to be released + */ +static inline void usbg_free_interf_os_desc( + struct usbg_function_os_desc *f_os_desc) +{ + if (!f_os_desc) + return; + + free(f_os_desc->compatible_id); + free(f_os_desc->sub_compatible_id); +} + +/** + * @brief Set OS Descriptor compatibility of given function + * @param f Pointer to function + * @param iname Interface name + * @param f_os_desc OS Descriptor compatibility to be set + * @return 0 on success, usbg_error if error occurred + */ +extern int usbg_set_interf_os_desc(usbg_function *f, const char *iname, + const struct usbg_function_os_desc *f_os_desc); + /* USB configurations allocation and configuration */ /** @@ -2009,6 +2009,70 @@ out: return ret; } +int usbg_get_interf_os_desc(usbg_function *f, const char *iname, + struct usbg_function_os_desc *f_os_desc) +{ + int ret = USBG_ERROR_NOT_SUPPORTED; + int nmb; + char spath[USBG_MAX_PATH_LENGTH]; + + if (!iname) + return ret; + + nmb = snprintf(spath, sizeof(spath), "%s/%s/%s/interface.%s", f->path, + f->name, OS_DESC_DIR, iname); + if (nmb >= sizeof(spath)) { + ret = USBG_ERROR_PATH_TOO_LONG; + goto out; + } + + ret = usbg_read_string_alloc(spath, "", "compatible_id", + &f_os_desc->compatible_id); + if (ret < 0) + goto out; + + ret = usbg_read_string_alloc(spath, "", "sub_compatible_id", + &f_os_desc->sub_compatible_id); + if (ret < 0) + goto free_compatible; + + return ret; + +free_compatible: + free(f_os_desc->compatible_id); +out: + return ret; +} + +int usbg_set_interf_os_desc(usbg_function *f, const char *iname, + const struct usbg_function_os_desc *f_os_desc) +{ + int ret = USBG_ERROR_NOT_SUPPORTED; + int nmb; + char spath[USBG_MAX_PATH_LENGTH]; + + if (!iname) + return ret; + + nmb = snprintf(spath, sizeof(spath), "%s/%s/%s/interface.%s", f->path, + f->name, OS_DESC_DIR, iname); + if (nmb >= sizeof(spath)) { + ret = USBG_ERROR_PATH_TOO_LONG; + goto out; + } + + ret = usbg_write_string(spath, "", "compatible_id", + f_os_desc->compatible_id); + if (ret < 0) + return ret; + + ret = usbg_write_string(spath, "", "sub_compatible_id", + f_os_desc->sub_compatible_id); + +out: + return ret; +} + int usbg_create_config(usbg_gadget *g, int id, const char *label, const struct usbg_config_attrs *c_attrs, const struct usbg_config_strs *c_strs, |