summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2017-01-24 14:22:19 -0800
committerKrzysztof Opasiak <k.opasiak@samsung.com>2017-12-12 14:06:36 +0100
commit0bc519f2f27703689c7436ce86b506c3cbd02463 (patch)
tree57ec447f86b41f0ad22bf7f7f36470e92e0a1531
parentabf422bffca4a4767e7e242c44910dbf5ef7094f (diff)
downloadlibusbg-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.h45
-rw-r--r--src/usbg.c64
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 */
/**
diff --git a/src/usbg.c b/src/usbg.c
index 1c93f7b..090aea2 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -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,