]> git.ipfire.org Git - thirdparty/iw.git/blame - ftm.c
update nl80211.h
[thirdparty/iw.git] / ftm.c
CommitLineData
02b85d80
JB
1#include <errno.h>
2
3#include <netlink/genl/genl.h>
4#include <netlink/genl/family.h>
5#include <netlink/genl/ctrl.h>
6#include <netlink/msg.h>
7#include <netlink/attr.h>
8#include <inttypes.h>
9
10#include "nl80211.h"
11#include "iw.h"
12
13SECTION(ftm);
14
15static int handle_ftm_stats(struct nl_msg *msg, void *arg)
16{
17 struct nlattr *tb[NL80211_ATTR_MAX + 1];
18 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
19 struct nlattr *info[NL80211_FTM_STATS_MAX + 1];
20 static struct nla_policy info_policy[NL80211_FTM_STATS_MAX + 1] = {
21 [NL80211_FTM_STATS_SUCCESS_NUM] = { .type = NLA_U32 },
22 [NL80211_FTM_STATS_PARTIAL_NUM] = { .type = NLA_U32 },
23 [NL80211_FTM_STATS_FAILED_NUM] = { .type = NLA_U32 },
24 [NL80211_FTM_STATS_ASAP_NUM] = { .type = NLA_U32 },
25 [NL80211_FTM_STATS_NON_ASAP_NUM] = { .type = NLA_U32 },
26 [NL80211_FTM_STATS_TOTAL_DURATION_MSEC] = { .type = NLA_U64 },
27 [NL80211_FTM_STATS_UNKNOWN_TRIGGERS_NUM] = { .type = NLA_U32 },
28 [NL80211_FTM_STATS_RESCHEDULE_REQUESTS_NUM]
29 = { .type = NLA_U32 },
30 [NL80211_FTM_STATS_OUT_OF_WINDOW_TRIGGERS_NUM]
31 = { .type = NLA_U32 },
32 };
33
34 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
35 genlmsg_attrlen(gnlh, 0), NULL);
36
37 if (!tb[NL80211_ATTR_FTM_RESPONDER_STATS]) {
38 fprintf(stderr, "FTM responder statistics are missing");
39 return NL_SKIP;
40 }
41
42 nla_parse(info, NL80211_REG_RULE_ATTR_MAX,
43 nla_data(tb[NL80211_ATTR_FTM_RESPONDER_STATS]),
44 nla_len(tb[NL80211_ATTR_FTM_RESPONDER_STATS]),
45 info_policy);
46
47 printf("FTM responder stats:\n");
48
49 if (info[NL80211_FTM_STATS_SUCCESS_NUM])
50 printf("\tSuccess num %u\n",
51 nla_get_u32(info[NL80211_FTM_STATS_SUCCESS_NUM]));
52
53 if (info[NL80211_FTM_STATS_PARTIAL_NUM])
54 printf("\tPartial success num %u\n",
55 nla_get_u32(info[NL80211_FTM_STATS_PARTIAL_NUM]));
56
57 if (info[NL80211_FTM_STATS_FAILED_NUM])
58 printf("\tFailed num %u\n",
59 nla_get_u32(info[NL80211_FTM_STATS_FAILED_NUM]));
60
61 if (info[NL80211_FTM_STATS_ASAP_NUM])
62 printf("\tASAP success num %u\n",
63 nla_get_u32(info[NL80211_FTM_STATS_ASAP_NUM]));
64
65 if (info[NL80211_FTM_STATS_NON_ASAP_NUM])
66 printf("\tNon ASAP num %u\n",
67 nla_get_u32(info[NL80211_FTM_STATS_NON_ASAP_NUM]));
68
69 if (info[NL80211_FTM_STATS_TOTAL_DURATION_MSEC])
70 printf("\tTotal duration %" PRIu64 "\n",
71 nla_get_u64(info[NL80211_FTM_STATS_TOTAL_DURATION_MSEC]));
72
73 if (info[NL80211_FTM_STATS_UNKNOWN_TRIGGERS_NUM])
74 printf("\tUnknown triggers num %u\n",
75 nla_get_u32(info[NL80211_FTM_STATS_UNKNOWN_TRIGGERS_NUM]));
76
77 if (info[NL80211_FTM_STATS_RESCHEDULE_REQUESTS_NUM])
78 printf("\tRescheduled requests num %u\n",
79 nla_get_u32(info[NL80211_FTM_STATS_RESCHEDULE_REQUESTS_NUM]));
80
81 if (info[NL80211_FTM_STATS_OUT_OF_WINDOW_TRIGGERS_NUM])
82 printf("\tOut of window num %u\n",
83 nla_get_u32(info[NL80211_FTM_STATS_OUT_OF_WINDOW_TRIGGERS_NUM]));
84
85 return NL_SKIP;
86}
87
88static int handle_ftm_get_stats(struct nl80211_state *state,
89 struct nl_msg *msg, int argc, char **argv,
90 enum id_input id)
91{
92 register_handler(handle_ftm_stats, NULL);
93 return 0;
94}
95
96COMMAND(ftm, get_stats, "",
97 NL80211_CMD_GET_FTM_RESPONDER_STATS, 0, CIB_NETDEV, handle_ftm_get_stats,
98 "Get FTM responder statistics.\n");
99
100static int handle_ftm_start_responder(struct nl80211_state *state,
101 struct nl_msg *msg, int argc, char **argv,
102 enum id_input id)
103{
104 int i;
105 char buf[256];
106 bool lci_present = false, civic_present = false;
107 struct nlattr *ftm = nla_nest_start(msg, NL80211_ATTR_FTM_RESPONDER);
108
109 if (!ftm)
110 return -ENOBUFS;
111
112 nla_put_flag(msg, NL80211_FTM_RESP_ATTR_ENABLED);
113
114 for (i = 0; i < argc; i++) {
115 if (strncmp(argv[i], "lci=", 4) == 0) {
116 size_t lci_len = strlen(argv[i] + 4);
117
118 if (lci_present || !lci_len || lci_len % 2 ||
119 !hex2bin(argv[i] + 4, buf)) {
120 printf("Illegal LCI buffer!\n");
121 return HANDLER_RET_USAGE;
122 }
123
124 lci_present = true;
125 NLA_PUT(msg, NL80211_FTM_RESP_ATTR_LCI,
126 lci_len / 2, buf);
127 } else if (strncmp(argv[i], "civic=", 6) == 0) {
128 size_t civic_len = strlen(argv[i] + 6);
129
130 if (civic_present || !civic_len || civic_len % 2 ||
131 !hex2bin(argv[i] + 6, buf)) {
132 printf("Illegal CIVIC buffer!\n");
133 return HANDLER_RET_USAGE;
134 }
135
136 civic_present = true;
137 NLA_PUT(msg, NL80211_FTM_RESP_ATTR_CIVICLOC,
138 civic_len / 2, buf);
139 } else {
140 printf("Illegal argument: %s\n", argv[i]);
141 return HANDLER_RET_USAGE;
142 }
143 }
144
145 nla_nest_end(msg, ftm);
146
147 return 0;
148
149nla_put_failure:
150 return -ENOMEM;
151}
152
153COMMAND(ftm, start_responder,
154 "[lci=<lci buffer in hex>] [civic=<civic buffer in hex>]",
155 NL80211_CMD_SET_BEACON, 0, CIB_NETDEV,
156 handle_ftm_start_responder,
157 "Start an FTM responder. Needs a running ap interface\n");