From 5ab3f478654c4a4a060b1b690ceec1037b2eb2af Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Fri, 28 Feb 2014 09:59:19 +0100 Subject: [PATCH] libusbgx: Add return value to usb function related functions. Each usbg_set_*() may fail so it should have a return value to notify user about reason of failure. To be consistent with rest of API usbg_create_function() should also return error code to notify user about reasons of failure instead of binary information (NULL or not). Signed-off-by: Krzysztof Opasiak [Port from libusbg and update description] Signed-off-by: Krzysztof Opasiak --- examples/gadget-acm-ecm.c | 12 ++-- include/usbg/usbg.h | 20 ++++--- src/usbg.c | 140 +++++++++++++++++++++++++++++----------------- 3 files changed, 108 insertions(+), 64 deletions(-) diff --git a/examples/gadget-acm-ecm.c b/examples/gadget-acm-ecm.c index b1131b4..678514c 100644 --- a/examples/gadget-acm-ecm.c +++ b/examples/gadget-acm-ecm.c @@ -69,20 +69,20 @@ int main(void) goto out2; } - f_acm0 = usbg_create_function(g, F_ACM, "usb0", NULL); - if (!f_acm0) { + usbg_ret = usbg_create_function(g, F_ACM, "usb0", NULL, &f_acm0); + if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating acm0 function\n"); goto out2; } - f_acm1 = usbg_create_function(g, F_ACM, "usb1", NULL); - if (!f_acm1) { + usbg_ret = usbg_create_function(g, F_ACM, "usb1", NULL, &f_acm1); + if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating acm1 function\n"); goto out2; } - f_ecm = usbg_create_function(g, F_ECM, "usb0", NULL); - if (!f_ecm) { + usbg_ret = usbg_create_function(g, F_ECM, "usb0", NULL, &f_acm1); + if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating ecm function\n"); goto out2; } diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h index 6f41763..5a84066 100644 --- a/include/usbg/usbg.h +++ b/include/usbg/usbg.h @@ -435,10 +435,12 @@ extern int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd); * @param type Type of function * @param instance Function instance name * @param f_attrs Function attributes to be set. If NULL setting is omitted. - * @return Pointer to function or NULL if it cannot be created + * @param f Pointer to be filled with pointer to function + * @note Given strings are assumed to be in US English + * @return 0 on success usbg_error if error occurred */ -extern usbg_function *usbg_create_function(usbg_gadget *g, usbg_function_type type, - char *instance, usbg_function_attrs *f_attrs); +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 @@ -640,29 +642,33 @@ extern usbg_function_attrs *usbg_get_function_attrs(usbg_function *f, * @brief Set attributes of given function * @param f Pointer to function * @param f_attrs Attributes to be set + * @return 0 on success, usbg_error if error occurred */ -extern void usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs); +extern int usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs); /** * @brief Set USB function network device address * @param f Pointer to function * @param addr Pointer to Ethernet address + * @return 0 on success, usbg_error if error occurred */ -extern void usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *addr); +extern int usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *addr); /** * @brief Set USB function network host address * @param f Pointer to function * @param addr Pointer to Ethernet address + * @return 0 on success, usbg_error if error occurred */ -extern void usbg_set_net_host_addr(usbg_function *f, struct ether_addr *addr); +extern int usbg_set_net_host_addr(usbg_function *f, struct ether_addr *addr); /** * @brief Set USB function network qmult * @param f Pointer to function * @param qmult Queue length multiplier + * @return 0 on success, usbg_error if error occurred */ -extern void usbg_set_net_qmult(usbg_function *f, int qmult); +extern int usbg_set_net_qmult(usbg_function *f, int qmult); /** * @def usbg_for_each_gadget(g, s) diff --git a/src/usbg.c b/src/usbg.c index 5a4202c..08cd397 100644 --- a/src/usbg.c +++ b/src/usbg.c @@ -1162,52 +1162,58 @@ int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd) return ret; } -usbg_function *usbg_create_function(usbg_gadget *g, usbg_function_type type, - char *instance, usbg_function_attrs *f_attrs) +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_STR_LENGTH]; - usbg_function *f; - int ret; + usbg_function *func; + int ret = USBG_ERROR_INVALID_PARAM; - if (!g) - return NULL; + if (!g || !f) + return ret; /** * @todo Check for legal function type */ sprintf(name, "%s.%s", function_names[type], instance); - f = usbg_get_function(g, name); - if (f) { + func = usbg_get_function(g, name); + if (func) { ERROR("duplicate function name\n"); - return NULL; + return USBG_ERROR_EXIST; } sprintf(fpath, "%s/%s/%s/%s", g->path, g->name, FUNCTIONS_DIR, name); - f = malloc(sizeof(usbg_function)); - if (!f) { - ERRORNO("allocating function\n"); - return NULL; - } - - strcpy(f->name, name); - sprintf(f->path, "%s/%s/%s", g->path, g->name, FUNCTIONS_DIR); - f->type = type; + *f = malloc(sizeof(usbg_function)); + func = *f; + if (func) { + strcpy(func->name, name); + sprintf(func->path, "%s/%s/%s", g->path, g->name, FUNCTIONS_DIR); + func->type = type; - ret = mkdir(fpath, S_IRWXU|S_IRWXG|S_IRWXO); - if (ret < 0) { - ERRORNO("%s\n", fpath); - free(f); - return NULL; - } + ret = mkdir(fpath, S_IRWXU | S_IRWXG | S_IRWXO); - if (f_attrs) - usbg_set_function_attrs(f, f_attrs); + if (!ret) { + /* Success */ + ret = USBG_SUCCESS; + if (f_attrs) + ret = usbg_set_function_attrs(func, f_attrs); + } else { + ret = usbg_translate_error(errno); + } - INSERT_TAILQ_STRING_ORDER(&g->functions, fhead, name, f, fnode); + if (ret == USBG_SUCCESS) + INSERT_TAILQ_STRING_ORDER(&g->functions, fhead, name, + func, fnode); + else + usbg_free_function(func); + } else { + ERRORNO("allocating function\n"); + ret = USBG_ERROR_NO_MEM; + } - return f; + return ret; } usbg_config *usbg_create_config(usbg_gadget *g, char *name, @@ -1469,61 +1475,93 @@ usbg_function_attrs *usbg_get_function_attrs(usbg_function *f, return f_attrs; } -void usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs) +int usbg_set_function_net_attrs(usbg_function *f, usbg_f_net_attrs *attrs) { + int ret = USBG_SUCCESS; char *addr; + addr = ether_ntoa(&attrs->dev_addr); + ret = usbg_write_string(f->path, f->name, "dev_addr", addr); + if (ret != USBG_SUCCESS) + goto out; + + addr = ether_ntoa(&attrs->host_addr); + ret = usbg_write_string(f->path, f->name, "host_addr", addr); + if (ret != USBG_SUCCESS) + goto out; + + ret = usbg_write_string(f->path, f->name, "ifname", attrs->ifname); + if (ret != USBG_SUCCESS) + goto out; + + ret = usbg_write_dec(f->path, f->name, "qmult", attrs->qmult); + +out: + return ret; +} + +int usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs) +{ + int ret = USBG_ERROR_INVALID_PARAM; + if (!f || !f_attrs) - return; + return USBG_ERROR_INVALID_PARAM; switch (f->type) { case F_SERIAL: case F_ACM: case F_OBEX: - usbg_write_dec(f->path, f->name, "port_num", f_attrs->serial.port_num); + ret = usbg_write_dec(f->path, f->name, "port_num", f_attrs->serial.port_num); break; case F_ECM: case F_SUBSET: case F_NCM: case F_EEM: case F_RNDIS: - addr = ether_ntoa(&f_attrs->net.dev_addr); - usbg_write_string(f->path, f->name, "dev_addr", addr); - - addr = ether_ntoa(&f_attrs->net.host_addr); - usbg_write_string(f->path, f->name, "host_addr", addr); - - usbg_write_string(f->path, f->name, "ifname", f_attrs->net.ifname); - - usbg_write_dec(f->path, f->name, "qmult", f_attrs->net.qmult); + ret = usbg_set_function_net_attrs(f, &f_attrs->net); break; case F_PHONET: - usbg_write_string(f->path, f->name, "ifname", f_attrs->phonet.ifname); + ret = usbg_write_string(f->path, f->name, "ifname", f_attrs->phonet.ifname); break; default: ERROR("Unsupported function type\n"); } + + return ret; } -void usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *dev_addr) +int usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *dev_addr) { - char *str_addr; + int ret = USBG_SUCCESS; + + if (f && dev_addr) { + char *str_addr = ether_ntoa(dev_addr); + ret = usbg_write_string(f->path, f->name, "dev_addr", str_addr); + } else { + ret = USBG_ERROR_INVALID_PARAM; + } - str_addr = ether_ntoa(dev_addr); - usbg_write_string(f->path, f->name, "dev_addr", str_addr); + return ret; } -void usbg_set_net_host_addr(usbg_function *f, struct ether_addr *host_addr) +int usbg_set_net_host_addr(usbg_function *f, struct ether_addr *host_addr) { - char *str_addr; + int ret = USBG_SUCCESS; - str_addr = ether_ntoa(host_addr); - usbg_write_string(f->path, f->name, "host_addr", str_addr); + if (f && host_addr) { + char *str_addr = ether_ntoa(host_addr); + ret = usbg_write_string(f->path, f->name, "host_addr", str_addr); + } else { + ret = USBG_ERROR_INVALID_PARAM; + } + + return ret; } -void usbg_set_net_qmult(usbg_function *f, int qmult) +int usbg_set_net_qmult(usbg_function *f, int qmult) { - usbg_write_dec(f->path, f->name, "qmult", qmult); + return f ? usbg_write_dec(f->path, f->name, "qmult", qmult) + : USBG_ERROR_INVALID_PARAM; } usbg_gadget *usbg_get_first_gadget(usbg_state *s) -- 2.7.4