Function settings may be complicated and their configuration
may take a long while. To save time it would be convenient
to allow for storing function settings in a file.

Signed-off-by: Krzysztof Opasiak <k.opas...@samsung.com>
---
 include/usbg/usbg.h |   11 ++++
 src/usbg.c          |  156 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 167 insertions(+)

diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index e123365..99c201c 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -22,6 +22,7 @@
 #include <netinet/ether.h>
 #include <stdint.h>
 #include <limits.h>
+#include <stdio.h> /* For FILE * */
 
 /**
  * @file include/usbg/usbg.h
@@ -895,6 +896,16 @@ extern usbg_config *usbg_get_next_config(usbg_config *c);
  */
 extern usbg_binding *usbg_get_next_binding(usbg_binding *b);
 
+/* 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);
+
 /**
  * @}
  */
diff --git a/src/usbg.c b/src/usbg.c
index 55edd9e..34b7fb6 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -26,6 +26,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <ctype.h>
+#include <libconfig.h>
 
 #define STRINGS_DIR "strings"
 #define CONFIGS_DIR "configs"
@@ -2461,3 +2462,158 @@ usbg_binding *usbg_get_next_binding(usbg_binding *b)
 {
        return b ? TAILQ_NEXT(b, bnode) : NULL;
 }
+
+#define USBG_ATTRS_TAG "attrs"
+#define USBG_TYPE_TAG "type"
+#define USBG_INSTANCE_TAG "instance"
+#define USBG_TAB_WIDTH 4
+
+static int usbg_export_f_net_attrs(usbg_f_net_attrs *attrs,
+                                     config_setting_t *root)
+{
+       config_setting_t *node;
+       char *addr;
+       char addr_buf[USBG_MAX_STR_LENGTH];
+       int cfg_ret;
+       int ret = USBG_ERROR_NO_MEM;
+
+       node = config_setting_add(root, "dev_addr", CONFIG_TYPE_STRING);
+       if (!node)
+               goto out;
+
+       addr = ether_ntoa_r(&attrs->dev_addr, addr_buf);
+       cfg_ret = config_setting_set_string(node, addr);
+       if (cfg_ret != CONFIG_TRUE) {
+               ret = USBG_ERROR_OTHER_ERROR;
+               goto out;
+       }
+
+       node = config_setting_add(root, "host_addr", CONFIG_TYPE_STRING);
+       if (!node)
+               goto out;
+
+       addr = ether_ntoa_r(&attrs->host_addr, addr_buf);
+       cfg_ret = config_setting_set_string(node, addr);
+       if (cfg_ret != CONFIG_TRUE) {
+               ret = USBG_ERROR_OTHER_ERROR;
+               goto out;
+       }
+
+       node = config_setting_add(root, "qmult", CONFIG_TYPE_INT);
+       if (!node)
+               goto out;
+
+       cfg_ret = config_setting_set_int(node, attrs->qmult);
+       ret = cfg_ret == CONFIG_TRUE ? 0 : USBG_ERROR_OTHER_ERROR;
+
+       /* if name is read only so we don't export it */
+out:
+       return ret;
+
+}
+
+static int usbg_export_function_attrs(usbg_function *f, config_setting_t *root)
+{
+       config_setting_t *node;
+       usbg_function_attrs f_attrs;
+       int usbg_ret, cfg_ret;
+       int ret = USBG_ERROR_NO_MEM;
+
+       usbg_ret = usbg_get_function_attrs(f, &f_attrs);
+       if (usbg_ret) {
+               ret = usbg_ret;
+               goto out;
+       }
+
+       switch (f->type) {
+       case F_SERIAL:
+       case F_ACM:
+       case F_OBEX:
+               node = config_setting_add(root, "port_num", CONFIG_TYPE_INT);
+               if (!node)
+                       goto out;
+
+               cfg_ret = config_setting_set_int(node, f_attrs.serial.port_num);
+               ret = cfg_ret == CONFIG_TRUE ? 0 : USBG_ERROR_OTHER_ERROR;
+               break;
+       case F_ECM:
+       case F_SUBSET:
+       case F_NCM:
+       case F_EEM:
+       case F_RNDIS:
+               ret = usbg_export_f_net_attrs(&f_attrs.net, root);
+               break;
+       case F_PHONET:
+               /* Don't export ifname because it is read only */
+               break;
+       case F_FFS:
+               /* We don't need to export ffs attributes
+                * due to instance name export */
+               ret = USBG_SUCCESS;
+               break;
+       default:
+               ERROR("Unsupported function type\n");
+               ret = USBG_ERROR_NOT_SUPPORTED;
+       }
+
+out:
+       return ret;
+}
+
+/* This function does not import instance name becuase this is more property
+ * of a gadget than a function itselt */
+static int usbg_export_function_prep(usbg_function *f, config_setting_t *root)
+{
+       config_setting_t *node;
+       int ret = USBG_ERROR_NO_MEM;
+       int cfg_ret;
+
+       node = config_setting_add(root, USBG_TYPE_TAG, CONFIG_TYPE_STRING);
+       if (!node)
+               goto out;
+
+       cfg_ret = config_setting_set_string(node, usbg_get_function_type_str(
+                                                   f->type));
+       if (cfg_ret != CONFIG_TRUE) {
+               ret = USBG_ERROR_OTHER_ERROR;
+               goto out;
+       }
+
+       node = config_setting_add(root, USBG_ATTRS_TAG, CONFIG_TYPE_GROUP);
+       if (!node)
+               goto out;
+
+       ret = usbg_export_function_attrs(f, node);
+out:
+       return ret;
+}
+
+
+/* Export gadget/function/config API implementation */
+int usbg_export_function(usbg_function *f, FILE *stream)
+{
+       config_t cfg;
+       config_setting_t *root;
+       int ret;
+
+       if (!f || !stream)
+               return USBG_ERROR_INVALID_PARAM;
+
+       config_init(&cfg);
+
+       /* Set format */
+       config_set_tab_width(&cfg, USBG_TAB_WIDTH);
+
+       /* Allways successful */
+       root = config_root_setting(&cfg);
+
+       ret = usbg_export_function_prep(f, root);
+       if (ret != USBG_SUCCESS)
+               goto out;
+
+       config_write(&cfg, stream);
+out:
+       config_destroy(&cfg);
+       return 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