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

Reply via email to