00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <malloc.h>
00015 #include <unistd.h>
00016 #include <stdio.h>
00017 #include <getopt.h>
00018 extern char *optarg;
00019 extern int optind, opterr, optopt;
00020 #include <errno.h>
00021 #include <string.h>
00022 #include <assert.h>
00023 #include <limits.h>
00024 #include <asm/types.h>
00025 #include <sys/types.h>
00026 #include <sys/socket.h>
00027 #include <sys/ioctl.h>
00028 #include <linux/wireless.h>
00029
00030 #include "dyn_wireless.h"
00031 #include "debug.h"
00032 #include "util.h"
00033
00034 #define DEBUG_FLAG '4'
00035
00036 #define USAGE "iwspy_sim -d <device> [-h] {[<mac_address> "\
00037 "<qualities_file>] .. | -m <mac_address>}\n"
00038 #define MAX_LINE 80
00039 #define MAX_FILES 64
00040
00041 extern int opt_debug;
00042
00043 static struct option const long_options[] =
00044 {
00045 {"help", no_argument, NULL, 'h'},
00046 {"device", required_argument, NULL, 'd'},
00047 {0, 0, 0, 0}
00048 };
00049
00050 int free_nodes(struct quality_values *q)
00051 {
00052 struct quality_values *t;
00053
00054 while (q != NULL) {
00055 t = q;
00056 q = q->next;
00057 free(t);
00058 }
00059
00060 return 0;
00061 }
00062
00063
00064
00065
00066
00067
00068 struct quality_values *read_quals(FILE *f, int *ival, int *filetype)
00069 {
00070 struct quality_values *q, *t;
00071 char buf[MAX_LINE], hw[ETH_ALEN+1], addr[20];
00072 int ret, qual;
00073 unsigned long tstamp;
00074
00075
00076 q = t = dyn_wireless_get_quals_node(NULL);
00077
00078
00079 *ival = 0;
00080 fgets(buf, MAX_LINE, f);
00081 ret = sscanf(buf, "# %d %d", ival, filetype);
00082 if (ret != 2) {
00083 fprintf(stderr, "Header not found! ´# <ival(in msec)> "
00084 "<filetype (0:no timestamps, 1:timestamps in seconds"
00085 ", 2:timestamps in tens of milli seconds>'. "
00086 "buf: '%s'\n", buf);
00087 return NULL;
00088 }
00089 fgets(buf, MAX_LINE, f);
00090 ret = sscanf(buf, "# %19s %6s", addr, hw);
00091 if (ret != 2) {
00092 fprintf(stderr, "Addresses not found. Should be: "
00093 "'# <ip-addr> <hw-addr>'. buf: '%s'\n", buf);
00094 return NULL;
00095 }
00096
00097 while (fgets(buf, MAX_LINE, f)) {
00098 if (*filetype == 0)
00099 sscanf(buf, "%d", &qual);
00100
00101 else if (*filetype == 1 || *filetype == 2 || *filetype == 3)
00102 sscanf(buf, "%lu %d", &tstamp, &qual);
00103 else {
00104 fprintf(stderr, "Unknown filetype! (%d)\n", *filetype);
00105 return NULL;
00106 }
00107 if (qual < 0 || qual > 100) {
00108 fprintf(stderr, "Invalid quality value! (%lu) "
00109 "(%d) '%s'\n",
00110 tstamp, qual, buf);
00111 return NULL;
00112 }
00113 if (t->num_of_quals >= MAX_NUM_QUALS)
00114 t = dyn_wireless_get_quals_node(t);
00115
00116 t->sim_quals[t->num_of_quals] = qual;
00117 t->sim_timestamps[t->num_of_quals] = tstamp;
00118 t->num_of_quals++;
00119 }
00120
00121 return q;
00122 }
00123
00124 FILE *get_file(char *name)
00125 {
00126 FILE *fd;
00127
00128 fd = fopen(name, "r");
00129 if (fd)
00130 return fd;
00131 fprintf(stderr, "get_file - %s: %s\n", name, strerror(errno));
00132
00133 return NULL;
00134 }
00135
00136 int close_file(FILE *f)
00137 {
00138 fclose(f);
00139 return 0;
00140 }
00141
00142 int parse_hw_address(char *string, char *hw)
00143 {
00144 int ret;
00145
00146 ret = sscanf(string, "%02x:%02x:%02x:%02x:%02x:%02x",
00147 (unsigned int *)&hw[0], (unsigned int *)&hw[1],
00148 (unsigned int *)&hw[2], (unsigned int *)&hw[3],
00149 (unsigned int *)&hw[4], (unsigned int *)&hw[5]);
00150 if (ret == 6)
00151 return 1;
00152
00153 return 0;
00154 }
00155
00156 void print_quals(struct quality_values *q)
00157 {
00158 unsigned long i, j;
00159
00160 j = 0;
00161 while (q != NULL) {
00162 for (i = 0; i < q->num_of_quals; i++)
00163 if (q->sim_timestamps[i] > 0)
00164 printf("%-4lu %3d\n", q->sim_timestamps[i],
00165 q->sim_quals[i]);
00166 else
00167 printf("%-4ld %3d\n", i + j, q->sim_quals[i]);
00168 j += q->num_of_quals;
00169 q = q->next;
00170 }
00171 }
00172
00173 int parse_pairs(int oindex, int const argc, char **argv, char *hw,
00174 FILE *qfile[], int *qfile_index)
00175 {
00176 int ret;
00177
00178 *qfile_index = 0;
00179 while (oindex < argc-1) {
00180 printf("oindex = %d, argc = %d, qfile_index = %d\n",
00181 oindex, argc, *qfile_index );
00182 ret = parse_hw_address(argv[oindex],
00183 &hw[(*qfile_index)*ETH_ALEN]);
00184 if (!ret) {
00185 fprintf(stderr, "Couldn't parse hw address!\n");
00186 printf(USAGE);
00187 return 1;
00188 }
00189 qfile[*qfile_index] = get_file(argv[oindex+1]);
00190 if (qfile[*qfile_index] == NULL)
00191 return 1;
00192 (*qfile_index)++;
00193 if (*qfile_index >= MAX_FILES)
00194 return 2;
00195 oindex += 2;
00196 }
00197
00198 return 0;
00199 }
00200
00201 static int feed_quality_values(int sock, char *ifname, char *hw,
00202 FILE *qfile[], int qfile_index)
00203 {
00204 struct quality_values *quals[MAX_FILES];
00205 int ivals[MAX_FILES], filetype[MAX_FILES], min_ival = INT_MAX;
00206 int nodes_left = 1, i, ret, r;
00207
00208
00209 DEBUG(DEBUG_FLAG, "feed_quality_values (%d)\n", qfile_index);
00210 for (i = 0; i < qfile_index; i++) {
00211 assert(qfile[i] != NULL);
00212 quals[i] = read_quals(qfile[i], &ivals[i], &filetype[i]);
00213 if (quals[i] == NULL) {
00214 DEBUG(DEBUG_FLAG, "Reading quals failed! (%d)\n",
00215 qfile_index);
00216 }
00217 if (ivals[i] < min_ival)
00218 min_ival = ivals[i];
00219 }
00220
00221 DEBUG(DEBUG_FLAG, "min_ival = %d, MAX_NUM_QUALS = %d\n",
00222 min_ival, MAX_NUM_QUALS);
00223 while (nodes_left) {
00224 nodes_left = 0;
00225 for (i = 0; i < qfile_index; i++) {
00226 if (quals[i] == NULL)
00227
00228 continue;
00229 ret = dyn_wireless_check_simulator(sock, ifname,
00230 &hw[i*ETH_ALEN]);
00231 if (ret == 3) {
00232 DEBUG(DEBUG_FLAG, "Feeding new chunk (%s)\n",
00233 ether_hwtoa((unsigned char *)
00234 &hw[i*ETH_ALEN]));
00235 r = dyn_wireless_set_simulator(sock, ifname,
00236 &hw[i*ETH_ALEN],
00237 quals[i],
00238 ivals[i],
00239 filetype[i]);
00240 if (r)
00241 return r;
00242 quals[i] = quals[i]->next;
00243 if (quals[i] != NULL)
00244 nodes_left = 1;
00245 } else if (ret == 2) {
00246
00247
00248
00249 if (quals[i]->next != NULL)
00250 nodes_left = 1;
00251 } else if (ret == 1) {
00252 DEBUG(DEBUG_FLAG, "Entry not found (%s)\n",
00253 ether_hwtoa((unsigned char *)
00254 &hw[i*ETH_ALEN]));
00255 } else {
00256 DEBUG(DEBUG_FLAG, "check_quals returned %d\n",
00257 ret);
00258 }
00259
00260
00261 }
00262
00263 if (nodes_left)
00264 usleep(100000);
00265 }
00266
00267 for (i = 0; i < qfile_index; i++) {
00268 free_nodes(quals[i]);
00269 }
00270
00271 return 0;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 int main(int argc, char **argv)
00289 {
00290 int oindex = 0, ret = 1, ret2 = 0;
00291 char hw[MAX_FILES*ETH_ALEN];
00292 char get_hw[ETH_ALEN];
00293 FILE *qfile[MAX_FILES];
00294 int qfile_index = 0;
00295 struct quality_values *quals = NULL;
00296 char ifname[IFNAMSIZ+1];
00297 signed char c;
00298 int sock, i;
00299
00300 memset(qfile, 0, sizeof(qfile));
00301 while ((c = getopt_long(argc, argv, "+d:hm:v", long_options, &oindex))
00302 != EOF) {
00303 switch (c) {
00304 case 'd':
00305 DEBUG(DEBUG_FLAG, "option d (Device) with value "
00306 "'%s'\n", optarg);
00307 ret = dyn_wireless_get_ifname(optarg, ifname);
00308 break;
00309 case 'm':
00310 DEBUG(DEBUG_FLAG, "option m (Mac address) with value "
00311 "'%s'\n", optarg);
00312 ret2 = parse_hw_address(optarg, get_hw);
00313 break;
00314 case 'h':
00315 printf(USAGE);
00316 return 0;
00317 break;
00318 case 'v':
00319 opt_debug = 1;
00320 break;
00321 default:
00322 fprintf(stderr, "Unknown option %c\n", c);
00323 printf(USAGE);
00324 break;
00325 }
00326 }
00327
00328
00329 if (ret) {
00330 printf("Couldn't parse device name!\n");
00331 printf(USAGE);
00332 return 1;
00333 }
00334
00335
00336
00337 sock = dyn_wireless_create_socket();
00338 if (sock < 0) {
00339 fprintf(stderr, "Socket creation failed (%s)\n",
00340 strerror(errno));
00341 return 1;
00342 }
00343
00344 if (ret2) {
00345
00346 DEBUG(DEBUG_FLAG, "GET\n");
00347 quals = dyn_wireless_get_simulator(sock, ifname, get_hw);
00348 print_quals(quals);
00349 free_nodes(quals);
00350 } else {
00351
00352
00353 DEBUG(DEBUG_FLAG, "SET\n");
00354 if (parse_pairs(optind, argc, argv, hw, qfile, &qfile_index)) {
00355 fprintf(stderr, "Command line parsing failed!\n");
00356 return 1;
00357 }
00358 feed_quality_values(sock, ifname, hw, qfile, qfile_index);
00359 }
00360
00361 for (i = 0; qfile[i] != NULL; i++)
00362 close_file(qfile[i]);
00363 return 0;
00364 }