diff options
author | Inaky Perez-Gonzalez <inaky@linux.intel.com> | 2009-04-20 17:11:28 -0700 |
---|---|---|
committer | Inaky Perez-Gonzalez <inaky@linux.intel.com> | 2009-04-21 15:01:25 -0700 |
commit | fdf913c4e26d8b25861f95152e3308c38cbbda7a (patch) | |
tree | 8b8c3f11b800d029ef9b902526684dae19a4bad7 /lib/op-msg.c | |
parent | 822eb164a15ae746c5a8c514f581fb47200fe463 (diff) |
libwimaxll: introduce 'any' handles to receive callbacks from any device
An 'any' handle is a handle opened with NULL as device name. No
commands can be executed with it, but it will emit callbacks for any
WiMAX device that would otherwise generate them for a handle opened
for it exclusively.
When the callback is executed, the handle is temporarily modified to
contain the interface index for whom the callback is emitted, which
can be recovered with wimaxll_ifidx().
The code modifications are quite minimal, mainly dealing with not
allowing command execution and updating the handle's interface index
before executing a callback.
This code also adds a path in wimaxll_open() to allow opening an
interface by interface index, by specifying "#NUMBER" (where NUMBER is
the interface index).
Errors to in some calls to libnl are better reported now.
Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Diffstat (limited to 'lib/op-msg.c')
-rw-r--r-- | lib/op-msg.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/op-msg.c b/lib/op-msg.c index 1b15b75..c3c9426 100644 --- a/lib/op-msg.c +++ b/lib/op-msg.c @@ -162,6 +162,7 @@ int wimaxll_gnl_handle_msg_to_user(struct wimaxll_handle *wmx, struct genlmsghdr *gnl_hdr; struct nlattr *tb[WIMAX_GNL_ATTR_MAX+1]; const char *pipe_name; + unsigned dest_ifidx; void *data; d_fnstart(7, wmx, "(wmx %p msg %p)\n", wmx, msg); @@ -185,7 +186,8 @@ int wimaxll_gnl_handle_msg_to_user(struct wimaxll_handle *wmx, result = -EINVAL; goto error_no_attrs; } - if (wmx->ifidx != nla_get_u32(tb[WIMAX_GNL_MSG_IFIDX])) { + dest_ifidx = nla_get_u32(tb[WIMAX_GNL_MSG_IFIDX]); + if (wmx->ifidx > 0 && wmx->ifidx != dest_ifidx) { result = -ENODEV; goto error_no_attrs; } @@ -211,9 +213,18 @@ int wimaxll_gnl_handle_msg_to_user(struct wimaxll_handle *wmx, size, pipe_name); d_dump(2, wmx, data, size); + /* If this is an "any" handle, set the wmx->ifidx to the + * received one so the callback can now where did the thing + * come from. Will be restored. + */ + if (wmx->ifidx == 0) { + wmx->ifidx = dest_ifidx; + dest_ifidx = 0; + } /* Now execute the callback for handling msg-to-user */ result = wmx->msg_to_user_cb(wmx, wmx->msg_to_user_priv, pipe_name, data, size); + wmx->ifidx = dest_ifidx; error_no_attrs: error_parse: d_fnend(7, wmx, "(wmx %p msg %p) = %d\n", wmx, msg, result); @@ -400,6 +411,9 @@ ssize_t wimaxll_msg_write(struct wimaxll_handle *wmx, void *msg; d_fnstart(3, wmx, "(wmx %p buf %p size %zu)\n", wmx, buf, size); + result = -EBADF; + if (wmx->ifidx == 0) + goto error_not_any; nl_msg = nlmsg_new(); if (nl_msg == NULL) { result = nl_get_errno(); @@ -442,6 +456,7 @@ error_msg_send: error_msg_prep: nlmsg_free(nl_msg); error_msg_alloc: +error_not_any: d_fnend(3, wmx, "(wmx %p buf %p size %zu) = %zd\n", wmx, buf, size, result); return result; |