blob: dfef639dd8d7818c32157f8b61548d731dcc0a84 [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.
4 * Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
5 * 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';
132 if (type == 2)
133 snprintf(intf_arg, sizeof(intf_arg), " -I %s",
134 get_station_ifname());
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200135 fprintf(f, "#!" SHELL "\n"
Pradeep Reddy POTTETIeeb2ccb2016-08-30 12:41:03 +0530136 "ping%s -c %d%s -s %d%s -q%s %s > " SIGMA_TMPDIR
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200137 "/sigma_dut-ping.%d &\n"
138 "echo $! > " SIGMA_TMPDIR "/sigma_dut-ping-pid.%d\n",
Pradeep Reddy POTTETIeeb2ccb2016-08-30 12:41:03 +0530139 type == 2 ? "6" : "", pkts, int_arg, size, extra,
140 intf_arg, dst, id, id);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200141
142 fclose(f);
143 if (chmod(SIGMA_TMPDIR "/sigma_dut-ping.sh",
144 S_IRUSR | S_IWUSR | S_IXUSR) < 0)
145 return -2;
146
147 if (system(SIGMA_TMPDIR "/sigma_dut-ping.sh") != 0) {
148 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to start ping");
149 return -2;
150 }
151
152 unlink(SIGMA_TMPDIR "/sigma_dut-ping.sh");
153
154 snprintf(resp, sizeof(resp), "streamID,%d", id);
155 send_resp(dut, conn, SIGMA_COMPLETE, resp);
156 return 0;
157}
158
159
160static int cmd_traffic_stop_ping(struct sigma_dut *dut,
161 struct sigma_conn *conn,
162 struct sigma_cmd *cmd)
163{
164 const char *val;
165 int id, pid;
166 FILE *f;
167 char buf[100];
168 int res_found = 0, sent = 0, received = 0;
169
170 val = get_param(cmd, "streamID");
171 if (val == NULL)
172 return -1;
173 id = atoi(val);
174
175 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping-pid.%d", id);
176 f = fopen(buf, "r");
177 if (f == NULL) {
178 send_resp(dut, conn, SIGMA_ERROR,
179 "ErrorCode,Unknown streamID");
180 return 0;
181 }
182 if (fscanf(f, "%d", &pid) != 1 || pid <= 0) {
183 sigma_dut_print(dut, DUT_MSG_ERROR, "No PID for ping process");
184 fclose(f);
185 unlink(buf);
186 return -2;
187 }
188
189 fclose(f);
190 unlink(buf);
191
192 sigma_dut_print(dut, DUT_MSG_DEBUG, "Ping process pid %d", pid);
193 if (kill(pid, SIGINT) < 0 && errno != ESRCH) {
194 sigma_dut_print(dut, DUT_MSG_DEBUG, "kill failed: %s",
195 strerror(errno));
196 }
197 usleep(250000);
198
199 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id);
200 f = fopen(buf, "r");
201 if (f == NULL) {
202 sigma_dut_print(dut, DUT_MSG_DEBUG,
203 "No ping result file found");
204 send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0");
205 return 0;
206 }
207
208 while (fgets(buf, sizeof(buf), f)) {
209 char *pos;
210
211 pos = strstr(buf, " packets transmitted");
212 if (pos) {
213 pos--;
214 while (pos > buf && isdigit(pos[-1]))
215 pos--;
216 sent = atoi(pos);
217 res_found = 1;
218 }
219
220 pos = strstr(buf, " packets received");
221 if (pos == NULL)
222 pos = strstr(buf, " received");
223 if (pos) {
224 pos--;
225 while (pos > buf && isdigit(pos[-1]))
226 pos--;
227 received = atoi(pos);
228 res_found = 1;
229 }
230 }
231 fclose(f);
232 snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id);
233 unlink(buf);
234
235 if (!res_found) {
236 sigma_dut_print(dut, DUT_MSG_DEBUG,
237 "No ping results found");
238 send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0");
239 return 0;
240 }
241
242 snprintf(buf, sizeof(buf), "sent,%d,replies,%d", sent, received);
243 send_resp(dut, conn, SIGMA_COMPLETE, buf);
244 return 0;
245}
246
247
248void traffic_register_cmds(void)
249{
250 sigma_dut_reg_cmd("traffic_send_ping", NULL, cmd_traffic_send_ping);
251 sigma_dut_reg_cmd("traffic_stop_ping", NULL, cmd_traffic_stop_ping);
252}