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