xref: /wlan-dirver/utils/sigma-dut/wlantest.c (revision f722271e7b368f3d96d247dac8ee42a11e89ad0d)
1 /*
2  * Sigma Control API DUT (wlantest)
3  * Copyright (c) 2010-2011, Atheros Communications, Inc.
4  * Copyright (c) 2011-2013, 2017, Qualcomm Atheros, Inc.
5  * All Rights Reserved.
6  * Licensed under the Clear BSD license. See README for more details.
7  */
8 
9 #include "sigma_dut.h"
10 #include <sys/un.h>
11 #include "wlantest_ctrl.h"
12 
13 
14 #ifndef ETH_ALEN
15 #define ETH_ALEN 6
16 #endif
17 
18 int hwaddr_aton(const char *txt, unsigned char *addr);
19 
20 
attr_get(u8 * buf,size_t buflen,enum wlantest_ctrl_attr attr,size_t * len)21 static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
22 		     size_t *len)
23 {
24 	u8 *pos = buf;
25 
26 	while (pos + 8 <= buf + buflen) {
27 		enum wlantest_ctrl_attr a;
28 		size_t alen;
29 		a = WPA_GET_BE32(pos);
30 		pos += 4;
31 		alen = WPA_GET_BE32(pos);
32 		pos += 4;
33 		if (pos + alen > buf + buflen)
34 			return NULL;
35 		if (a == attr) {
36 			*len = alen;
37 			return pos;
38 		}
39 		pos += alen;
40 	}
41 
42 	return NULL;
43 }
44 
45 
attr_hdr_add(u8 * pos,u8 * end,enum wlantest_ctrl_attr attr,size_t len)46 static u8 * attr_hdr_add(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
47 			 size_t len)
48 {
49 	if (pos == NULL || end - pos < (int) (8 + len))
50 		return NULL;
51 	WPA_PUT_BE32(pos, attr);
52 	pos += 4;
53 	WPA_PUT_BE32(pos, len);
54 	pos += 4;
55 	return pos;
56 }
57 
58 
attr_add_str(u8 * pos,u8 * end,enum wlantest_ctrl_attr attr,const char * str)59 static u8 * attr_add_str(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
60 			 const char *str)
61 {
62 	size_t len = strlen(str);
63 
64 	if (pos == NULL || end - pos < (int) (8 + len))
65 		return NULL;
66 	WPA_PUT_BE32(pos, attr);
67 	pos += 4;
68 	WPA_PUT_BE32(pos, len);
69 	pos += 4;
70 	memcpy(pos, str, len);
71 	pos += len;
72 	return pos;
73 }
74 
75 
attr_add_be32(u8 * pos,u8 * end,enum wlantest_ctrl_attr attr,u32 val)76 static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
77 			  u32 val)
78 {
79 	if (pos == NULL || end - pos < 12)
80 		return NULL;
81 	WPA_PUT_BE32(pos, attr);
82 	pos += 4;
83 	WPA_PUT_BE32(pos, 4);
84 	pos += 4;
85 	WPA_PUT_BE32(pos, val);
86 	pos += 4;
87 	return pos;
88 }
89 
90 
open_wlantest(void)91 static int open_wlantest(void)
92 {
93 	int s;
94 	struct sockaddr_un addr;
95 
96 	s = socket(AF_UNIX, SOCK_SEQPACKET, 0);
97 	if (s < 0) {
98 		perror("socket");
99 		return -1;
100 	}
101 
102 	memset(&addr, 0, sizeof(addr));
103 	addr.sun_family = AF_UNIX;
104 	strlcpy(addr.sun_path + 1, WLANTEST_SOCK_NAME,
105 		sizeof(addr.sun_path) - 1);
106 	if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
107 		perror("connect");
108 		close(s);
109 		return -1;
110 	}
111 
112 	return s;
113 }
114 
115 
cmd_send_and_recv(int s,const u8 * cmd,size_t cmd_len,u8 * resp,size_t max_resp_len)116 static int cmd_send_and_recv(int s, const u8 *cmd, size_t cmd_len,
117 			     u8 *resp, size_t max_resp_len)
118 {
119 	int res;
120 	enum wlantest_ctrl_cmd cmd_resp;
121 
122 	if (send(s, cmd, cmd_len, 0) < 0)
123 		return -1;
124 	res = recv(s, resp, max_resp_len, 0);
125 	if (res < 4)
126 		return -1;
127 
128 	cmd_resp = WPA_GET_BE32(resp);
129 	if (cmd_resp == WLANTEST_CTRL_SUCCESS)
130 		return res;
131 
132 	return -1;
133 }
134 
135 
cmd_simple(int s,enum wlantest_ctrl_cmd cmd)136 static int cmd_simple(int s, enum wlantest_ctrl_cmd cmd)
137 {
138 	u8 buf[4];
139 	int res;
140 	WPA_PUT_BE32(buf, cmd);
141 	res = cmd_send_and_recv(s, buf, sizeof(buf), buf, sizeof(buf));
142 	return res < 0 ? -1 : 0;
143 }
144 
145 
run_wlantest_simple(struct sigma_dut * dut,struct sigma_conn * conn,enum wlantest_ctrl_cmd cmd)146 static int run_wlantest_simple(struct sigma_dut *dut, struct sigma_conn *conn,
147 			       enum wlantest_ctrl_cmd cmd)
148 {
149 	int s, ret;
150 
151 	s = open_wlantest();
152 	if (s < 0) {
153 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
154 			  "available");
155 		return 0;
156 	}
157 
158 	ret = cmd_simple(s, cmd);
159 	close(s);
160 
161 	return ret < 0 ? -2 : 1;
162 }
163 
164 
cmd_wlantest_version(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)165 static enum sigma_cmd_result cmd_wlantest_version(struct sigma_dut *dut,
166 						  struct sigma_conn *conn,
167 						  struct sigma_cmd *cmd)
168 {
169 	int s;
170 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
171 	u8 buf[4];
172 	char *version;
173 	size_t len;
174 	int rlen;
175 	char *rbuf;
176 
177 	s = open_wlantest();
178 	if (s < 0) {
179 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
180 			  "available");
181 		return 0;
182 	}
183 
184 	WPA_PUT_BE32(buf, WLANTEST_CTRL_VERSION);
185 	rlen = cmd_send_and_recv(s, buf, sizeof(buf), resp, sizeof(resp));
186 	close(s);
187 	if (rlen < 0)
188 		return -2;
189 
190 	version = (char *) attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_VERSION,
191 				    &len);
192 	if (version == NULL)
193 		return -2;
194 
195 	rbuf = malloc(9 + len);
196 	if (rbuf == NULL)
197 		return -2;
198 	memcpy(rbuf, "version,", 8);
199 	memcpy(rbuf + 8, version, len);
200 	rbuf[8 + len] = '\0';
201 	send_resp(dut, conn, SIGMA_COMPLETE, rbuf);
202 	free(rbuf);
203 	return 0;
204 }
205 
206 
cmd_wlantest_set_channel(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)207 enum sigma_cmd_result cmd_wlantest_set_channel(struct sigma_dut *dut,
208 					       struct sigma_conn *conn,
209 					       struct sigma_cmd *cmd)
210 {
211 	char buf[100];
212 	const char *chan;
213 
214 	if (dut->sniffer_ifname == NULL) {
215 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Sniffer "
216 			  "interface not available");
217 		return 0;
218 	}
219 
220 	chan = get_param(cmd, "channel");
221 	if (chan == NULL)
222 		return -1;
223 
224 	snprintf(buf, sizeof(buf), "iw dev %s set type monitor",
225 		 dut->sniffer_ifname);
226 	if (system(buf) != 0) {
227 		snprintf(buf, sizeof(buf), "ifconfig %s down",
228 			 dut->sniffer_ifname);
229 		if (system(buf) != 0) {
230 			sigma_dut_print(dut, DUT_MSG_INFO,
231 					"Failed to run '%s'", buf);
232 			return -2;
233 		}
234 
235 		snprintf(buf, sizeof(buf), "iw dev %s set type monitor",
236 			 dut->sniffer_ifname);
237 		if (system(buf) != 0) {
238 			sigma_dut_print(dut, DUT_MSG_INFO,
239 					"Failed to run '%s'", buf);
240 			return -2;
241 		}
242 	}
243 
244 	snprintf(buf, sizeof(buf), "iw dev %s set channel %d HT20",
245 		 dut->sniffer_ifname, atoi(chan));
246 	if (system(buf) != 0) {
247 		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s'", buf);
248 		return -2;
249 	}
250 
251 	snprintf(buf, sizeof(buf), "ifconfig %s up", dut->sniffer_ifname);
252 	if (system(buf) != 0) {
253 		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s'", buf);
254 		return -2;
255 	}
256 
257 	dut->mode = SIGMA_MODE_SNIFFER;
258 
259 	return 1;
260 }
261 
262 
cmd_wlantest_flush(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)263 static enum sigma_cmd_result cmd_wlantest_flush(struct sigma_dut *dut,
264 						struct sigma_conn *conn,
265 						struct sigma_cmd *cmd)
266 {
267 	return run_wlantest_simple(dut, conn, WLANTEST_CTRL_FLUSH);
268 }
269 
270 
cmd_wlantest_send_frame(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)271 enum sigma_cmd_result cmd_wlantest_send_frame(struct sigma_dut *dut,
272 					      struct sigma_conn *conn,
273 					      struct sigma_cmd *cmd)
274 {
275 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
276 	u8 buf[100], *end, *pos;
277 	int rlen;
278 	enum wlantest_inject_frame frame;
279 	enum wlantest_inject_protection prot;
280 	const char *val;
281 	int s;
282 
283 	/* wlantest_send_frame,PMFFrameType,disassoc,PMFProtected,Unprotected,sender,AP,bssid,00:11:22:33:44:55,stationID,00:66:77:88:99:aa */
284 
285 	if (dut->mode == SIGMA_MODE_STATION) {
286 		sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
287 				"wlantest_send_frame to sta_send_frame");
288 		return cmd_sta_send_frame(dut, conn, cmd);
289 	}
290 
291 	if (dut->mode == SIGMA_MODE_AP) {
292 		sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert "
293 				"wlantest_send_frame to ap_send_frame");
294 		return cmd_ap_send_frame(dut, conn, cmd);
295 	}
296 
297 	pos = buf;
298 	end = buf + sizeof(buf);
299 	WPA_PUT_BE32(pos, WLANTEST_CTRL_INJECT);
300 	pos += 4;
301 
302 	val = get_param(cmd, "Type");
303 	if (val == NULL)
304 		val = get_param(cmd, "PMFFrameType");
305 	if (val == NULL)
306 		return -1;
307 	if (strcasecmp(val, "disassoc") == 0)
308 		frame = WLANTEST_FRAME_DISASSOC;
309 	else if (strcasecmp(val, "deauth") == 0)
310 		frame = WLANTEST_FRAME_DEAUTH;
311 	else if (strcasecmp(val, "saquery") == 0)
312 		frame = WLANTEST_FRAME_SAQUERYREQ;
313 	else if (strcasecmp(val, "auth") == 0)
314 		frame = WLANTEST_FRAME_AUTH;
315 	else if (strcasecmp(val, "assocreq") == 0)
316 		frame = WLANTEST_FRAME_ASSOCREQ;
317 	else if (strcasecmp(val, "reassocreq") == 0)
318 		frame = WLANTEST_FRAME_REASSOCREQ;
319 	else {
320 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
321 			  "PMFFrameType");
322 		return 0;
323 	}
324 	pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_FRAME, frame);
325 
326 	val = get_param(cmd, "Protected");
327 	if (val == NULL)
328 		val = get_param(cmd, "PMFProtected");
329 	if (val == NULL)
330 		return -1;
331 	if (strcasecmp(val, "CorrectKey") == 0)
332 		prot = WLANTEST_INJECT_PROTECTED;
333 	else if (strcasecmp(val, "IncorrectKey") == 0)
334 		prot = WLANTEST_INJECT_INCORRECT_KEY;
335 	else if (strcasecmp(val, "Unprotected") == 0)
336 		prot = WLANTEST_INJECT_UNPROTECTED;
337 	else {
338 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
339 			  "PMFProtected");
340 		return 0;
341 	}
342 	pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_PROTECTION, prot);
343 
344 	val = get_param(cmd, "sender");
345 	if (val == NULL)
346 		return -1;
347 	if (strcasecmp(val, "ap") == 0) {
348 		pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_SENDER_AP,
349 				    1);
350 	} else if (strcasecmp(val, "sta") == 0) {
351 		pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_SENDER_AP,
352 				    0);
353 	} else {
354 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
355 			  "sender");
356 		return 0;
357 	}
358 
359 	val = get_param(cmd, "bssid");
360 	if (val == NULL)
361 		return -1;
362 	pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
363 	if (hwaddr_aton(val, pos) < 0) {
364 		send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid bssid");
365 		return 0;
366 	}
367 	pos += ETH_ALEN;
368 
369 	val = get_param(cmd, "stationID");
370 	if (val == NULL)
371 		return -1;
372 	pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
373 	if (hwaddr_aton(val, pos) < 0) {
374 		send_resp(dut, conn, SIGMA_INVALID,
375 			  "errorCode,Invalid stationID");
376 		return 0;
377 	}
378 	pos += ETH_ALEN;
379 
380 	s = open_wlantest();
381 	if (s < 0) {
382 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
383 			  "available");
384 		return 0;
385 	}
386 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
387 	close(s);
388 	if (rlen < 0)
389 		return -2;
390 	return 1;
391 }
392 
393 
394 static enum sigma_cmd_result
cmd_wlantest_add_passphrase(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)395 cmd_wlantest_add_passphrase(struct sigma_dut *dut, struct sigma_conn *conn,
396 			    struct sigma_cmd *cmd)
397 {
398 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
399 	u8 buf[100], *end, *pos;
400 	int rlen;
401 	const char *val;
402 	int s;
403 
404 	pos = buf;
405 	end = buf + sizeof(buf);
406 	WPA_PUT_BE32(pos, WLANTEST_CTRL_ADD_PASSPHRASE);
407 	pos += 4;
408 
409 	val = get_param(cmd, "passphrase");
410 	if (val) {
411 		if (strlen(val) < 8 || strlen(val) > 63)
412 			return -1;
413 		pos = attr_add_str(pos, end, WLANTEST_ATTR_PASSPHRASE, val);
414 	} else {
415 		val = get_param(cmd, "wepkey");
416 		if (!val)
417 			return -1;
418 		pos = attr_add_str(pos, end, WLANTEST_ATTR_WEPKEY, val);
419 	}
420 	val = get_param(cmd, "bssid");
421 	if (val) {
422 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
423 		if (hwaddr_aton(val, pos) < 0) {
424 			send_resp(dut, conn, SIGMA_INVALID,
425 				  "errorCode,Invalid bssid");
426 			return 0;
427 		}
428 		pos += ETH_ALEN;
429 	}
430 
431 	s = open_wlantest();
432 	if (s < 0) {
433 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
434 			  "available");
435 		return 0;
436 	}
437 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
438 	close(s);
439 	if (rlen < 0)
440 		return -2;
441 	return 1;
442 }
443 
444 
445 static enum sigma_cmd_result
cmd_wlantest_clear_sta_counters(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)446 cmd_wlantest_clear_sta_counters(struct sigma_dut *dut, struct sigma_conn *conn,
447 				struct sigma_cmd *cmd)
448 {
449 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
450 	u8 buf[100], *end, *pos;
451 	int rlen;
452 	const char *val;
453 	int s;
454 
455 	pos = buf;
456 	end = buf + sizeof(buf);
457 	WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_STA_COUNTERS);
458 	pos += 4;
459 
460 	val = get_param(cmd, "bssid");
461 	if (val == NULL)
462 		return -1;
463 	if (val) {
464 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
465 		if (hwaddr_aton(val, pos) < 0) {
466 			send_resp(dut, conn, SIGMA_INVALID,
467 				  "errorCode,Invalid bssid");
468 			return 0;
469 		}
470 		pos += ETH_ALEN;
471 	}
472 
473 	val = get_param(cmd, "stationID");
474 	if (val == NULL)
475 		return -1;
476 	if (val) {
477 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
478 		if (hwaddr_aton(val, pos) < 0) {
479 			send_resp(dut, conn, SIGMA_INVALID,
480 				  "errorCode,Invalid stationID");
481 			return 0;
482 		}
483 		pos += ETH_ALEN;
484 	}
485 
486 	s = open_wlantest();
487 	if (s < 0) {
488 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
489 			  "available");
490 		return 0;
491 	}
492 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
493 	close(s);
494 	if (rlen < 0)
495 		return -2;
496 	return 1;
497 }
498 
499 
500 static enum sigma_cmd_result
cmd_wlantest_clear_bss_counters(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)501 cmd_wlantest_clear_bss_counters(struct sigma_dut *dut, struct sigma_conn *conn,
502 				struct sigma_cmd *cmd)
503 {
504 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
505 	u8 buf[100], *end, *pos;
506 	int rlen;
507 	const char *val;
508 	int s;
509 
510 	pos = buf;
511 	end = buf + sizeof(buf);
512 	WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_BSS_COUNTERS);
513 	pos += 4;
514 
515 	val = get_param(cmd, "bssid");
516 	if (val == NULL)
517 		return -1;
518 	if (val) {
519 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
520 		if (hwaddr_aton(val, pos) < 0) {
521 			send_resp(dut, conn, SIGMA_INVALID,
522 				  "errorCode,Invalid bssid");
523 			return 0;
524 		}
525 		pos += ETH_ALEN;
526 	}
527 
528 	s = open_wlantest();
529 	if (s < 0) {
530 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
531 			  "available");
532 		return 0;
533 	}
534 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
535 	close(s);
536 	if (rlen < 0)
537 		return -2;
538 	return 1;
539 }
540 
541 
542 static enum sigma_cmd_result
cmd_wlantest_clear_tdls_counters(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)543 cmd_wlantest_clear_tdls_counters(struct sigma_dut *dut, struct sigma_conn *conn,
544 				 struct sigma_cmd *cmd)
545 {
546 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
547 	u8 buf[100], *end, *pos;
548 	int rlen;
549 	const char *val;
550 	int s;
551 
552 	pos = buf;
553 	end = buf + sizeof(buf);
554 	WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_TDLS_COUNTERS);
555 	pos += 4;
556 
557 	val = get_param(cmd, "bssid");
558 	if (val == NULL)
559 		return -1;
560 	if (val) {
561 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
562 		if (hwaddr_aton(val, pos) < 0) {
563 			send_resp(dut, conn, SIGMA_INVALID,
564 				  "errorCode,Invalid bssid");
565 			return 0;
566 		}
567 		pos += ETH_ALEN;
568 	}
569 
570 	val = get_param(cmd, "stationID");
571 	if (val == NULL)
572 		return -1;
573 	if (val) {
574 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
575 		if (hwaddr_aton(val, pos) < 0) {
576 			send_resp(dut, conn, SIGMA_INVALID,
577 				  "errorCode,Invalid stationID");
578 			return 0;
579 		}
580 		pos += ETH_ALEN;
581 	}
582 
583 	val = get_param(cmd, "stationID2");
584 	if (val == NULL)
585 		return -1;
586 	if (val) {
587 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA2_ADDR,
588 				   ETH_ALEN);
589 		if (hwaddr_aton(val, pos) < 0) {
590 			send_resp(dut, conn, SIGMA_INVALID,
591 				  "errorCode,Invalid stationID2");
592 			return 0;
593 		}
594 		pos += ETH_ALEN;
595 	}
596 
597 	s = open_wlantest();
598 	if (s < 0) {
599 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
600 			  "available");
601 		return 0;
602 	}
603 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
604 	close(s);
605 	if (rlen < 0)
606 		return -2;
607 	return 1;
608 }
609 
610 
611 struct sta_counters {
612 	const char *name;
613 	enum wlantest_sta_counter num;
614 };
615 
616 static const struct sta_counters sta_counters[] = {
617 	{ "auth_tx", WLANTEST_STA_COUNTER_AUTH_TX },
618 	{ "auth_rx", WLANTEST_STA_COUNTER_AUTH_RX },
619 	{ "assocreq_tx", WLANTEST_STA_COUNTER_ASSOCREQ_TX },
620 	{ "reassocreq_tx", WLANTEST_STA_COUNTER_REASSOCREQ_TX },
621 	{ "ptk_learned", WLANTEST_STA_COUNTER_PTK_LEARNED },
622 	{ "valid_deauth_tx", WLANTEST_STA_COUNTER_VALID_DEAUTH_TX },
623 	{ "valid_deauth_rx", WLANTEST_STA_COUNTER_VALID_DEAUTH_RX },
624 	{ "invalid_deauth_tx", WLANTEST_STA_COUNTER_INVALID_DEAUTH_TX },
625 	{ "invalid_deauth_rx", WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX },
626 	{ "valid_disassoc_tx", WLANTEST_STA_COUNTER_VALID_DISASSOC_TX },
627 	{ "valid_disassoc_rx", WLANTEST_STA_COUNTER_VALID_DISASSOC_RX },
628 	{ "invalid_disassoc_tx", WLANTEST_STA_COUNTER_INVALID_DISASSOC_TX },
629 	{ "invalid_disassoc_rx", WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX },
630 	{ "valid_saqueryreq_tx", WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_TX },
631 	{ "valid_saqueryreq_rx", WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_RX },
632 	{ "invalid_saqueryreq_tx",
633 	  WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_TX },
634 	{ "invalid_saqueryreq_rx",
635 	  WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_RX },
636 	{ "valid_saqueryresp_tx", WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_TX },
637 	{ "valid_saqueryresp_rx", WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_RX },
638 	{ "invalid_saqueryresp_tx",
639 	  WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_TX },
640 	{ "invalid_saqueryresp_rx",
641 	  WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX },
642 	{ "ping_ok", WLANTEST_STA_COUNTER_PING_OK },
643 	{ "assocresp_comeback", WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK },
644 	{ "reassocresp_comeback", WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK },
645 	{ "ping_ok_first_assoc", WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC },
646 	{ "valid_deauth_rx_ack", WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK },
647 	{ "valid_disassoc_rx_ack",
648 	  WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK },
649 	{ "invalid_deauth_rx_ack",
650 	  WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK },
651 	{ "invalid_disassoc_rx_ack",
652 	  WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK },
653 	{ "deauth_rx_asleep", WLANTEST_STA_COUNTER_DEAUTH_RX_ASLEEP },
654 	{ "deauth_rx_awake", WLANTEST_STA_COUNTER_DEAUTH_RX_AWAKE },
655 	{ "disassoc_rx_asleep", WLANTEST_STA_COUNTER_DISASSOC_RX_ASLEEP },
656 	{ "disassoc_rx_awake", WLANTEST_STA_COUNTER_DISASSOC_RX_AWAKE },
657 	{ "prot_data_tx", WLANTEST_STA_COUNTER_PROT_DATA_TX },
658 	{ "deauth_rx_rc6", WLANTEST_STA_COUNTER_DEAUTH_RX_RC6 },
659 	{ "deauth_rx_rc7", WLANTEST_STA_COUNTER_DEAUTH_RX_RC7 },
660 	{ "disassoc_rx_rc6", WLANTEST_STA_COUNTER_DISASSOC_RX_RC6 },
661 	{ "disassoc_rx_rc7", WLANTEST_STA_COUNTER_DISASSOC_RX_RC7 },
662 	{ NULL, 0 }
663 };
664 
665 static enum sigma_cmd_result
cmd_wlantest_get_sta_counter(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)666 cmd_wlantest_get_sta_counter(struct sigma_dut *dut, struct sigma_conn *conn,
667 			     struct sigma_cmd *cmd)
668 {
669 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
670 	u8 buf[100], *end, *pos;
671 	int rlen;
672 	const char *val;
673 	int s, i;
674 	char ret[100];
675 	size_t len;
676 
677 	pos = buf;
678 	end = buf + sizeof(buf);
679 	WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_STA_COUNTER);
680 	pos += 4;
681 
682 	val = get_param(cmd, "bssid");
683 	if (val == NULL)
684 		return -1;
685 	if (val) {
686 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
687 		if (hwaddr_aton(val, pos) < 0) {
688 			send_resp(dut, conn, SIGMA_INVALID,
689 				  "errorCode,Invalid bssid");
690 			return 0;
691 		}
692 		pos += ETH_ALEN;
693 	}
694 
695 	val = get_param(cmd, "stationID");
696 	if (val == NULL)
697 		return -1;
698 	if (val) {
699 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
700 		if (hwaddr_aton(val, pos) < 0) {
701 			send_resp(dut, conn, SIGMA_INVALID,
702 				  "errorCode,Invalid stationID");
703 			return 0;
704 		}
705 		pos += ETH_ALEN;
706 	}
707 
708 	val = get_param(cmd, "field");
709 	if (val == NULL)
710 		return -1;
711 	for (i = 0; sta_counters[i].name; i++) {
712 		if (strcasecmp(sta_counters[i].name, val) == 0)
713 			break;
714 	}
715 	if (sta_counters[i].name == NULL) {
716 		send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
717 		return 0;
718 	}
719 	pos = attr_add_be32(pos, end, WLANTEST_ATTR_STA_COUNTER,
720 			    sta_counters[i].num);
721 
722 	s = open_wlantest();
723 	if (s < 0) {
724 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
725 			  "available");
726 		return 0;
727 	}
728 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
729 	close(s);
730 
731 
732 	pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
733 	if (pos == NULL || len != 4)
734 		return -2;
735 	snprintf(ret, sizeof(ret), "counter,%u", WPA_GET_BE32(pos));
736 	send_resp(dut, conn, SIGMA_COMPLETE, ret);
737 	return 0;
738 }
739 
740 
741 struct bss_counters {
742 	const char *name;
743 	enum wlantest_bss_counter num;
744 };
745 
746 static const struct bss_counters bss_counters[] = {
747 	{ "valid_bip_mmie", WLANTEST_BSS_COUNTER_VALID_BIP_MMIE },
748 	{ "invalid_bip_mmie", WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE },
749 	{ "missing_bip_mmie", WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE },
750 	{ "bip_deauth", WLANTEST_BSS_COUNTER_BIP_DEAUTH },
751 	{ "bip_disassoc", WLANTEST_BSS_COUNTER_BIP_DISASSOC },
752 	{ NULL, 0 }
753 };
754 
755 static enum sigma_cmd_result
cmd_wlantest_get_bss_counter(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)756 cmd_wlantest_get_bss_counter(struct sigma_dut *dut, struct sigma_conn *conn,
757 			     struct sigma_cmd *cmd)
758 {
759 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
760 	u8 buf[100], *end, *pos;
761 	int rlen;
762 	const char *val;
763 	int s, i;
764 	char ret[100];
765 	size_t len;
766 
767 	pos = buf;
768 	end = buf + sizeof(buf);
769 	WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_BSS_COUNTER);
770 	pos += 4;
771 
772 	val = get_param(cmd, "bssid");
773 	if (val == NULL)
774 		return -1;
775 	if (val) {
776 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
777 		if (hwaddr_aton(val, pos) < 0) {
778 			send_resp(dut, conn, SIGMA_INVALID,
779 				  "errorCode,Invalid bssid");
780 			return 0;
781 		}
782 		pos += ETH_ALEN;
783 	}
784 
785 	val = get_param(cmd, "field");
786 	if (val == NULL)
787 		return -1;
788 	for (i = 0; bss_counters[i].name; i++) {
789 		if (strcasecmp(bss_counters[i].name, val) == 0)
790 			break;
791 	}
792 	if (bss_counters[i].name == NULL) {
793 		send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
794 		return 0;
795 	}
796 	pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_COUNTER,
797 			    bss_counters[i].num);
798 
799 	s = open_wlantest();
800 	if (s < 0) {
801 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
802 			  "available");
803 		return 0;
804 	}
805 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
806 	close(s);
807 
808 	pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
809 	if (pos == NULL || len != 4)
810 		return -2;
811 	snprintf(ret, sizeof(ret), "counter,%u", WPA_GET_BE32(pos));
812 	send_resp(dut, conn, SIGMA_COMPLETE, ret);
813 	return 0;
814 }
815 
816 
817 struct tdls_counters {
818 	const char *name;
819 	enum wlantest_tdls_counter num;
820 };
821 
822 static const struct tdls_counters tdls_counters[] = {
823 	{ "valid_direct_link", WLANTEST_TDLS_COUNTER_VALID_DIRECT_LINK },
824 	{ "invalid_direct_link", WLANTEST_TDLS_COUNTER_INVALID_DIRECT_LINK },
825 	{ "valid_ap_path", WLANTEST_TDLS_COUNTER_VALID_AP_PATH },
826 	{ "invalid_ap_path", WLANTEST_TDLS_COUNTER_INVALID_AP_PATH },
827 	{ "setup_req", WLANTEST_TDLS_COUNTER_SETUP_REQ },
828 	{ "setup_resp_ok", WLANTEST_TDLS_COUNTER_SETUP_RESP_OK },
829 	{ "setup_resp_fail", WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL },
830 	{ "setup_conf_ok", WLANTEST_TDLS_COUNTER_SETUP_CONF_OK },
831 	{ "setup_conf_fail", WLANTEST_TDLS_COUNTER_SETUP_CONF_FAIL },
832 	{ "teardown", WLANTEST_TDLS_COUNTER_TEARDOWN },
833 	{ NULL, 0 }
834 };
835 
836 static enum sigma_cmd_result
cmd_wlantest_get_tdls_counter(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)837 cmd_wlantest_get_tdls_counter(struct sigma_dut *dut, struct sigma_conn *conn,
838 			      struct sigma_cmd *cmd)
839 {
840 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
841 	u8 buf[100], *end, *pos;
842 	int rlen;
843 	const char *val;
844 	int s, i;
845 	char ret[100];
846 	size_t len;
847 
848 	pos = buf;
849 	end = buf + sizeof(buf);
850 	WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_TDLS_COUNTER);
851 	pos += 4;
852 
853 	val = get_param(cmd, "bssid");
854 	if (val == NULL)
855 		return -1;
856 	if (val) {
857 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
858 		if (hwaddr_aton(val, pos) < 0) {
859 			send_resp(dut, conn, SIGMA_INVALID,
860 				  "errorCode,Invalid bssid");
861 			return 0;
862 		}
863 		pos += ETH_ALEN;
864 	}
865 
866 	val = get_param(cmd, "stationID");
867 	if (val == NULL)
868 		return -1;
869 	if (val) {
870 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
871 		if (hwaddr_aton(val, pos) < 0) {
872 			send_resp(dut, conn, SIGMA_INVALID,
873 				  "errorCode,Invalid stationID");
874 			return 0;
875 		}
876 		pos += ETH_ALEN;
877 	}
878 
879 	val = get_param(cmd, "stationID2");
880 	if (val == NULL)
881 		return -1;
882 	if (val) {
883 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA2_ADDR,
884 				   ETH_ALEN);
885 		if (hwaddr_aton(val, pos) < 0) {
886 			send_resp(dut, conn, SIGMA_INVALID,
887 				  "errorCode,Invalid stationID");
888 			return 0;
889 		}
890 		pos += ETH_ALEN;
891 	}
892 
893 	val = get_param(cmd, "field");
894 	if (val == NULL)
895 		return -1;
896 	for (i = 0; tdls_counters[i].name; i++) {
897 		if (strcasecmp(tdls_counters[i].name, val) == 0)
898 			break;
899 	}
900 	if (tdls_counters[i].name == NULL) {
901 		send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
902 		return 0;
903 	}
904 	pos = attr_add_be32(pos, end, WLANTEST_ATTR_TDLS_COUNTER,
905 			    tdls_counters[i].num);
906 
907 	s = open_wlantest();
908 	if (s < 0) {
909 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
910 			  "available");
911 		return 0;
912 	}
913 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
914 	close(s);
915 
916 
917 	pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
918 	if (pos == NULL || len != 4)
919 		return -2;
920 	snprintf(ret, sizeof(ret), "counter,%u", WPA_GET_BE32(pos));
921 	send_resp(dut, conn, SIGMA_COMPLETE, ret);
922 	return 0;
923 }
924 
925 
926 struct sta_infos {
927 	const char *name;
928 	enum wlantest_sta_info num;
929 };
930 
931 static const struct sta_infos sta_infos[] = {
932 	{ "proto", WLANTEST_STA_INFO_PROTO },
933 	{ "pairwise", WLANTEST_STA_INFO_PAIRWISE },
934 	{ "key_mgmt", WLANTEST_STA_INFO_KEY_MGMT },
935 	{ "rsn_capab", WLANTEST_STA_INFO_RSN_CAPAB },
936 	{ "state", WLANTEST_STA_INFO_STATE },
937 	{ NULL, 0 }
938 };
939 
cmd_wlantest_info_sta(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)940 static enum sigma_cmd_result cmd_wlantest_info_sta(struct sigma_dut *dut,
941 						   struct sigma_conn *conn,
942 						   struct sigma_cmd *cmd)
943 {
944 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
945 	u8 buf[100], *end, *pos;
946 	int rlen;
947 	const char *val;
948 	int s, i;
949 	char ret[120];
950 	size_t len;
951 	char info[100];
952 
953 	pos = buf;
954 	end = buf + sizeof(buf);
955 	WPA_PUT_BE32(pos, WLANTEST_CTRL_INFO_STA);
956 	pos += 4;
957 
958 	val = get_param(cmd, "bssid");
959 	if (val == NULL)
960 		return -1;
961 	if (val) {
962 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
963 		if (hwaddr_aton(val, pos) < 0) {
964 			send_resp(dut, conn, SIGMA_INVALID,
965 				  "errorCode,Invalid bssid");
966 			return 0;
967 		}
968 		pos += ETH_ALEN;
969 	}
970 
971 	val = get_param(cmd, "stationID");
972 	if (val == NULL)
973 		return -1;
974 	if (val) {
975 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
976 		if (hwaddr_aton(val, pos) < 0) {
977 			send_resp(dut, conn, SIGMA_INVALID,
978 				  "errorCode,Invalid stationID");
979 			return 0;
980 		}
981 		pos += ETH_ALEN;
982 	}
983 
984 	val = get_param(cmd, "field");
985 	if (val == NULL)
986 		return -1;
987 	for (i = 0; sta_infos[i].name; i++) {
988 		if (strcasecmp(sta_infos[i].name, val) == 0)
989 			break;
990 	}
991 	if (sta_infos[i].name == NULL) {
992 		send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
993 		return 0;
994 	}
995 	pos = attr_add_be32(pos, end, WLANTEST_ATTR_STA_INFO,
996 			    sta_infos[i].num);
997 
998 	s = open_wlantest();
999 	if (s < 0) {
1000 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
1001 			  "available");
1002 		return 0;
1003 	}
1004 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
1005 	close(s);
1006 
1007 
1008 	pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_INFO, &len);
1009 	if (pos == NULL)
1010 		return -2;
1011 	if (len >= sizeof(info))
1012 		len = sizeof(info) - 1;
1013 	memcpy(info, pos, len);
1014 	info[len] = '\0';
1015 	snprintf(ret, sizeof(ret), "info,%s", info);
1016 	send_resp(dut, conn, SIGMA_COMPLETE, ret);
1017 	return 0;
1018 }
1019 
1020 
1021 struct bss_infos {
1022 	const char *name;
1023 	enum wlantest_bss_info num;
1024 };
1025 
1026 static const struct bss_infos bss_infos[] = {
1027 	{ "proto", WLANTEST_BSS_INFO_PROTO },
1028 	{ "pairwise", WLANTEST_BSS_INFO_PAIRWISE },
1029 	{ "group", WLANTEST_BSS_INFO_GROUP },
1030 	{ "group_mgmt", WLANTEST_BSS_INFO_GROUP_MGMT },
1031 	{ "key_mgmt", WLANTEST_BSS_INFO_KEY_MGMT },
1032 	{ "rsn_capab", WLANTEST_BSS_INFO_RSN_CAPAB },
1033 	{ NULL, 0 }
1034 };
1035 
cmd_wlantest_info_bss(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)1036 static enum sigma_cmd_result cmd_wlantest_info_bss(struct sigma_dut *dut,
1037 						   struct sigma_conn *conn,
1038 						   struct sigma_cmd *cmd)
1039 {
1040 	u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
1041 	u8 buf[100], *end, *pos;
1042 	int rlen;
1043 	const char *val;
1044 	int s, i;
1045 	char ret[120];
1046 	size_t len;
1047 	char info[100];
1048 
1049 	pos = buf;
1050 	end = buf + sizeof(buf);
1051 	WPA_PUT_BE32(pos, WLANTEST_CTRL_INFO_BSS);
1052 	pos += 4;
1053 
1054 	val = get_param(cmd, "bssid");
1055 	if (val == NULL)
1056 		return -1;
1057 	if (val) {
1058 		pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
1059 		if (hwaddr_aton(val, pos) < 0) {
1060 			send_resp(dut, conn, SIGMA_INVALID,
1061 				  "errorCode,Invalid bssid");
1062 			return 0;
1063 		}
1064 		pos += ETH_ALEN;
1065 	}
1066 
1067 	val = get_param(cmd, "field");
1068 	if (val == NULL)
1069 		return -1;
1070 	for (i = 0; bss_infos[i].name; i++) {
1071 		if (strcasecmp(bss_infos[i].name, val) == 0)
1072 			break;
1073 	}
1074 	if (bss_infos[i].name == NULL) {
1075 		send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid field");
1076 		return 0;
1077 	}
1078 	pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_INFO,
1079 			    bss_infos[i].num);
1080 
1081 	s = open_wlantest();
1082 	if (s < 0) {
1083 		send_resp(dut, conn, SIGMA_ERROR, "errorCode,wlantest not "
1084 			  "available");
1085 		return 0;
1086 	}
1087 	rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
1088 	close(s);
1089 
1090 
1091 	pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_INFO, &len);
1092 	if (pos == NULL)
1093 		return -2;
1094 	if (len >= sizeof(info))
1095 		len = sizeof(info) - 1;
1096 	memcpy(info, pos, len);
1097 	info[len] = '\0';
1098 	snprintf(ret, sizeof(ret), "info,%s", info);
1099 	send_resp(dut, conn, SIGMA_COMPLETE, ret);
1100 	return 0;
1101 }
1102 
1103 
wlantest_register_cmds(void)1104 void wlantest_register_cmds(void)
1105 {
1106 	sigma_dut_reg_cmd("wlantest_version", NULL, cmd_wlantest_version);
1107 	sigma_dut_reg_cmd("wlantest_set_channel", NULL,
1108 			  cmd_wlantest_set_channel);
1109 	sigma_dut_reg_cmd("wlantest_flush", NULL, cmd_wlantest_flush);
1110 	sigma_dut_reg_cmd("wlantest_send_frame", NULL,
1111 			  cmd_wlantest_send_frame);
1112 	sigma_dut_reg_cmd("wlantest_add_passphrase", NULL,
1113 			  cmd_wlantest_add_passphrase);
1114 	sigma_dut_reg_cmd("wlantest_clear_sta_counters", NULL,
1115 			  cmd_wlantest_clear_sta_counters);
1116 	sigma_dut_reg_cmd("wlantest_clear_bss_counters", NULL,
1117 			  cmd_wlantest_clear_bss_counters);
1118 	sigma_dut_reg_cmd("wlantest_clear_tdls_counters", NULL,
1119 			  cmd_wlantest_clear_tdls_counters);
1120 	sigma_dut_reg_cmd("wlantest_get_sta_counter", NULL,
1121 			  cmd_wlantest_get_sta_counter);
1122 	sigma_dut_reg_cmd("wlantest_get_bss_counter", NULL,
1123 			  cmd_wlantest_get_bss_counter);
1124 	sigma_dut_reg_cmd("wlantest_get_tdls_counter", NULL,
1125 			  cmd_wlantest_get_tdls_counter);
1126 	sigma_dut_reg_cmd("wlantest_info_sta", NULL, cmd_wlantest_info_sta);
1127 	sigma_dut_reg_cmd("wlantest_info_bss", NULL, cmd_wlantest_info_bss);
1128 }
1129