diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2011-12-15 18:33:08 +0100 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2011-12-15 19:16:47 +0100 |
commit | 3cb819ac570b3c623daf0dbf22a4c951d3bf85ee (patch) | |
tree | b089e5ec2a56dcf45c3dca6ced9de6bea5bcc9ea | |
parent | 2a49520d38b9e7fac09a18faca7307f9f1bd1c29 (diff) | |
download | neard-3cb819ac570b3c623daf0dbf22a4c951d3bf85ee.tar.gz neard-3cb819ac570b3c623daf0dbf22a4c951d3bf85ee.tar.bz2 neard-3cb819ac570b3c623daf0dbf22a4c951d3bf85ee.zip |
netlink: Implement DEP related messages and events
-rw-r--r-- | src/near.h | 3 | ||||
-rw-r--r-- | src/netlink.c | 112 |
2 files changed, 115 insertions, 0 deletions
@@ -126,6 +126,9 @@ int __near_tag_read(struct near_target *target, near_tag_read_cb cb); int __near_netlink_get_adapters(void); int __near_netlink_start_poll(int idx, uint32_t protocols); int __near_netlink_stop_poll(int idx); +int __near_netlink_dep_link_up(uint32_t idx, uint32_t target_idx, + uint8_t comm_mode, uint8_t rf_mode); +int __near_netlink_dep_link_down(uint32_t idx); int __near_netlink_activate_target(uint32_t adapter_idx, uint32_t target_idx, uint32_t protocol); diff --git a/src/netlink.c b/src/netlink.c index 3c26687..651186f 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -272,6 +272,72 @@ nla_put_failure: return err; } +int __near_netlink_dep_link_up(uint32_t idx, uint32_t target_idx, + uint8_t comm_mode, uint8_t rf_mode) +{ + struct nl_msg *msg; + void *hdr; + int family, err = 0; + + DBG(""); + + msg = nlmsg_alloc(); + if (msg == NULL) + return -ENOMEM; + + family = genl_family_get_id(nfc_state->nlnfc); + + hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, + NLM_F_REQUEST, NFC_CMD_DEP_LINK_UP, NFC_GENL_VERSION); + if (hdr == NULL) { + err = -EINVAL; + goto nla_put_failure; + } + + NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, idx); + NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target_idx); + NLA_PUT_U8(msg, NFC_ATTR_COMM_MODE, comm_mode); + NLA_PUT_U8(msg, NFC_ATTR_RF_MODE, rf_mode); + + err = nl_send_msg(nfc_state->nl_sock, msg, NULL, NULL); + +nla_put_failure: + nlmsg_free(msg); + + return err; +} + +int __near_netlink_dep_link_down(uint32_t idx) +{ + struct nl_msg *msg; + void *hdr; + int family, err = 0; + + DBG(""); + + msg = nlmsg_alloc(); + if (msg == NULL) + return -ENOMEM; + + family = genl_family_get_id(nfc_state->nlnfc); + + hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, + NLM_F_REQUEST, NFC_CMD_DEP_LINK_DOWN, NFC_GENL_VERSION); + if (hdr == NULL) { + err = -EINVAL; + goto nla_put_failure; + } + + NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, idx); + + err = nl_send_msg(nfc_state->nl_sock, msg, NULL, NULL); + +nla_put_failure: + nlmsg_free(msg); + + return err; +} + static int no_seq_check(struct nl_msg *n, void *arg) { DBG(""); @@ -393,6 +459,46 @@ nla_put_failure: return err; } +static int nfc_netlink_event_dep_up(struct genlmsghdr *gnlh) +{ + struct nlattr *attrs[NFC_ATTR_MAX + 1]; + uint32_t idx, target_idx = 0; + uint8_t rf_mode; + + DBG(""); + + nla_parse(attrs, NFC_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + if (attrs[NFC_ATTR_DEVICE_INDEX] == NULL) { + near_error("Missing device index"); + return -ENODEV; + } + + if (attrs[NFC_ATTR_COMM_MODE] == NULL || + attrs[NFC_ATTR_RF_MODE] == NULL) { + near_error("Missing rf or comm modes"); + return -ENODEV; + } + + idx = nla_get_u32(attrs[NFC_ATTR_DEVICE_INDEX]); + rf_mode = nla_get_u8(attrs[NFC_ATTR_RF_MODE]); + + if (rf_mode == NFC_RF_INITIATOR) { + if (attrs[NFC_ATTR_TARGET_INDEX] == NULL) { + near_error("Missing target index"); + return -ENODEV; + }; + + target_idx = nla_get_u32(attrs[NFC_ATTR_TARGET_INDEX]); + + DBG("%d %d", idx, target_idx); + + return 0; + } else { + return -EOPNOTSUPP; + } +} + static int nfc_netlink_event(struct nl_msg *n, void *arg) { struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(n)); @@ -414,6 +520,12 @@ static int nfc_netlink_event(struct nl_msg *n, void *arg) nfc_netlink_event_adapter(gnlh, FALSE); break; + + case NFC_CMD_DEP_LINK_UP: + DBG("DEP link is up"); + nfc_netlink_event_dep_up(gnlh); + + break; } return NL_SKIP; |