[PATCH 4/5] libusbg: Replace usage of function name with type and instance.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



User of library should not use directly function name but
only type of the function and name of instance. Using this
will separate user for naming convention on Config FS.

Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx>
---
 examples/show-gadgets.c |   20 ++--
 include/usbg/usbg.h     |   29 ++++--
 src/usbg.c              |  239 ++++++++++++++++++++++++++++++-----------------
 3 files changed, 184 insertions(+), 104 deletions(-)

diff --git a/examples/show-gadgets.c b/examples/show-gadgets.c
index df86cb9..971beb4 100644
--- a/examples/show-gadgets.c
+++ b/examples/show-gadgets.c
@@ -70,11 +70,13 @@ void show_gadget(usbg_gadget *g)
 
 void show_function(usbg_function *f)
 {
-	char buf[USBG_MAX_STR_LENGTH];
+	char instance[USBG_MAX_STR_LENGTH];
+	usbg_function_type type;
 	int usbg_ret;
 	usbg_function_attrs f_attrs;
 
-	usbg_get_function_name(f, buf, USBG_MAX_STR_LENGTH);
+	usbg_get_function_instance(f, instance, USBG_MAX_STR_LENGTH);
+	type = usbg_get_function_type(f);
 	usbg_ret = usbg_get_function_attrs(f, &f_attrs);
 	if (usbg_ret != USBG_SUCCESS) {
 		fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
@@ -82,8 +84,9 @@ void show_function(usbg_function *f)
 		return;
 	}
 
-	fprintf(stdout, "  Function '%s'\n", buf);
-	switch (usbg_get_function_type(f)) {
+	fprintf(stdout, "  Function, type: %s instance: %s\n",
+			usbg_get_function_type_str(type), instance);
+	switch (type) {
 	case F_SERIAL:
 	case F_ACM:
 	case F_OBEX:
@@ -114,7 +117,8 @@ void show_config(usbg_config *c)
 {
 	usbg_binding *b;
 	usbg_function *f;
-	char buf[USBG_MAX_STR_LENGTH], buf2[USBG_MAX_STR_LENGTH];
+	char buf[USBG_MAX_STR_LENGTH], instance[USBG_MAX_STR_LENGTH];
+	usbg_function_type type;
 	usbg_config_attrs c_attrs;
 	usbg_config_strs c_strs;
 	int usbg_ret;
@@ -144,8 +148,10 @@ void show_config(usbg_config *c)
 	usbg_for_each_binding(b, c) {
 		usbg_get_binding_name(b, buf, USBG_MAX_STR_LENGTH);
 		f = usbg_get_binding_target(b);
-		usbg_get_function_name(f, buf2, USBG_MAX_STR_LENGTH);
-		fprintf(stdout, "    %s -> %s\n", buf, buf2);
+		usbg_get_function_instance(f, instance, USBG_MAX_STR_LENGTH);
+		type = usbg_get_function_type(f);
+		fprintf(stdout, "    %s -> %s %s\n", buf,
+				usbg_get_function_type_str(type), instance);
 	}
 }
 
diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index d416624..35b35f7 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -255,10 +255,12 @@ extern usbg_gadget *usbg_get_gadget(usbg_state *s, const char *name);
 /**
  * @brief Get a function by name
  * @param g Pointer to gadget
- * @param name Name of the function
+ * @param type Function type
+ * @param instance Instance of function
  * @return Pointer to function or NULL if a matching function isn't found
  */
-extern usbg_function *usbg_get_function(usbg_gadget *g, const char *name);
+extern usbg_function *usbg_get_function(usbg_gadget *g,
+		usbg_function_type type, const char *instance);
 
 /**
  * @brief Get a configuration by name
@@ -517,20 +519,27 @@ extern int usbg_create_function(usbg_gadget *g, usbg_function_type type,
 		char *instance, usbg_function_attrs *f_attrs, usbg_function **f);
 
 /**
- * @brief Get function name length
- * @param f Config which name length should be returned
+ * @brief Get function instance name length
+ * @param f function which name length should be returned
  * @return Length of name string or usbg_error if error occurred.
  */
-extern size_t usbg_get_function_name_len(usbg_function *f);
+extern size_t usbg_get_function_instance_len(usbg_function *f);
 
 /**
- * @brieg Get config name
+ * @brief Get function instance name
  * @param f Pointer to function
- * @param buf Buffer where name should be copied
+ * @param buf Buffer where instance name should be copied
  * @param len Length of given buffer
  * @return 0 on success or usbg_error if error occurred.
  */
-extern int usbg_get_function_name(usbg_function *f, char *buf, size_t len);
+extern int usbg_get_function_instance(usbg_function *f, char *buf, size_t len);
+
+/**
+ * @brief Get function type as a string
+ * @param type Function type
+ * @return String suitable for given function type
+ */
+extern const char *usbg_get_function_type_str(usbg_function_type type);
 
 /* USB configurations allocation and configuration */
 
@@ -706,8 +715,8 @@ extern int usbg_get_gadget_udc(usbg_gadget *g, char *buf, size_t len);
 /**
  * @brief Get type of given function
  * @param f Pointer to function
- * @return Type of function
- * @warning Pointer to function has to be valid.
+ * @return usbg_function_type (0 or above) or
+ *  usbg_error (below 0) if error occurred
  */
 extern usbg_function_type usbg_get_function_type(usbg_function *f);
 
diff --git a/src/usbg.c b/src/usbg.c
index e2e4600..96dba75 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -71,6 +71,7 @@ struct usbg_function
 
 	char *name;
 	char *path;
+	char *instance;
 
 	usbg_function_type type;
 };
@@ -284,13 +285,46 @@ static int usbg_lookup_function_type(char *name)
 	return i;
 }
 
-static inline const char *usbg_get_function_type_name(
-		usbg_function_type type)
+const const char *usbg_get_function_type_str(usbg_function_type type)
 {
 	return type > 0 && type < sizeof(function_names)/sizeof(char *) ?
 			function_names[type] : NULL;
 }
 
+static usbg_error usbg_split_function_instance_type(const char *full_name,
+		usbg_function_type *f_type, const char **instance)
+{
+	const char *dot;
+	char *type_name = NULL;
+	int f_type_ret;
+	usbg_error ret = USBG_ERROR_INVALID_PARAM;
+
+	dot = strchr(full_name, '.');
+	if (!dot || dot == full_name || *(dot + 1) == '\0')
+		goto out;
+
+	*instance = dot + 1;
+
+	type_name = strndup(full_name, dot - full_name);
+	if (!type_name) {
+		ret = USBG_ERROR_NO_MEM;
+		goto out;
+	}
+
+	f_type_ret = usbg_lookup_function_type(type_name);
+
+	if (f_type_ret >= 0) {
+		*f_type = (usbg_function_type)f_type_ret;
+		ret = USBG_SUCCESS;
+	} else {
+		ret = USBG_ERROR_NOT_SUPPORTED;
+	}
+
+out:
+	free(type_name);
+	return ret;
+}
+
 static int bindings_select(const struct dirent *dent)
 {
 	if (dent->d_type == DT_LNK)
@@ -532,25 +566,43 @@ static usbg_config *usbg_allocate_config(char *path, char *name,
 	return c;
 }
 
-static usbg_function *usbg_allocate_function(char *path, char *name,
-		usbg_gadget *parent)
+static usbg_function *usbg_allocate_function(const char *path,
+		usbg_function_type type, const char *instance, usbg_gadget *parent)
 {
 	usbg_function *f;
+	const char *type_name;
+	int ret;
 
 	f = malloc(sizeof(usbg_function));
-	if (f) {
-		f->name = strdup(name);
-		f->path = strdup(path);
-		f->parent = parent;
-
-		if (!(f->name) || !(f->path)) {
-			free(f->name);
-			free(f->path);
-			free(f);
-			f = NULL;
-		}
+	if (!f)
+		goto out;
+
+	type_name = usbg_get_function_type_str(type);
+	if (!type_name) {
+		free(f);
+		f = NULL;
+		goto out;
+	}
+
+	ret = asprintf(&(f->name), "%s.%s", type_name, instance);
+	if (ret < 0) {
+		free(f);
+		f = NULL;
+		goto out;
 	}
+	f->instance = f->name + strlen(type_name) + 1;
+	f->path = strdup(path);
+	f->parent = parent;
+	f->type = type;
 
+	if (!(f->path)) {
+		free(f->name);
+		free(f->path);
+		free(f);
+		f = NULL;
+	}
+
+out:
 	return f;
 }
 
@@ -723,24 +775,29 @@ static int usbg_parse_functions(char *path, usbg_gadget *g)
 	}
 
 	n = scandir(fpath, &dent, file_select, alphasort);
-	if (n >= 0) {
-		for (i = 0; i < n; i++) {
+	if (n < 0) {
+		ret = usbg_translate_error(errno);
+		goto out;
+	}
+
+	for (i = 0; i < n; i++) {
+		if (ret == USBG_SUCCESS) {
+			const char *instance;
+			usbg_function_type type;
+			ret = usbg_split_function_instance_type(
+					dent[i]->d_name, &type, &instance);
 			if (ret == USBG_SUCCESS) {
-				f = usbg_allocate_function(fpath, dent[i]->d_name, g);
-				if (f) {
-					f->type = usbg_lookup_function_type(
-							strtok(dent[i]->d_name, "."));
+				f = usbg_allocate_function(fpath, type,
+						instance, g);
+				if (f)
 					TAILQ_INSERT_TAIL(&g->functions, f, fnode);
-				} else {
+				else
 					ret = USBG_ERROR_NO_MEM;
-				}
 			}
-			free(dent[i]);
 		}
-		free(dent);
-	} else {
-		ret = usbg_translate_error(errno);
+		free(dent[i]);
 	}
+	free(dent);
 
 out:
 	return ret;
@@ -790,18 +847,63 @@ static int usbg_parse_config_strs(char *path, char *name,
 	return ret;
 }
 
+static int usbg_parse_config_binding(usbg_config *c, char *bpath,
+		int path_size)
+{
+	int nmb;
+	int ret;
+	char target[USBG_MAX_PATH_LENGTH];
+	char *target_name;
+	const char *instance;
+	usbg_function_type type;
+	usbg_function *f;
+	usbg_binding *b;
+
+	nmb = readlink(bpath, target, sizeof(target));
+	if (nmb < 0) {
+		ret = usbg_translate_error(errno);
+		goto out;
+	}
+
+	/* readlink() don't add this,
+	 * so we have to do it manually */
+	target[nmb] = '\0';
+	/* Target contains a full path
+	 * but we need only function dir name */
+	target_name = strrchr(target, '/') + 1;
+
+	ret = usbg_split_function_instance_type(target_name, &type, &instance);
+	if (ret != USBG_SUCCESS)
+		goto out;
+
+	f = usbg_get_function(c->parent, type, instance);
+	if (!f) {
+		ret = USBG_ERROR_OTHER_ERROR;
+		goto out;
+	}
+
+	/* We have to cut last part of path */
+	bpath[path_size] = '\0';
+	/* path_to_config_dir \0 config_name */
+	b = usbg_allocate_binding(bpath, bpath + path_size + 1, c);
+	if (b) {
+		b->target = f;
+		TAILQ_INSERT_TAIL(&c->bindings, b, bnode);
+	} else {
+		ret = USBG_ERROR_NO_MEM;
+	}
+
+out:
+	return ret;
+}
+
 static int usbg_parse_config_bindings(usbg_config *c)
 {
 	int i, n, nmb;
 	int ret = USBG_SUCCESS;
 	struct dirent **dent;
 	char bpath[USBG_MAX_PATH_LENGTH];
-	char target[USBG_MAX_PATH_LENGTH];
-	char *target_name;
 	int end;
-	usbg_gadget *g = c->parent;
-	usbg_binding *b;
-	usbg_function *f;
 
 	end = snprintf(bpath, sizeof(bpath), "%s/%s", c->path, c->name);
 	if (end >= sizeof(bpath)) {
@@ -820,33 +922,9 @@ static int usbg_parse_config_bindings(usbg_config *c)
 			nmb = snprintf(&(bpath[end]), sizeof(bpath) - end,
 					"/%s", dent[i]->d_name);
 
-			if (nmb < sizeof(bpath) - end) {
-				nmb = readlink(bpath, target, sizeof(target));
-				if (nmb >= 0) {
-					/* readlink() don't add this,
-					 * so we have to do it manually */
-					target[nmb] = '\0';
-					/* Target contains a full path
-					 * but we need only function dir name */
-					target_name = strrchr(target, '/') + 1;
-
-					f = usbg_get_function(g, target_name);
-
-					/* We have to cut last part of path */
-					bpath[end] = '\0';
-					b = usbg_allocate_binding(bpath, dent[i]->d_name, c);
-					if (b) {
-						b->target = f;
-						TAILQ_INSERT_TAIL(&c->bindings, b, bnode);
-					} else {
-						ret = USBG_ERROR_NO_MEM;
-					}
-				} else {
-					ret = usbg_translate_error(errno);
-				}
-			} else {
-				ret = USBG_ERROR_PATH_TOO_LONG;
-			}
+			ret = nmb < sizeof(bpath) - end ?
+					usbg_parse_config_binding(c, bpath, end)
+					: USBG_ERROR_PATH_TOO_LONG;
 		} /* ret == USBG_SUCCESS */
 		free(dent[i]);
 	}
@@ -1130,15 +1208,16 @@ usbg_gadget *usbg_get_gadget(usbg_state *s, const char *name)
 	return NULL;
 }
 
-usbg_function *usbg_get_function(usbg_gadget *g, const char *name)
+usbg_function *usbg_get_function(usbg_gadget *g,
+		usbg_function_type type, const char *instance)
 {
-	usbg_function *f;
+	usbg_function *f = NULL;
 
 	TAILQ_FOREACH(f, &g->functions, fnode)
-		if (!strcmp(f->name, name))
-			return f;
+		if (f->type == type && (!strcmp(f->instance, instance)))
+			break;
 
-	return NULL;
+	return f;
 }
 
 usbg_config *usbg_get_config(usbg_gadget *g, const char *name)
@@ -1738,26 +1817,14 @@ int usbg_create_function(usbg_gadget *g, usbg_function_type type,
 		char *instance, usbg_function_attrs *f_attrs, usbg_function **f)
 {
 	char fpath[USBG_MAX_PATH_LENGTH];
-	char name[USBG_MAX_PATH_LENGTH];
-	const char *type_name;
 	usbg_function *func;
 	int ret = USBG_ERROR_INVALID_PARAM;
 	int n, free_space;
 
-	if (!g || !f)
+	if (!g || !f || !instance)
 		return ret;
 
-	type_name = usbg_get_function_type_name(type);
-	if (!type_name)
-		goto out;
-
-	n = snprintf(name, sizeof(name), "%s.%s", type_name, instance);
-	if (n >= sizeof(name)) {
-		ret = USBG_ERROR_PATH_TOO_LONG;
-		goto out;
-	}
-
-	func = usbg_get_function(g, name);
+	func = usbg_get_function(g, type, instance);
 	if (func) {
 		ERROR("duplicate function name\n");
 		ret = USBG_ERROR_EXIST;
@@ -1771,7 +1838,7 @@ int usbg_create_function(usbg_gadget *g, usbg_function_type type,
 		goto out;
 	}
 
-	*f = usbg_allocate_function(fpath, name, g);
+	*f = usbg_allocate_function(fpath, type, instance, g);
 	func = *f;
 	if (!func) {
 		ERRORNO("allocating function\n");
@@ -1779,10 +1846,8 @@ int usbg_create_function(usbg_gadget *g, usbg_function_type type,
 	}
 
 	free_space = sizeof(fpath) - n;
-	n = snprintf(&(fpath[n]), free_space, "/%s", name);
+	n = snprintf(&(fpath[n]), free_space, "/%s", func->name);
 	if (n < free_space) {
-		func->type = type;
-
 		ret = mkdir(fpath, S_IRWXU | S_IRWXG | S_IRWXO);
 		if (!ret) {
 			/* Success */
@@ -1886,16 +1951,16 @@ int usbg_get_config_name(usbg_config *c, char *buf, size_t len)
 	return ret;
 }
 
-size_t usbg_get_function_name_len(usbg_function *f)
+size_t usbg_get_function_instance_len(usbg_function *f)
 {
-	return f ? strlen(f->name) : USBG_ERROR_INVALID_PARAM;
+	return f ? strlen(f->instance) : USBG_ERROR_INVALID_PARAM;
 }
 
-int usbg_get_function_name(usbg_function *f, char *buf, size_t len)
+int usbg_get_function_instance(usbg_function *f, char *buf, size_t len)
 {
 	int ret = USBG_SUCCESS;
 	if (f && buf)
-		strncpy(buf, f->name, len);
+		strncpy(buf, f->instance, len);
 	else
 		ret = USBG_ERROR_INVALID_PARAM;
 
@@ -2126,7 +2191,7 @@ int usbg_disable_gadget(usbg_gadget *g)
 
 usbg_function_type usbg_get_function_type(usbg_function *f)
 {
-	return f->type;
+	return f ? f->type : USBG_ERROR_INVALID_PARAM;
 }
 
 int usbg_get_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux