blob: eb58258d6c07a4e5b0edfaa526688b9674cc000c [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (station/AP)
3 * Copyright (c) 2010, Atheros Communications, Inc.
Jouni Malinen9d7e31d2017-12-22 18:55:04 +02004 * Copyright (c) 2011-2013, 2016-2017 Qualcomm Atheros, Inc.
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005 * 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/types.h>
11#include <sys/stat.h>
12#include <fcntl.h>
13#include <signal.h>
14#include <ctype.h>
15
Pradeep Reddy POTTETIeeb2ccb2016-08-30 12:41:03 +053016#include "wpa_helpers.h"
17
Jouni Malinencd4e3c32015-10-29 12:39:56 +020018#ifdef ANDROID
19#define SHELL "/system/bin/sh"
20#else /* ANDROID */
21#define SHELL "/bin/sh"
22#endif /* ANDROID */
23
24
Jouni Malinencd4e3c32015-10-29 12:39:56 +020025static int cmd_traffic_send_ping(struct sigma_dut *dut,
26 struct sigma_conn *conn,
27 struct sigma_cmd *cmd)
28{
29 const char *dst, *val;
30 int size, dur, pkts;
31 int id;
32 char resp[100];
33 float interval;
34 double rate;
35 FILE *f;
36 char buf[100];
37 int type = 1;
38 int dscp = 0, use_dscp = 0;
Pradeep Reddy POTTETIeeb2ccb2016-08-30 12:41:03 +053039 char extra[100], int_arg[100], intf_arg[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020040
41 val = get_param(cmd, "Type");
42 if (!val)
43 val = get_param(cmd, "IPType");
44 if (val)
45 type = atoi(val);
46 if (type != 1 && type != 2) {
47 send_resp(dut, conn, SIGMA_ERROR,
48 "ErrorCode,Unsupported address type");
49 return 0;
50 }
51
52 dst = get_param(cmd, "destination");
53 if (dst == NULL || (type == 1 && !is_ip_addr(dst)) ||
54 (type == 2 && !is_ipv6_addr(dst)))
55 return -1;
56
57 val = get_param(cmd, "frameSize");
58 if (val == NULL)
59 return -1;
60 size = atoi(val);
61
62 val = get_param(cmd, "frameRate");
63 if (val == NULL)
64 return -1;
65 rate = atof(val);
66 if (rate <= 0)
67 return -1;
68
69 val = get_param(cmd, "duration");
70 if (val == NULL)
71 return -1;
72 dur = atoi(val);
Pradeep Reddy POTTETI95093ac2016-10-13 17:22:03 +053073 if (dur <= 0 || dur > 3600)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020074 dur = 3600;
75
76 pkts = dur * rate;
77 interval = (float) 1 / rate;
78 if (interval > 100000)
79 return -1;
80
81 val = get_param(cmd, "DSCP");
82 if (val) {
83 dscp = atoi(val);
84 if (dscp < 0 || dscp > 63) {
85 send_resp(dut, conn, SIGMA_ERROR,
86 "ErrorCode,Invalid DSCP value");
87 return 0;
88 }
89 use_dscp = 1;
90 }
91
92 id = dut->next_streamid++;
93 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id);
94 unlink(buf);
95 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping-pid.%d", id);
96 unlink(buf);
97
98 sigma_dut_print(dut, DUT_MSG_DEBUG, "Send ping: pkts=%d interval=%f "
99 "streamid=%d",
100 pkts, interval, id);
101
102 f = fopen(SIGMA_TMPDIR "/sigma_dut-ping.sh", "w");
103 if (f == NULL)
104 return -2;
105
106 extra[0] = '\0';
107 if (use_dscp) {
108 snprintf(extra, sizeof(extra), " -Q 0x%02x",
109 dscp << 2);
110 }
111
112 int_arg[0] = '\0';
113 if (rate != 1)
114 snprintf(int_arg, sizeof(int_arg), " -i %f", interval);
Pradeep Reddy POTTETIeeb2ccb2016-08-30 12:41:03 +0530115 intf_arg[0] = '\0';
Purushottam Kushwahaa11683a2017-12-11 12:36:43 +0530116 if (dut->ndp_enable)
117 strlcpy(intf_arg, " -I nan0", sizeof(intf_arg));
118 else if (type == 2)
119 snprintf(intf_arg, sizeof(intf_arg), " -I %s",
120 get_station_ifname());
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200121 fprintf(f, "#!" SHELL "\n"
Purushottam Kushwahaa11683a2017-12-11 12:36:43 +0530122 "ping%s -c %d%s -s %d%s -q%s %s > " SIGMA_TMPDIR
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200123 "/sigma_dut-ping.%d &\n"
124 "echo $! > " SIGMA_TMPDIR "/sigma_dut-ping-pid.%d\n",
Pradeep Reddy POTTETIeeb2ccb2016-08-30 12:41:03 +0530125 type == 2 ? "6" : "", pkts, int_arg, size, extra,
Purushottam Kushwahaa11683a2017-12-11 12:36:43 +0530126 intf_arg, dst, id, id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200127
128 fclose(f);
129 if (chmod(SIGMA_TMPDIR "/sigma_dut-ping.sh",
130 S_IRUSR | S_IWUSR | S_IXUSR) < 0)
131 return -2;
132
133 if (system(SIGMA_TMPDIR "/sigma_dut-ping.sh") != 0) {
134 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to start ping");
135 return -2;
136 }
137
138 unlink(SIGMA_TMPDIR "/sigma_dut-ping.sh");
139
140 snprintf(resp, sizeof(resp), "streamID,%d", id);
141 send_resp(dut, conn, SIGMA_COMPLETE, resp);
142 return 0;
143}
144
145
146static int cmd_traffic_stop_ping(struct sigma_dut *dut,
147 struct sigma_conn *conn,
148 struct sigma_cmd *cmd)
149{
150 const char *val;
151 int id, pid;
152 FILE *f;
153 char buf[100];
154 int res_found = 0, sent = 0, received = 0;
155
156 val = get_param(cmd, "streamID");
157 if (val == NULL)
158 return -1;
159 id = atoi(val);
160
161 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping-pid.%d", id);
162 f = fopen(buf, "r");
163 if (f == NULL) {
164 send_resp(dut, conn, SIGMA_ERROR,
165 "ErrorCode,Unknown streamID");
166 return 0;
167 }
168 if (fscanf(f, "%d", &pid) != 1 || pid <= 0) {
169 sigma_dut_print(dut, DUT_MSG_ERROR, "No PID for ping process");
170 fclose(f);
171 unlink(buf);
172 return -2;
173 }
174
175 fclose(f);
176 unlink(buf);
177
178 sigma_dut_print(dut, DUT_MSG_DEBUG, "Ping process pid %d", pid);
179 if (kill(pid, SIGINT) < 0 && errno != ESRCH) {
180 sigma_dut_print(dut, DUT_MSG_DEBUG, "kill failed: %s",
181 strerror(errno));
182 }
183 usleep(250000);
184
185 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id);
186 f = fopen(buf, "r");
187 if (f == NULL) {
188 sigma_dut_print(dut, DUT_MSG_DEBUG,
189 "No ping result file found");
190 send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0");
191 return 0;
192 }
193
194 while (fgets(buf, sizeof(buf), f)) {
195 char *pos;
196
197 pos = strstr(buf, " packets transmitted");
198 if (pos) {
199 pos--;
200 while (pos > buf && isdigit(pos[-1]))
201 pos--;
202 sent = atoi(pos);
203 res_found = 1;
204 }
205
206 pos = strstr(buf, " packets received");
207 if (pos == NULL)
208 pos = strstr(buf, " received");
209 if (pos) {
210 pos--;
211 while (pos > buf && isdigit(pos[-1]))
212 pos--;
213 received = atoi(pos);
214 res_found = 1;
215 }
216 }
217 fclose(f);
218 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id);
219 unlink(buf);
220
221 if (!res_found) {
222 sigma_dut_print(dut, DUT_MSG_DEBUG,
223 "No ping results found");
224 send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0");
225 return 0;
226 }
227
228 snprintf(buf, sizeof(buf), "sent,%d,replies,%d", sent, received);
229 send_resp(dut, conn, SIGMA_COMPLETE, buf);
230 return 0;
231}
232
233
234void traffic_register_cmds(void)
235{
236 sigma_dut_reg_cmd("traffic_send_ping", NULL, cmd_traffic_send_ping);
237 sigma_dut_reg_cmd("traffic_stop_ping", NULL, cmd_traffic_stop_ping);
238}