xref: /wlan-dirver/utils/sigma-dut/basic.c (revision cd4e3c3e0365aac6e078aab03f11d01d8f1020d5)
1*cd4e3c3eSJouni Malinen /*
2*cd4e3c3eSJouni Malinen  * Sigma Control API DUT (station/AP)
3*cd4e3c3eSJouni Malinen  * Copyright (c) 2010, Atheros Communications, Inc.
4*cd4e3c3eSJouni Malinen  * Copyright (c) 2011-2014, Qualcomm Atheros, Inc.
5*cd4e3c3eSJouni Malinen  * All Rights Reserved.
6*cd4e3c3eSJouni Malinen  * Licensed under the Clear BSD license. See README for more details.
7*cd4e3c3eSJouni Malinen  */
8*cd4e3c3eSJouni Malinen 
9*cd4e3c3eSJouni Malinen #include "sigma_dut.h"
10*cd4e3c3eSJouni Malinen #ifdef __linux__
11*cd4e3c3eSJouni Malinen #include <sys/stat.h>
12*cd4e3c3eSJouni Malinen #endif /* __linux__ */
13*cd4e3c3eSJouni Malinen #include "wpa_helpers.h"
14*cd4e3c3eSJouni Malinen 
15*cd4e3c3eSJouni Malinen 
16*cd4e3c3eSJouni Malinen static int cmd_ca_get_version(struct sigma_dut *dut, struct sigma_conn *conn,
17*cd4e3c3eSJouni Malinen 			      struct sigma_cmd *cmd)
18*cd4e3c3eSJouni Malinen {
19*cd4e3c3eSJouni Malinen 	const char *info;
20*cd4e3c3eSJouni Malinen 
21*cd4e3c3eSJouni Malinen 	info = get_param(cmd, "TestInfo");
22*cd4e3c3eSJouni Malinen 	if (info) {
23*cd4e3c3eSJouni Malinen 		char buf[200];
24*cd4e3c3eSJouni Malinen 		snprintf(buf, sizeof(buf), "NOTE CAPI:TestInfo:%s", info);
25*cd4e3c3eSJouni Malinen 		wpa_command(get_main_ifname(), buf);
26*cd4e3c3eSJouni Malinen 	}
27*cd4e3c3eSJouni Malinen 
28*cd4e3c3eSJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0");
29*cd4e3c3eSJouni Malinen 	return 0;
30*cd4e3c3eSJouni Malinen }
31*cd4e3c3eSJouni Malinen 
32*cd4e3c3eSJouni Malinen 
33*cd4e3c3eSJouni Malinen #ifdef __linux__
34*cd4e3c3eSJouni Malinen 
35*cd4e3c3eSJouni Malinen static void first_line(char *s)
36*cd4e3c3eSJouni Malinen {
37*cd4e3c3eSJouni Malinen 	while (*s) {
38*cd4e3c3eSJouni Malinen 		if (*s == '\r' || *s == '\n') {
39*cd4e3c3eSJouni Malinen 			*s = '\0';
40*cd4e3c3eSJouni Malinen 			return;
41*cd4e3c3eSJouni Malinen 		}
42*cd4e3c3eSJouni Malinen 		s++;
43*cd4e3c3eSJouni Malinen 	}
44*cd4e3c3eSJouni Malinen }
45*cd4e3c3eSJouni Malinen 
46*cd4e3c3eSJouni Malinen 
47*cd4e3c3eSJouni Malinen static void get_ver(const char *cmd, char *buf, size_t buflen)
48*cd4e3c3eSJouni Malinen {
49*cd4e3c3eSJouni Malinen 	FILE *f;
50*cd4e3c3eSJouni Malinen 	char *pos;
51*cd4e3c3eSJouni Malinen 
52*cd4e3c3eSJouni Malinen 	buf[0] = '\0';
53*cd4e3c3eSJouni Malinen 	f = popen(cmd, "r");
54*cd4e3c3eSJouni Malinen 	if (f == NULL)
55*cd4e3c3eSJouni Malinen 		return;
56*cd4e3c3eSJouni Malinen 	if (fgets(buf, buflen, f))
57*cd4e3c3eSJouni Malinen 		first_line(buf);
58*cd4e3c3eSJouni Malinen 	pclose(f);
59*cd4e3c3eSJouni Malinen 
60*cd4e3c3eSJouni Malinen 	pos = strstr(buf, " v");
61*cd4e3c3eSJouni Malinen 	if (pos == NULL)
62*cd4e3c3eSJouni Malinen 		buf[0] = '\0';
63*cd4e3c3eSJouni Malinen 	else
64*cd4e3c3eSJouni Malinen 		memmove(buf, pos + 1, strlen(pos));
65*cd4e3c3eSJouni Malinen }
66*cd4e3c3eSJouni Malinen 
67*cd4e3c3eSJouni Malinen #endif /* __linux__ */
68*cd4e3c3eSJouni Malinen 
69*cd4e3c3eSJouni Malinen 
70*cd4e3c3eSJouni Malinen static int cmd_device_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
71*cd4e3c3eSJouni Malinen 			       struct sigma_cmd *cmd)
72*cd4e3c3eSJouni Malinen {
73*cd4e3c3eSJouni Malinen 	const char *model = "N/A";
74*cd4e3c3eSJouni Malinen 	const char *version = "N/A";
75*cd4e3c3eSJouni Malinen #ifdef __linux__
76*cd4e3c3eSJouni Malinen 	char model_buf[128];
77*cd4e3c3eSJouni Malinen 	char ver_buf[128];
78*cd4e3c3eSJouni Malinen #endif /* __linux__ */
79*cd4e3c3eSJouni Malinen 	char resp[200];
80*cd4e3c3eSJouni Malinen 
81*cd4e3c3eSJouni Malinen #ifdef __linux__
82*cd4e3c3eSJouni Malinen 	{
83*cd4e3c3eSJouni Malinen 		char path[128];
84*cd4e3c3eSJouni Malinen 		struct stat s;
85*cd4e3c3eSJouni Malinen 		FILE *f;
86*cd4e3c3eSJouni Malinen 		char compat_ver[128];
87*cd4e3c3eSJouni Malinen 		char wpa_supplicant_ver[128];
88*cd4e3c3eSJouni Malinen 		char hostapd_ver[128];
89*cd4e3c3eSJouni Malinen 
90*cd4e3c3eSJouni Malinen 		snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211",
91*cd4e3c3eSJouni Malinen 			 get_main_ifname());
92*cd4e3c3eSJouni Malinen 		if (stat(path, &s) == 0) {
93*cd4e3c3eSJouni Malinen 			ssize_t res;
94*cd4e3c3eSJouni Malinen 			char *pos;
95*cd4e3c3eSJouni Malinen 			snprintf(path, sizeof(path),
96*cd4e3c3eSJouni Malinen 				 "/sys/class/net/%s/device/driver",
97*cd4e3c3eSJouni Malinen 				 get_main_ifname());
98*cd4e3c3eSJouni Malinen 			res = readlink(path, path, sizeof(path));
99*cd4e3c3eSJouni Malinen 			if (res < 0)
100*cd4e3c3eSJouni Malinen 				model = "Linux/";
101*cd4e3c3eSJouni Malinen 			else {
102*cd4e3c3eSJouni Malinen 				if (res >= (int) sizeof(path))
103*cd4e3c3eSJouni Malinen 					res = sizeof(path) - 1;
104*cd4e3c3eSJouni Malinen 				path[res] = '\0';
105*cd4e3c3eSJouni Malinen 				pos = strrchr(path, '/');
106*cd4e3c3eSJouni Malinen 				if (pos == NULL)
107*cd4e3c3eSJouni Malinen 					pos = path;
108*cd4e3c3eSJouni Malinen 				else
109*cd4e3c3eSJouni Malinen 					pos++;
110*cd4e3c3eSJouni Malinen 				snprintf(model_buf, sizeof(model_buf),
111*cd4e3c3eSJouni Malinen 					 "Linux/%s", pos);
112*cd4e3c3eSJouni Malinen 				model = model_buf;
113*cd4e3c3eSJouni Malinen 			}
114*cd4e3c3eSJouni Malinen 		} else
115*cd4e3c3eSJouni Malinen 			model = "Linux";
116*cd4e3c3eSJouni Malinen 
117*cd4e3c3eSJouni Malinen 		/* TODO: get version from wpa_supplicant (+ driver via wpa_s)
118*cd4e3c3eSJouni Malinen 		 */
119*cd4e3c3eSJouni Malinen 
120*cd4e3c3eSJouni Malinen 		f = fopen("/sys/module/compat/parameters/"
121*cd4e3c3eSJouni Malinen 			  "backported_kernel_version", "r");
122*cd4e3c3eSJouni Malinen 		if (f == NULL)
123*cd4e3c3eSJouni Malinen 			f = fopen("/sys/module/compat/parameters/"
124*cd4e3c3eSJouni Malinen 				  "compat_version", "r");
125*cd4e3c3eSJouni Malinen 		if (f) {
126*cd4e3c3eSJouni Malinen 			if (fgets(compat_ver, sizeof(compat_ver), f) == NULL)
127*cd4e3c3eSJouni Malinen 				compat_ver[0] = '\0';
128*cd4e3c3eSJouni Malinen 			else
129*cd4e3c3eSJouni Malinen 				first_line(compat_ver);
130*cd4e3c3eSJouni Malinen 			fclose(f);
131*cd4e3c3eSJouni Malinen 		} else
132*cd4e3c3eSJouni Malinen 			compat_ver[0] = '\0';
133*cd4e3c3eSJouni Malinen 
134*cd4e3c3eSJouni Malinen 		get_ver("./hostapd -v 2>&1", hostapd_ver, sizeof(hostapd_ver));
135*cd4e3c3eSJouni Malinen 		if (hostapd_ver[0] == '\0')
136*cd4e3c3eSJouni Malinen 			get_ver("hostapd -v 2>&1", hostapd_ver,
137*cd4e3c3eSJouni Malinen 				sizeof(hostapd_ver));
138*cd4e3c3eSJouni Malinen 		get_ver("./wpa_supplicant -v", wpa_supplicant_ver,
139*cd4e3c3eSJouni Malinen 			sizeof(wpa_supplicant_ver));
140*cd4e3c3eSJouni Malinen 		if (wpa_supplicant_ver[0] == '\0')
141*cd4e3c3eSJouni Malinen 			get_ver("wpa_supplicant -v", wpa_supplicant_ver,
142*cd4e3c3eSJouni Malinen 				sizeof(wpa_supplicant_ver));
143*cd4e3c3eSJouni Malinen 
144*cd4e3c3eSJouni Malinen 		snprintf(ver_buf, sizeof(ver_buf),
145*cd4e3c3eSJouni Malinen 			 "drv=%s%s%s%s%s/sigma=" SIGMA_DUT_VER "%s%s",
146*cd4e3c3eSJouni Malinen 			 compat_ver,
147*cd4e3c3eSJouni Malinen 			 wpa_supplicant_ver[0] ? "/wpas=" : "",
148*cd4e3c3eSJouni Malinen 			 wpa_supplicant_ver,
149*cd4e3c3eSJouni Malinen 			 hostapd_ver[0] ? "/hapd=" : "",
150*cd4e3c3eSJouni Malinen 			 hostapd_ver,
151*cd4e3c3eSJouni Malinen 			 dut->version ? "@" : "",
152*cd4e3c3eSJouni Malinen 			 dut->version ? dut->version : "");
153*cd4e3c3eSJouni Malinen 		version = ver_buf;
154*cd4e3c3eSJouni Malinen 	}
155*cd4e3c3eSJouni Malinen #endif /* __linux__ */
156*cd4e3c3eSJouni Malinen 
157*cd4e3c3eSJouni Malinen 	snprintf(resp, sizeof(resp), "vendor,Qualcomm Atheros,"
158*cd4e3c3eSJouni Malinen 		 "model,%s,version,%s", model, version);
159*cd4e3c3eSJouni Malinen 
160*cd4e3c3eSJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
161*cd4e3c3eSJouni Malinen 	return 0;
162*cd4e3c3eSJouni Malinen }
163*cd4e3c3eSJouni Malinen 
164*cd4e3c3eSJouni Malinen 
165*cd4e3c3eSJouni Malinen static int check_device_list_interfaces(struct sigma_cmd *cmd)
166*cd4e3c3eSJouni Malinen {
167*cd4e3c3eSJouni Malinen 	if (get_param(cmd, "interfaceType") == NULL)
168*cd4e3c3eSJouni Malinen 		return -1;
169*cd4e3c3eSJouni Malinen 	return 0;
170*cd4e3c3eSJouni Malinen }
171*cd4e3c3eSJouni Malinen 
172*cd4e3c3eSJouni Malinen 
173*cd4e3c3eSJouni Malinen static int cmd_device_list_interfaces(struct sigma_dut *dut,
174*cd4e3c3eSJouni Malinen 				      struct sigma_conn *conn,
175*cd4e3c3eSJouni Malinen 				      struct sigma_cmd *cmd)
176*cd4e3c3eSJouni Malinen {
177*cd4e3c3eSJouni Malinen 	const char *type;
178*cd4e3c3eSJouni Malinen 	char resp[200];
179*cd4e3c3eSJouni Malinen 
180*cd4e3c3eSJouni Malinen 	type = get_param(cmd, "interfaceType");
181*cd4e3c3eSJouni Malinen 	if (type == NULL)
182*cd4e3c3eSJouni Malinen 		return -1;
183*cd4e3c3eSJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "device_list_interfaces - "
184*cd4e3c3eSJouni Malinen 			"interfaceType=%s", type);
185*cd4e3c3eSJouni Malinen 	if (strcmp(type, "802.11") != 0)
186*cd4e3c3eSJouni Malinen 		return -2;
187*cd4e3c3eSJouni Malinen 
188*cd4e3c3eSJouni Malinen 	snprintf(resp, sizeof(resp), "interfaceType,802.11,"
189*cd4e3c3eSJouni Malinen 		 "interfaceID,%s", get_main_ifname());
190*cd4e3c3eSJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
191*cd4e3c3eSJouni Malinen 
192*cd4e3c3eSJouni Malinen 	return 0;
193*cd4e3c3eSJouni Malinen }
194*cd4e3c3eSJouni Malinen 
195*cd4e3c3eSJouni Malinen 
196*cd4e3c3eSJouni Malinen void basic_register_cmds(void)
197*cd4e3c3eSJouni Malinen {
198*cd4e3c3eSJouni Malinen 	sigma_dut_reg_cmd("ca_get_version", NULL, cmd_ca_get_version);
199*cd4e3c3eSJouni Malinen 	sigma_dut_reg_cmd("device_get_info", NULL, cmd_device_get_info);
200*cd4e3c3eSJouni Malinen 	sigma_dut_reg_cmd("device_list_interfaces",
201*cd4e3c3eSJouni Malinen 			  check_device_list_interfaces,
202*cd4e3c3eSJouni Malinen 			  cmd_device_list_interfaces);
203*cd4e3c3eSJouni Malinen }
204