1cd4e3c3eSJouni Malinen /*
2cd4e3c3eSJouni Malinen * Sigma Control API DUT (station/AP)
3cd4e3c3eSJouni Malinen * Copyright (c) 2010, Atheros Communications, Inc.
453053690SJouni Malinen * Copyright (c) 2019, The Linux Foundation
5cd4e3c3eSJouni Malinen * All Rights Reserved.
6cd4e3c3eSJouni Malinen * Licensed under the Clear BSD license. See README for more details.
7cd4e3c3eSJouni Malinen */
8cd4e3c3eSJouni Malinen
9cd4e3c3eSJouni Malinen #include "sigma_dut.h"
10cd4e3c3eSJouni Malinen #include "wpa_helpers.h"
11cd4e3c3eSJouni Malinen
12cd4e3c3eSJouni Malinen
cmd_sta_atheros(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)1353053690SJouni Malinen static enum sigma_cmd_result cmd_sta_atheros(struct sigma_dut *dut,
1453053690SJouni Malinen struct sigma_conn *conn,
15cd4e3c3eSJouni Malinen struct sigma_cmd *cmd)
16cd4e3c3eSJouni Malinen {
17cd4e3c3eSJouni Malinen char buf[2048], *pos;
18cd4e3c3eSJouni Malinen int i;
19cd4e3c3eSJouni Malinen const char *intf, *c;
20cd4e3c3eSJouni Malinen char resp[200];
21cd4e3c3eSJouni Malinen
22cd4e3c3eSJouni Malinen intf = get_param(cmd, "interface");
23cd4e3c3eSJouni Malinen c = get_param(cmd, "cmd");
24cd4e3c3eSJouni Malinen if (c == NULL)
2553053690SJouni Malinen return INVALID_SEND_STATUS;
26cd4e3c3eSJouni Malinen
27cd4e3c3eSJouni Malinen buf[0] = '\0';
28cd4e3c3eSJouni Malinen if (strncmp(c, "ctrl=", 5) == 0) {
29cd4e3c3eSJouni Malinen size_t rlen;
30cd4e3c3eSJouni Malinen c += 5;
31cd4e3c3eSJouni Malinen if (wpa_command_resp(intf, c, buf, sizeof(buf)) < 0)
3253053690SJouni Malinen return ERROR_SEND_STATUS;
33cd4e3c3eSJouni Malinen rlen = strlen(buf);
34cd4e3c3eSJouni Malinen if (rlen > 0 && buf[rlen - 1] == '\n')
35cd4e3c3eSJouni Malinen buf[rlen - 1] = '\0';
36cd4e3c3eSJouni Malinen } else if (strncmp(c, "timeout=", 8) == 0) {
37cd4e3c3eSJouni Malinen unsigned int timeout;
38cd4e3c3eSJouni Malinen timeout = atoi(c + 8);
39cd4e3c3eSJouni Malinen if (timeout == 0)
4053053690SJouni Malinen return INVALID_SEND_STATUS;
41cd4e3c3eSJouni Malinen dut->default_timeout = timeout;
42cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Set DUT default timeout "
43cd4e3c3eSJouni Malinen "to %u seconds", dut->default_timeout);
44cd4e3c3eSJouni Malinen snprintf(buf, sizeof(buf), "OK");
45cd4e3c3eSJouni Malinen } else
4653053690SJouni Malinen return ERROR_SEND_STATUS;
47cd4e3c3eSJouni Malinen
48cd4e3c3eSJouni Malinen i = snprintf(resp, sizeof(resp), "resp,");
4912366462SAnkita Bajaj if (i < 0)
5053053690SJouni Malinen return ERROR_SEND_STATUS;
51cd4e3c3eSJouni Malinen pos = buf;
52cd4e3c3eSJouni Malinen while (*pos && i + 1 < (int) sizeof(resp)) {
53cd4e3c3eSJouni Malinen char c = *pos++;
54cd4e3c3eSJouni Malinen if (c == '\n' || c == '\r' || c == ',')
55cd4e3c3eSJouni Malinen c = '^';
56cd4e3c3eSJouni Malinen resp[i++] = c;
57cd4e3c3eSJouni Malinen }
58cd4e3c3eSJouni Malinen resp[i] = '\0';
59cd4e3c3eSJouni Malinen
60cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, resp);
6153053690SJouni Malinen return STATUS_SENT;
62cd4e3c3eSJouni Malinen }
63cd4e3c3eSJouni Malinen
64cd4e3c3eSJouni Malinen
req_intf(struct sigma_cmd * cmd)65cd4e3c3eSJouni Malinen static int req_intf(struct sigma_cmd *cmd)
66cd4e3c3eSJouni Malinen {
67cd4e3c3eSJouni Malinen return get_param(cmd, "interface") == NULL ? -1 : 0;
68cd4e3c3eSJouni Malinen }
69cd4e3c3eSJouni Malinen
70cd4e3c3eSJouni Malinen
71291d97daSPeng Xu #ifdef NL80211_SUPPORT
cmd_atheros_config_scan(struct sigma_dut * dut,struct sigma_conn * conn,struct sigma_cmd * cmd)7253053690SJouni Malinen static enum sigma_cmd_result cmd_atheros_config_scan(struct sigma_dut *dut,
73291d97daSPeng Xu struct sigma_conn *conn,
74291d97daSPeng Xu struct sigma_cmd *cmd)
75291d97daSPeng Xu {
76291d97daSPeng Xu struct nl_msg *msg;
77291d97daSPeng Xu int ret;
78291d97daSPeng Xu struct nlattr *params;
79291d97daSPeng Xu const char *val;
80291d97daSPeng Xu int ifindex;
81291d97daSPeng Xu
82291d97daSPeng Xu val = get_param(cmd, "enable");
83291d97daSPeng Xu if (!val)
8453053690SJouni Malinen return INVALID_SEND_STATUS;
85291d97daSPeng Xu ifindex = if_nametoindex("wlan0");
86291d97daSPeng Xu if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
87291d97daSPeng Xu NL80211_CMD_VENDOR)) ||
88291d97daSPeng Xu nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
89291d97daSPeng Xu nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
90291d97daSPeng Xu nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
91291d97daSPeng Xu QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
92291d97daSPeng Xu !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
93291d97daSPeng Xu nla_put_u8(msg,
94291d97daSPeng Xu QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE,
95291d97daSPeng Xu atoi(val))) {
96291d97daSPeng Xu sigma_dut_print(dut, DUT_MSG_ERROR,
97291d97daSPeng Xu "%s: err in adding vendor_cmd and vendor_data",
98291d97daSPeng Xu __func__);
99291d97daSPeng Xu nlmsg_free(msg);
100*829f82c8SJouni Malinen return ERROR_SEND_STATUS;
101291d97daSPeng Xu }
102291d97daSPeng Xu nla_nest_end(msg, params);
103291d97daSPeng Xu
104291d97daSPeng Xu ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
105291d97daSPeng Xu if (ret) {
106291d97daSPeng Xu sigma_dut_print(dut, DUT_MSG_ERROR,
107291d97daSPeng Xu "%s: err in send_and_recv_msgs, ret=%d",
108291d97daSPeng Xu __func__, ret);
109*829f82c8SJouni Malinen return ERROR_SEND_STATUS;
110291d97daSPeng Xu }
111291d97daSPeng Xu
11253053690SJouni Malinen return STATUS_SENT;
113291d97daSPeng Xu }
114291d97daSPeng Xu #endif /* NL80211_SUPPORT */
115291d97daSPeng Xu
116291d97daSPeng Xu
atheros_register_cmds(void)117cd4e3c3eSJouni Malinen void atheros_register_cmds(void)
118cd4e3c3eSJouni Malinen {
119cd4e3c3eSJouni Malinen sigma_dut_reg_cmd("sta_atheros", req_intf, cmd_sta_atheros);
120291d97daSPeng Xu #ifdef NL80211_SUPPORT
121291d97daSPeng Xu sigma_dut_reg_cmd("atheros_config_scan", NULL, cmd_atheros_config_scan);
122291d97daSPeng Xu #endif /* NL80211_SUPPORT */
123cd4e3c3eSJouni Malinen }
124