summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2013-11-18 01:42:46 +0100
committerSamuel Ortiz <sameo@linux.intel.com>2013-11-18 01:42:46 +0100
commitb7f624308f1b5f3169d23f8607c5821bc38ad673 (patch)
tree3449e29571812672886518d88f2d99fa916d32ab
parent6f542a7fff3807252c4cbdb4407d0374215a29e8 (diff)
downloadneard-b7f624308f1b5f3169d23f8607c5821bc38ad673.tar.gz
neard-b7f624308f1b5f3169d23f8607c5821bc38ad673.tar.bz2
neard-b7f624308f1b5f3169d23f8607c5821bc38ad673.zip
netlink: Expose NL_CB_FINISH handler
In some cases (e.g. multipart messages) it is interesting to know when a messages is finished. Some multipart messages can carry a NULL payload and without having a NL_CB_FINISH handler, neard never knows when it's actually finished.
-rw-r--r--src/netlink.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/src/netlink.c b/src/netlink.c
index 38d66d6..936f65a 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -68,6 +68,12 @@ struct nlnfc_state {
static struct nlnfc_state *nfc_state;
static GIOChannel *netlink_channel = NULL;
+struct send_msg_data {
+ void *data;
+ int *done;
+ int (*finish_handler)(struct nl_msg *, void *);
+};
+
static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
void *arg)
{
@@ -80,13 +86,17 @@ static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
return NL_STOP;
}
-static int finish_handler(struct nl_msg *msg, void *arg)
+static int __finish_handler(struct nl_msg *msg, void *arg)
{
- int *ret = arg;
+ struct send_msg_data *data = arg;
+
DBG("");
- *ret = 1;
+ if (data->finish_handler)
+ data->finish_handler(msg, data->data);
+
+ *(data->done) = 1;
return NL_SKIP;
}
@@ -102,12 +112,14 @@ static int ack_handler(struct nl_msg *msg, void *arg)
return NL_STOP;
}
-static int nl_send_msg(struct nl_sock *sock, struct nl_msg *msg,
+static int __nl_send_msg(struct nl_sock *sock, struct nl_msg *msg,
int (*rx_handler)(struct nl_msg *, void *),
+ int (*finish_handler)(struct nl_msg *, void *),
void *data)
{
struct nl_cb *cb;
int err, done;
+ struct send_msg_data send_data;
DBG("");
@@ -124,9 +136,12 @@ static int nl_send_msg(struct nl_sock *sock, struct nl_msg *msg,
}
err = done = 0;
+ send_data.done = &done;
+ send_data.data = data;
+ send_data.finish_handler = finish_handler;
+ nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, __finish_handler, &send_data);
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
- nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &done);
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &done);
if (rx_handler)
@@ -140,6 +155,13 @@ static int nl_send_msg(struct nl_sock *sock, struct nl_msg *msg,
return err;
}
+static inline int nl_send_msg(struct nl_sock *sock, struct nl_msg *msg,
+ int (*rx_handler)(struct nl_msg *, void *),
+ void *data)
+{
+ return __nl_send_msg(sock, msg, rx_handler, NULL, data);
+}
+
static int get_devices_handler(struct nl_msg *n, void *arg)
{
struct nlmsghdr *nlh = nlmsg_hdr(n);