xref: /wlan-dirver/utils/sigma-dut/utils.c (revision a2cb567bb34eb6c5d4d704cdce6784d6d1b26400)
1cd4e3c3eSJouni Malinen /*
2cd4e3c3eSJouni Malinen  * Sigma Control API DUT (station/AP)
3659a34c4SAmarnath Hullur Subramanyam  * Copyright (c) 2014-2017, Qualcomm Atheros, Inc.
4cd4e3c3eSJouni Malinen  * All Rights Reserved.
5cd4e3c3eSJouni Malinen  * Licensed under the Clear BSD license. See README for more details.
6cd4e3c3eSJouni Malinen  */
7cd4e3c3eSJouni Malinen 
8cd4e3c3eSJouni Malinen #include "sigma_dut.h"
9cd4e3c3eSJouni Malinen #include <sys/stat.h>
10cd4e3c3eSJouni Malinen #include "wpa_helpers.h"
11cd4e3c3eSJouni Malinen 
12cd4e3c3eSJouni Malinen enum driver_type wifi_chip_type = DRIVER_NOT_SET;
13cd4e3c3eSJouni Malinen enum openwrt_driver_type openwrt_chip_type = OPENWRT_DRIVER_NOT_SET;
14cd4e3c3eSJouni Malinen 
15cd4e3c3eSJouni Malinen 
16cd4e3c3eSJouni Malinen int file_exists(const char *fname)
17cd4e3c3eSJouni Malinen {
18cd4e3c3eSJouni Malinen 	struct stat s;
19cd4e3c3eSJouni Malinen 	return stat(fname, &s) == 0;
20cd4e3c3eSJouni Malinen }
21cd4e3c3eSJouni Malinen 
22cd4e3c3eSJouni Malinen 
23cd4e3c3eSJouni Malinen int set_wifi_chip(const char *chip_type)
24cd4e3c3eSJouni Malinen {
25cd4e3c3eSJouni Malinen 	if (!strncmp(chip_type, "WCN", strlen("WCN")))
26cd4e3c3eSJouni Malinen 		wifi_chip_type = DRIVER_WCN;
27cd4e3c3eSJouni Malinen 	else if (!strncmp(chip_type, "ATHEROS", strlen("ATHEROS")))
28cd4e3c3eSJouni Malinen 		wifi_chip_type = DRIVER_ATHEROS;
29cd4e3c3eSJouni Malinen 	else if (!strncmp(chip_type, "AR6003", strlen("AR6003")))
30cd4e3c3eSJouni Malinen 		wifi_chip_type = DRIVER_AR6003;
31cd4e3c3eSJouni Malinen 	else if (strcmp(chip_type, "MAC80211") == 0)
32cd4e3c3eSJouni Malinen 		wifi_chip_type = DRIVER_MAC80211;
33cd4e3c3eSJouni Malinen 	else if (strcmp(chip_type, "QNXNTO") == 0)
34cd4e3c3eSJouni Malinen 		wifi_chip_type = DRIVER_QNXNTO;
35cd4e3c3eSJouni Malinen 	else if (strcmp(chip_type, "OPENWRT") == 0)
36cd4e3c3eSJouni Malinen 		wifi_chip_type = DRIVER_OPENWRT;
37b692f107SSreelakshmi Konamki 	else if (!strncmp(chip_type, "LINUX-WCN", strlen("LINUX-WCN")))
38b692f107SSreelakshmi Konamki 		wifi_chip_type = DRIVER_LINUX_WCN;
39cd4e3c3eSJouni Malinen 	else
40cd4e3c3eSJouni Malinen 		return -1;
41cd4e3c3eSJouni Malinen 
42cd4e3c3eSJouni Malinen 	return 0;
43cd4e3c3eSJouni Malinen }
44cd4e3c3eSJouni Malinen 
45cd4e3c3eSJouni Malinen 
46cd4e3c3eSJouni Malinen enum driver_type get_driver_type(void)
47cd4e3c3eSJouni Malinen {
48cd4e3c3eSJouni Malinen 	struct stat s;
49cd4e3c3eSJouni Malinen 	if (wifi_chip_type == DRIVER_NOT_SET) {
50cd4e3c3eSJouni Malinen 		/* Check for 60G driver */
51cd4e3c3eSJouni Malinen 		ssize_t len;
52cd4e3c3eSJouni Malinen 		char link[256];
53cd4e3c3eSJouni Malinen 		char buf[256];
54cd4e3c3eSJouni Malinen 		char *ifname = get_station_ifname();
55cd4e3c3eSJouni Malinen 
56cd4e3c3eSJouni Malinen 		snprintf(buf, sizeof(buf), "/sys/class/net/%s/device/driver",
57cd4e3c3eSJouni Malinen 			 ifname);
58cd4e3c3eSJouni Malinen 		len = readlink(buf, link, sizeof(link) - 1);
59cd4e3c3eSJouni Malinen 		if (len >= 0) {
60cd4e3c3eSJouni Malinen 			link[len] = '\0';
61cd4e3c3eSJouni Malinen 			if (strstr(link, DRIVER_NAME_60G))
62cd4e3c3eSJouni Malinen 				return DRIVER_WIL6210;
63cd4e3c3eSJouni Malinen 		}
64cd4e3c3eSJouni Malinen 
65cd4e3c3eSJouni Malinen 		if (stat("/sys/module/mac80211", &s) == 0)
66cd4e3c3eSJouni Malinen 			return DRIVER_MAC80211;
67cd4e3c3eSJouni Malinen 		return DRIVER_ATHEROS;
68cd4e3c3eSJouni Malinen 	}
69cd4e3c3eSJouni Malinen 	return wifi_chip_type;
70cd4e3c3eSJouni Malinen }
71cd4e3c3eSJouni Malinen 
72cd4e3c3eSJouni Malinen 
73cd4e3c3eSJouni Malinen enum openwrt_driver_type get_openwrt_driver_type(void)
74cd4e3c3eSJouni Malinen {
75cd4e3c3eSJouni Malinen 	struct stat s;
76cd4e3c3eSJouni Malinen 
77cd4e3c3eSJouni Malinen 	if (openwrt_chip_type == OPENWRT_DRIVER_NOT_SET) {
78a62e20abSSarvepalli, Rajesh Babu 		if (stat("/sys/module/umac", &s) == 0)
79cd4e3c3eSJouni Malinen 			openwrt_chip_type = OPENWRT_DRIVER_ATHEROS;
80cd4e3c3eSJouni Malinen 	}
81cd4e3c3eSJouni Malinen 
82cd4e3c3eSJouni Malinen 	return openwrt_chip_type;
83cd4e3c3eSJouni Malinen }
84cd4e3c3eSJouni Malinen 
85cd4e3c3eSJouni Malinen 
86cd4e3c3eSJouni Malinen enum sigma_program sigma_program_to_enum(const char *prog)
87cd4e3c3eSJouni Malinen {
88cd4e3c3eSJouni Malinen 	if (prog == NULL)
89cd4e3c3eSJouni Malinen 		return PROGRAM_UNKNOWN;
90cd4e3c3eSJouni Malinen 
91cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "TDLS") == 0)
92cd4e3c3eSJouni Malinen 		return PROGRAM_TDLS;
93cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "HS2") == 0)
94cd4e3c3eSJouni Malinen 		return PROGRAM_HS2;
95cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "HS2_R2") == 0 ||
96cd4e3c3eSJouni Malinen 	    strcasecmp(prog, "HS2-R2") == 0)
97cd4e3c3eSJouni Malinen 		return PROGRAM_HS2_R2;
98cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "WFD") == 0)
99cd4e3c3eSJouni Malinen 		return PROGRAM_WFD;
100659a34c4SAmarnath Hullur Subramanyam 	if (strcasecmp(prog, "DisplayR2") == 0)
101659a34c4SAmarnath Hullur Subramanyam 		return PROGRAM_DISPLAYR2;
102cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "PMF") == 0)
103cd4e3c3eSJouni Malinen 		return PROGRAM_PMF;
104cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "WPS") == 0)
105cd4e3c3eSJouni Malinen 		return PROGRAM_WPS;
106cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "11n") == 0)
107cd4e3c3eSJouni Malinen 		return PROGRAM_HT;
108cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "VHT") == 0)
109cd4e3c3eSJouni Malinen 		return PROGRAM_VHT;
110cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "60GHZ") == 0)
111cd4e3c3eSJouni Malinen 		return PROGRAM_60GHZ;
112cd4e3c3eSJouni Malinen 	if (strcasecmp(prog, "NAN") == 0)
113cd4e3c3eSJouni Malinen 		return PROGRAM_NAN;
11412dd4145Spriyadharshini gowthaman 	if (strcasecmp(prog, "LOC") == 0)
11512dd4145Spriyadharshini gowthaman 		return PROGRAM_LOC;
116b4e05fc1Spriyadharshini gowthaman 	if (strcasecmp(prog, "MBO") == 0)
117b4e05fc1Spriyadharshini gowthaman 		return PROGRAM_MBO;
11833ea287aSAdil Saeed Musthafa 	if (strcasecmp(prog, "IoTLP") == 0)
11933ea287aSAdil Saeed Musthafa 		return PROGRAM_IOTLP;
1205c3813a7SJouni Malinen 	if (strcasecmp(prog, "DPP") == 0)
1215c3813a7SJouni Malinen 		return PROGRAM_DPP;
122*a2cb567bSAnkita Bajaj 	if (strcasecmp(prog, "OCE") == 0)
123*a2cb567bSAnkita Bajaj 		return PROGRAM_OCE;
124cd4e3c3eSJouni Malinen 
125cd4e3c3eSJouni Malinen 	return PROGRAM_UNKNOWN;
126cd4e3c3eSJouni Malinen }
12772462ef3Spriyadharshini gowthaman 
12872462ef3Spriyadharshini gowthaman 
12972462ef3Spriyadharshini gowthaman static int parse_hex(char c)
13072462ef3Spriyadharshini gowthaman {
13172462ef3Spriyadharshini gowthaman 	if (c >= '0' && c <= '9')
13272462ef3Spriyadharshini gowthaman 		return c - '0';
13372462ef3Spriyadharshini gowthaman 	if (c >= 'a' && c <= 'f')
13472462ef3Spriyadharshini gowthaman 		return c - 'a' + 10;
13572462ef3Spriyadharshini gowthaman 	if (c >= 'A' && c <= 'F')
13672462ef3Spriyadharshini gowthaman 		return c - 'A' + 10;
13772462ef3Spriyadharshini gowthaman 	return -1;
13872462ef3Spriyadharshini gowthaman }
13972462ef3Spriyadharshini gowthaman 
14072462ef3Spriyadharshini gowthaman 
14172462ef3Spriyadharshini gowthaman static int hex_byte(const char *str)
14272462ef3Spriyadharshini gowthaman {
14372462ef3Spriyadharshini gowthaman 	int res1, res2;
14472462ef3Spriyadharshini gowthaman 
14572462ef3Spriyadharshini gowthaman 	res1 = parse_hex(str[0]);
14672462ef3Spriyadharshini gowthaman 	if (res1 < 0)
14772462ef3Spriyadharshini gowthaman 		return -1;
14872462ef3Spriyadharshini gowthaman 	res2 = parse_hex(str[1]);
14972462ef3Spriyadharshini gowthaman 	if (res2 < 0)
15072462ef3Spriyadharshini gowthaman 		return -1;
15172462ef3Spriyadharshini gowthaman 	return (res1 << 4) | res2;
15272462ef3Spriyadharshini gowthaman }
15372462ef3Spriyadharshini gowthaman 
15472462ef3Spriyadharshini gowthaman 
15508cf231dSJouni Malinen int parse_hexstr(const char *hex, unsigned char *buf, size_t buflen)
15608cf231dSJouni Malinen {
15708cf231dSJouni Malinen 	size_t i;
15808cf231dSJouni Malinen 	const char *pos = hex;
15908cf231dSJouni Malinen 
16008cf231dSJouni Malinen 	for (i = 0; i < buflen; i++) {
16108cf231dSJouni Malinen 		int val;
16208cf231dSJouni Malinen 
16308cf231dSJouni Malinen 		if (*pos == '\0')
16408cf231dSJouni Malinen 			break;
16508cf231dSJouni Malinen 		val = hex_byte(pos);
16608cf231dSJouni Malinen 		if (val < 0)
16708cf231dSJouni Malinen 			return -1;
16808cf231dSJouni Malinen 		buf[i] = val;
16908cf231dSJouni Malinen 		pos += 2;
17008cf231dSJouni Malinen 	}
17108cf231dSJouni Malinen 
17208cf231dSJouni Malinen 	return i;
17308cf231dSJouni Malinen }
17408cf231dSJouni Malinen 
17508cf231dSJouni Malinen 
17672462ef3Spriyadharshini gowthaman int parse_mac_address(struct sigma_dut *dut, const char *arg,
17772462ef3Spriyadharshini gowthaman 		      unsigned char *addr)
17872462ef3Spriyadharshini gowthaman {
17972462ef3Spriyadharshini gowthaman 	int i;
18072462ef3Spriyadharshini gowthaman 	const char *pos = arg;
18172462ef3Spriyadharshini gowthaman 
18272462ef3Spriyadharshini gowthaman 	if (strlen(arg) != 17)
18372462ef3Spriyadharshini gowthaman 		goto fail;
18472462ef3Spriyadharshini gowthaman 
18572462ef3Spriyadharshini gowthaman 	for (i = 0; i < ETH_ALEN; i++) {
18672462ef3Spriyadharshini gowthaman 		int val;
18772462ef3Spriyadharshini gowthaman 
18872462ef3Spriyadharshini gowthaman 		val = hex_byte(pos);
18972462ef3Spriyadharshini gowthaman 		if (val < 0)
19072462ef3Spriyadharshini gowthaman 			goto fail;
19172462ef3Spriyadharshini gowthaman 		addr[i] = val;
19272462ef3Spriyadharshini gowthaman 		if (i + 1 < ETH_ALEN) {
19372462ef3Spriyadharshini gowthaman 			pos += 2;
19472462ef3Spriyadharshini gowthaman 			if (*pos != ':')
19572462ef3Spriyadharshini gowthaman 				goto fail;
19672462ef3Spriyadharshini gowthaman 			pos++;
19772462ef3Spriyadharshini gowthaman 		}
19872462ef3Spriyadharshini gowthaman 	}
19972462ef3Spriyadharshini gowthaman 
20072462ef3Spriyadharshini gowthaman 	return 0;
20172462ef3Spriyadharshini gowthaman 
20272462ef3Spriyadharshini gowthaman fail:
20372462ef3Spriyadharshini gowthaman 	sigma_dut_print(dut, DUT_MSG_ERROR,
20472462ef3Spriyadharshini gowthaman 			"Invalid MAC address %s (expected format xx:xx:xx:xx:xx:xx)",
20572462ef3Spriyadharshini gowthaman 			arg);
20672462ef3Spriyadharshini gowthaman 	return -1;
20772462ef3Spriyadharshini gowthaman }
2087192dc42SRakesh Sunki 
2097192dc42SRakesh Sunki 
2107192dc42SRakesh Sunki unsigned int channel_to_freq(unsigned int channel)
2117192dc42SRakesh Sunki {
2127192dc42SRakesh Sunki 	if (channel >= 1 && channel <= 13)
2137192dc42SRakesh Sunki 		return 2407 + 5 * channel;
2147192dc42SRakesh Sunki 	if (channel == 14)
2157192dc42SRakesh Sunki 		return 2484;
2167192dc42SRakesh Sunki 	if (channel >= 36 && channel <= 165)
2177192dc42SRakesh Sunki 		return 5000 + 5 * channel;
2187192dc42SRakesh Sunki 
2197192dc42SRakesh Sunki 	return 0;
2207192dc42SRakesh Sunki }
2217192dc42SRakesh Sunki 
2227192dc42SRakesh Sunki 
2237192dc42SRakesh Sunki unsigned int freq_to_channel(unsigned int freq)
2247192dc42SRakesh Sunki {
2257192dc42SRakesh Sunki 	if (freq >= 2412 && freq <= 2472)
2267192dc42SRakesh Sunki 		return (freq - 2407) / 5;
2277192dc42SRakesh Sunki 	if (freq == 2484)
2287192dc42SRakesh Sunki 		return 14;
2297192dc42SRakesh Sunki 	if (freq >= 5180 && freq <= 5825)
2307192dc42SRakesh Sunki 		return (freq - 5000) / 5;
2317192dc42SRakesh Sunki 	return 0;
2327192dc42SRakesh Sunki }
233769731a2SPeng Xu 
234769731a2SPeng Xu 
2358f8e74b5SRakesh Sunki void convert_mac_addr_to_ipv6_lladdr(u8 *mac_addr, char *ipv6_buf,
2368f8e74b5SRakesh Sunki 				     size_t buf_len)
2378f8e74b5SRakesh Sunki {
2388f8e74b5SRakesh Sunki 	u8 temp = mac_addr[0] ^ 0x02;
2398f8e74b5SRakesh Sunki 
2408f8e74b5SRakesh Sunki 	snprintf(ipv6_buf, buf_len, "fe80::%02x%02x:%02xff:fe%02x:%02x%02x",
2418f8e74b5SRakesh Sunki 		 temp, mac_addr[1], mac_addr[2],
2428f8e74b5SRakesh Sunki 		 mac_addr[3], mac_addr[4], mac_addr[5]);
2438f8e74b5SRakesh Sunki }
2448f8e74b5SRakesh Sunki 
2458f8e74b5SRakesh Sunki 
246769731a2SPeng Xu #ifndef ANDROID
247769731a2SPeng Xu 
248769731a2SPeng Xu size_t strlcpy(char *dest, const char *src, size_t siz)
249769731a2SPeng Xu {
250769731a2SPeng Xu 	const char *s = src;
251769731a2SPeng Xu 	size_t left = siz;
252769731a2SPeng Xu 
253769731a2SPeng Xu 	if (left) {
254769731a2SPeng Xu 		/* Copy string up to the maximum size of the dest buffer */
255769731a2SPeng Xu 		while (--left != 0) {
256769731a2SPeng Xu 			if ((*dest++ = *s++) == '\0')
257769731a2SPeng Xu 				break;
258769731a2SPeng Xu 		}
259769731a2SPeng Xu 	}
260769731a2SPeng Xu 
261769731a2SPeng Xu 	if (left == 0) {
262769731a2SPeng Xu 		/* Not enough room for the string; force NUL-termination */
263769731a2SPeng Xu 		if (siz != 0)
264769731a2SPeng Xu 			*dest = '\0';
265769731a2SPeng Xu 		while (*s++)
266769731a2SPeng Xu 			; /* determine total src string length */
267769731a2SPeng Xu 	}
268769731a2SPeng Xu 
269769731a2SPeng Xu 	return s - src - 1;
270769731a2SPeng Xu }
271769731a2SPeng Xu 
272769731a2SPeng Xu 
273769731a2SPeng Xu size_t strlcat(char *dst, const char *str, size_t size)
274769731a2SPeng Xu {
275769731a2SPeng Xu 	char *pos;
276769731a2SPeng Xu 	size_t dstlen, srclen, copy;
277769731a2SPeng Xu 
278769731a2SPeng Xu 	srclen = strlen(str);
279769731a2SPeng Xu 	for (pos = dst; pos - dst < size && *dst; pos++)
280769731a2SPeng Xu 		;
281769731a2SPeng Xu 	dstlen = pos - dst;
282769731a2SPeng Xu 	if (*dst)
283769731a2SPeng Xu 		return dstlen + srclen;
284769731a2SPeng Xu 	if (dstlen + srclen + 1 > size)
285769731a2SPeng Xu 		copy = size - dstlen - 1;
286769731a2SPeng Xu 	else
287769731a2SPeng Xu 		copy = srclen;
288769731a2SPeng Xu 	memcpy(pos, str, copy);
289769731a2SPeng Xu 	pos[copy] = '\0';
290769731a2SPeng Xu 	return dstlen + srclen;
291769731a2SPeng Xu }
292769731a2SPeng Xu 
293769731a2SPeng Xu #endif /* ANDROID */
294