summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Opasiak <k.opasiak@samsung.com>2015-12-22 22:47:05 +0100
committerKrzysztof Opasiak <k.opasiak@samsung.com>2015-12-23 00:49:03 +0100
commit5fff0aefae56e94be4fbe8b9f9f77b7922a3b392 (patch)
treeb367735b713cb14be129ebb579be736971465e52 /src
parentb5288f38defd7714ff8bd2fe7982f3d0ffbe0c49 (diff)
downloadlibusbg-5fff0aefae56e94be4fbe8b9f9f77b7922a3b392.tar.gz
libusbg-5fff0aefae56e94be4fbe8b9f9f77b7922a3b392.tar.bz2
libusbg-5fff0aefae56e94be4fbe8b9f9f77b7922a3b392.zip
libusbgx: net: Add implementation of function specific API
Implement all function-specific functions from header file Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
Diffstat (limited to 'src')
-rw-r--r--src/function/ether.c338
1 files changed, 196 insertions, 142 deletions
diff --git a/src/function/ether.c b/src/function/ether.c
index a778aee..3bdda43 100644
--- a/src/function/ether.c
+++ b/src/function/ether.c
@@ -12,90 +12,99 @@
#include "usbg/usbg.h"
#include "usbg/usbg_internal.h"
+#include "usbg/function/net.h"
#include <malloc.h>
#ifdef HAS_LIBCONFIG
#include <libconfig.h>
#endif
-struct usbg_f_ether {
+struct usbg_f_net {
struct usbg_function func;
};
-GENERIC_ALLOC_INST(ether, struct usbg_f_ether, func);
+#define NET_DEC_ATTR(_name) \
+ { \
+ .name = #_name, \
+ .ro = false, \
+ .offset = offsetof(struct usbg_f_net_attrs, _name), \
+ .get = usbg_get_dec, \
+ .set = usbg_set_dec, \
+ .import = usbg_get_config_node_int, \
+ .export = usbg_set_config_node_int, \
+ }
+
+#define NET_RO_STRING_ATTR(_name) \
+ { \
+ .name = #_name, \
+ .ro = true, \
+ .offset = offsetof(struct usbg_f_net_attrs, _name), \
+ .get = usbg_get_string, \
+ .export = usbg_set_config_node_string, \
+ }
+
+#define NET_ETHER_ADDR_ATTR(_name) \
+ { \
+ .name = #_name, \
+ .ro = false, \
+ .offset = offsetof(struct usbg_f_net_attrs, _name), \
+ .get = usbg_get_ether_addr, \
+ .set = usbg_set_ether_addr, \
+ .import = usbg_get_config_node_ether_addr, \
+ .export = usbg_set_config_node_ether_addr, \
+ }
-GENERIC_FREE_INST(ether, struct usbg_f_ether, func);
+static struct {
+ const char *name;
+ bool ro;
+ size_t offset;
+ usbg_attr_get_func get;
+ usbg_attr_set_func set;
+ usbg_import_node_func import;
+ usbg_export_node_func export;
+} net_attr[USBG_F_NET_ATTR_MAX] = {
+ [USBG_F_NET_DEV_ADDR] = NET_ETHER_ADDR_ATTR(dev_addr),
+ [USBG_F_NET_HOST_ADDR] = NET_ETHER_ADDR_ATTR(host_addr),
+ [USBG_F_NET_IFNAME] = NET_RO_STRING_ATTR(ifname),
+ [USBG_F_NET_QMULT] = NET_DEC_ATTR(qmult),
+};
+
+#undef NET_DEC_ATTR
+#undef NET_STRING_ATTR
+
+GENERIC_ALLOC_INST(ether, struct usbg_f_net, func);
+
+GENERIC_FREE_INST(ether, struct usbg_f_net, func);
static int ether_set_attrs(struct usbg_function *f,
const usbg_function_attrs *f_attrs)
{
int ret = USBG_SUCCESS;
- char addr_buf[USBG_MAX_STR_LENGTH];
const usbg_f_net_attrs *attrs = &f_attrs->attrs.net;
- char *addr;
-
- /* ifname is read only so we accept only empty string for this param */
- if (attrs->ifname && attrs->ifname[0]) {
- ret = USBG_ERROR_INVALID_PARAM;
- goto out;
- }
-
- addr = usbg_ether_ntoa_r(&attrs->dev_addr, addr_buf);
- ret = usbg_write_string(f->path, f->name, "dev_addr", addr);
- if (ret != USBG_SUCCESS)
- goto out;
- addr = usbg_ether_ntoa_r(&attrs->host_addr, addr_buf);
- ret = usbg_write_string(f->path, f->name, "host_addr", addr);
- if (ret != USBG_SUCCESS)
- goto out;
+ if (f_attrs->header.attrs_type &&
+ f_attrs->header.attrs_type != USBG_F_ATTRS_NET)
+ return USBG_ERROR_INVALID_PARAM;
- ret = usbg_write_dec(f->path, f->name, "qmult", attrs->qmult);
+ /* ifname is read only so we accept only empty string for this param */
+ if (attrs->ifname && attrs->ifname[0])
+ return USBG_ERROR_INVALID_PARAM;
-out:
- return ret;
+ return usbg_f_net_set_attrs(usbg_to_net_function(f),
+ (struct usbg_f_net_attrs *)attrs);
}
static int ether_get_attrs(struct usbg_function *f,
usbg_function_attrs *f_attrs)
{
- struct ether_addr *addr;
- struct ether_addr addr_buf;
- char str_addr[USBG_MAX_STR_LENGTH];
+ int ret;
usbg_f_net_attrs *attrs = &f_attrs->attrs.net;
- int ret = USBG_ERROR_INVALID_PARAM;
-
- ret = usbg_read_string(f->path, f->name, "dev_addr", str_addr);
- if (ret != USBG_SUCCESS)
- goto out;
-
- addr = ether_aton_r(str_addr, &addr_buf);
- if (addr) {
- attrs->dev_addr = *addr;
- } else {
- ret = USBG_ERROR_IO;
- goto out;
- }
-
- ret = usbg_read_string(f->path, f->name, "host_addr", str_addr);
- if (ret != USBG_SUCCESS)
- goto out;
- addr = ether_aton_r(str_addr, &addr_buf);
- if (addr) {
- attrs->host_addr = *addr;
- } else {
- ret = USBG_ERROR_IO;
- goto out;
- }
-
- ret = usbg_read_dec(f->path, f->name, "qmult", &(attrs->qmult));
+ ret = usbg_f_net_get_attrs(usbg_to_net_function(f),
+ (struct usbg_f_net_attrs *)attrs);
if (ret != USBG_SUCCESS)
goto out;
- ret = usbg_read_string_alloc(f->path, f->name, "ifname",
- &(attrs->ifname));
-
f_attrs->header.attrs_type = USBG_F_ATTRS_NET;
out:
return ret;
@@ -113,103 +122,52 @@ static void ether_cleanup_attrs(struct usbg_function *f,
static int ether_libconfig_import(struct usbg_function *f,
config_setting_t *root)
{
- config_setting_t *node;
- int ret = USBG_SUCCESS;
- int qmult;
- struct ether_addr *addr;
- struct ether_addr addr_buf;
- const char *str;
-
-#define GET_OPTIONAL_ADDR(NAME) \
- do { \
- node = config_setting_get_member(root, #NAME); \
- if (node) { \
- str = config_setting_get_string(node); \
- if (!str) { \
- ret = USBG_ERROR_INVALID_TYPE; \
- goto out; \
- } \
- \
- addr = ether_aton_r(str, &addr_buf); \
- if (!addr) { \
- ret = USBG_ERROR_INVALID_VALUE; \
- goto out; \
- } \
- ret = usbg_set_net_##NAME(f, addr); \
- if (ret != USBG_SUCCESS) \
- goto out; \
- } \
- } while (0)
-
- GET_OPTIONAL_ADDR(host_addr);
- GET_OPTIONAL_ADDR(dev_addr);
-
-#undef GET_OPTIONAL_ADDR
-
- node = config_setting_get_member(root, "qmult");
- if (node) {
- if (!usbg_config_is_int(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
- qmult = config_setting_get_int(node);
- ret = usbg_set_net_qmult(f, qmult);
+ struct usbg_f_net *nf = usbg_to_net_function(f);
+ union usbg_f_net_attr_val val;
+ int i;
+ int ret = 0;
+
+ for (i = USBG_F_NET_ATTR_MIN; i < USBG_F_NET_ATTR_MAX; ++i) {
+ if (net_attr[i].ro)
+ continue;
+
+ ret = net_attr[i].import(root, net_attr[i].name, &val);
+ /* node not found */
+ if (ret == 0)
+ continue;
+ /* error */
+ if (ret < 0)
+ break;
+
+ ret = usbg_f_net_set_attr_val(nf, i, val);
+ if (ret)
+ break;
}
-out:
return ret;
}
static int ether_libconfig_export(struct usbg_function *f,
config_setting_t *root)
{
- config_setting_t *node;
- char *addr;
- char addr_buf[USBG_MAX_STR_LENGTH];
- int cfg_ret, usbg_ret;
- usbg_function_attrs f_attrs;
- usbg_f_net_attrs *attrs = &f_attrs.attrs.net;
- int ret = USBG_ERROR_NO_MEM;
-
- usbg_ret = ether_get_attrs(f, &f_attrs);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
-
- node = config_setting_add(root, "dev_addr", CONFIG_TYPE_STRING);
- if (!node)
- goto cleanup;
-
- addr = usbg_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 cleanup;
+ struct usbg_f_net *nf = usbg_to_net_function(f);
+ union usbg_f_net_attr_val val;
+ int i;
+ int ret = 0;
+
+ for (i = USBG_F_NET_ATTR_MIN; i < USBG_F_NET_ATTR_MAX; ++i) {
+ if (net_attr[i].ro)
+ continue;
+
+ ret = usbg_f_net_get_attr_val(nf, i, &val);
+ if (ret)
+ break;
+
+ ret = net_attr[i].export(root, net_attr[i].name, &val);
+ if (ret)
+ break;
}
- node = config_setting_add(root, "host_addr", CONFIG_TYPE_STRING);
- if (!node)
- goto cleanup;
-
- addr = usbg_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 cleanup;
- }
-
- node = config_setting_add(root, "qmult", CONFIG_TYPE_INT);
- if (!node)
- goto cleanup;
-
- cfg_ret = config_setting_set_int(node, attrs->qmult);
- ret = cfg_ret == CONFIG_TRUE ? 0 : USBG_ERROR_OTHER_ERROR;
-
- /* ifname is read only so we don't export it */
-cleanup:
- ether_cleanup_attrs(f, &f_attrs);
-out:
return ret;
}
@@ -256,3 +214,99 @@ struct usbg_function_type usbg_f_type_rndis = {
ETHER_FUNCTION_OPTS
};
+/* API implementation */
+
+usbg_f_net *usbg_to_net_function(usbg_function *f)
+{
+ return f->ops == &usbg_f_type_ecm
+ || f->ops == &usbg_f_type_subset
+ || f->ops == &usbg_f_type_ncm
+ || f->ops == &usbg_f_type_eem
+ || f->ops == &usbg_f_type_rndis ?
+ container_of(f, struct usbg_f_net, func) : NULL;
+}
+
+usbg_function *usbg_from_net_function(usbg_f_net *nf)
+{
+ return &nf->func;
+}
+
+int usbg_f_net_get_attrs(usbg_f_net *nf,
+ struct usbg_f_net_attrs *attrs)
+{
+ int i;
+ int ret = 0;
+
+ for (i = USBG_F_NET_ATTR_MIN; i < USBG_F_NET_ATTR_MAX; ++i) {
+ ret = usbg_f_net_get_attr_val(nf, i,
+ (union usbg_f_net_attr_val *)
+ ((char *)attrs
+ + net_attr[i].offset));
+ if (ret)
+ break;
+ }
+
+ return ret;
+
+}
+
+int usbg_f_net_set_attrs(usbg_f_net *nf,
+ const struct usbg_f_net_attrs *attrs)
+{
+ int i;
+ int ret = 0;
+
+ for (i = USBG_F_NET_ATTR_MIN; i < USBG_F_NET_ATTR_MAX; ++i) {
+ if (net_attr[i].ro)
+ continue;
+
+ ret = usbg_f_net_set_attr_val(nf, i,
+ *(union usbg_f_net_attr_val *)
+ ((char *)attrs
+ + net_attr[i].offset));
+ if (ret)
+ break;
+ }
+
+ return ret;
+
+}
+
+int usbg_f_net_get_attr_val(usbg_f_net *nf, enum usbg_f_net_attr attr,
+ union usbg_f_net_attr_val *val)
+{
+ return net_attr[attr].get(nf->func.path, nf->func.name,
+ net_attr[attr].name, val);
+}
+
+int usbg_f_net_set_attr_val(usbg_f_net *nf, enum usbg_f_net_attr attr,
+ union usbg_f_net_attr_val val)
+{
+ return net_attr[attr].ro ?
+ USBG_ERROR_INVALID_PARAM :
+ net_attr[attr].set(nf->func.path, nf->func.name,
+ net_attr[attr].name, &val);
+}
+
+int usbg_f_net_get_ifname_s(usbg_f_net *nf, char *buf, int len)
+{
+ struct usbg_function *f;
+ int ret;
+
+ if (!nf || !buf)
+ return USBG_ERROR_INVALID_PARAM;
+
+ f = &nf->func;
+ /*
+ * TODO:
+ * Rework usbg_common to make this function consistent with doc.
+ * This below is only an ugly hack
+ */
+ ret = usbg_read_string_limited(f->path, f->name, "ifname", buf, len);
+ if (ret)
+ goto out;
+
+ ret = strlen(buf);
+out:
+ return ret;
+}