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>
15 static int handle_ftm_stats(struct nl_msg
*msg
, void *arg
)
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
},
34 nla_parse(tb
, NL80211_ATTR_MAX
, genlmsg_attrdata(gnlh
, 0),
35 genlmsg_attrlen(gnlh
, 0), NULL
);
37 if (!tb
[NL80211_ATTR_FTM_RESPONDER_STATS
]) {
38 fprintf(stderr
, "FTM responder statistics are missing");
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
]),
47 printf("FTM responder stats:\n");
49 if (info
[NL80211_FTM_STATS_SUCCESS_NUM
])
50 printf("\tSuccess num %u\n",
51 nla_get_u32(info
[NL80211_FTM_STATS_SUCCESS_NUM
]));
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
]));
57 if (info
[NL80211_FTM_STATS_FAILED_NUM
])
58 printf("\tFailed num %u\n",
59 nla_get_u32(info
[NL80211_FTM_STATS_FAILED_NUM
]));
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
]));
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
]));
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
]));
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
]));
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
]));
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
]));
88 static int handle_ftm_get_stats(struct nl80211_state
*state
,
89 struct nl_msg
*msg
, int argc
, char **argv
,
92 register_handler(handle_ftm_stats
, NULL
);
96 COMMAND(ftm
, get_stats
, "",
97 NL80211_CMD_GET_FTM_RESPONDER_STATS
, 0, CIB_NETDEV
, handle_ftm_get_stats
,
98 "Get FTM responder statistics.\n");
100 static int handle_ftm_start_responder(struct nl80211_state
*state
,
101 struct nl_msg
*msg
, int argc
, char **argv
,
106 bool lci_present
= false, civic_present
= false;
107 struct nlattr
*ftm
= nla_nest_start(msg
, NL80211_ATTR_FTM_RESPONDER
);
112 nla_put_flag(msg
, NL80211_FTM_RESP_ATTR_ENABLED
);
114 for (i
= 0; i
< argc
; i
++) {
115 if (strncmp(argv
[i
], "lci=", 4) == 0) {
116 size_t lci_len
= strlen(argv
[i
] + 4);
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
;
125 NLA_PUT(msg
, NL80211_FTM_RESP_ATTR_LCI
,
127 } else if (strncmp(argv
[i
], "civic=", 6) == 0) {
128 size_t civic_len
= strlen(argv
[i
] + 6);
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
;
136 civic_present
= true;
137 NLA_PUT(msg
, NL80211_FTM_RESP_ATTR_CIVICLOC
,
140 printf("Illegal argument: %s\n", argv
[i
]);
141 return HANDLER_RET_USAGE
;
145 nla_nest_end(msg
, ftm
);
153 COMMAND(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");