nfctool: Add command line options to power up or down a device
authorThierry Escande <thierry.escande@linux.intel.com>
Fri, 3 May 2013 15:03:04 +0000 (17:03 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 21 May 2013 10:39:41 +0000 (12:39 +0200)
--enable (-1 for short) turns the specified device on
--disable (-0) turns it off

If both are specified, only --enable is applied

tools/nfctool/main.c
tools/nfctool/netlink.c
tools/nfctool/netlink.h
tools/nfctool/nfctool.h

index f11d800..340f53b 100644 (file)
@@ -135,6 +135,23 @@ static int nfctool_snl_send_request(struct nfc_adapter *adapter)
        return err;
 }
 
+static int nfctool_set_powered(gboolean powered)
+{
+       struct nfc_adapter *adapter;
+       int err;
+
+       adapter = adapter_get(opts.adapter_idx);
+       if (!adapter)
+               return -ENODEV;
+
+       err = nl_set_powered(adapter, powered);
+
+       if (err == 0)
+               adapter->powered = powered;
+
+       return err;
+}
+
 static int nfctool_dep_link_up_cb(guint8 cmd, guint32 idx, gpointer data)
 {
        struct nfc_adapter *adapter;
@@ -339,6 +356,8 @@ struct nfctool_options opts = {
        .poll_mode = POLLING_MODE_INITIATOR,
        .device_name = NULL,
        .adapter_idx = INVALID_ADAPTER_IDX,
+       .enable_dev = FALSE,
+       .disable_dev = FALSE,
        .set_param = FALSE,
        .lto = -1,
        .rw = -1,
@@ -485,6 +504,10 @@ static GOptionEntry option_entries[] = {
        { "poll", 'p', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
          opt_parse_poll_arg, "start polling as initiator, target, or both; "
          "default mode is initiator", "[Initiator|Target|Both]" },
+       { "enable", '1', 0, G_OPTION_ARG_NONE, &opts.enable_dev,
+         "enable device", NULL },
+       { "disable", '0', 0, G_OPTION_ARG_NONE, &opts.disable_dev,
+         "disable device", NULL },
        { "set-param", 's', 0, G_OPTION_ARG_CALLBACK, opt_parse_set_param_arg,
          "set lto, rw, and/or miux parameters", "lto=150,rw=1,miux=100" },
        { "snl", 'k', 0, G_OPTION_ARG_CALLBACK, &opt_parse_snl_arg,
@@ -551,6 +574,9 @@ static int nfctool_options_parse(int argc, char **argv)
                }
        }
 
+       if (opts.enable_dev || opts.disable_dev)
+               opts.list = TRUE;
+
        opts.need_netlink = opts.list || opts.poll ||
                            opts.set_param || opts.snl;
 
@@ -560,7 +586,8 @@ static int nfctool_options_parse(int argc, char **argv)
                goto exit;
        }
 
-       if ((opts.poll || opts.set_param || opts.sniff || opts.snl) &&
+       if ((opts.poll || opts.set_param || opts.sniff || opts.snl ||
+           opts.enable_dev || opts.disable_dev) &&
            opts.adapter_idx == INVALID_ADAPTER_IDX) {
                print_error("Please specify a device with -d nfcX option");
 
@@ -642,6 +669,15 @@ int main(int argc, char **argv)
                        goto exit_err;
        }
 
+       if (opts.enable_dev || opts.disable_dev) {
+               err = nfctool_set_powered(opts.enable_dev);
+
+               if (err && err != -EALREADY)
+                       goto exit_err;
+
+               err = 0;
+       }
+
        if (opts.list && !opts.set_param)
                adapter_idx_print_info(opts.adapter_idx);
 
index dc66528..18c48a6 100644 (file)
@@ -556,6 +556,43 @@ nla_put_failure:
        return err;
 }
 
+int nl_set_powered(struct nfc_adapter *adapter, gboolean powered)
+{
+       struct nl_msg *msg;
+       void *hdr;
+       int err;
+       uint8_t cmd;
+
+       DBG("");
+
+       msg = nlmsg_alloc();
+       if (msg == NULL)
+               return -ENOMEM;
+
+       if (powered == TRUE)
+               cmd = NFC_CMD_DEV_UP;
+       else
+               cmd = NFC_CMD_DEV_DOWN;
+
+       hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, nfc_state->nfc_id, 0,
+                       NLM_F_REQUEST, cmd, NFC_GENL_VERSION);
+       if (hdr == NULL) {
+               err = -EINVAL;
+               goto nla_put_failure;
+       }
+
+       err = -EMSGSIZE;
+
+       NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, adapter->idx);
+
+       err = nl_send_msg(nfc_state->cmd_sock, msg, NULL, NULL);
+
+nla_put_failure:
+       nlmsg_free(msg);
+
+       return err;
+}
+
 int nl_send_sdreq(struct nfc_adapter *adapter, GSList *uris)
 {
        struct nl_msg *msg;
index e1b8bd7..651a8aa 100644 (file)
@@ -46,4 +46,6 @@ int nl_get_params(struct nfc_adapter *adapter);
 
 int nl_send_sdreq(struct nfc_adapter *adapter, GSList *uris);
 
+int nl_set_powered(struct nfc_adapter *adapter, gboolean powered);
+
 #endif /* __NETLINK_H */
index 53d8f35..7248ab1 100644 (file)
@@ -65,6 +65,8 @@ struct nfctool_options {
        guint8 poll_mode;
        gchar *device_name;
        guint32 adapter_idx;
+       gboolean enable_dev;
+       gboolean disable_dev;
        gboolean set_param;
        gint32 lto;
        gint32 rw;