/* * rwpmobgen.c -- A Randon Waypoint mobility generator for Network Simulator 2 (NS2). * Author: Muhammad Abdulla * License: GPL */ #include #include #include #include #include #include #include #include char *program_name; typedef enum {false, true} bool; void print_usage (FILE *stream, int exit_code); int nodes; double minspeed; double maxspeed; double x; double y; double simtime; int nocores; double coremins; // minimum speed for cores double coremaxs; // minimum speed for cores double pause_time; double theta; // angle double etime; // travel time (epoch time) double speed; // speed of travel double avgspeed; double avgdist; struct npos { double x; double y; double z; double t; // pause time }; struct npos *positions; int main (int argc, char *argv[] ) { int i; bool n_given = false; bool m_given = false; bool M_given = false; bool x_given = false; bool y_given = false; bool p_given = false; bool t_given = false; bool c_given = false; bool z_given = false; bool Z_given = false; double ptime; char *serror = ""; srand48(time(NULL)/7*(long)getpid()); program_name = argv[0]; int next_option; // A string listing valid short options letters. const char* const short_options = "hn:x:y:m:M:p:t:c:z:Z:"; // An array describing valid long options. const struct option long_options[] = { { "help", 0, NULL, 'h' }, { "nodes", 1, NULL, 'n' }, { "x", 1, NULL, 'x' }, { "y", 1, NULL, 'y' }, { "minspeed", 1, NULL, 'm' }, { "maxspeed", 1, NULL, 'M' }, { "pause", 1, NULL, 'p' }, { "simtime", 1, NULL, 't' }, { "nocores", 1, NULL, 'c' }, { "coremins", 1, NULL, 'z' }, { "coremaxs", 1, NULL, 'Z' }, { NULL, 0, NULL, 0 } /* Required at end of array. */ }; do { next_option = getopt_long (argc, argv, short_options, long_options, NULL); switch (next_option) { case 'h': print_usage (stdout, 0); break; case 'n': // -n or --nodes nodes = atoi(optarg); n_given = true; break; case 'x': // -x x = atof(optarg); x_given = true; break; case 'y': // -y y = atof(optarg); y_given = true; break; case 'm': // -m or --minspeed minspeed = atof(optarg); m_given = true; break; case 'M': // -M or --maxspeed maxspeed = atof(optarg); M_given = true; break; case 'p': // -p or --pause pause_time = atof(optarg); p_given = true; break; case 't': // -t or --simtime simtime = atof(optarg); t_given = true; break; case 'z': // -z or --coremins coremins = atof(optarg); z_given = true; break; case 'Z': // -c or --coremaxs coremaxs = atof(optarg); Z_given = true; break; case 'c': // -c or --nocores nocores = atoi(optarg); c_given = true; break; case '?': // The user specified an invalid option. print_usage (stderr, 1); break; case -1: // Done with options. break; default: // Something else: unexpected. abort (); } } while ( next_option != -1 ); if ( !n_given ) { serror = "error: number of nodes missing"; } else if ( nodes <= 0 ) { serror = "error: number of nodes not positive"; } else if ( !x_given ) { serror = "error: width (x) missing"; } else if ( x <= 0 ) { serror = "error: x not positive"; } else if ( !y_given ) { serror = "error: length (y) missing"; } else if ( y <= 0 ) { serror = "error: y not positive"; } else if ( !p_given ) { serror = "error: pause time missing"; } else if ( pause <= 0 ) { serror = "error: pause time not positive"; } else if ( !m_given ) { serror = "error: minspeed missing"; } else if ( minspeed <= 0 ) { serror = "error: minspeed not positive"; } else if ( !M_given ) { serror = "error: maxspeed missing"; } else if ( minspeed >= maxspeed ) { serror = "error: maxspeed has to be larger than minspeed"; } else if ( !t_given ) { serror = "error: simtime missing"; } else if ( simtime <= 0 ) { serror = "error: simtime non positive"; } if ( !c_given ) { if ( z_given || Z_given ) { serror = "error: number of cores should be given if coremins/coremaxs are set"; } } else { if ( !z_given ) { coremins = 2 * minspeed; } if ( !Z_given ) { coremaxs = 2 * maxspeed; } if ( coremins >= coremaxs ) { serror = "error: core maxspeed has to be larger than core minspeed"; } } if ( strlen(serror) > 0 ) { fprintf(stderr, "%s\n", serror); exit(1); } positions = (struct npos *) malloc(nodes * sizeof(struct npos)); assert(positions != NULL); // set initial position of nodes randomly for ( i = 0; i < nodes; i++ ) { positions[i].x = x * drand48(); positions[i].y = y * drand48(); positions[i].z = 0.0; positions[i].t = 0.0; fprintf(stdout, "$node_(%d) set X_ %.1f \n", i, positions[i].x); fprintf(stdout, "$node_(%d) set Y_ %.1f \n", i, positions[i].y); fprintf(stdout, "$node_(%d) set Z_ %.1f \n", i, positions[i].z); fprintf(stdout, "\n"); } double nx, ny, dist; struct npos *p; bool is_core; // generate movements for each node according to the random waypoint mobility model for ( i = 0; i < nodes; i++ ) { p = &positions[i]; if ( c_given && i < nocores ) { is_core = true; } else { is_core = false; } while ( p->t < simtime ) { if ( is_core ) { // cores are expected to have a different set of v_min and v_max speed = coremins + (coremaxs - coremins) * drand48(); } else { speed = minspeed + (maxspeed - minspeed) * drand48(); } if ( speed <= 0.0 ) { continue; } nx = x * drand48(); ny = y * drand48(); dist = sqrt ( pow(p->x - nx, 2.0) + pow(p->y - ny, 2.0) ); etime = dist / speed; fprintf(stdout, "$ns_ at %.1f \"$node_(%d) setdest %f %f %f\" \n", p->t, i, nx, ny, speed); p->t += etime; p->x = nx; p->y = ny; ptime = 2 * pause_time * drand48(); p->t += ptime; } } } void print_usage (FILE *stream, int exit_code) { fprintf (stream, "Usage: %s -n num_nodes -x x -y y -m minspeed -M maxspeed -p pause-time\n", program_name); fprintf (stream, " -h --help Display this usage information.\n" " -x --x width Width of rectangular area (Required).\n" " -y --y length Length of rectangular area (Required).\n" " -n --nodes num_nodes Number of nodes (Required, must be larger than zero).\n" " -m --minspeed speed Minimum speed (Required, must be larger than zero).\n" " -M --maxspeed speed Maximum speed (Required, must be larger than minspeed).\n" " -t --time simtime Simulation time(Required, must be larger 0).\n" " -p --pause pause-time Pause time between epochs (Required, must be non-negative).\n" " -c --nocores nocores Number of cores (the first nocores will be made cores).\n" " -z --coremins cm Minimum speed for cores (will set to twice minspeed if not given).\n" " -Z --coremaxs cM Maximum speed for cores (will set to twice maxspeed if not given).\n" ); exit (exit_code); }