From 8a8e28cfb44dadc830b8e0931c96ec1d9818b53c Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Fri, 20 Mar 2020 09:03:51 +0900 Subject: Rewrite usb_function to hide global variable _available_funcs To prevent the global variable _available_funcs from being exposed. Change-Id: I26b09d3fa8fb5c8117c0029eb94dd3b7efe9a2c7 (cherry picked from commit 3d1a1c4e666cd31b88cd678968658368e988cbaa) --- hw/usb_cfs_client_common.c | 174 ++++++++++++++++++--------------------------- hw/usb_client_common.c | 18 +---- hw/usb_gadget.h | 10 ++- hw/usb_gadget_common.c | 33 ++++++++- 4 files changed, 110 insertions(+), 125 deletions(-) diff --git a/hw/usb_cfs_client_common.c b/hw/usb_cfs_client_common.c index 577e508..029988b 100644 --- a/hw/usb_cfs_client_common.c +++ b/hw/usb_cfs_client_common.c @@ -69,44 +69,29 @@ struct usbg_gadget_strs default_g_strs = { .serial = "01234TEST", }; -static bool cfs_match_func(struct usb_function *f, - const char *name, const char *instance) { - if (strcmp(name, usbg_get_function_type_str(USBG_F_FFS))) { - /* Standard functions */ - if (!strcmp(name, f->name) && !strcmp(instance, f->instance)) - return true; - } else { - /* Function with service */ - const char *sep, *fname, *finst; - int len; - - sep = strchr(instance, NAME_INSTANCE_SEP); - if (!sep || strlen(sep + 1) < 1) - return false; - - fname = instance; - len = sep - instance; - finst = sep + 1; - - if (strlen(f->name) == len - && !strncmp(f->name, fname, len) - && !strcmp(f->instance, finst)) - return true; - } - - return false; -} - - -static int cfs_find_func(const char *name, const char *instance) +static struct usb_function *cfs_find_usb_function(usbg_function *function) { - int i; - - for (i = 0; _available_funcs[i]; ++i) - if (cfs_match_func(_available_funcs[i], name, instance)) - return i; + char *sep; + char buf[MAX_INSTANCE_LEN]; + const char *instance = usbg_get_function_instance(function); + const char *name = usbg_get_function_type_str(usbg_get_function_type(function)); + + /* Ex. name:"ffs", instance: "sdb.default" */ + if (strcmp(name, usbg_get_function_type_str(USBG_F_FFS)) == 0) { + strncpy(buf, instance, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + + /* Ex. "sdb.default" ==> "sdb" + "default" */ + sep = strchr(buf, NAME_INSTANCE_SEP); + if (!sep || !sep[1]) + return NULL; + *sep = '\0'; + + name = buf; + instance = sep + 1; + } - return -ENOENT; + return find_usb_function_by_name_instance(name, instance); } static bool cfs_is_function_supported(struct usb_client *usb, @@ -134,11 +119,6 @@ static bool cfs_is_gadget_supported(struct usb_client *usb, if (!gadget || !gadget->configs || !gadget->funcs) return false; - /* - * TODO - * Here is a good place to ensure that serial is immutable - */ - /* No real restrictions for strings */ for (j = 0; gadget->configs && gadget->configs[j]; ++j) { struct usb_configuration *config = gadget->configs[j]; @@ -288,23 +268,15 @@ out_rmdir: static int cfs_cleanup_ffs_service(usbg_function *function) { int ret; - int index; - const char *name; - const char *instance; char buf[MAX_INSTANCE_LEN]; struct usb_function *usb_function; if (!function) return -EINVAL; - instance = usbg_get_function_instance(function); /* Ex: sdb.default */ - name = usbg_get_function_type_str(usbg_get_function_type(function)); /* Fixed: ffs */ - - index = cfs_find_func(name, instance); - if (index < 0) - return index; - - usb_function = _available_funcs[index]; + usb_function = cfs_find_usb_function(function); + if (!usb_function) + return -ENOENT; /* stop .socket first and stop .service later becuase of socket activation */ if (usb_function->service) { @@ -374,6 +346,41 @@ static int cfs_set_rndis_mac_addr(usbg_gadget *gadget, usbg_function *func) return ret; } +static int cfs_cleanup_all_config_and_function(struct cfs_client *cfs_client) +{ + int ret; + usbg_config *config; + usbg_function *function; + + /* delete all configs */ +restart_rm_config: + usbg_for_each_config(config, cfs_client->gadget) { + ret = usbg_rm_config(config, USBG_RM_RECURSE); + if (ret) + return ret; + + goto restart_rm_config; /* You cannot delete a config directly in an iterator. */ + } + + /* delete all functions */ +restart_rm_function: + usbg_for_each_function(function, cfs_client->gadget) { + if (usbg_get_function_type(function) == USBG_F_FFS) { + ret = cfs_cleanup_ffs_service(function); + if (ret) + return ret; + } + + ret = usbg_rm_function(function, USBG_RM_RECURSE); + if (ret) + return ret; + + goto restart_rm_function; /* You cannot delete a function directly in an iterator. */ + } + + return 0; +} + static int cfs_set_gadget_config(struct cfs_client *cfs_client, int config_id, struct usb_configuration *usb_config) { int i; @@ -411,10 +418,11 @@ static int cfs_set_gadget_config(struct cfs_client *cfs_client, int config_id, s /* In functionfs, the instance is used in the format "[sdb|mtp].default" instead of "default" */ if (usb_func->is_functionfs) { function_type = USBG_F_FFS; - snprintf(instance, sizeof(instance) - 1, "%s%c%s", usb_func->name, NAME_INSTANCE_SEP, usb_func->instance); + snprintf(instance, sizeof(instance), "%s%c%s", usb_func->name, NAME_INSTANCE_SEP, usb_func->instance); } else { function_type = usbg_lookup_function_type(usb_func->name); - strncpy(instance, usb_func->instance, MAX_INSTANCE_LEN - 1); + strncpy(instance, usb_func->instance, sizeof(instance) - 1); + instance[sizeof(instance) - 1] = '\0'; } ret = usbg_create_function(cfs_client->gadget, function_type, instance, NULL, &function); @@ -446,8 +454,6 @@ static int cfs_reconfigure_gadget(struct usb_client *usb, { int i; int ret; - usbg_config *config; - usbg_function *function; struct cfs_client *cfs_client; if (!usb || !gadget || !cfs_is_gadget_supported(usb, gadget)) @@ -465,31 +471,9 @@ static int cfs_reconfigure_gadget(struct usb_client *usb, return ret; } - /* delete all configs */ -restart_rm_config: - usbg_for_each_config(config, cfs_client->gadget) { - ret = usbg_rm_config(config, USBG_RM_RECURSE); - if (ret) - return ret; - - goto restart_rm_config; /* You cannot delete a config directly in an iterator. */ - } - - /* delete all functions */ -restart_rm_function: - usbg_for_each_function(function, cfs_client->gadget) { - if (usbg_get_function_type(function) == USBG_F_FFS) { - ret = cfs_cleanup_ffs_service(function); - if (ret) - return ret; - } - - ret = usbg_rm_function(function, USBG_RM_RECURSE); - if (ret) - return ret; - - goto restart_rm_function; /* You cannot delete a function directly in an iterator. */ - } + ret = cfs_cleanup_all_config_and_function(cfs_client); + if (ret) + return ret; for (i = 0; gadget->configs && gadget->configs[i]; ++i) { ret = cfs_set_gadget_config(cfs_client, i + 1, gadget->configs[i]); @@ -502,22 +486,14 @@ restart_rm_function: static void cfs_start_stop_service_and_handler(usbg_gadget *gadget, enum cfs_function_service_operation operation) { - int index; - const char *name; - const char *instance; usbg_function *function; struct usb_function *usb_function; usbg_for_each_function(function, gadget) { - instance = usbg_get_function_instance(function); - name = usbg_get_function_type_str(usbg_get_function_type(function)); - - index = cfs_find_func(name, instance); - if (index < 0) + usb_function = cfs_find_usb_function(function); + if (!usb_function) continue; - usb_function = _available_funcs[index]; - switch(operation) { case CFS_FUNCTION_SERVICE_START: if (usb_function->handler) @@ -627,6 +603,7 @@ int hw_cfs_gadget_open(struct hw_info *info, cfs_client->client.disable = cfs_disable; *common = &cfs_client->client.common; + return 0; err_create_gadget: @@ -641,9 +618,6 @@ err_usbg_init: EXPORT int hw_cfs_gadget_close(struct hw_common *common) { - int ret; - const char *name; - const char *instance; usbg_function *function; struct cfs_client *cfs_client; struct usb_function *usb_func; @@ -651,19 +625,13 @@ int hw_cfs_gadget_close(struct hw_common *common) if (!common) return -EINVAL; - cfs_client = container_of(common, struct cfs_client, - client.common); + cfs_client = container_of(common, struct cfs_client, client.common); usbg_for_each_function(function, cfs_client->gadget) { - instance = usbg_get_function_instance(function); - name = usbg_get_function_type_str(usbg_get_function_type(function)); - - ret = cfs_find_func(name, instance); - if (ret < 0) + usb_func = cfs_find_usb_function(function); + if (!usb_func) continue; - usb_func = _available_funcs[ret]; - if (usb_func->is_functionfs && usb_func->service) { (void)systemd_stop_unit_wait_stopped(usb_func->service, ".socket", -1); (void)systemd_stop_unit_wait_stopped(usb_func->service, ".service", -1); diff --git a/hw/usb_client_common.c b/hw/usb_client_common.c index 6822f32..963687a 100644 --- a/hw/usb_client_common.c +++ b/hw/usb_client_common.c @@ -58,18 +58,6 @@ #define EXPORT __attribute__ ((visibility("default"))) #endif -static struct usb_function *legacy_find_func(const char *name) -{ - int i; - - for (i = 0; _available_funcs[i]; ++i) - if (!strcmp(name, _available_funcs[i]->name)) - return _available_funcs[i]; - - return NULL; -} - - static bool legacy_is_function_supported(struct usb_client *usb, struct usb_function *func) { @@ -79,7 +67,7 @@ static bool legacy_is_function_supported(struct usb_client *usb, * we should also parse sysfs to check if it is build into * slp-gadget. */ - if (legacy_find_func(func->name)) + if (find_usb_function_by_name(func->name)) return true; else return false; @@ -287,7 +275,7 @@ static void legacy_start_stop_service_and_handler(bool start) begin = buf; for (fname = strsep(&begin, sep); fname; fname = strsep(&begin, sep)) { - func = legacy_find_func(fname); + func = find_usb_function_by_name(fname); if (!func) continue; @@ -315,7 +303,7 @@ second_configuration: begin = buf; for (fname = strsep(&begin, sep); fname; fname = strsep(&begin, sep)) { - func = legacy_find_func(fname); + func = find_usb_function_by_name(fname); if (!func) continue; diff --git a/hw/usb_gadget.h b/hw/usb_gadget.h index fedd8e7..02ec7ed 100644 --- a/hw/usb_gadget.h +++ b/hw/usb_gadget.h @@ -131,16 +131,14 @@ struct usb_gadget_id { struct usb_gadget_translator { struct hw_common common; - int (*id_to_gadget)(struct usb_gadget_id *gadget_id, - struct usb_gadget **gadget); - + int (*id_to_gadget)(struct usb_gadget_id *gadget_id, struct usb_gadget **gadget); void (*cleanup_gadget)(struct usb_gadget *gadget); }; -int simple_translator_open(struct hw_info *info, - const char *id, struct hw_common **common); +int simple_translator_open(struct hw_info *info, const char *id, struct hw_common **common); int simple_translator_close(struct hw_common *common); -extern struct usb_function *_available_funcs[]; +struct usb_function *find_usb_function_by_name(const char *name); +struct usb_function *find_usb_function_by_name_instance(const char *name, const char *instance); #endif diff --git a/hw/usb_gadget_common.c b/hw/usb_gadget_common.c index 08fe8a4..c8eddc4 100644 --- a/hw/usb_gadget_common.c +++ b/hw/usb_gadget_common.c @@ -45,6 +45,8 @@ #define EXPORT __attribute__ ((visibility("default"))) #endif +static struct usb_function *_available_funcs[]; + static void simple_cleanup_config(struct usb_configuration *config) { int i; @@ -442,7 +444,7 @@ DEFINE_USB_FUNCTION(USB_FUNCTION_RMNET, rmnet, 0, NULL, N #undef DEFINE_USB_FUNCTION /* Caution: index order of arrary is important, because simple_id_to_gadget() uses it. */ -struct usb_function *_available_funcs[] = { +static struct usb_function *_available_funcs[] = { [USB_FUNCTION_IDX_MTP] = &_mtp_function, [USB_FUNCTION_IDX_ACM] = &_acm_function, [USB_FUNCTION_IDX_SDB] = &_sdb_function, @@ -454,6 +456,35 @@ struct usb_function *_available_funcs[] = { [USB_FUNCTION_IDX_MAX] = NULL /* An indicator to end the array */ }; +struct usb_function *find_usb_function_by_name(const char *name) +{ + int i; + + if(!name || !name[0]) + return NULL; + + for (i = 0; _available_funcs[i]; i++) + if (!strcmp(name, _available_funcs[i]->name)) + return _available_funcs[i]; + + return NULL; +} + +struct usb_function *find_usb_function_by_name_instance(const char *name, const char *instance) +{ + int i; + + if(!name || !name[0] || !instance || !instance[0]) + return NULL; + + for (i = 0; _available_funcs[i]; ++i) + if (!strcmp(name, _available_funcs[i]->name) && !strcmp(instance, _available_funcs[i]->instance)) + return _available_funcs[i]; + + return NULL; +} + + EXPORT int simple_translator_open(struct hw_info *info, const char *id, struct hw_common **common) -- cgit v1.2.3