blob: f75d51597f4ef6cd46a88af482b41e6ab275646f [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
25static int is_ipv6_addr(const char *str)
26{
27 const char *pos = str;
28
29 while (*pos) {
30 if (*pos != ':' && (*pos < '0' || *pos > '9') &&
31 (*pos < 'a' || *pos > 'f') &&
32 (*pos < 'A' || *pos > 'F'))
33 return 0;
34 pos++;
35 }
36
37 return 1;
38}
39
40
41static int cmd_traffic_send_ping(struct sigma_dut *dut,
42 struct sigma_conn *conn,
43 struct sigma_cmd *cmd)
44{
45 const char *dst, *val;
46 int size, dur, pkts;
47 int id;
48 char resp[100];
49 float interval;
50 double rate;
51 FILE *f;
52 char buf[100];
53 int type = 1;
54 int dscp = 0, use_dscp = 0;
Pradeep Reddy POTTETIeeb2ccb2016-08-30 12:41:03 +053055 char extra[100], int_arg[100], intf_arg[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020056
57 val = get_param(cmd, "Type");
58 if (!val)
59 val = get_param(cmd, "IPType");
60 if (val)
61 type = atoi(val);
62 if (type != 1 && type != 2) {
63 send_resp(dut, conn, SIGMA_ERROR,
64 "ErrorCode,Unsupported address type");
65 return 0;
66 }
67
68 dst = get_param(cmd, "destination");
69 if (dst == NULL || (type == 1 && !is_ip_addr(dst)) ||
70 (type == 2 && !is_ipv6_addr(dst)))
71 return -1;
72
73 val = get_param(cmd, "frameSize");
74 if (val == NULL)
75 return -1;
76 size = atoi(val);
77
78 val = get_param(cmd, "frameRate");
79 if (val == NULL)
80 return -1;
81 rate = atof(val);
82 if (rate <= 0)
83 return -1;
84
85 val = get_param(cmd, "duration");
86 if (val == NULL)
87 return -1;
88 dur = atoi(val);
Pradeep Reddy POTTETI95093ac2016-10-13 17:22:03 +053089 if (dur <= 0 || dur > 3600)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020090 dur = 3600;
91
92 pkts = dur * rate;
93 interval = (float) 1 / rate;
94 if (interval > 100000)
95 return -1;
96
97 val = get_param(cmd, "DSCP");
98 if (val) {
99 dscp = atoi(val);
100 if (dscp < 0 || dscp > 63) {
101 send_resp(dut, conn, SIGMA_ERROR,
102 "ErrorCode,Invalid DSCP value");
103 return 0;
104 }
105 use_dscp = 1;
106 }
107
108 id = dut->next_streamid++;
109 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id);
110 unlink(buf);
111 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping-pid.%d", id);
112 unlink(buf);
113
114 sigma_dut_print(dut, DUT_MSG_DEBUG, "Send ping: pkts=%d interval=%f "
115 "streamid=%d",
116 pkts, interval, id);
117
118 f = fopen(SIGMA_TMPDIR "/sigma_dut-ping.sh", "w");
119 if (f == NULL)
120 return -2;
121
122 extra[0] = '\0';
123 if (use_dscp) {
124 snprintf(extra, sizeof(extra), " -Q 0x%02x",
125 dscp << 2);
126 }
127
128 int_arg[0] = '\0';
129 if (rate != 1)
130 snprintf(int_arg, sizeof(int_arg), " -i %f", interval);
Pradeep Reddy POTTETIeeb2ccb2016-08-30 12:41:03 +0530131 intf_arg[0] = '\0';
Purushottam Kushwahaa11683a2017-12-11 12:36:43 +0530132 if (dut->ndp_enable)
133 strlcpy(intf_arg, " -I nan0", sizeof(intf_arg));
134 else if (type == 2)
135 snprintf(intf_arg, sizeof(intf_arg), " -I %s",
136 get_station_ifname());
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200137 fprintf(f, "#!" SHELL "\n"
Purushottam Kushwahaa11683a2017-12-11 12:36:43 +0530138 "ping%s -c %d%s -s %d%s -q%s %s > " SIGMA_TMPDIR
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200139 "/sigma_dut-ping.%d &\n"
140 "echo $! > " SIGMA_TMPDIR "/sigma_dut-ping-pid.%d\n",
Pradeep Reddy POTTETIeeb2ccb2016-08-30 12:41:03 +0530141 type == 2 ? "6" : "", pkts, int_arg, size, extra,
Purushottam Kushwahaa11683a2017-12-11 12:36:43 +0530142 intf_arg, dst, id, id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200143
144 fclose(f);
145 if (chmod(SIGMA_TMPDIR "/sigma_dut-ping.sh",
146 S_IRUSR | S_IWUSR | S_IXUSR) < 0)
147 return -2;
148
149 if (system(SIGMA_TMPDIR "/sigma_dut-ping.sh") != 0) {
150 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to start ping");
151 return -2;
152 }
153
154 unlink(SIGMA_TMPDIR "/sigma_dut-ping.sh");
155
156 snprintf(resp, sizeof(resp), "streamID,%d", id);
157 send_resp(dut, conn, SIGMA_COMPLETE, resp);
158 return 0;
159}
160
161
162static int cmd_traffic_stop_ping(struct sigma_dut *dut,
163 struct sigma_conn *conn,
164 struct sigma_cmd *cmd)
165{
166 const char *val;
167 int id, pid;
168 FILE *f;
169 char buf[100];
170 int res_found = 0, sent = 0, received = 0;
171
172 val = get_param(cmd, "streamID");
173 if (val == NULL)
174 return -1;
175 id = atoi(val);
176
177 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping-pid.%d", id);
178 f = fopen(buf, "r");
179 if (f == NULL) {
180 send_resp(dut, conn, SIGMA_ERROR,
181 "ErrorCode,Unknown streamID");
182 return 0;
183 }
184 if (fscanf(f, "%d", &pid) != 1 || pid <= 0) {
185 sigma_dut_print(dut, DUT_MSG_ERROR, "No PID for ping process");
186 fclose(f);
187 unlink(buf);
188 return -2;
189 }
190
191 fclose(f);
192 unlink(buf);
193
194 sigma_dut_print(dut, DUT_MSG_DEBUG, "Ping process pid %d", pid);
195 if (kill(pid, SIGINT) < 0 && errno != ESRCH) {
196 sigma_dut_print(dut, DUT_MSG_DEBUG, "kill failed: %s",
197 strerror(errno));
198 }
199 usleep(250000);
200
201 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id);
202 f = fopen(buf, "r");
203 if (f == NULL) {
204 sigma_dut_print(dut, DUT_MSG_DEBUG,
205 "No ping result file found");
206 send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0");
207 return 0;
208 }
209
210 while (fgets(buf, sizeof(buf), f)) {
211 char *pos;
212
213 pos = strstr(buf, " packets transmitted");
214 if (pos) {
215 pos--;
216 while (pos > buf && isdigit(pos[-1]))
217 pos--;
218 sent = atoi(pos);
219 res_found = 1;
220 }
221
222 pos = strstr(buf, " packets received");
223 if (pos == NULL)
224 pos = strstr(buf, " received");
225 if (pos) {
226 pos--;
227 while (pos > buf && isdigit(pos[-1]))
228 pos--;
229 received = atoi(pos);
230 res_found = 1;
231 }
232 }
233 fclose(f);
234 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id);
235 unlink(buf);
236
237 if (!res_found) {
238 sigma_dut_print(dut, DUT_MSG_DEBUG,
239 "No ping results found");
240 send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0");
241 return 0;
242 }
243
244 snprintf(buf, sizeof(buf), "sent,%d,replies,%d", sent, received);
245 send_resp(dut, conn, SIGMA_COMPLETE, buf);
246 return 0;
247}
248
249
250void traffic_register_cmds(void)
251{
252 sigma_dut_reg_cmd("traffic_send_ping", NULL, cmd_traffic_send_ping);
253 sigma_dut_reg_cmd("traffic_stop_ping", NULL, cmd_traffic_stop_ping);
254}