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