diff -Naur ns-2.29-original/autoconf.h ns-2.29-new/autoconf.h --- ns-2.29-original/autoconf.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/autoconf.h 2008-04-09 13:15:05.000000000 +0200 @@ -0,0 +1,92 @@ +/* autoconf.h. Generated by configure. */ +/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ +/* + * Copyright (c) 1997 University of Southern California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, advertising + * materials, and other materials related to such distribution and use + * acknowledge that the software was developed by the University of + * Southern California, Information Sciences Institute. The name of the + * University may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +/* This file should contain variables changed only by autoconf. */ + +#define NSPERL_PATH "@PERL@" +#define NSTCLSH_PATH "@V_TCLSH@" + +/* If you need these from tcl, see the file tcl/lib/ns-autoconf.tcl.in */ + +/* + * Put autoconf #define's here to keep them off the command line. + * see autoconf.info(Header Templates) in the autoconf docs. + */ + +#define _GNU_SOURCE 1 + +/* what does random(3) return? */ +#define RANDOM_RETURN_TYPE long + +/* type definitions */ +/* #undef int8_t */ +/* #undef int16_t */ +/* #undef int32_t */ +/* #undef u_int8_t */ +/* #undef u_int16_t */ +/* #undef u_int32_t */ + +/* 64-bits */ +#define HAVE_INT64 1 +#define SIZEOF_LONG 4 +/* #undef int64_t */ + +/* socklen_t (for nse) */ +#define HAVE_SOCKLEN_T 1 + +/* functions */ +#define HAVE_BCOPY 1 +#define HAVE_BZERO 1 +#define HAVE_GETRUSAGE 1 +#define HAVE_SBRK 1 +#define HAVE_SNPRINTF 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOQ 1 +/* #undef HAVE_ADDR2ASCII */ +#define HAVE_FEENABLEEXCEPT 1 + +/* headers */ +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_ARPA_INET_H 1 +#define HAVE_NETINET_IN_H 1 +#define HAVE_NET_ETHERNET_H 1 +#define HAVE_FENV_H 1 + +/* structures */ +#define HAVE_ETHER_HEADER_STRUCT 1 +#define HAVE_ETHER_ADDRESS_STRUCT 1 + +/* constants */ +#define HAVE_SIOCGIFHWADDR 1 + + +/* stl */ +#ifdef __cplusplus +#define HAVE_STL 1 + +#define CPP_REQUIRES_NAMESPACE 1 +#ifdef CPP_REQUIRES_NAMESPACE +using namespace CPP_NAMESPACE; +#endif /* CPP_NAMESPACE */ +#endif /* __cplusplus */ + diff -Naur ns-2.29-original/common/packet.h ns-2.29-new/common/packet.h --- ns-2.29-original/common/packet.h 2009-04-13 11:39:11.000000000 +0200 +++ ns-2.29-new/common/packet.h 2008-04-09 13:12:04.000000000 +0200 @@ -167,6 +167,9 @@ // HDLC packet PT_HDLC, + // WIMAX inter-BS packets + PT_WIMAXBS, + // insert new packet types here PT_NTYPE // This MUST be the LAST one }; @@ -263,6 +266,9 @@ // XCP name_[PT_XCP]="xcp"; + // WIMAX + name_[PT_WIMAXBS]="wimaxCtrl"; + name_[PT_NTYPE]= "undefined"; } const char* name(packet_t p) const { diff -Naur ns-2.29-original/config.log ns-2.29-new/config.log --- ns-2.29-original/config.log 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/config.log 2009-04-13 15:34:50.000000000 +0200 @@ -0,0 +1,1625 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by configure, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ ./configure + +## --------- ## +## Platform. ## +## --------- ## + +hostname = linux +uname -m = i686 +uname -r = 2.6.11.4-20a-default +uname -s = Linux +uname -v = #1 Wed Mar 23 21:52:37 UTC 2005 + +/usr/bin/uname -p = unknown +/bin/uname -X = unknown + +/bin/arch = i686 +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /usr/sbin +PATH: /bin +PATH: /usr/bin +PATH: /sbin +PATH: /usr/X11R6/bin + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:1443: checking build system type +configure:1461: result: i686-pc-linux-gnu +configure:1469: checking host system type +configure:1483: result: i686-pc-linux-gnu +configure:1491: checking target system type +configure:1505: result: i686-pc-linux-gnu +configure:1566: checking for gcc +configure:1582: found /usr/bin/gcc +configure:1592: result: gcc +configure:1836: checking for C compiler version +configure:1839: gcc --version &5 +gcc (GCC) 3.3.5 20050117 (prerelease) (SUSE Linux) +Copyright (C) 2003 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:1842: $? = 0 +configure:1844: gcc -v &5 +Reading specs from /usr/lib/gcc-lib/i586-suse-linux/3.3.5/specs +Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --enable-languages=c,c++,f77,objc,java,ada --disable-checking --libdir=/usr/lib --enable-libgcj --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit i586-suse-linux +Thread model: posix +gcc version 3.3.5 20050117 (prerelease) (SUSE Linux) +configure:1847: $? = 0 +configure:1849: gcc -V &5 +gcc: `-V' option must have argument +configure:1852: $? = 1 +configure:1875: checking for C compiler default output file name +configure:1878: gcc conftest.c >&5 +configure:1881: $? = 0 +configure:1927: result: a.out +configure:1932: checking whether the C compiler works +configure:1938: ./a.out +configure:1941: $? = 0 +configure:1958: result: yes +configure:1965: checking whether we are cross compiling +configure:1967: result: no +configure:1970: checking for suffix of executables +configure:1972: gcc -o conftest conftest.c >&5 +configure:1975: $? = 0 +configure:2000: result: +configure:2006: checking for suffix of object files +configure:2027: gcc -c conftest.c >&5 +configure:2030: $? = 0 +configure:2052: result: o +configure:2056: checking whether we are using the GNU C compiler +configure:2080: gcc -c conftest.c >&5 +configure:2086: $? = 0 +configure:2089: test -z || test ! -s conftest.err +configure:2092: $? = 0 +configure:2095: test -s conftest.o +configure:2098: $? = 0 +configure:2111: result: yes +configure:2117: checking whether gcc accepts -g +configure:2138: gcc -c -g conftest.c >&5 +configure:2144: $? = 0 +configure:2147: test -z || test ! -s conftest.err +configure:2150: $? = 0 +configure:2153: test -s conftest.o +configure:2156: $? = 0 +configure:2167: result: yes +configure:2184: checking for gcc option to accept ANSI C +configure:2254: gcc -c -g -O2 conftest.c >&5 +configure:2260: $? = 0 +configure:2263: test -z || test ! -s conftest.err +configure:2266: $? = 0 +configure:2269: test -s conftest.o +configure:2272: $? = 0 +configure:2290: result: none needed +configure:2308: gcc -c -g -O2 conftest.c >&5 +conftest.c:2: error: syntax error before "me" +configure:2314: $? = 1 +configure: failed program was: +| #ifndef __cplusplus +| choke me +| #endif +configure:2496: checking for g++ +configure:2512: found /usr/bin/g++ +configure:2522: result: g++ +configure:2538: checking for C++ compiler version +configure:2541: g++ --version &5 +g++ (GCC) 3.3.5 20050117 (prerelease) (SUSE Linux) +Copyright (C) 2003 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:2544: $? = 0 +configure:2546: g++ -v &5 +Reading specs from /usr/lib/gcc-lib/i586-suse-linux/3.3.5/specs +Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --enable-languages=c,c++,f77,objc,java,ada --disable-checking --libdir=/usr/lib --enable-libgcj --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit i586-suse-linux +Thread model: posix +gcc version 3.3.5 20050117 (prerelease) (SUSE Linux) +configure:2549: $? = 0 +configure:2551: g++ -V &5 +g++: `-V' option must have argument +configure:2554: $? = 1 +configure:2557: checking whether we are using the GNU C++ compiler +configure:2581: g++ -c conftest.cc >&5 +configure:2587: $? = 0 +configure:2590: test -z || test ! -s conftest.err +configure:2593: $? = 0 +configure:2596: test -s conftest.o +configure:2599: $? = 0 +configure:2612: result: yes +configure:2618: checking whether g++ accepts -g +configure:2639: g++ -c -g conftest.cc >&5 +configure:2645: $? = 0 +configure:2648: test -z || test ! -s conftest.err +configure:2651: $? = 0 +configure:2654: test -s conftest.o +configure:2657: $? = 0 +configure:2668: result: yes +configure:2710: g++ -c -g -O2 conftest.cc >&5 +configure:2716: $? = 0 +configure:2719: test -z || test ! -s conftest.err +configure:2722: $? = 0 +configure:2725: test -s conftest.o +configure:2728: $? = 0 +configure:2754: g++ -c -g -O2 conftest.cc >&5 +conftest.cc: In function `int main()': +conftest.cc:14: error: `exit' undeclared (first use this function) +conftest.cc:14: error: (Each undeclared identifier is reported only once for + each function it appears in.) +configure:2760: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| /* end confdefs.h. */ +| +| int +| main () +| { +| exit (42); +| ; +| return 0; +| } +configure:2710: g++ -c -g -O2 conftest.cc >&5 +configure:2716: $? = 0 +configure:2719: test -z || test ! -s conftest.err +configure:2722: $? = 0 +configure:2725: test -s conftest.o +configure:2728: $? = 0 +configure:2754: g++ -c -g -O2 conftest.cc >&5 +configure:2760: $? = 0 +configure:2763: test -z || test ! -s conftest.err +configure:2766: $? = 0 +configure:2769: test -s conftest.o +configure:2772: $? = 0 +configure:2801: checking how to run the C preprocessor +configure:2836: gcc -E conftest.c +configure:2842: $? = 0 +configure:2874: gcc -E conftest.c +conftest.c:13:28: ac_nonexistent.h: No such file or directory +configure:2880: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| /* end confdefs.h. */ +| #include +configure:2919: result: gcc -E +configure:2943: gcc -E conftest.c +configure:2949: $? = 0 +configure:2981: gcc -E conftest.c +conftest.c:13:28: ac_nonexistent.h: No such file or directory +configure:2987: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| /* end confdefs.h. */ +| #include +configure:3031: checking for egrep +configure:3041: result: grep -E +configure:3046: checking for ANSI C header files +configure:3071: gcc -c -g -O2 conftest.c >&5 +configure:3077: $? = 0 +configure:3080: test -z || test ! -s conftest.err +configure:3083: $? = 0 +configure:3086: test -s conftest.o +configure:3089: $? = 0 +configure:3178: gcc -o conftest -g -O2 conftest.c >&5 +configure:3181: $? = 0 +configure:3183: ./conftest +configure:3186: $? = 0 +configure:3201: result: yes +configure:3225: checking for sys/types.h +configure:3241: gcc -c -g -O2 conftest.c >&5 +configure:3247: $? = 0 +configure:3250: test -z || test ! -s conftest.err +configure:3253: $? = 0 +configure:3256: test -s conftest.o +configure:3259: $? = 0 +configure:3270: result: yes +configure:3225: checking for sys/stat.h +configure:3241: gcc -c -g -O2 conftest.c >&5 +configure:3247: $? = 0 +configure:3250: test -z || test ! -s conftest.err +configure:3253: $? = 0 +configure:3256: test -s conftest.o +configure:3259: $? = 0 +configure:3270: result: yes +configure:3225: checking for stdlib.h +configure:3241: gcc -c -g -O2 conftest.c >&5 +configure:3247: $? = 0 +configure:3250: test -z || test ! -s conftest.err +configure:3253: $? = 0 +configure:3256: test -s conftest.o +configure:3259: $? = 0 +configure:3270: result: yes +configure:3225: checking for string.h +configure:3241: gcc -c -g -O2 conftest.c >&5 +configure:3247: $? = 0 +configure:3250: test -z || test ! -s conftest.err +configure:3253: $? = 0 +configure:3256: test -s conftest.o +configure:3259: $? = 0 +configure:3270: result: yes +configure:3225: checking for memory.h +configure:3241: gcc -c -g -O2 conftest.c >&5 +configure:3247: $? = 0 +configure:3250: test -z || test ! -s conftest.err +configure:3253: $? = 0 +configure:3256: test -s conftest.o +configure:3259: $? = 0 +configure:3270: result: yes +configure:3225: checking for strings.h +configure:3241: gcc -c -g -O2 conftest.c >&5 +configure:3247: $? = 0 +configure:3250: test -z || test ! -s conftest.err +configure:3253: $? = 0 +configure:3256: test -s conftest.o +configure:3259: $? = 0 +configure:3270: result: yes +configure:3225: checking for inttypes.h +configure:3241: gcc -c -g -O2 conftest.c >&5 +configure:3247: $? = 0 +configure:3250: test -z || test ! -s conftest.err +configure:3253: $? = 0 +configure:3256: test -s conftest.o +configure:3259: $? = 0 +configure:3270: result: yes +configure:3225: checking for stdint.h +configure:3241: gcc -c -g -O2 conftest.c >&5 +configure:3247: $? = 0 +configure:3250: test -z || test ! -s conftest.err +configure:3253: $? = 0 +configure:3256: test -s conftest.o +configure:3259: $? = 0 +configure:3270: result: yes +configure:3225: checking for unistd.h +configure:3241: gcc -c -g -O2 conftest.c >&5 +configure:3247: $? = 0 +configure:3250: test -z || test ! -s conftest.err +configure:3253: $? = 0 +configure:3256: test -s conftest.o +configure:3259: $? = 0 +configure:3270: result: yes +configure:3287: checking for string.h +configure:3292: result: yes +configure:3441: checking for main in -lXbsd +configure:3465: gcc -o conftest -g -O2 conftest.c -lXbsd >&5 +/usr/lib/gcc-lib/i586-suse-linux/3.3.5/../../../../i586-suse-linux/bin/ld: cannot find -lXbsd +collect2: ld returned 1 exit status +configure:3471: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| /* end confdefs.h. */ +| +| +| int +| main () +| { +| main (); +| ; +| return 0; +| } +configure:3496: result: no +configure:3502: checking for socket in -lsocket +configure:3532: gcc -o conftest -g -O2 conftest.c -lsocket >&5 +/usr/lib/gcc-lib/i586-suse-linux/3.3.5/../../../../i586-suse-linux/bin/ld: cannot find -lsocket +collect2: ld returned 1 exit status +configure:3538: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| /* end confdefs.h. */ +| +| /* Override any gcc2 internal prototype to avoid an error. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| /* We use char because int might match the return type of a gcc2 +| builtin and then its argument prototype would still apply. */ +| char socket (); +| int +| main () +| { +| socket (); +| ; +| return 0; +| } +configure:3563: result: no +configure:3569: checking for gethostbyname in -lnsl +configure:3599: gcc -o conftest -g -O2 conftest.c -lnsl >&5 +configure:3605: $? = 0 +configure:3608: test -z || test ! -s conftest.err +configure:3611: $? = 0 +configure:3614: test -s conftest +configure:3617: $? = 0 +configure:3630: result: yes +configure:3636: checking for dcgettext in -lintl +configure:3666: gcc -o conftest -g -O2 conftest.c -lintl >&5 +/usr/lib/gcc-lib/i586-suse-linux/3.3.5/../../../../i586-suse-linux/bin/ld: cannot find -lintl +collect2: ld returned 1 exit status +configure:3672: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| /* end confdefs.h. */ +| +| /* Override any gcc2 internal prototype to avoid an error. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| /* We use char because int might match the return type of a gcc2 +| builtin and then its argument prototype would still apply. */ +| char dcgettext (); +| int +| main () +| { +| dcgettext (); +| ; +| return 0; +| } +configure:3697: result: no +configure:3703: checking for getnodebyname in -ldnet_stub +configure:3733: gcc -o conftest -g -O2 conftest.c -ldnet_stub >&5 +/usr/lib/gcc-lib/i586-suse-linux/3.3.5/../../../../i586-suse-linux/bin/ld: cannot find -ldnet_stub +collect2: ld returned 1 exit status +configure:3739: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| /* end confdefs.h. */ +| +| /* Override any gcc2 internal prototype to avoid an error. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| /* We use char because int might match the return type of a gcc2 +| builtin and then its argument prototype would still apply. */ +| char getnodebyname (); +| int +| main () +| { +| getnodebyname (); +| ; +| return 0; +| } +configure:3764: result: no +configure:3810: checking that g++ can handle -O2 +configure:3836: gcc -c -g -O2 conftest.c >&5 +conftest.c: In function `main': +conftest.c:34: error: `error' undeclared (first use in this function) +conftest.c:34: error: (Each undeclared identifier is reported only once +conftest.c:34: error: for each function it appears in.) +conftest.c:34: error: syntax error before "int" +configure:3842: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| /* end confdefs.h. */ +| +| int +| main () +| { +| #if __GNUC__ < 2 || __GNUC_MINOR__ < 8 +| /* gcc */ +| error +| #endif +| #if __GNUC_MINOR__ < 92 +| /* egcs */ +| int error; +| #endif +| +| ; +| return 0; +| } +configure:3864: result: no +configure:3982: checking if C++ libraries work without any namespace +configure:4003: g++ -c -g -O2 conftest.cc >&5 +conftest.cc: In function `int main()': +conftest.cc:29: error: `cout' undeclared (first use this function) +conftest.cc:29: error: (Each undeclared identifier is reported only once for + each function it appears in.) +configure:4009: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| /* end confdefs.h. */ +| #include +| +| int +| main () +| { +| cout.fail(); +| +| ; +| return 0; +| } +configure:4031: result: no +configure:4039: checking if C++ libraries work with namespace std +configure:4060: g++ -c -g -O2 conftest.cc >&5 +configure:4066: $? = 0 +configure:4069: test -z || test ! -s conftest.err +configure:4072: $? = 0 +configure:4075: test -s conftest.o +configure:4078: $? = 0 +configure:4080: result: yes +configure:4097: checking if STL works without any namespace +configure:4117: g++ -c -g -O2 conftest.cc >&5 +conftest.cc: In function `int main()': +conftest.cc:29: error: `list' undeclared (first use this function) +conftest.cc:29: error: (Each undeclared identifier is reported only once for + each function it appears in.) +conftest.cc:29: error: syntax error before `>' token +configure:4123: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| /* end confdefs.h. */ +| #include +| +| int +| main () +| { +| list test; +| +| ; +| return 0; +| } +configure:4145: result: no +configure:4153: checking if STL works with namespace std +configure:4174: g++ -c -g -O2 conftest.cc >&5 +configure:4180: $? = 0 +configure:4183: test -z || test ! -s conftest.err +configure:4186: $? = 0 +configure:4189: test -s conftest.o +configure:4192: $? = 0 +configure:4194: result: yes +configure:4274: checking should use STL +configure:4299: result: yes +configure:4522: checking for tcl.h +configure:4575: result: -I../include +configure:4581: checking for libtcl8.4 +configure:4645: result: -L../lib -ltcl8.4 +configure:4651: checking for init.tcl +configure:4690: result: ../lib/tcl8.4 +configure:4707: checking for tclsh8.4.11 +configure:4740: result: no +configure:4707: checking for tclsh8.4 +configure:4725: found ../bin/tclsh8.4 +configure:4737: result: ../bin/tclsh8.4 +configure:4965: checking for tk.h +configure:5018: result: -I../include +configure:5024: checking for libtk8.4 +configure:5088: result: -L../lib -ltk8.4 +configure:5094: checking for tk.tcl +configure:5133: result: ../lib/tk8.4 +configure:5232: checking for otcl.h +configure:5285: result: -I../otcl-1.11 +configure:5291: checking for libotcl1.11 +configure:5355: result: -L../otcl-1.11 -lotcl +configure:5482: checking for tclcl.h +configure:5535: result: -I../tclcl-1.17 +configure:5541: checking for libtclcl +configure:5605: result: -L../tclcl-1.17 -ltclcl +configure:5611: checking for tcl2c++ +configure:5650: result: ../tclcl-1.17 +configure:5850: checking for libtcldbg +configure:5895: result: no +configure:6005: checking dmalloc +configure:6007: result: not requested with --with-dmalloc +configure:6288: checking for perl +configure:6327: result: /usr/bin +/usr/bin/perl -e require 5.002 +configure:6436: checking for ANSI C header files +configure:6591: result: yes +configure:6623: checking arpa/inet.h usability +configure:6635: gcc -c -g -O2 conftest.c >&5 +configure:6641: $? = 0 +configure:6644: test -z || test ! -s conftest.err +configure:6647: $? = 0 +configure:6650: test -s conftest.o +configure:6653: $? = 0 +configure:6663: result: yes +configure:6667: checking arpa/inet.h presence +configure:6677: gcc -E conftest.c +configure:6683: $? = 0 +configure:6703: result: yes +configure:6738: checking for arpa/inet.h +configure:6745: result: yes +configure:6623: checking fenv.h usability +configure:6635: gcc -c -g -O2 conftest.c >&5 +configure:6641: $? = 0 +configure:6644: test -z || test ! -s conftest.err +configure:6647: $? = 0 +configure:6650: test -s conftest.o +configure:6653: $? = 0 +configure:6663: result: yes +configure:6667: checking fenv.h presence +configure:6677: gcc -E conftest.c +configure:6683: $? = 0 +configure:6703: result: yes +configure:6738: checking for fenv.h +configure:6745: result: yes +configure:6623: checking netinet/in.h usability +configure:6635: gcc -c -g -O2 conftest.c >&5 +configure:6641: $? = 0 +configure:6644: test -z || test ! -s conftest.err +configure:6647: $? = 0 +configure:6650: test -s conftest.o +configure:6653: $? = 0 +configure:6663: result: yes +configure:6667: checking netinet/in.h presence +configure:6677: gcc -E conftest.c +configure:6683: $? = 0 +configure:6703: result: yes +configure:6738: checking for netinet/in.h +configure:6745: result: yes +configure:6614: checking for string.h +configure:6619: result: yes +configure:6614: checking for strings.h +configure:6619: result: yes +configure:6623: checking time.h usability +configure:6635: gcc -c -g -O2 conftest.c >&5 +configure:6641: $? = 0 +configure:6644: test -z || test ! -s conftest.err +configure:6647: $? = 0 +configure:6650: test -s conftest.o +configure:6653: $? = 0 +configure:6663: result: yes +configure:6667: checking time.h presence +configure:6677: gcc -E conftest.c +configure:6683: $? = 0 +configure:6703: result: yes +configure:6738: checking for time.h +configure:6745: result: yes +configure:6614: checking for unistd.h +configure:6619: result: yes +configure:6623: checking net/ethernet.h usability +configure:6635: gcc -c -g -O2 conftest.c >&5 +configure:6641: $? = 0 +configure:6644: test -z || test ! -s conftest.err +configure:6647: $? = 0 +configure:6650: test -s conftest.o +configure:6653: $? = 0 +configure:6663: result: yes +configure:6667: checking net/ethernet.h presence +configure:6677: gcc -E conftest.c +configure:6683: $? = 0 +configure:6703: result: yes +configure:6738: checking for net/ethernet.h +configure:6745: result: yes +configure:6759: checking for main in -lm +configure:6783: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:6789: $? = 0 +configure:6792: test -z || test ! -s conftest.err +configure:6795: $? = 0 +configure:6798: test -s conftest +configure:6801: $? = 0 +configure:6814: result: yes +configure:6839: checking for bcopy +configure:6896: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:6902: $? = 0 +configure:6905: test -z || test ! -s conftest.err +configure:6908: $? = 0 +configure:6911: test -s conftest +configure:6914: $? = 0 +configure:6926: result: yes +configure:6839: checking for bzero +configure:6896: gcc -o conftest -g -O2 conftest.c -lm >&5 +conftest.c:69: warning: conflicting types for built-in function `bzero' +configure:6902: $? = 0 +configure:6905: test -z || test ! -s conftest.err +configure:6908: $? = 0 +configure:6911: test -s conftest +configure:6914: $? = 0 +configure:6926: result: yes +configure:6839: checking for fesetprecision +configure:6896: gcc -o conftest -g -O2 conftest.c -lm >&5 +/tmp/ccAfx8rU.o(.text+0x11): In function `main': +/home/aymen/ns/ns-allinone-2.29/ns-2.29/conftest.c:86: undefined reference to `fesetprecision' +/tmp/ccAfx8rU.o(.data+0x0): undefined reference to `fesetprecision' +collect2: ld returned 1 exit status +configure:6902: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STL 1 +| #define CPP_REQUIRES_NAMESPACE 1 +| #define HAVE_TCL_H 1 +| #define HAVE_LIBTCL8_4 1 +| #define HAVE_TK_H 1 +| #define HAVE_LIBTK8_4 1 +| #define HAVE_OTCL_H 1 +| #define HAVE_LIBOTCL1_11 1 +| #define HAVE_TCLCL_H 1 +| #define HAVE_LIBTCLCL 1 +| #define STDC_HEADERS 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FENV_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_NET_ETHERNET_H 1 +| #define HAVE_LIBM 1 +| #define HAVE_BCOPY 1 +| #define HAVE_BZERO 1 +| /* end confdefs.h. */ +| /* Define fesetprecision to an innocuous variant, in case declares fesetprecision. +| For example, HP-UX 11i declares gettimeofday. */ +| #define fesetprecision innocuous_fesetprecision +| +| /* System header to define __stub macros and hopefully few prototypes, +| which can conflict with char fesetprecision (); below. +| Prefer to if __STDC__ is defined, since +| exists even on freestanding compilers. */ +| +| #ifdef __STDC__ +| # include +| #else +| # include +| #endif +| +| #undef fesetprecision +| +| /* Override any gcc2 internal prototype to avoid an error. */ +| #ifdef __cplusplus +| extern "C" +| { +| #endif +| /* We use char because int might match the return type of a gcc2 +| builtin and then its argument prototype would still apply. */ +| char fesetprecision (); +| /* The GNU C library defines this for functions which it implements +| to always fail with ENOSYS. Some functions are actually named +| something starting with __ and the normal name is an alias. */ +| #if defined (__stub_fesetprecision) || defined (__stub___fesetprecision) +| choke me +| #else +| char (*f) () = fesetprecision; +| #endif +| #ifdef __cplusplus +| } +| #endif +| +| int +| main () +| { +| return f != fesetprecision; +| ; +| return 0; +| } +configure:6926: result: no +configure:6839: checking for feenableexcept +configure:6896: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:6902: $? = 0 +configure:6905: test -z || test ! -s conftest.err +configure:6908: $? = 0 +configure:6911: test -s conftest +configure:6914: $? = 0 +configure:6926: result: yes +configure:6839: checking for getrusage +configure:6896: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:6902: $? = 0 +configure:6905: test -z || test ! -s conftest.err +configure:6908: $? = 0 +configure:6911: test -s conftest +configure:6914: $? = 0 +configure:6926: result: yes +configure:6839: checking for sbrk +configure:6896: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:6902: $? = 0 +configure:6905: test -z || test ! -s conftest.err +configure:6908: $? = 0 +configure:6911: test -s conftest +configure:6914: $? = 0 +configure:6926: result: yes +configure:6839: checking for snprintf +configure:6896: gcc -o conftest -g -O2 conftest.c -lm >&5 +conftest.c:73: warning: conflicting types for built-in function `snprintf' +configure:6902: $? = 0 +configure:6905: test -z || test ! -s conftest.err +configure:6908: $? = 0 +configure:6911: test -s conftest +configure:6914: $? = 0 +configure:6926: result: yes +configure:6937: checking return type of random +configure:6962: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:6965: $? = 0 +configure:6967: ./conftest +configure:6970: $? = 0 +configure:6972: result: long +configure:6996: checking for int8_t +configure:7020: gcc -c -g -O2 conftest.c >&5 +configure:7026: $? = 0 +configure:7029: test -z || test ! -s conftest.err +configure:7032: $? = 0 +configure:7035: test -s conftest.o +configure:7038: $? = 0 +configure:7049: result: yes +configure:7061: checking for int16_t +configure:7085: gcc -c -g -O2 conftest.c >&5 +configure:7091: $? = 0 +configure:7094: test -z || test ! -s conftest.err +configure:7097: $? = 0 +configure:7100: test -s conftest.o +configure:7103: $? = 0 +configure:7114: result: yes +configure:7126: checking for int32_t +configure:7150: gcc -c -g -O2 conftest.c >&5 +configure:7156: $? = 0 +configure:7159: test -z || test ! -s conftest.err +configure:7162: $? = 0 +configure:7165: test -s conftest.o +configure:7168: $? = 0 +configure:7179: result: yes +configure:7191: checking for u_int8_t +configure:7215: gcc -c -g -O2 conftest.c >&5 +configure:7221: $? = 0 +configure:7224: test -z || test ! -s conftest.err +configure:7227: $? = 0 +configure:7230: test -s conftest.o +configure:7233: $? = 0 +configure:7244: result: yes +configure:7256: checking for u_int16_t +configure:7280: gcc -c -g -O2 conftest.c >&5 +configure:7286: $? = 0 +configure:7289: test -z || test ! -s conftest.err +configure:7292: $? = 0 +configure:7295: test -s conftest.o +configure:7298: $? = 0 +configure:7309: result: yes +configure:7321: checking for u_int32_t +configure:7345: gcc -c -g -O2 conftest.c >&5 +configure:7351: $? = 0 +configure:7354: test -z || test ! -s conftest.err +configure:7357: $? = 0 +configure:7360: test -s conftest.o +configure:7363: $? = 0 +configure:7374: result: yes +configure:7386: checking for u_char +configure:7410: gcc -c -g -O2 conftest.c >&5 +configure:7416: $? = 0 +configure:7419: test -z || test ! -s conftest.err +configure:7422: $? = 0 +configure:7425: test -s conftest.o +configure:7428: $? = 0 +configure:7439: result: yes +configure:7451: checking for u_int +configure:7475: gcc -c -g -O2 conftest.c >&5 +configure:7481: $? = 0 +configure:7484: test -z || test ! -s conftest.err +configure:7487: $? = 0 +configure:7490: test -s conftest.o +configure:7493: $? = 0 +configure:7504: result: yes +configure:7523: checking for strtoq +configure:7580: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:7586: $? = 0 +configure:7589: test -z || test ! -s conftest.err +configure:7592: $? = 0 +configure:7595: test -s conftest +configure:7598: $? = 0 +configure:7610: result: yes +configure:7523: checking for strtoll +configure:7580: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:7586: $? = 0 +configure:7589: test -z || test ! -s conftest.err +configure:7592: $? = 0 +configure:7595: test -s conftest +configure:7598: $? = 0 +configure:7610: result: yes +configure:7625: checking for long +configure:7649: gcc -c -g -O2 conftest.c >&5 +configure:7655: $? = 0 +configure:7658: test -z || test ! -s conftest.err +configure:7661: $? = 0 +configure:7664: test -s conftest.o +configure:7667: $? = 0 +configure:7678: result: yes +configure:7681: checking size of long +configure:7993: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:7996: $? = 0 +configure:7998: ./conftest +configure:8001: $? = 0 +configure:8024: result: 4 +configure:8126: checking for __int64_t +configure:8146: gcc -o conftest -g -O2 conftest.c -lm >&5 +conftest.c: In function `main': +conftest.c:55: error: `__int64_t' undeclared (first use in this function) +conftest.c:55: error: (Each undeclared identifier is reported only once +conftest.c:55: error: for each function it appears in.) +conftest.c:55: error: syntax error before "x" +conftest.c:55: error: `x' undeclared (first use in this function) +configure:8149: $? = 1 +configure: program exited with status 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STL 1 +| #define CPP_REQUIRES_NAMESPACE 1 +| #define HAVE_TCL_H 1 +| #define HAVE_LIBTCL8_4 1 +| #define HAVE_TK_H 1 +| #define HAVE_LIBTK8_4 1 +| #define HAVE_OTCL_H 1 +| #define HAVE_LIBOTCL1_11 1 +| #define HAVE_TCLCL_H 1 +| #define HAVE_LIBTCLCL 1 +| #define STDC_HEADERS 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FENV_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_NET_ETHERNET_H 1 +| #define HAVE_LIBM 1 +| #define HAVE_BCOPY 1 +| #define HAVE_BZERO 1 +| #define HAVE_FEENABLEEXCEPT 1 +| #define HAVE_GETRUSAGE 1 +| #define HAVE_SBRK 1 +| #define HAVE_SNPRINTF 1 +| #define RANDOM_RETURN_TYPE long +| #define HAVE_STRTOQ 1 +| #define HAVE_STRTOLL 1 +| #define SIZEOF_LONG 4 +| /* end confdefs.h. */ +| +| main() { __int64_t x; exit (sizeof(x) >= 8 ? 0 : 1); } +| +configure:8168: result: no +configure:8174: checking for long long +configure:8194: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:8197: $? = 0 +configure:8199: ./conftest +configure:8202: $? = 0 +configure:8216: result: yes +configure:8224: checking for int64_t +configure:8250: result: yes +configure:8260: checking which kind of 64-bit int to use +configure:8272: result: int64_t +configure:8293: checking for struct ether_header +configure:8321: gcc -c -g -O2 conftest.c >&5 +configure:8327: $? = 0 +configure:8330: test -z || test ! -s conftest.err +configure:8333: $? = 0 +configure:8336: test -s conftest.o +configure:8339: $? = 0 +configure:8346: result: found +configure:8361: checking for struct ether_addr +configure:8389: gcc -c -g -O2 conftest.c >&5 +configure:8395: $? = 0 +configure:8398: test -z || test ! -s conftest.err +configure:8401: $? = 0 +configure:8404: test -s conftest.o +configure:8407: $? = 0 +configure:8414: result: found +configure:8433: checking for addr2ascii +configure:8490: gcc -o conftest -g -O2 conftest.c -lm >&5 +/tmp/cccj0pfr.o(.text+0x11): In function `main': +/home/aymen/ns/ns-allinone-2.29/ns-2.29/conftest.c:97: undefined reference to `addr2ascii' +/tmp/cccj0pfr.o(.data+0x0): undefined reference to `addr2ascii' +collect2: ld returned 1 exit status +configure:8496: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STL 1 +| #define CPP_REQUIRES_NAMESPACE 1 +| #define HAVE_TCL_H 1 +| #define HAVE_LIBTCL8_4 1 +| #define HAVE_TK_H 1 +| #define HAVE_LIBTK8_4 1 +| #define HAVE_OTCL_H 1 +| #define HAVE_LIBOTCL1_11 1 +| #define HAVE_TCLCL_H 1 +| #define HAVE_LIBTCLCL 1 +| #define STDC_HEADERS 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FENV_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_NET_ETHERNET_H 1 +| #define HAVE_LIBM 1 +| #define HAVE_BCOPY 1 +| #define HAVE_BZERO 1 +| #define HAVE_FEENABLEEXCEPT 1 +| #define HAVE_GETRUSAGE 1 +| #define HAVE_SBRK 1 +| #define HAVE_SNPRINTF 1 +| #define RANDOM_RETURN_TYPE long +| #define HAVE_STRTOQ 1 +| #define HAVE_STRTOLL 1 +| #define SIZEOF_LONG 4 +| #define HAVE_INT64 1 +| #define HAVE_ETHER_HEADER_STRUCT 1 +| #define HAVE_ETHER_ADDRESS_STRUCT 1 +| /* end confdefs.h. */ +| /* Define addr2ascii to an innocuous variant, in case declares addr2ascii. +| For example, HP-UX 11i declares gettimeofday. */ +| #define addr2ascii innocuous_addr2ascii +| +| /* System header to define __stub macros and hopefully few prototypes, +| which can conflict with char addr2ascii (); below. +| Prefer to if __STDC__ is defined, since +| exists even on freestanding compilers. */ +| +| #ifdef __STDC__ +| # include +| #else +| # include +| #endif +| +| #undef addr2ascii +| +| /* Override any gcc2 internal prototype to avoid an error. */ +| #ifdef __cplusplus +| extern "C" +| { +| #endif +| /* We use char because int might match the return type of a gcc2 +| builtin and then its argument prototype would still apply. */ +| char addr2ascii (); +| /* The GNU C library defines this for functions which it implements +| to always fail with ENOSYS. Some functions are actually named +| something starting with __ and the normal name is an alias. */ +| #if defined (__stub_addr2ascii) || defined (__stub___addr2ascii) +| choke me +| #else +| char (*f) () = addr2ascii; +| #endif +| #ifdef __cplusplus +| } +| #endif +| +| int +| main () +| { +| return f != addr2ascii; +| ; +| return 0; +| } +configure:8520: result: no +configure:8551: gcc -o conftest -g -O2 conftest.c -lm >&5 +configure:8554: $? = 0 +configure:8556: ./conftest +configure:8559: $? = 0 +configure:8577: checking for Linux compliant tcphdr +configure:8606: gcc -c -g -O2 conftest.c >&5 +configure:8612: $? = 0 +configure:8615: test -z || test ! -s conftest.err +configure:8618: $? = 0 +configure:8621: test -s conftest.o +configure:8624: $? = 0 +configure:8628: result: found +configure:8643: checking for BSD compliant tcphdr +configure:8672: gcc -c -g -O2 conftest.c >&5 +conftest.c: In function `main': +conftest.c:69: error: structure has no member named `th_sport' +configure:8678: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "" +| #define PACKAGE_TARNAME "" +| #define PACKAGE_VERSION "" +| #define PACKAGE_STRING "" +| #define PACKAGE_BUGREPORT "" +| #define _GNU_SOURCE 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STL 1 +| #define CPP_REQUIRES_NAMESPACE 1 +| #define HAVE_TCL_H 1 +| #define HAVE_LIBTCL8_4 1 +| #define HAVE_TK_H 1 +| #define HAVE_LIBTK8_4 1 +| #define HAVE_OTCL_H 1 +| #define HAVE_LIBOTCL1_11 1 +| #define HAVE_TCLCL_H 1 +| #define HAVE_LIBTCLCL 1 +| #define STDC_HEADERS 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FENV_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_NET_ETHERNET_H 1 +| #define HAVE_LIBM 1 +| #define HAVE_BCOPY 1 +| #define HAVE_BZERO 1 +| #define HAVE_FEENABLEEXCEPT 1 +| #define HAVE_GETRUSAGE 1 +| #define HAVE_SBRK 1 +| #define HAVE_SNPRINTF 1 +| #define RANDOM_RETURN_TYPE long +| #define HAVE_STRTOQ 1 +| #define HAVE_STRTOLL 1 +| #define SIZEOF_LONG 4 +| #define HAVE_INT64 1 +| #define HAVE_ETHER_HEADER_STRUCT 1 +| #define HAVE_ETHER_ADDRESS_STRUCT 1 +| #define HAVE_SIOCGIFHWADDR 1 +| /* end confdefs.h. */ +| +| #include +| #include +| +| int +| main () +| { +| +| int main() +| { +| struct tcphdr *tcp; +| tcp->th_sport= 1; +| +| return 0; +| } +| +| ; +| return 0; +| } +configure:8702: result: not found +configure:8708: checking for socklen_t +configure:8731: gcc -c -g -O2 conftest.c >&5 +configure:8737: $? = 0 +configure:8740: test -z || test ! -s conftest.err +configure:8743: $? = 0 +configure:8746: test -s conftest.o +configure:8749: $? = 0 +configure:8761: result: yes +configure:8774: checking for main in -lpcap +configure:8798: gcc -o conftest -g -O2 conftest.c -lpcap -lm >&5 +configure:8804: $? = 0 +configure:8807: test -z || test ! -s conftest.err +configure:8810: $? = 0 +configure:8813: test -s conftest +configure:8816: $? = 0 +configure:8829: result: yes +configure:8838: checking to make nse +configure:8842: result: yes +configure:8894: checking for dlopen in -ldl +configure:8924: gcc -o conftest -g -O2 conftest.c -ldl -lm >&5 +configure:8930: $? = 0 +configure:8933: test -z || test ! -s conftest.err +configure:8936: $? = 0 +configure:8939: test -s conftest +configure:8942: $? = 0 +configure:8955: result: yes +configure:9146: checking for a BSD-compatible install +configure:9201: result: /usr/bin/install -c +configure:9310: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by config.status, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on linux + +config.status:744: creating Makefile +config.status:744: creating tcl/lib/ns-autoconf.tcl +config.status:744: creating indep-utils/webtrace-conv/ucb/Makefile +config.status:744: creating indep-utils/webtrace-conv/dec/Makefile +config.status:744: creating indep-utils/webtrace-conv/nlanr/Makefile +config.status:744: creating indep-utils/webtrace-conv/epa/Makefile +config.status:744: creating indep-utils/cmu-scen-gen/setdest/Makefile +config.status:810: creating autoconf.h +config.status:1004: autoconf.h is unchanged + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_build=i686-pc-linux-gnu +ac_cv_build_alias=i686-pc-linux-gnu +ac_cv_c_compiler_gnu=yes +ac_cv_cxx_compiler_gnu=yes +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_CXXFLAGS_set= +ac_cv_env_CXXFLAGS_value= +ac_cv_env_CXX_set= +ac_cv_env_CXX_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_exeext= +ac_cv_func_addr2ascii=no +ac_cv_func_bcopy=yes +ac_cv_func_bzero=yes +ac_cv_func_feenableexcept=yes +ac_cv_func_fesetprecision=no +ac_cv_func_getrusage=yes +ac_cv_func_sbrk=yes +ac_cv_func_snprintf=yes +ac_cv_func_strtoll=yes +ac_cv_func_strtoq=yes +ac_cv_header_arpa_inet_h=yes +ac_cv_header_fenv_h=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_net_ethernet_h=yes +ac_cv_header_netinet_in_h=yes +ac_cv_header_stdc=yes +ac_cv_header_stdint_h=yes +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_time_h=yes +ac_cv_header_unistd_h=yes +ac_cv_host=i686-pc-linux-gnu +ac_cv_host_alias=i686-pc-linux-gnu +ac_cv_lib_Xbsd_main=no +ac_cv_lib_dl_dlopen=yes +ac_cv_lib_dnet_stub_getnodebyname=no +ac_cv_lib_intl_dcgettext=no +ac_cv_lib_m_main=yes +ac_cv_lib_nsl_gethostbyname=yes +ac_cv_lib_pcap_main=yes +ac_cv_lib_socket_socket=no +ac_cv_objext=o +ac_cv_path_V_TCLSH=../bin/tclsh8.4 +ac_cv_path_install='/usr/bin/install -c' +ac_cv_prog_CPP='gcc -E' +ac_cv_prog_ac_ct_CC=gcc +ac_cv_prog_ac_ct_CXX=g++ +ac_cv_prog_cc_g=yes +ac_cv_prog_cc_stdc= +ac_cv_prog_cxx_g=yes +ac_cv_prog_egrep='grep -E' +ac_cv_sizeof_long=4 +ac_cv_target=i686-pc-linux-gnu +ac_cv_target_alias=i686-pc-linux-gnu +ac_cv_type_int16_t=yes +ac_cv_type_int32_t=yes +ac_cv_type_int64_t=yes +ac_cv_type_int8_t=yes +ac_cv_type_long=yes +ac_cv_type_socklen_t=yes +ac_cv_type_u_char=yes +ac_cv_type_u_int=yes +ac_cv_type_u_int16_t=yes +ac_cv_type_u_int32_t=yes +ac_cv_type_u_int8_t=yes + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +CC='gcc' +CFLAGS='-g -O2' +CPP='gcc -E' +CPPFLAGS='' +CPP_NAMESPACE='std' +CXX='g++' +CXXFLAGS='-g -O2' +DEFS='-DHAVE_CONFIG_H' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='grep -E' +EXEEXT='' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +LDFLAGS='' +LIBOBJS='' +LIBS='-lm ' +LTLIBOBJS='' +OBJEXT='o' +PACKAGE_BUGREPORT='' +PACKAGE_NAME='' +PACKAGE_STRING='' +PACKAGE_TARNAME='' +PACKAGE_VERSION='' +PATH_SEPARATOR=':' +PERL='/usr/bin/perl' +SHELL='/bin/sh' +V_ALL='' +V_AR='ar cr' +V_BROKEN_OBJ='' +V_CCOPT=' -Wall' +V_DEFINE='-DTCLCL_CLASSINSTVAR -DNDEBUG -DLINUX_TCP_HEADER -DUSE_SHM' +V_DEFINES='-DHAVE_LIBTCLCL -DHAVE_TCLCL_H -DHAVE_LIBOTCL1_11 -DHAVE_OTCL_H -DHAVE_LIBTK8_4 -DHAVE_TK_H -DHAVE_LIBTCL8_4 -DHAVE_TCL_H ' +V_INCLUDE='' +V_INCLUDES='-I/home/aymen/ns/ns-allinone-2.29/tclcl-1.17 -I/home/aymen/ns/ns-allinone-2.29/otcl-1.11 -I/home/aymen/ns/ns-allinone-2.29/include -I/home/aymen/ns/ns-allinone-2.29/include -I/usr/include/pcap' +V_LIB=' -lnsl -lpcap -ldl' +V_LIBRARY_TCL='../lib/tcl8.4' +V_LIBRARY_TK='../lib/tk8.4' +V_LIBS='-L/home/aymen/ns/ns-allinone-2.29/tclcl-1.17 -ltclcl -L/home/aymen/ns/ns-allinone-2.29/otcl-1.11 -lotcl -L/home/aymen/ns/ns-allinone-2.29/lib -ltk8.4 -L/home/aymen/ns/ns-allinone-2.29/lib -ltcl8.4' +V_LIB_OTCL='-L/home/aymen/ns/ns-allinone-2.29/otcl-1.11 -lotcl' +V_LIB_TCL='-L/home/aymen/ns/ns-allinone-2.29/lib -ltcl8.4' +V_LIB_TCLCL='-L/home/aymen/ns/ns-allinone-2.29/tclcl-1.17 -ltclcl' +V_LIB_TK='-L/home/aymen/ns/ns-allinone-2.29/lib -ltk8.4' +V_LSSCRIPT='' +V_NS_TCL_LIB_STL='$(NS_TCL_LIB_STL)' +V_OBJ='' +V_OBJ_CRYPT='' +V_RANLIB='ranlib' +V_SHELL='' +V_SIGRET='void' +V_STATIC='' +V_STLOBJ='$(OBJ_STL)' +V_TARCMD='tar cfh' +V_TAR_EXTRA='' +V_TAR_TARGET='linux-gnu' +V_TCL2CPP='../tclcl-1.17/tcl2c++' +V_TCLSH='/home/aymen/ns/ns-allinone-2.29/bin/tclsh8.4' +V_TCL_LIBRARY_FILES='$(TCL_84_LIBRARY_FILES)' +V_TKDOSNAMES='$(LIBRARY_TK)/optMenu.tcl $(LIBRARY_TK)/scrlbar.tcl' +ac_ct_CC='gcc' +ac_ct_CXX='g++' +bindir='${exec_prefix}/bin' +build='i686-pc-linux-gnu' +build_alias='' +build_cpu='i686' +build_nse='nse' +build_os='linux-gnu' +build_vendor='pc' +datadir='${prefix}/share' +exec_prefix='${prefix}' +host='i686-pc-linux-gnu' +host_alias='' +host_cpu='i686' +host_os='linux-gnu' +host_vendor='pc' +includedir='${prefix}/include' +infodir='${prefix}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localstatedir='${prefix}/var' +mandir='${prefix}/man' +oldincludedir='/usr/include' +prefix='/usr/local' +program_transform_name='s,x,x,' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target='i686-pc-linux-gnu' +target_alias='' +target_cpu='i686' +target_os='linux-gnu' +target_vendor='pc' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +#define CPP_REQUIRES_NAMESPACE 1 +#define HAVE_ARPA_INET_H 1 +#define HAVE_BCOPY 1 +#define HAVE_BZERO 1 +#define HAVE_ETHER_ADDRESS_STRUCT 1 +#define HAVE_ETHER_HEADER_STRUCT 1 +#define HAVE_FEENABLEEXCEPT 1 +#define HAVE_FENV_H 1 +#define HAVE_GETRUSAGE 1 +#define HAVE_INT64 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIBM 1 +#define HAVE_LIBOTCL1_11 1 +#define HAVE_LIBTCL8_4 1 +#define HAVE_LIBTCLCL 1 +#define HAVE_LIBTK8_4 1 +#define HAVE_MEMORY_H 1 +#define HAVE_NETINET_IN_H 1 +#define HAVE_NET_ETHERNET_H 1 +#define HAVE_OTCL_H 1 +#define HAVE_SBRK 1 +#define HAVE_SIOCGIFHWADDR 1 +#define HAVE_SNPRINTF 1 +#define HAVE_SOCKLEN_T 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STL 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOQ 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_TCLCL_H 1 +#define HAVE_TCL_H 1 +#define HAVE_TIME_H 1 +#define HAVE_TK_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_UNISTD_H 1 +#define PACKAGE_BUGREPORT "" +#define PACKAGE_NAME "" +#define PACKAGE_STRING "" +#define PACKAGE_TARNAME "" +#define PACKAGE_VERSION "" +#define RANDOM_RETURN_TYPE long +#define SIZEOF_LONG 4 +#define STDC_HEADERS 1 +#define STDC_HEADERS 1 +#define _GNU_SOURCE 1 +#endif +#ifdef __cplusplus +extern "C" void std::exit (int) throw (); using std::exit; + +configure: exit 0 diff -Naur ns-2.29-original/config.status ns-2.29-new/config.status --- ns-2.29-original/config.status 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/config.status 2009-04-13 15:34:49.000000000 +0200 @@ -0,0 +1,1053 @@ +#! /bin/sh +# Generated by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=${CONFIG_SHELL-/bin/sh} +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +config_files=" Makefile tcl/lib/ns-autoconf.tcl indep-utils/webtrace-conv/ucb/Makefile indep-utils/webtrace-conv/dec/Makefile indep-utils/webtrace-conv/nlanr/Makefile indep-utils/webtrace-conv/epa/Makefile indep-utils/cmu-scen-gen/setdest/Makefile" +config_headers=" autoconf.h" + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +ac_cs_version="\ +config.status +configured by ./configure, generated by GNU Autoconf 2.59, + with options \"\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=. +INSTALL="/usr/bin/install -c" +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + echo "running /bin/sh ./configure " $ac_configure_extra_args " --no-create --no-recursion" >&6 + exec /bin/sh ./configure $ac_configure_extra_args --no-create --no-recursion +fi + +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "tcl/lib/ns-autoconf.tcl" ) CONFIG_FILES="$CONFIG_FILES tcl/lib/ns-autoconf.tcl" ;; + "indep-utils/webtrace-conv/ucb/Makefile" ) CONFIG_FILES="$CONFIG_FILES indep-utils/webtrace-conv/ucb/Makefile" ;; + "indep-utils/webtrace-conv/dec/Makefile" ) CONFIG_FILES="$CONFIG_FILES indep-utils/webtrace-conv/dec/Makefile" ;; + "indep-utils/webtrace-conv/nlanr/Makefile" ) CONFIG_FILES="$CONFIG_FILES indep-utils/webtrace-conv/nlanr/Makefile" ;; + "indep-utils/webtrace-conv/epa/Makefile" ) CONFIG_FILES="$CONFIG_FILES indep-utils/webtrace-conv/epa/Makefile" ;; + "indep-utils/cmu-scen-gen/setdest/Makefile" ) CONFIG_FILES="$CONFIG_FILES indep-utils/cmu-scen-gen/setdest/Makefile" ;; + "autoconf.h" ) CONFIG_HEADERS="$CONFIG_HEADERS autoconf.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t$/@;t t/; /@;t t$/s/[\\&,]/\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t$/,;t t/' >$tmp/subs.sed <<\CEOF +s,@SHELL@,/bin/sh,;t t +s,@PATH_SEPARATOR@,:,;t t +s,@PACKAGE_NAME@,,;t t +s,@PACKAGE_TARNAME@,,;t t +s,@PACKAGE_VERSION@,,;t t +s,@PACKAGE_STRING@,,;t t +s,@PACKAGE_BUGREPORT@,,;t t +s,@exec_prefix@,${prefix},;t t +s,@prefix@,/usr/local,;t t +s,@program_transform_name@,s,x,x,,;t t +s,@bindir@,${exec_prefix}/bin,;t t +s,@sbindir@,${exec_prefix}/sbin,;t t +s,@libexecdir@,${exec_prefix}/libexec,;t t +s,@datadir@,${prefix}/share,;t t +s,@sysconfdir@,${prefix}/etc,;t t +s,@sharedstatedir@,${prefix}/com,;t t +s,@localstatedir@,${prefix}/var,;t t +s,@libdir@,${exec_prefix}/lib,;t t +s,@includedir@,${prefix}/include,;t t +s,@oldincludedir@,/usr/include,;t t +s,@infodir@,${prefix}/info,;t t +s,@mandir@,${prefix}/man,;t t +s,@build_alias@,,;t t +s,@host_alias@,,;t t +s,@target_alias@,,;t t +s,@DEFS@,-DHAVE_CONFIG_H,;t t +s,@ECHO_C@,,;t t +s,@ECHO_N@,-n,;t t +s,@ECHO_T@,,;t t +s,@LIBS@,-lm ,;t t +s,@build@,i686-pc-linux-gnu,;t t +s,@build_cpu@,i686,;t t +s,@build_vendor@,pc,;t t +s,@build_os@,linux-gnu,;t t +s,@host@,i686-pc-linux-gnu,;t t +s,@host_cpu@,i686,;t t +s,@host_vendor@,pc,;t t +s,@host_os@,linux-gnu,;t t +s,@target@,i686-pc-linux-gnu,;t t +s,@target_cpu@,i686,;t t +s,@target_vendor@,pc,;t t +s,@target_os@,linux-gnu,;t t +s,@CC@,gcc,;t t +s,@CFLAGS@,-g -O2,;t t +s,@LDFLAGS@,,;t t +s,@CPPFLAGS@,,;t t +s,@ac_ct_CC@,gcc,;t t +s,@EXEEXT@,,;t t +s,@OBJEXT@,o,;t t +s,@CXX@,g++,;t t +s,@CXXFLAGS@,-g -O2,;t t +s,@ac_ct_CXX@,g++,;t t +s,@CPP@,gcc -E,;t t +s,@EGREP@,grep -E,;t t +s,@CPP_NAMESPACE@,std,;t t +s,@V_TCL_LIBRARY_FILES@,$(TCL_84_LIBRARY_FILES),;t t +s,@V_TCLSH@,/home/aymen/ns/ns-allinone-2.29/bin/tclsh8.4,;t t +s,@V_LIBRARY_TCL@,../lib/tcl8.4,;t t +s,@V_TKDOSNAMES@,$(LIBRARY_TK)/optMenu.tcl $(LIBRARY_TK)/scrlbar.tcl,;t t +s,@V_LIBRARY_TK@,../lib/tk8.4,;t t +s,@V_TCL2CPP@,../tclcl-1.17/tcl2c++,;t t +s,@PERL@,/usr/bin/perl,;t t +s,@build_nse@,nse,;t t +s,@V_INCLUDES@,-I/home/aymen/ns/ns-allinone-2.29/tclcl-1.17 -I/home/aymen/ns/ns-allinone-2.29/otcl-1.11 -I/home/aymen/ns/ns-allinone-2.29/include -I/home/aymen/ns/ns-allinone-2.29/include -I/usr/include/pcap,;t t +s,@V_LIBS@,-L/home/aymen/ns/ns-allinone-2.29/tclcl-1.17 -ltclcl -L/home/aymen/ns/ns-allinone-2.29/otcl-1.11 -lotcl -L/home/aymen/ns/ns-allinone-2.29/lib -ltk8.4 -L/home/aymen/ns/ns-allinone-2.29/lib -ltcl8.4,;t t +s,@V_DEFINES@,-DHAVE_LIBTCLCL -DHAVE_TCLCL_H -DHAVE_LIBOTCL1_11 -DHAVE_OTCL_H -DHAVE_LIBTK8_4 -DHAVE_TK_H -DHAVE_LIBTCL8_4 -DHAVE_TCL_H ,;t t +s,@V_STATIC@,,;t t +s,@V_TAR_TARGET@,linux-gnu,;t t +s,@V_LIB_TCLCL@,-L/home/aymen/ns/ns-allinone-2.29/tclcl-1.17 -ltclcl,;t t +s,@V_LIB_OTCL@,-L/home/aymen/ns/ns-allinone-2.29/otcl-1.11 -lotcl,;t t +s,@V_LIB_TCL@,-L/home/aymen/ns/ns-allinone-2.29/lib -ltcl8.4,;t t +s,@V_LIB_TK@,-L/home/aymen/ns/ns-allinone-2.29/lib -ltk8.4,;t t +s,@V_ALL@,,;t t +s,@V_CCOPT@, -Wall,;t t +s,@V_TAR_EXTRA@,,;t t +s,@V_LIB@, -lnsl -lpcap -ldl,;t t +s,@V_DEFINE@,-DTCLCL_CLASSINSTVAR -DNDEBUG -DLINUX_TCP_HEADER -DUSE_SHM,;t t +s,@V_SIGRET@,void,;t t +s,@V_SHELL@,,;t t +s,@V_TARCMD@,tar cfh,;t t +s,@V_INCLUDE@,,;t t +s,@V_OBJ@,,;t t +s,@V_BROKEN_OBJ@,,;t t +s,@V_OBJ_CRYPT@,,;t t +s,@V_RANLIB@,ranlib,;t t +s,@V_AR@,ar cr,;t t +s,@V_STLOBJ@,$(OBJ_STL),;t t +s,@V_NS_TCL_LIB_STL@,$(NS_TCL_LIB_STL),;t t +s,@V_LSSCRIPT@,,;t t +s,@INSTALL_PROGRAM@,${INSTALL},;t t +s,@INSTALL_SCRIPT@,${INSTALL},;t t +s,@INSTALL_DATA@,${INSTALL} -m 644,;t t +s,@LIBOBJS@,,;t t +s,@LTLIBOBJS@,,;t t +CEOF + + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + sed "/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + + # Handle all the #define templates only if necessary. + if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then + # If there are no defines, we may have an empty if/fi + : + cat >$tmp/defines.sed <$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in + + cat >$tmp/defines.sed <$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in + + fi # grep + + # Handle all the #undef templates + cat >$tmp/undefs.sed <$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in + + cat >$tmp/undefs.sed <$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done + +{ (exit 0); exit 0; } diff -Naur ns-2.29-original/mac/mac-stats.h ns-2.29-new/mac/mac-stats.h --- ns-2.29-original/mac/mac-stats.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/mac/mac-stats.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,273 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author woon + */ + +#ifndef mac_stats_h +#define mac_stats_h + +/** Action to execute on the threshold */ +enum threshold_action_t { + NO_ACTION_TH, + INIT_ACTION_TH, + ROLLBACK_ACTION_TH, + EXEC_ACTION_TH +}; + +/** + * NIST: Stats Watch + * Used to maintain statistics of a particular parameter + * + * Positive gradient means that when the value measured increases, it will trigger INIT_ACTION_TH + * A positive gradient is used for measurements such as packet loss, where as negative gradient + * is used for RSSI. + */ +class StatWatch : public TimerHandler { +public: + StatWatch(double ti=1, double alpha=1, bool pos_gradient=true) : TimerHandler() { + timer_interval_ = ti; + alpha_ = alpha; + pos_gradient_ = pos_gradient; + current_ = 0; + average_ = 0; + instant_ = 0; + total_ = 0; + sample_number_ = 0; + th_set_ = false; + init_sent_ = false; + init_th_ = 0; + rollback_th_ = 0; + exec_th_ = 0; + pending_action_ = NO_ACTION_TH; + delay_ = 0; + } + virtual void expire(Event*) { schedule_next(); } + + inline void reset() { + average_ = 0; + instant_ = 0; + total_ = 0; + sample_number_ = 0; + } + + inline void set_thresholds (double init_th, double rollback_th, double exec_th) { + assert ( (pos_gradient_ && rollback_th <= init_th && init_th <= exec_th) + || (!pos_gradient_ && rollback_th >= init_th && init_th >= exec_th)); + init_th_ = init_th; + rollback_th_ = rollback_th; + exec_th_ = exec_th; + th_set_ = true; + } + + inline void set_timer_interval(double ti) { timer_interval_ = ti; } + inline void set_alpha(double a) { alpha_= a; } + inline void set_current(double c) { current_= c; } + inline void set_pos_gradient(bool b) { pos_gradient_ = b; } + inline void set_delay (double d) { delay_ = d; } + virtual threshold_action_t update(double new_val) { + old_average_ = average_; + average_ = alpha_*new_val + (1-alpha_)*average_; + total_ += new_val; + sample_number_++; + instant_ = new_val; + + //evaluate if threshold has been crossed + if (th_set_) { + if (pos_gradient_) { + //check if threshold is crossed + if (old_average_ > rollback_th_ && average_ <= rollback_th_ && init_sent_) { + pending_action_ = ROLLBACK_ACTION_TH; + ts_ = NOW+delay_; + } else if (old_average_ < exec_th_ && average_ >= exec_th_) { + pending_action_ = EXEC_ACTION_TH; + ts_ = NOW+delay_; + } else if (old_average_ < init_th_ && average_ >= init_th_) { + pending_action_ = INIT_ACTION_TH; + ts_ = NOW+delay_; + } else { + //check if threshold is canceled + if (pending_action_ == ROLLBACK_ACTION_TH && average_ > rollback_th_ + || pending_action_ == EXEC_ACTION_TH && average_ < exec_th_ + || pending_action_ == INIT_ACTION_TH && average_ < init_th_) { + pending_action_ = NO_ACTION_TH; + } + } + //check if action is still valid + if (pending_action_ != NO_ACTION_TH && NOW >= ts_) { + threshold_action_t tmp = pending_action_; + pending_action_ = NO_ACTION_TH; + return tmp; + } + + } else { + //check if threshold is crossed + if (old_average_ < rollback_th_ && average_ >= rollback_th_ && init_sent_) { + pending_action_ = ROLLBACK_ACTION_TH; + ts_ = NOW+delay_; + } else if (old_average_ > exec_th_ && average_ <= exec_th_) { + pending_action_ = EXEC_ACTION_TH; + ts_ = NOW+delay_; + } else if (old_average_ > init_th_ && average_ <= init_th_) { + pending_action_ = INIT_ACTION_TH; + ts_ = NOW+delay_; + } else { + //check if threshold is canceled + if (pending_action_ == ROLLBACK_ACTION_TH && average_ < rollback_th_ + || pending_action_ == EXEC_ACTION_TH && average_ > exec_th_ + || pending_action_ == INIT_ACTION_TH && average_ > init_th_) { + pending_action_ = NO_ACTION_TH; + } + } + //check if action is still valid + if (pending_action_ != NO_ACTION_TH && NOW >= ts_) { + threshold_action_t tmp = pending_action_; + pending_action_ = NO_ACTION_TH; + return tmp; + } + } + } + return NO_ACTION_TH; + } + inline void schedule_next() { resched(timer_interval_); } + + inline double current() { return current_; } + inline double total() { return total_; } + inline double sample_number() { return sample_number_; } + inline double average() { return average_; } + inline double old_average() { return old_average_; } + inline double instant() { return instant_; } + inline double simple_average() { return total_/sample_number_; } + +protected: + double timer_interval_; + double alpha_; + double current_; + double average_; + double old_average_; + double instant_; + double total_; + int sample_number_; + bool pos_gradient_; + double delay_; + threshold_action_t pending_action_; + double ts_; + bool th_set_; + bool init_sent_; + double init_th_; + double rollback_th_; + double exec_th_; +}; + +/** + * Class to handle throughput measurements + */ +class ThroughputWatch: public StatWatch { + public: + /** + * Constructor + */ + ThroughputWatch() { } + + /** + * Virtual desctructor + */ + virtual ~ThroughputWatch() {}; + + inline void set_alpha(double a) { size_.set_alpha(a); time_.set_alpha(a); } + inline double get_timer_interval () { return 0.01; } + + threshold_action_t update(double size, double time) { + size_.update (size); + time_.update (time-time_.current()); + time_.set_current (time); + old_average_ = average_; + average_ = size_.average()/time_.average(); + + //evaluate if threshold has been crossed + if (th_set_) { + if (pos_gradient_) { + //check if threshold is crossed + if (old_average_ > rollback_th_ && average_ <= rollback_th_ && init_sent_) { + pending_action_ = ROLLBACK_ACTION_TH; + ts_ = NOW+delay_; + } else if (old_average_ < exec_th_ && average_ >= exec_th_) { + pending_action_ = EXEC_ACTION_TH; + ts_ = NOW+delay_; + } else if (old_average_ < init_th_ && average_ >= init_th_) { + pending_action_ = INIT_ACTION_TH; + ts_ = NOW+delay_; + } else { + //check if threshold is canceled + if (pending_action_ == ROLLBACK_ACTION_TH && average_ > rollback_th_ + || pending_action_ == EXEC_ACTION_TH && average_ < exec_th_ + || pending_action_ == INIT_ACTION_TH && average_ < init_th_) { + pending_action_ = NO_ACTION_TH; + } + } + //check if action is still valid + if (pending_action_ != NO_ACTION_TH && NOW >= ts_) { + threshold_action_t tmp = pending_action_; + pending_action_ = NO_ACTION_TH; + return tmp; + } + + } else { + //check if threshold is crossed + if (old_average_ < rollback_th_ && average_ >= rollback_th_ && init_sent_) { + pending_action_ = ROLLBACK_ACTION_TH; + ts_ = NOW+delay_; + } else if (old_average_ > exec_th_ && average_ <= exec_th_) { + pending_action_ = EXEC_ACTION_TH; + ts_ = NOW+delay_; + } else if (old_average_ > init_th_ && average_ <= init_th_) { + pending_action_ = INIT_ACTION_TH; + ts_ = NOW+delay_; + } else { + //check if threshold is canceled + if (pending_action_ == ROLLBACK_ACTION_TH && average_ < rollback_th_ + || pending_action_ == EXEC_ACTION_TH && average_ > exec_th_ + || pending_action_ == INIT_ACTION_TH && average_ > init_th_) { + pending_action_ = NO_ACTION_TH; + } + } + //check if action is still valid + if (pending_action_ != NO_ACTION_TH && NOW >= ts_) { + threshold_action_t tmp = pending_action_; + pending_action_ = NO_ACTION_TH; + printf ("Action triggered %d\n", tmp); + return tmp; + } + } + } + return NO_ACTION_TH; + } + + protected: + /** + * Watch for packet size + */ + StatWatch size_; + + /** + * Watch for inter arrival time + */ + StatWatch time_; + +}; + + + +#endif //mac_stats_h diff -Naur ns-2.29-original/Makefile.in ns-2.29-new/Makefile.in --- ns-2.29-original/Makefile.in 2009-04-13 12:12:35.000000000 +0200 +++ ns-2.29-new/Makefile.in 2009-04-13 15:01:22.000000000 +0200 @@ -70,6 +70,7 @@ -I./diffusion3/lib/nr -I./diffusion3/ns \ -I./diffusion3/filter_core -I./asim/ -I./qs \ -I./diffserv -I./satellite \ + -I./wimax \ -I./wpan @@ -301,6 +302,37 @@ wpan/p802_15_4nam.o wpan/p802_15_4phy.o \ wpan/p802_15_4sscs.o wpan/p802_15_4timer.o \ wpan/p802_15_4trace.o wpan/p802_15_4transac.o \ + wimax/ofdmphy.o \ + wimax/mac802_16pkt.o \ + wimax/serviceflowqos.o \ + wimax/serviceflow.o \ + wimax/serviceflowhandler.o \ + wimax/connection.o \ + wimax/connectionmanager.o \ + wimax/peernode.o \ + wimax/mac802_16.o \ + wimax/sduclassifier.o \ + wimax/destclassifier.o \ + wimax/mac802_16timer.o \ + wimax/WiMAXneighborentry.o \ + wimax/neighbordb.o \ + wimax/scheduling/wimaxscheduler.o \ + wimax/scheduling/bsscheduler.o \ + wimax/scheduling/ssscheduler.o \ + wimax/scheduling/ulsubframetimer.o \ + wimax/scheduling/dlsubframetimer.o \ + wimax/scheduling/burst.o \ + wimax/scheduling/contentionslot.o \ + wimax/scheduling/contentionrequest.o \ + wimax/scheduling/contentiontimer.o \ + wimax/scheduling/dlburst.o \ + wimax/scheduling/ulburst.o \ + wimax/scheduling/framemap.o \ + wimax/scheduling/phypdu.o \ + wimax/scheduling/profile.o \ + wimax/scheduling/subframe.o \ + wimax/scheduling/scanningstation.o \ + wimax/scheduling/wimaxctrlagent.o \ @V_STLOBJ@ @@ -456,6 +488,7 @@ tcl/lib/ns-srcrt.tcl \ tcl/mcast/ns-lms.tcl \ tcl/lib/ns-qsnode.tcl \ + tcl/lib/ns-wimax.tcl \ @V_NS_TCL_LIB_STL@ $(GEN_DIR)ns_tcl.cc: $(NS_TCL_LIB) diff -Naur ns-2.29-original/tcl/lib/ns-autoconf.tcl ns-2.29-new/tcl/lib/ns-autoconf.tcl --- ns-2.29-original/tcl/lib/ns-autoconf.tcl 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/tcl/lib/ns-autoconf.tcl 2008-06-11 16:53:43.000000000 +0200 @@ -0,0 +1,50 @@ +# -*- Mode:tcl -*- +# +# Copyright (c) 1997 University of Southern California. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that the above copyright notice and this paragraph are +# duplicated in all such forms and that any documentation, advertising +# materials, and other materials related to such distribution and use +# acknowledge that the software was developed by the University of +# Southern California, Information Sciences Institute. The name of the +# University may not be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +# +# + +# This file should contain variables changed only by autoconf. + +proc checkout_executable {exe_var best alternate text} { + global $exe_var + set $exe_var $best + if {"$best" == "" || ![file executable $best]} { + puts stderr $text + set $exe_var $alternate + } +} + +# +# Keep track of where the good perl is. +# +checkout_executable PERL "/usr/bin/perl" perl "\ + When configured, ns found the right version of perl in\ + /usr/bin/perl + but it doesn't seem to be there anymore, so\ + ns will fall back on running the first perl in your path.\ + The wrong version of perl may break the test suites.\ + Reconfigure and rebuild ns if this is a problem.\ +" +checkout_executable TCLSH "/home/aymen/ns/ns-allinone-2.29/bin/tclsh8.4" tclsh "\ + When configured, ns found the right version of tclsh in\ + /home/aymen/ns/ns-allinone-2.29/bin/tclsh8.4 + but it doesn't seem to be there anymore, so\ + ns will fall back on running the first tclsh in your path.\ + The wrong version of tclsh may break the test suites.\ + Reconfigure and rebuild ns if this is a problem.\ +" diff -Naur ns-2.29-original/tcl/lib/ns-autoconf.tcl.in ns-2.29-new/tcl/lib/ns-autoconf.tcl.in --- ns-2.29-original/tcl/lib/ns-autoconf.tcl.in 2009-04-13 11:57:25.000000000 +0200 +++ ns-2.29-new/tcl/lib/ns-autoconf.tcl.in 1970-01-01 01:00:00.000000000 +0100 @@ -1,50 +0,0 @@ -# -*- Mode:tcl -*- -# -# Copyright (c) 1997 University of Southern California. -# All rights reserved. -# -# Redistribution and use in source and binary forms are permitted -# provided that the above copyright notice and this paragraph are -# duplicated in all such forms and that any documentation, advertising -# materials, and other materials related to such distribution and use -# acknowledge that the software was developed by the University of -# Southern California, Information Sciences Institute. The name of the -# University may not be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED -# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -# -# - -# This file should contain variables changed only by autoconf. - -proc checkout_executable {exe_var best alternate text} { - global $exe_var - set $exe_var $best - if {"$best" == "" || ![file executable $best]} { - puts stderr $text - set $exe_var $alternate - } -} - -# -# Keep track of where the good perl is. -# -checkout_executable PERL "@PERL@" perl "\ - When configured, ns found the right version of perl in\ - @PERL@ - but it doesn't seem to be there anymore, so\ - ns will fall back on running the first perl in your path.\ - The wrong version of perl may break the test suites.\ - Reconfigure and rebuild ns if this is a problem.\ -" -checkout_executable TCLSH "@V_TCLSH@" tclsh "\ - When configured, ns found the right version of tclsh in\ - @V_TCLSH@ - but it doesn't seem to be there anymore, so\ - ns will fall back on running the first tclsh in your path.\ - The wrong version of tclsh may break the test suites.\ - Reconfigure and rebuild ns if this is a problem.\ -" diff -Naur ns-2.29-original/tcl/lib/ns-lib.tcl ns-2.29-new/tcl/lib/ns-lib.tcl --- ns-2.29-original/tcl/lib/ns-lib.tcl 2009-04-13 11:57:25.000000000 +0200 +++ ns-2.29-new/tcl/lib/ns-lib.tcl 2008-04-09 13:12:04.000000000 +0200 @@ -217,6 +217,9 @@ #LMS source ../mcast/ns-lms.tcl +#WIMAX +source ns-wimax.tcl + # STL dependent modules get included # ONLY when STL is found diff -Naur ns-2.29-original/tcl/lib/ns-packet.tcl ns-2.29-new/tcl/lib/ns-packet.tcl --- ns-2.29-original/tcl/lib/ns-packet.tcl 2009-04-13 11:57:25.000000000 +0200 +++ ns-2.29-new/tcl/lib/ns-packet.tcl 2008-04-09 13:12:04.000000000 +0200 @@ -170,6 +170,8 @@ Encap # common/encap.cc IPinIP # IP encapsulation HDLC # High Level Data Link Control +# WIMAX: + 802_16 # Mac IEEE 802.16 } { add-packet-header $prot } diff -Naur ns-2.29-original/tcl/lib/ns-wimax.tcl ns-2.29-new/tcl/lib/ns-wimax.tcl --- ns-2.29-original/tcl/lib/ns-wimax.tcl 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/tcl/lib/ns-wimax.tcl 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,54 @@ +# This class contains default value for tcl + +Phy/WirelessPhy/OFDM set g_ 0 + +Mac/802_16 set queue_length_ 50 ;#maximum number of packets + +Mac/802_16 set frame_duration_ 0.004 +Mac/802_16 set channel_ 0 +Mac/802_16 set fbandwidth_ 5e+6 +Mac/802_16 set rtg_ 10 +Mac/802_16 set ttg_ 10 +Mac/802_16 set dcd_interval_ 5 ;#max 10s +Mac/802_16 set ucd_interval_ 5 ;#max 10s +Mac/802_16 set init_rng_interval_ 1 ;#max 2s +Mac/802_16 set lost_dlmap_interval_ 0.6 +Mac/802_16 set lost_ulmap_interval_ 0.6 +Mac/802_16 set t1_timeout_ [expr 5* [Mac/802_16 set dcd_interval_]] +Mac/802_16 set t2_timeout_ [expr 5* [Mac/802_16 set init_rng_interval_]] +Mac/802_16 set t3_timeout_ 0.2 +Mac/802_16 set t6_timeout_ 3 +Mac/802_16 set t12_timeout_ [expr 5* [Mac/802_16 set ucd_interval_]] +Mac/802_16 set t16_timeout_ 3 ;#qos dependant +Mac/802_16 set t17_timeout_ 5 +Mac/802_16 set t21_timeout_ 0.02 ;#max 10s. Use 20ms to replace preamble scanning +Mac/802_16 set contention_rng_retry_ 16 +Mac/802_16 set invited_rng_retry_ 16 ;#16 +Mac/802_16 set request_retry_ 2 ;#16 +Mac/802_16 set reg_req_retry_ 3 +Mac/802_16 set tproc_ 0.001 +Mac/802_16 set dsx_req_retry_ 3 +Mac/802_16 set dsx_rsp_retry_ 3 + +Mac/802_16 set rng_backoff_start_ 2 +Mac/802_16 set rng_backoff_stop_ 6 +Mac/802_16 set bw_backoff_start_ 2 +Mac/802_16 set bw_backoff_stop_ 6 + +Mac/802_16 set scan_duration_ 50 +Mac/802_16 set interleaving_interval_ 50 +Mac/802_16 set scan_iteration_ 2 +Mac/802_16 set t44_timeout_ 0.1 +Mac/802_16 set max_dir_scan_time_ 0.2 ;#max scan for each neighbor BSs +Mac/802_16 set client_timeout_ 0.5 +Mac/802_16 set nbr_adv_interval_ 0.5 +Mac/802_16 set scan_req_retry_ 5 + +Mac/802_16 set lgd_factor_ 1 +Mac/802_16 set print_stats_ false ;#true to activate print of statistics +Mac/802_16 set rxp_avg_alpha_ 1 +Mac/802_16 set delay_avg_alpha_ 1 +Mac/802_16 set jitter_avg_alpha_ 1 +Mac/802_16 set loss_avg_alpha_ 1 +Mac/802_16 set throughput_avg_alpha_ 1 +Mac/802_16 set throughput_delay_ 0.02 diff -Naur ns-2.29-original/tcl/wimax/8MN_datarate.tcl ns-2.29-new/tcl/wimax/8MN_datarate.tcl --- ns-2.29-original/tcl/wimax/8MN_datarate.tcl 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/tcl/wimax/8MN_datarate.tcl 2008-10-27 15:28:14.000000000 +0100 @@ -0,0 +1,815 @@ +# Test script to evaluate datarate in 802.16 networks. +# @author rouil +# Scenario: Communication between MN and Sink Node with MN attached to BS. + +# +# Topology scenario: +# +# +# |-----| +# | MN0 | ; 1.0.1 +# |-----| +# +# +# (^) +# | +# |--------------| +# | Base Station | ; 1.0.0 +# |--------------| +# | +# | +# |-----------| +# | Sink node | ; 0.0.0 +# |-----------| +# + +#check input parameters +if {$argc != 3} { + puts "" + puts "Wrong Number of Arguments! 3 arguments for this script" + puts "Usage: ns datarate.tcl modulation cyclic_prefix " + puts "modulation: OFDM_BPSK_1_2, OFDM_QPSK_1_2, OFDM_QPSK_3_4" + puts " OFDM_16QAM_1_2, OFDM_16QAM_3_4, OFDM_64QAM_2_3, OFDM_64QAM_3_4" + puts "cyclic_prefix: 0.25, 0.125, 0.0625, 0.03125" + puts "rtPS scheduler: NIST_RR, RR, mSIR, WRR, TRS_RR, TRS_mSIR" + exit +} + +# set global variables +set output_dir . +set traffic_start 20 +set traffic_stop 70 +set simulation_stop 70 + +# Configure Wimax +Mac/802_16 set debug_ 0 +Mac/802_16 set frame_duration_ 0.020 + +#define coverage area for base station: 20m coverage +Phy/WirelessPhy/OFDM set g_ [lindex $argv 1] +Phy/WirelessPhy set Pt_ 0.025 +Phy/WirelessPhy set RXThresh_ 2.025e-12 ;# 500m radius +Phy/WirelessPhy set CSThresh_ [expr 0.9*[Phy/WirelessPhy set RXThresh_]] + +# Parameter for wireless nodes +set opt(chan) Channel/WirelessChannel ;# channel type +set opt(prop) Propagation/TwoRayGround ;# radio-propagation model +set opt(netif) Phy/WirelessPhy/OFDM ;# network interface type +set opt(mac) Mac/802_16 ;# MAC type +set opt(ifq) Queue/DropTail/PriQueue ;# interface queue type +set opt(ll) LL ;# link layer type +set opt(ant) Antenna/OmniAntenna ;# antenna model +set opt(ifqlen) 50 ;# max packet in ifq +set opt(adhocRouting) DSDV ;# routing protocol + +set opt(x) 1100 ;# X dimension of the topography +set opt(y) 1100 ;# Y dimension of the topography + +#defines function for flushing and closing files +proc finish {} { + global ns tf output_dir nb_mn + $ns flush-trace + close $tf + exit 0 +} + +#create the simulator +set ns [new Simulator] +$ns use-newtrace + +#create the topography +set topo [new Topography] +$topo load_flatgrid $opt(x) $opt(y) +#puts "Topology created" + +#open file for trace +set tf [open $output_dir/8MN_out.res w] +$ns trace-all $tf +#puts "Output file configured" + +# set up for hierarchical routing (needed for routing over a basestation) +$ns node-config -addressType hierarchical +AddrParams set domain_num_ 2 ;# domain number +lappend cluster_num 1 1 ;# cluster number for each domain +AddrParams set cluster_num_ $cluster_num +#Aymen#lappend eilastlevel 1 2 ;# number of nodes for each cluster (1 for sink and one for mobile node + base station +lappend eilastlevel 1 29 + +AddrParams set nodes_num_ $eilastlevel +puts "Configuration of hierarchical addressing done" + +# Create God +create-god 30 + +#creates the sink node in first address space. +set sinkNode [$ns node 0.0.0] +puts "sink node created" + +#creates the Access Point (Base station) +$ns node-config -adhocRouting $opt(adhocRouting) \ + -llType $opt(ll) \ + -macType $opt(mac) \ + -ifqType $opt(ifq) \ + -ifqLen $opt(ifqlen) \ + -antType $opt(ant) \ + -propType $opt(prop) \ + -phyType $opt(netif) \ + -channel [new $opt(chan)] \ + -topoInstance $topo \ + -wiredRouting ON \ + -agentTrace OFF \ + -routerTrace OFF \ + -macTrace ON \ + -movementTrace OFF + + + + + + +#puts "Configuration of base station" + +set bstation [$ns node 1.0.0] +$bstation random-motion 0 +#provide some co-ord (fixed) to base station node +$bstation set X_ 550.0 +$bstation set Y_ 550.0 +$bstation set Z_ 0.0 +set clas [new SDUClassifier/Dest] +[$bstation set mac_(0)] add-classifier $clas + + +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set bs_sched [new WimaxScheduler/BS] +$bs_sched set-default-modulation [lindex $argv 0] ;#OFDM_BPSK_1_2 +[$bstation set mac_(0)] set-scheduler $bs_sched +[$bstation set mac_(0)] set-channel 0 +puts "Base-Station node created" + + + +# create the link between sink node and base station +$ns duplex-link $sinkNode $bstation 100Mb 1ms DropTail +###################### + + + + + + + + + + + + +######################################################## + +set nb_UGS 0 + + + +#### interval_ ######## +set interval_ugs(1) 0.15 + +set interval_ugs(2) 0.15 +set interval_ugs(3) 0.15 +set interval_ugs(4) 0.15 +set interval_ugs(5) 0.15 +set interval_ugs(6) 0.04 +set interval_ugs(7) 0.05 +set interval_ugs(8) 0.1 +set interval_ugs(9) 0.1 +####################### + + +#### SNR ######### +set SNR_ugs(1) 9.5 + +set SNR_ugs(2) 12.5 +set SNR_ugs(3) 16.5 +set SNR_ugs(4) 20.5 +set SNR_ugs(5) 22.5 +set SNR_ugs(6) 12.5 +set SNR_ugs(7) 12.5 +set SNR_ugs(8) 12.5 +set SNR_ugs(9) 12.5 +################## + + +$ns node-config -wiredRouting OFF \ + -macTrace ON ;# Mobile nodes cannot do routing. + +for {set j 1} {$j < [expr $nb_UGS + 1]} {incr j} { +set wl_node_ugs($j) [$ns node 1.0.[expr $j]] ;# create the node with given @. + +$wl_node_ugs($j) random-motion 0 ;# disable random motion +$wl_node_ugs($j) base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +#compute position of the node +$wl_node_ugs($j) set X_ [expr 450 + 5 * $j] +$wl_node_ugs($j) set Y_ [expr 450] +$wl_node_ugs($j) set Z_ 0.0 + +#puts "wireless node $j created" + +set clas [new SDUClassifier/Dest] +[$wl_node_ugs($j) set mac_(0)] add-classifier $clas +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set ss_sched [new WimaxScheduler/SS] +[$wl_node_ugs($j) set mac_(0)] set-scheduler $ss_sched +[$wl_node_ugs($j) set mac_(0)] set-channel 0 + + +#Create a UDP agent and attach it to wl_node$j +set udp_ugs($j) [new Agent/UDP] +$udp_ugs($j) set packetSize_ 1000 +$ns attach-agent $wl_node_ugs($j) $udp_ugs($j) + + +# Create a CBR traffic source and attach it to udp4 +set cbr_ugs($j) [new Application/Traffic/CBR] +$cbr_ugs($j) set packetSize_ 1000 +$cbr_ugs($j) set interval_ $interval_ugs($j) +$cbr_ugs($j) attach-agent $udp_ugs($j) + +# Create the Null agent to sink traffic +set null_ugs($j) [new Agent/Null] +$ns attach-agent $sinkNode $null_ugs($j) + +# Attach the 2 agents +$ns connect $udp_ugs($j) $null_ugs($j) +$udp_ugs($j) set fid_ $j + + +## add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +##ServiceFlowSchedulingType: 0=>SERVICE_UGS, 1=>SERVICE_rtPS, 2=>SERVICE_nrtPS, 3=>SERVICE_BE +$ss_sched add-flow 5 [expr 30 + [$cbr_ugs($j) set packetSize_] * [Mac/802_16 set frame_duration_] / [$cbr_ugs($j) set interval_]] 0 0 + +##set-PeerNode-SNR PeerNode SNR +$ns at 1.3 "$bs_sched set-PeerNode-SNR [expr $j] $SNR_ugs($j)" + +##set-PeerNode-UGSPeriodicity PeerNode Periodicity +$ns at 1.3 "$bs_sched set-PeerNode-UGSPeriodicity [expr $j] 1" + +#Schedule start/stop of traffic +$ns at $traffic_start "$cbr_ugs($j) start" +$ns at $traffic_stop "$cbr_ugs($j) stop" + +} +#################### + + + + + + + + + +################################################ +## rtPS connections +set first_rtPS 101 +set nb_rtPS 0 + + + +$bs_sched set-SymbolNumberForUnicastRequest 3 + +#bs_sched set-rtPSscheduling scheduling +# "RR", "mSIR", "mmSIR", "WRR", "TRS_RR", "TRS_mSIR", ... +#set rtPS_scheduler_ "RR" + +set rtPS_scheduler_ [lindex $argv 2] + +$bs_sched set-rtPSscheduling $rtPS_scheduler_ + + +proc send_next_packet_VBR {udp_ size_ interval_} { + global ns traffic_stop +# $udp_ send [expr round([$size_ value])] +$udp_ send 1000 + +if {[$ns now] < [expr $traffic_stop - $interval_]} { + $ns at [expr [$ns now] + $interval_] "send_next_packet_VBR $udp_ $size_ $interval_" +} + +} + + +# seed the default RNG +global defaultRNG +$defaultRNG seed 9999 + + + + +#### interval_ ######## +set interval_rtPS(1) 0.1 +set interval_rtPS(2) 0.1 +set interval_rtPS(3) 0.1 + +set interval_rtPS(4) 0.01 +set interval_rtPS(5) 0.01 +set interval_rtPS(6) 0.01 +set interval_rtPS(7) 0.01 +set interval_rtPS(8) 0.01 +set interval_rtPS(9) 0.01 +####################### + + +#### SNR ######### +set SNR_rtPS(1) 7.0 +set SNR_rtPS(2) 7.5 +set SNR_rtPS(3) 9.0 + +set SNR_rtPS(4) 12.0 +set SNR_rtPS(5) 17.0 +set SNR_rtPS(6) 17.5 +set SNR_rtPS(7) 20.0 +set SNR_rtPS(8) 24.0 +set SNR_rtPS(9) 25.5 +################## + + + + +#### WRR ######### +if {$rtPS_scheduler_ == "WRR"} { +set WRR_rtPS(1) 1 +set WRR_rtPS(2) 1 +set WRR_rtPS(3) 1 +set WRR_rtPS(4) 2 +set WRR_rtPS(5) 2 +set WRR_rtPS(6) 3 +set WRR_rtPS(7) 3 + +set WRR_rtPS(8) 4 +set WRR_rtPS(9) 4 +} +################## + + +################## +#set-TRSparameters-SNR-Tr-Tp-L SNRth Tr Tp L +$bs_sched set-TRSparameters-SNR-Tr-Tp-L 8.5 2 3 4 +################## + + +$ns node-config -wiredRouting OFF \ + -macTrace ON ;# Mobile nodes cannot do routing. + +for {set j $first_rtPS} {$j < [expr $first_rtPS + $nb_rtPS]} {incr j} { +set wl_node_rtPS($j) [$ns node 1.0.[expr $nb_UGS + $j + 1 - $first_rtPS]] ;# create the node with given @. + +$wl_node_rtPS($j) random-motion 0 ;# disable random motion +$wl_node_rtPS($j) base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +#compute position of the node +$wl_node_rtPS($j) set X_ [expr 550 + 5 * [expr $j + 1 - $first_rtPS]] +$wl_node_rtPS($j) set Y_ [expr 650] +$wl_node_rtPS($j) set Z_ 0.0 + +#puts "wireless node $j created" + +set clas [new SDUClassifier/Dest] +[$wl_node_rtPS($j) set mac_(0)] add-classifier $clas +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set ss_sched [new WimaxScheduler/SS] +[$wl_node_rtPS($j) set mac_(0)] set-scheduler $ss_sched +[$wl_node_rtPS($j) set mac_(0)] set-channel 0 + + +#Create a UDP agent and attach it to wl_node$j +set udp_rtPS($j) [new Agent/UDP] +$ns attach-agent $wl_node_rtPS($j) $udp_rtPS($j) + +# Create the Null agent to sink traffic +set null_rtPS($j) [new Agent/Null] +$ns attach-agent $sinkNode $null_rtPS($j) + +# Attach the 2 agents +$ns connect $udp_rtPS($j) $null_rtPS($j) +$udp_rtPS($j) set fid_ $j + +set interval_rtPS($j) $interval_rtPS([expr $j + 1 - $first_rtPS]) + + +## exponential distribution +#set sizeRNG_rtPS($j) [new RNG] + +#set size_rtPS($j) [new RandomVariable/Exponential] +#$size_rtPS($j) set avg_ 1000 +#$size_rtPS($j) use-rng $sizeRNG_rtPS($j) + + +# uniform distribution +set sizeRNG_rtPS($j) [new RNG] + +set size_rtPS($j) [new RandomVariable/Uniform] +$size_rtPS($j) set min_ 500 +$size_rtPS($j) set max_ 1500 +$size_rtPS($j) use-rng $sizeRNG_rtPS($j) + + +## add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +##ServiceFlowSchedulingType: 0=>SERVICE_UGS, 1=>SERVICE_rtPS, 2=>SERVICE_nrtPS, 3=>SERVICE_BE +$ss_sched add-flow 5 0 0 1 + +##set-PeerNode-SNR PeerNode SNR +$ns at 1.3 "$bs_sched set-PeerNode-SNR [expr $nb_UGS + $j + 1 - $first_rtPS] $SNR_rtPS([expr $j + 1 - $first_rtPS])" + +##set-PeerNode-UnicastRequestPeriodicity PeerNode Periodicity +$ns at 1.3 "$bs_sched set-PeerNode-UnicastRequestPeriodicity [expr $nb_UGS + $j + 1 - $first_rtPS] 2" + + +if {$rtPS_scheduler_ == "WRR"} { + # set-PeerNode-WRRschedulingForrtPS PeerNode Weight + $ns at 1.3 "$bs_sched set-PeerNode-WRRschedulingForrtPS [expr $nb_UGS + $j + 1 - $first_rtPS] $WRR_rtPS([expr $j + 1 - $first_rtPS])" +} + + + +$ns at [expr 15.0 + [expr $j + 1 - $first_rtPS] * 0] "send_next_packet_VBR $udp_rtPS($j) $size_rtPS($j) $interval_rtPS($j)" + +#puts "n[expr $nb_UGS + $j + 1 - $first_rtPS] starts at [expr 15.0 + [expr $j + 1 - $first_rtPS] * 0]" + +} + + + + + + + +#################################################################### +set first_BE 301 + +$ns node-config -wiredRouting OFF \ + -macTrace ON ;# Mobile nodes cannot do routing. + +set wl_node_BE($first_BE) [$ns node 1.0.[expr $nb_UGS + $nb_rtPS + 1]] ;# create the node with given @. +$wl_node_BE($first_BE) random-motion 0 ;# disable random motion +$wl_node_BE($first_BE) base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +#compute position of the node +$wl_node_BE($first_BE) set X_ 559.0 +$wl_node_BE($first_BE) set Y_ 617.0 +$wl_node_BE($first_BE) set Z_ 0.0 + +puts "wireless node _BE $first_BE created" + +set clas [new SDUClassifier/Dest] +[$wl_node_BE($first_BE) set mac_(0)] add-classifier $clas +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set ss_sched [new WimaxScheduler/SS] +[$wl_node_BE($first_BE) set mac_(0)] set-scheduler $ss_sched +[$wl_node_BE($first_BE) set mac_(0)] set-channel 0 + +# css +##set-PeerNode-SNR PeerNode SNR +$ns at 1.3 "$bs_sched set-PeerNode-SNR [expr $nb_UGS + $nb_rtPS + 1] 12.31" + +##set-BwRequestSendingPeriod BwRequestSendingPeriod_ +$ss_sched set-BwRequestSendingPeriod 10 + +## add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +##ServiceFlowSchedulingType: 0 => SERVICE_UGS, 1=>SERVICE_rtPS, 2=> SERVICE_ertPS, 3=>SERVICE_nrtPS, 4=>SERVICE_BE +$ss_sched add-flow 1 0 0 4 + +#set data_to_send_BE($first_BE) 30000 + +#$ns at $traffic_start "$ss_sched set-BandwidthBEconnections $data_to_send_BE($first_BE)" + +#$ns at $traffic_start "uplink_ftp_tcp_data $wl_node_BE($first_BE) $first_BE $data_to_send_BE($first_BE)" + +$ns at 13.0 "uplink_ftp_tcp $wl_node_BE($first_BE) $first_BE" +################################################################################# + + + + + + + + + + + + +#################################################################### +$ns node-config -wiredRouting OFF \ + -macTrace ON ;# Mobile nodes cannot do routing. + +set wl_node_BE([expr $first_BE + 1]) [$ns node 1.0.[expr $nb_UGS + $nb_rtPS + 2]] ;# create the node with given @. +$wl_node_BE([expr $first_BE + 1]) random-motion 0 ;# disable random motion +$wl_node_BE([expr $first_BE + 1]) base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +#compute position of the node +$wl_node_BE([expr $first_BE + 1]) set X_ 465.0 +$wl_node_BE([expr $first_BE + 1]) set Y_ 523.0 +$wl_node_BE([expr $first_BE + 1]) set Z_ 0.0 + +puts "wireless node [expr $first_BE + 1] created" + +set clas [new SDUClassifier/Dest] +[$wl_node_BE([expr $first_BE + 1]) set mac_(0)] add-classifier $clas +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set ss_sched [new WimaxScheduler/SS] +[$wl_node_BE([expr $first_BE + 1]) set mac_(0)] set-scheduler $ss_sched +[$wl_node_BE([expr $first_BE + 1]) set mac_(0)] set-channel 0 + +# css +##set-PeerNode-SNR PeerNode SNR +$ns at 1.3 "$bs_sched set-PeerNode-SNR [expr $nb_UGS + $nb_rtPS + 2] 12.32" + +##set-BwRequestSendingPeriod BwRequestSendingPeriod_ +$ss_sched set-BwRequestSendingPeriod 10 + +## add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +##ServiceFlowSchedulingType: 0 => SERVICE_UGS, 1=>SERVICE_rtPS, 2=> SERVICE_ertPS, 3=>SERVICE_nrtPS, 4=>SERVICE_BE +$ss_sched add-flow 1 0 0 4 + +#set data_to_send_BE([expr $first_BE + 1]) 30000 +#$ns at $traffic_start "uplink_ftp_tcp_data $wl_node_BE([expr $first_BE + 1]) [expr $first_BE + 1] $data_to_send_BE([expr $first_BE + 1])" + +$ns at 13.0 "uplink_ftp_tcp $wl_node_BE([expr $first_BE + 1]) [expr $first_BE + 1]" +################################################################################# + + + + + + +proc uplink_ftp_tcp_data {wl_node fid data_to_send} { +global ns sinkNode +#Setup a TCP connection +set tcp [new Agent/TCP/Newreno] +$ns attach-agent $wl_node $tcp +set sink [new Agent/TCPSink] +$ns attach-agent $sinkNode $sink +$ns connect $tcp $sink +$tcp set fid_ $fid +$tcp set packetSize_ 1000 + +#setup a FTP over TCP connection +set ftp [new Application/FTP] +$ftp attach-agent $tcp +$ftp set type_ FTP +$ftp set packetSize_ 1000 + +$ftp send $data_to_send +} + + + +proc uplink_ftp_tcp {wl_node fid} { +global ns sinkNode +#Setup a TCP connection +set tcp [new Agent/TCP/Newreno] +$ns attach-agent $wl_node $tcp +set sink [new Agent/TCPSink] +$ns attach-agent $sinkNode $sink +$ns connect $tcp $sink +$tcp set fid_ $fid +$tcp set packetSize_ 1000 + +#setup a FTP over TCP connection +set ftp [new Application/FTP] +$ftp attach-agent $tcp +$ftp set type_ FTP +$ftp set packetSize_ 1000 + +$ftp start +} + + + +################procedure : Record #################### +set f0 [open 1_out.tr w] + +proc record {} { +global f0 cbr +set ns [Simulator instance] +set time 0.05 +set now [$ns now] +set packetSize [$cbr set packetSize_] +set rate [$cbr set rate_] +set seqno [$cbr set seqno_] +puts $f0 "$now paketSize $packetSize rate $rate seqno $seqno" +$ns at [expr $now + $time] "record" +} + +##$ns at $traffic_start "record" +######################################################## + + + + +$ns at $simulation_stop "finish" +puts "Starts simulation" +$ns run +puts "Simulation done." + + + + + + + +#################################################################### +#$ns node-config -wiredRouting OFF \ +# -macTrace ON ;# Mobile nodes cannot do routing. + +#set wl_node2 [$ns node 1.0.2] ;# create the node with given @. +#$wl_node2 random-motion 0 ;# disable random motion +#$wl_node2 base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +##compute position of the node +#$wl_node2 set X_ 510.0 +#$wl_node2 set Y_ 510.0 +#$wl_node2 set Z_ 0.0 + +#puts "wireless node 2 created" + +#set clas [new SDUClassifier/Dest] +#[$wl_node2 set mac_(0)] add-classifier $clas +##set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +#set ss_sched [new WimaxScheduler/SS] +#[$wl_node2 set mac_(0)] set-scheduler $ss_sched +#[$wl_node2 set mac_(0)] set-channel 0 + +#####downlink traffic +##create source traffic +##Create a UDP agent and attach it to node n0 +###set udp2 [new Agent/UDP] +###$udp2 set packetSize_ 1000 +###$ns attach-agent $sinkNode $udp2 + +## Create a CBR traffic source and attach it to udp0 +###set cbr2 [new Application/Traffic/CBR] +###$cbr2 set packetSize_ 1000 +###$cbr2 set interval_ 0.002 +###$cbr2 attach-agent $udp2 + +##create an sink into the sink node + +## Create the Null agent to sink traffic +###set null2 [new Agent/Null] +###$ns attach-agent $wl_node2 $null2 + +## Attach the 2 agents +###$ns connect $udp2 $null2 +###$udp2 set fid_ 2 +#### + + +####uplink traffic +##create source traffic +##Create a UDP agent and attach it to wl_node2 +#set udp2 [new Agent/UDP] +#$udp2 set packetSize_ 1000 +#$ns attach-agent $wl_node2 $udp2 + +## Create a CBR traffic source and attach it to udp0 +#set cbr2 [new Application/Traffic/CBR] +#$cbr2 set packetSize_ 1000 +#$cbr2 set interval_ 0.2 +#$cbr2 attach-agent $udp2 + +##create an sink into the sink node + +## Create the Null agent to sink traffic +#set null2 [new Agent/Null] +#$ns attach-agent $sinkNode $null2 + +## Attach the 2 agents +#$ns connect $udp2 $null2 +#$udp2 set fid_ 2 + + +###set-PeerNode-SNR PeerNode SNR +#$ns at 1.3 "$bs_sched set-PeerNode-SNR 2 7.2" + +###set-PeerNode-UGSPeriodicity PeerNode Periodicity +#$ns at 1.3 "$bs_sched set-PeerNode-UGSPeriodicity 2 1" + +### add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +###ServiceFlowSchedulingType: 0 => SERVICE_UGS, 1 => SERVICE_rtPS, 2 => SERVICE_nrtPS, 3 => SERVICE_BE +#$ss_sched add-flow 5 [expr 60 + [$cbr2 set packetSize_] * [Mac/802_16 set frame_duration_] / [$cbr2 set interval_]] 0 0 + +##Schedule start/stop of traffic +#$ns at $traffic_start "$cbr2 start" +#$ns at $traffic_stop "$cbr2 stop" +################################################################### + + + + + + +## echo random values +#for {set j 0} {$j < 5} {incr j} { +#puts "[expr round([$size12 value])]" +#} + + +## uniform distribution +#set sizeRNG12 [new RNG] + +#set size12_ [new RandomVariable/Uniform] +#$size12_ set min_ 500 +#$size12_ set max_ 1500 +#$size12_ use-rng $sizeRNG12 + +#for {set j 0} {$j < 5} {incr j} { +#puts "[expr round([$size12_ value])]" +#} + + + + + +#################################################################### +#$ns node-config -wiredRouting OFF \ +# -macTrace ON ;# Mobile nodes cannot do routing. + +#set wl_node14 [$ns node 1.0.6] ;# create the node with given @. +#$wl_node14 random-motion 0 ;# disable random motion +#$wl_node14 base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +##compute position of the node +#$wl_node14 set X_ 414.0 +#$wl_node14 set Y_ 514.0 +#$wl_node14 set Z_ 0.0 + +#puts "wireless node 14 created" + +#set clas [new SDUClassifier/Dest] +#[$wl_node14 set mac_(0)] add-classifier $clas +##set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +#set ss_sched [new WimaxScheduler/SS] +#[$wl_node14 set mac_(0)] set-scheduler $ss_sched +#[$wl_node14 set mac_(0)] set-channel 0 + + +##Create a UDP agent and attach it to wl_node14 +#set udp14 [new Agent/UDP] +#$ns attach-agent $wl_node14 $udp14 + +## Create the Null agent to sink traffic +#set null14 [new Agent/Null] +#$ns attach-agent $sinkNode $null14 + +## Attach the 2 agents +#$ns connect $udp14 $null14 +#$udp14 set fid_ 14 + +#set interval14 0.7 + + +#set sizeRNG14 [new RNG] + +#set size14 [new RandomVariable/Exponential] +#$size14 set avg_ 1000 +#$size14 use-rng $sizeRNG14 + + +### add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +###ServiceFlowSchedulingType: 0=>SERVICE_UGS, 1=>SERVICE_rtPS, 2=>SERVICE_nrtPS, 3=>SERVICE_BE +#$ss_sched add-flow 5 0 0 1 + +###set-PeerNode-SNR PeerNode SNR +#$ns at 1.3 "$bs_sched set-PeerNode-SNR 6 7.1" + +###set-PeerNode-UnicastRequestPeriodicity PeerNode Periodicity +#$ns at 1.3 "$bs_sched set-PeerNode-UnicastRequestPeriodicity 6 5" + + +##$ns at 4 "send_next_packet_VBR $udp14 $size14 $interval14" + +################################################################################# + + + + + + + + + +############################FTP over UDP############### +##proc uplink_ftp_udp {wl_node fid traffic_start} { + +##global sinkNode ns traffic_start +#Setup a TCP connection +##set udp [new Agent/UDP] +##$ns attach-agent $wl_node $udp +##set null [new Agent/Null] +##$ns attach-agent $sinkNode $null +##$ns connect $udp $null +##$udp set fid_ fid +##$udp set packetSize_ 1000 + +#setup a FTP over TCP connection +##set ftp [new Application/FTP] +##$ftp attach-agent $udp +##$ftp set type_ FTP +##$ftp set packetSize_ 1000 +##$ns at $traffic_start "$ftp send 5000" +##} +####################################################### diff -Naur ns-2.29-original/tcl/wimax/QoS_example1.tcl ns-2.29-new/tcl/wimax/QoS_example1.tcl --- ns-2.29-original/tcl/wimax/QoS_example1.tcl 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/tcl/wimax/QoS_example1.tcl 2008-04-09 16:19:02.000000000 +0200 @@ -0,0 +1,584 @@ +# Test script to evaluate datarate in 802.16 networks. + +#check input parameters +if {$argc != 3} { + puts "" + puts "Wrong Number of Arguments! 3 arguments for this script" + puts "Usage: ns datarate.tcl modulation cyclic_prefix " + puts "modulation: OFDM_BPSK_1_2, OFDM_QPSK_1_2, OFDM_QPSK_3_4" + puts " OFDM_16QAM_1_2, OFDM_16QAM_3_4, OFDM_64QAM_2_3, OFDM_64QAM_3_4" + puts "cyclic_prefix: 0.25, 0.125, 0.0625, 0.03125" + puts "rtPS scheduler: NIST_RR, RR, mSIR, WRR, TRS_RR, TRS_mSIR" + exit +} + +# set global variables +set output_dir . +set traffic_start 20 +set traffic_stop 100 +set simulation_stop 100 + +# Configure Wimax +Mac/802_16 set debug_ 0 +Mac/802_16 set frame_duration_ 0.020 + +#define coverage area for base station: 20m coverage +Phy/WirelessPhy/OFDM set g_ [lindex $argv 1] +Phy/WirelessPhy set Pt_ 0.025 +Phy/WirelessPhy set RXThresh_ 2.025e-12 ;# 500m radius +Phy/WirelessPhy set CSThresh_ [expr 0.9*[Phy/WirelessPhy set RXThresh_]] + +# Parameter for wireless nodes +set opt(chan) Channel/WirelessChannel ;# channel type +set opt(prop) Propagation/TwoRayGround ;# radio-propagation model +set opt(netif) Phy/WirelessPhy/OFDM ;# network interface type +set opt(mac) Mac/802_16 ;# MAC type +set opt(ifq) Queue/DropTail/PriQueue ;# interface queue type +set opt(ll) LL ;# link layer type +set opt(ant) Antenna/OmniAntenna ;# antenna model +set opt(ifqlen) 50 ;# max packet in ifq +set opt(adhocRouting) DSDV ;# routing protocol + +set opt(x) 1100 ;# X dimension of the topography +set opt(y) 1100 ;# Y dimension of the topography + +#defines function for flushing and closing files +proc finish {} { + global ns tf output_dir nb_mn + $ns flush-trace + close $tf + exit 0 +} + +#create the simulator +set ns [new Simulator] +$ns use-newtrace + +#create the topography +set topo [new Topography] +$topo load_flatgrid $opt(x) $opt(y) +#puts "Topology created" + +#open file for trace +set tf [open $output_dir/8MN_out.res w] +$ns trace-all $tf +#puts "Output file configured" + +# set up for hierarchical routing (needed for routing over a basestation) +$ns node-config -addressType hierarchical +AddrParams set domain_num_ 2 ;# domain number +lappend cluster_num 1 1 ;# cluster number for each domain +AddrParams set cluster_num_ $cluster_num +#lappend eilastlevel 1 2 ;# number of nodes for each cluster (1 for sink and one for MS + BS +lappend eilastlevel 1 29 + +AddrParams set nodes_num_ $eilastlevel +puts "Configuration of hierarchical addressing done" + +# Create God +create-god 30 + +#creates the sink node in first address space. +set sinkNode [$ns node 0.0.0] +puts "sink node created" + +#creates the Access Point (Base station) +$ns node-config -adhocRouting $opt(adhocRouting) \ + -llType $opt(ll) \ + -macType $opt(mac) \ + -ifqType $opt(ifq) \ + -ifqLen $opt(ifqlen) \ + -antType $opt(ant) \ + -propType $opt(prop) \ + -phyType $opt(netif) \ + -channel [new $opt(chan)] \ + -topoInstance $topo \ + -wiredRouting ON \ + -agentTrace OFF \ + -routerTrace OFF \ + -macTrace ON \ + -movementTrace OFF + + + + + + +#puts "Configuration of base station" + +set bstation [$ns node 1.0.0] +$bstation random-motion 0 +#provide some co-ord (fixed) to base station node +$bstation set X_ 550.0 +$bstation set Y_ 550.0 +$bstation set Z_ 0.0 +set clas [new SDUClassifier/Dest] +[$bstation set mac_(0)] add-classifier $clas + + +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set bs_sched [new WimaxScheduler/BS] +$bs_sched set-default-modulation [lindex $argv 0] ;#OFDM_BPSK_1_2 +[$bstation set mac_(0)] set-scheduler $bs_sched +[$bstation set mac_(0)] set-channel 0 +puts "Base-Station node created" + + + +# create the link between sink node and base station +$ns duplex-link $sinkNode $bstation 100Mb 1ms DropTail +###################### + + + + + + + + + + + + +######################################################## + +#set the bumber of UGS connections +set nb_UGS 5 + + + +#### interval_ of the CBR traffic #### +set interval_ugs(1) 0.15 +set interval_ugs(2) 0.2 +set interval_ugs(3) 0.25 +set interval_ugs(4) 0.27 +set interval_ugs(5) 0.3 + +set interval_ugs(6) 0.04 +set interval_ugs(7) 0.05 +set interval_ugs(8) 0.1 +set interval_ugs(9) 0.1 +###################################### + + +#### SNR of the UGS connections######### +set SNR_ugs(1) 9.5 +set SNR_ugs(2) 12.5 +set SNR_ugs(3) 16.5 +set SNR_ugs(4) 20.5 +set SNR_ugs(5) 22.5 + +set SNR_ugs(6) 12.5 +set SNR_ugs(7) 12.5 +set SNR_ugs(8) 12.5 +set SNR_ugs(9) 12.5 +######################################## + + +$ns node-config -wiredRouting OFF \ + -macTrace ON ;# Mobile nodes cannot do routing. + +for {set j 1} {$j < [expr $nb_UGS + 1]} {incr j} { +set wl_node_ugs($j) [$ns node 1.0.[expr $j]] ;# create the node with given @. + +$wl_node_ugs($j) random-motion 0 ;# disable random motion +$wl_node_ugs($j) base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +#compute position of the node +$wl_node_ugs($j) set X_ [expr 450 + 5 * $j] +$wl_node_ugs($j) set Y_ [expr 450] +$wl_node_ugs($j) set Z_ 0.0 + +#puts "wireless node $j created" + +set clas [new SDUClassifier/Dest] +[$wl_node_ugs($j) set mac_(0)] add-classifier $clas +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set ss_sched [new WimaxScheduler/SS] +[$wl_node_ugs($j) set mac_(0)] set-scheduler $ss_sched +[$wl_node_ugs($j) set mac_(0)] set-channel 0 + + +#Create a UDP agent and attach it to wl_node$j +set udp_ugs($j) [new Agent/UDP] +$udp_ugs($j) set packetSize_ 1000 +$ns attach-agent $wl_node_ugs($j) $udp_ugs($j) + + +# Create a CBR traffic source and attach it to udp4 +set cbr_ugs($j) [new Application/Traffic/CBR] +$cbr_ugs($j) set packetSize_ 1000 +$cbr_ugs($j) set interval_ $interval_ugs($j) +$cbr_ugs($j) attach-agent $udp_ugs($j) + +# Create the Null agent to sink traffic +set null_ugs($j) [new Agent/Null] +$ns attach-agent $sinkNode $null_ugs($j) + +# Attach the 2 agents +$ns connect $udp_ugs($j) $null_ugs($j) +$udp_ugs($j) set fid_ $j + + +## add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +##ServiceFlowSchedulingType: 0=>SERVICE_UGS, 1=>SERVICE_rtPS, 2=>SERVICE_nrtPS, 3=>SERVICE_BE +$ss_sched add-flow 5 [expr 30 + [$cbr_ugs($j) set packetSize_] * [Mac/802_16 set frame_duration_] / [$cbr_ugs($j) set interval_]] 0 0 + +##set-PeerNode-SNR PeerNode SNR +$ns at 1.5 "$bs_sched set-PeerNode-SNR [expr $j] $SNR_ugs($j)" + +##set-PeerNode-UGSPeriodicity PeerNode Periodicity (periodicity of the reservation, every k frames) +$ns at 1.5 "$bs_sched set-PeerNode-UGSPeriodicity [expr $j] 1" + +#Schedule start/stop of traffic +$ns at $traffic_start "$cbr_ugs($j) start" +$ns at $traffic_stop "$cbr_ugs($j) stop" + +} +#################### + + + + + + + + + +################################################ +## rtPS connections +# The identity of the first rtPS connection is k, the second is k+1, and so on +set first_rtPS 101 + +#set the bumber of rtPS connections +set nb_rtPS 9 + + +#set the number of symbols reserved for unicast request opportunities +$bs_sched set-SymbolNumberForUnicastRequest 3 + + +set rtPS_scheduler_ [lindex $argv 2] + +#bs_sched set-rtPSscheduling scheduling +$bs_sched set-rtPSscheduling $rtPS_scheduler_ + + +proc send_next_packet_VBR {udp_ size_ interval_} { + global ns traffic_stop +$udp_ send [expr round([$size_ value])] +#$udp_ send 1000 # constant if CBR + +if {[$ns now] < [expr $traffic_stop - $interval_]} { + $ns at [expr [$ns now] + $interval_] "send_next_packet_VBR $udp_ $size_ $interval_" +} + +} + + +# seed the default RNG +global defaultRNG +$defaultRNG seed 9999 + + + + +#### interval_ ######## +set interval_rtPS(1) 0.01 +set interval_rtPS(2) 0.04 +set interval_rtPS(3) 0.05 +set interval_rtPS(4) 0.02 +set interval_rtPS(5) 0.05 +set interval_rtPS(6) 0.04 +set interval_rtPS(7) 0.03 +set interval_rtPS(8) 0.02 +set interval_rtPS(9) 0.03 +####################### + + +#### SNR ############ +set SNR_rtPS(1) 7.0 +set SNR_rtPS(2) 7.5 +set SNR_rtPS(3) 9.0 +set SNR_rtPS(4) 12.0 +set SNR_rtPS(5) 17.0 +set SNR_rtPS(6) 17.5 +set SNR_rtPS(7) 20.0 +set SNR_rtPS(8) 24.0 +set SNR_rtPS(9) 25.5 +##################### + + + + +#### WRR ######################## +# set the weights if using WRR +if {$rtPS_scheduler_ == "WRR"} { +set WRR_rtPS(1) 1 +set WRR_rtPS(2) 1 +set WRR_rtPS(3) 1 +set WRR_rtPS(4) 2 +set WRR_rtPS(5) 2 +set WRR_rtPS(6) 3 +set WRR_rtPS(7) 3 + +set WRR_rtPS(8) 4 +set WRR_rtPS(9) 4 +} +################################## + + +################## +#set-TRSparameters-SNR-Tr-Tp-L SNRth Tr Tp L +$bs_sched set-TRSparameters-SNR-Tr-Tp-L 8.5 2 3 4 +################## + + +$ns node-config -wiredRouting OFF \ + -macTrace ON ;# Mobile nodes cannot do routing. + +for {set j $first_rtPS} {$j < [expr $first_rtPS + $nb_rtPS]} {incr j} { +set wl_node_rtPS($j) [$ns node 1.0.[expr $nb_UGS + $j + 1 - $first_rtPS]] ;# create the node with given @. + +$wl_node_rtPS($j) random-motion 0 ;# disable random motion +$wl_node_rtPS($j) base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +#compute position of the node +$wl_node_rtPS($j) set X_ [expr 550 + 5 * [expr $j + 1 - $first_rtPS]] +$wl_node_rtPS($j) set Y_ [expr 650] +$wl_node_rtPS($j) set Z_ 0.0 + +#puts "wireless node $j created" + +set clas [new SDUClassifier/Dest] +[$wl_node_rtPS($j) set mac_(0)] add-classifier $clas +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set ss_sched [new WimaxScheduler/SS] +[$wl_node_rtPS($j) set mac_(0)] set-scheduler $ss_sched +[$wl_node_rtPS($j) set mac_(0)] set-channel 0 + + +#Create a UDP agent and attach it to wl_node$j +set udp_rtPS($j) [new Agent/UDP] +$ns attach-agent $wl_node_rtPS($j) $udp_rtPS($j) + +# Create the Null agent to sink traffic +set null_rtPS($j) [new Agent/Null] +$ns attach-agent $sinkNode $null_rtPS($j) + +# Attach the 2 agents +$ns connect $udp_rtPS($j) $null_rtPS($j) +$udp_rtPS($j) set fid_ $j + +set interval_rtPS($j) $interval_rtPS([expr $j + 1 - $first_rtPS]) + + +## exponential distribution +#set sizeRNG_rtPS($j) [new RNG] + +#set size_rtPS($j) [new RandomVariable/Exponential] +#$size_rtPS($j) set avg_ 1000 +#$size_rtPS($j) use-rng $sizeRNG_rtPS($j) + + +# uniform distribution +set sizeRNG_rtPS($j) [new RNG] + +set size_rtPS($j) [new RandomVariable/Uniform] +$size_rtPS($j) set min_ 500 +$size_rtPS($j) set max_ 1500 +$size_rtPS($j) use-rng $sizeRNG_rtPS($j) + + +## add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +##ServiceFlowSchedulingType: 0=>SERVICE_UGS, 1=>SERVICE_rtPS, 2=>SERVICE_nrtPS, 3=>SERVICE_BE +$ss_sched add-flow 5 0 0 1 + +##set-PeerNode-SNR PeerNode SNR +$ns at 1.5 "$bs_sched set-PeerNode-SNR [expr $nb_UGS + $j + 1 - $first_rtPS] $SNR_rtPS([expr $j + 1 - $first_rtPS])" + +##set-PeerNode-UnicastRequestPeriodicity PeerNode Periodicity +$ns at 1.5 "$bs_sched set-PeerNode-UnicastRequestPeriodicity [expr $nb_UGS + $j + 1 - $first_rtPS] 2" + + +if {$rtPS_scheduler_ == "WRR"} { + # set-PeerNode-WRRschedulingForrtPS PeerNode Weight + $ns at 1.5 "$bs_sched set-PeerNode-WRRschedulingForrtPS [expr $nb_UGS + $j + 1 - $first_rtPS] $WRR_rtPS([expr $j + 1 - $first_rtPS])" +} + + + +$ns at [expr 15.0 + [expr $j + 1 - $first_rtPS] * 0] "send_next_packet_VBR $udp_rtPS($j) $size_rtPS($j) $interval_rtPS($j)" + +#puts "n[expr $nb_UGS + $j + 1 - $first_rtPS] starts at [expr 15.0 + [expr $j + 1 - $first_rtPS] * 0]" + +} + + + + + + + +#################################################################### +set first_BE 301 + +$ns node-config -wiredRouting OFF \ + -macTrace ON ;# Mobile nodes cannot do routing. + +set wl_node_BE($first_BE) [$ns node 1.0.[expr $nb_UGS + $nb_rtPS + 1]] ;# create the node with given @. +$wl_node_BE($first_BE) random-motion 0 ;# disable random motion +$wl_node_BE($first_BE) base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +#compute position of the node +$wl_node_BE($first_BE) set X_ 559.0 +$wl_node_BE($first_BE) set Y_ 617.0 +$wl_node_BE($first_BE) set Z_ 0.0 + +puts "wireless node _BE $first_BE created" + +set clas [new SDUClassifier/Dest] +[$wl_node_BE($first_BE) set mac_(0)] add-classifier $clas +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set ss_sched [new WimaxScheduler/SS] +[$wl_node_BE($first_BE) set mac_(0)] set-scheduler $ss_sched +[$wl_node_BE($first_BE) set mac_(0)] set-channel 0 + + +##set-PeerNode-SNR PeerNode SNR +$ns at 1.3 "$bs_sched set-PeerNode-SNR [expr $nb_UGS + $nb_rtPS + 1] 12.3" + +##set-BwRequestSendingPeriod BwRequestSendingPeriod_ +$ss_sched set-BwRequestSendingPeriod 10 + +## add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +##ServiceFlowSchedulingType: 0 => SERVICE_UGS, 1 => SERVICE_rtPS, 2 => SERVICE_nrtPS, 3 => SERVICE_BE +$ss_sched add-flow 1 0 0 3 + +#set data_to_send_BE($first_BE) 30000 +#$ns at $traffic_start "$ss_sched set-BandwidthBEconnections $data_to_send_BE($first_BE)" +#$ns at $traffic_start "uplink_ftp_tcp_data $wl_node_BE($first_BE) $first_BE $data_to_send_BE($first_BE)" + +$ns at 13.0 "uplink_ftp_tcp $wl_node_BE($first_BE) $first_BE" +################################################################################# + + + + + + + + + + + + +#################################################################### +$ns node-config -wiredRouting OFF \ + -macTrace ON ;# Mobile nodes cannot do routing. + +set wl_node_BE([expr $first_BE + 1]) [$ns node 1.0.[expr $nb_UGS + $nb_rtPS + 2]] ;# create the node with given @. +$wl_node_BE([expr $first_BE + 1]) random-motion 0 ;# disable random motion +$wl_node_BE([expr $first_BE + 1]) base-station [AddrParams addr2id [$bstation node-addr]] ;#attach mn to basestation +#compute position of the node +$wl_node_BE([expr $first_BE + 1]) set X_ 465.0 +$wl_node_BE([expr $first_BE + 1]) set Y_ 523.0 +$wl_node_BE([expr $first_BE + 1]) set Z_ 0.0 + +puts "wireless node [expr $first_BE + 1] created" + +set clas [new SDUClassifier/Dest] +[$wl_node_BE([expr $first_BE + 1]) set mac_(0)] add-classifier $clas +#set the scheduler for the node. Must be changed to -shed [new $opt(sched)] +set ss_sched [new WimaxScheduler/SS] +[$wl_node_BE([expr $first_BE + 1]) set mac_(0)] set-scheduler $ss_sched +[$wl_node_BE([expr $first_BE + 1]) set mac_(0)] set-channel 0 + + +##set-PeerNode-SNR PeerNode SNR +$ns at 1.3 "$bs_sched set-PeerNode-SNR [expr $nb_UGS + $nb_rtPS + 2] 12.32" + +##set-BwRequestSendingPeriod BwRequestSendingPeriod_ +$ss_sched set-BwRequestSendingPeriod 10 + +## add-flow TrafficPriority MaximumSustainedTrafficRate MinimumReservedTrafficRate ServiceFlowSchedulingType +##ServiceFlowSchedulingType: 0 => SERVICE_UGS, 1 => SERVICE_rtPS, 2 => SERVICE_nrtPS, 3 => SERVICE_BE +$ss_sched add-flow 1 0 0 3 + +#set data_to_send_BE([expr $first_BE + 1]) 30000 +#$ns at $traffic_start "uplink_ftp_tcp_data $wl_node_BE([expr $first_BE + 1]) [expr $first_BE + 1] $data_to_send_BE([expr $first_BE + 1])" + +$ns at 13.0 "uplink_ftp_tcp $wl_node_BE([expr $first_BE + 1]) [expr $first_BE + 1]" +################################################################################# + + + + + + +proc uplink_ftp_tcp_data {wl_node fid data_to_send} { +global ns sinkNode +#Setup a TCP connection +set tcp [new Agent/TCP/Newreno] +$ns attach-agent $wl_node $tcp +set sink [new Agent/TCPSink] +$ns attach-agent $sinkNode $sink +$ns connect $tcp $sink +$tcp set fid_ $fid +$tcp set packetSize_ 1000 + +#setup a FTP over TCP connection +set ftp [new Application/FTP] +$ftp attach-agent $tcp +$ftp set type_ FTP +$ftp set packetSize_ 1000 + +$ftp send $data_to_send +} + + + +proc uplink_ftp_tcp {wl_node fid} { +global ns sinkNode +#Setup a TCP connection +set tcp [new Agent/TCP/Newreno] +$ns attach-agent $wl_node $tcp +set sink [new Agent/TCPSink] +$ns attach-agent $sinkNode $sink +$ns connect $tcp $sink +$tcp set fid_ $fid +$tcp set packetSize_ 1000 + +#setup a FTP over TCP connection +set ftp [new Application/FTP] +$ftp attach-agent $tcp +$ftp set type_ FTP +$ftp set packetSize_ 1000 + +$ftp start +} + + + +################procedure : Record #################### +set f0 [open 1_out.tr w] + +proc record {} { +global f0 cbr +set ns [Simulator instance] +set time 0.05 +set now [$ns now] +set packetSize [$cbr set packetSize_] +set rate [$cbr set rate_] +set seqno [$cbr set seqno_] +puts $f0 "$now paketSize $packetSize rate $rate seqno $seqno" +$ns at [expr $now + $time] "record" +} + +##$ns at $traffic_start "record" +######################################################## + + + + +$ns at $simulation_stop "finish" +puts "Starts simulation" +$ns run +puts "Simulation done." \ Pas de fin de ligne à la fin du fichier. diff -Naur ns-2.29-original/wimax/connection.cc ns-2.29-new/wimax/connection.cc --- ns-2.29-original/wimax/connection.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/connection.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,186 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "connection.h" +#include "connectionmanager.h" +#include "mac802_16.h" + +static int basicIndex = BASIC_CID_START; +static int primaryIndex = PRIMARY_CID_START; +static int transportIndex = TRANSPORT_SEC_CID_START; +static int multicastIndex = MULTICAST_CID_START; + +/** + * Constructor used by BS to automatically assign CIDs + * @param type The connection type. + */ +Connection::Connection (ConnectionType_t type) : peer_(0), + frag_status_(FRAG_NOFRAG), + frag_nb_(0), + frag_byte_proc_(0), + frag_enable_(true) +{ + switch (type) { + case CONN_INIT_RANGING: + cid_ = INITIAL_RANGING_CID; + break; + case CONN_AAS_INIT_RANGING: + cid_ = AAS_INIT_RANGIN_CID; + break; + case CONN_PADDING: + cid_ = PADDING_CID; + break; + case CONN_BROADCAST: + cid_ = BROADCAST_CID; + break; + case CONN_MULTICAST_POLLING: + cid_ = multicastIndex++; + assert (multicastIndex <= MULTICAST_CID_STOP); + break; + case CONN_BASIC: + cid_ = basicIndex++; + assert (basicIndex <= BASIC_CID_STOP); + break; + case CONN_PRIMARY: + cid_ = primaryIndex++; + assert (primaryIndex <= PRIMARY_CID_STOP); + break; + case CONN_SECONDARY: + case CONN_DATA: + cid_ = transportIndex++; + assert (transportIndex <= TRANSPORT_SEC_CID_STOP); + break; + default: + fprintf (stderr, "Unsupported connection type\n"); + exit (1); + } + type_ = type; + queue_ = new PacketQueue(); + +} + +/** + * Constructor used by SSs when the CID is already known + * @param type The connection type + * @param cid The connection cid + */ +Connection::Connection (ConnectionType_t type, int cid) : peer_(0), + frag_status_(FRAG_NOFRAG), + frag_nb_(0), + frag_byte_proc_(0), + frag_enable_(true) +{ + cid_ = cid; + type_ = type; + queue_ = new PacketQueue(); + +} + +/** + * Destructor + */ +Connection::~Connection () +{ + flush_queue (); +} + +/** + * Set the connection manager + * @param manager The Connection manager + */ +void Connection::setManager (ConnectionManager *manager) +{ + manager_ = manager; +} + +/** + * Enqueue the given packet + * @param p The packet to enqueue + */ +void Connection::enqueue (Packet * p) +{ + queue_->enque (p); +} + +/** + * Dequeue a packet from the queue + * @param p The packet to enqueue + */ +Packet * Connection::dequeue () +{ + return queue_->deque (); +} + +/** + * Flush the queue and return the number of packets freed + * @return The number of packets flushed + */ +int Connection::flush_queue() +{ + int i=0; + Packet *p; + while ( (p=queue_->deque()) ) { + manager_->getMac()->drop(p, "CON"); + i++; + } + return i; +} + +/** + * Return queue size in bytes + + */ +int Connection::queueByteLength () +{ + return queue_->byteLength (); +} + +/** + * Return queue size in bytes + + */ +int Connection::queueLength () +{ + return queue_->length (); +} + +/** + * Update the fragmentation information + * @param status The new fragmentation status + * @param index The new fragmentation index + * @param bytes The number of bytes + */ +void Connection::updateFragmentation (fragment_status status, int index, int bytes) +{ + frag_status_ = status; + frag_nb_ = index; + frag_byte_proc_ = bytes; +} + + + +/// Added by Aymen +/** + * Enqueue the given packet at front of queue + * @param p The packet to enqueue + */ +void Connection::enqueueHead (Packet * p) +{ + queue_->enqueHead (p); +} +/// \ Pas de fin de ligne à la fin du fichier. diff -Naur ns-2.29-original/wimax/connection.h ns-2.29-new/wimax/connection.h --- ns-2.29-original/wimax/connection.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/connection.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,297 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef CONNECTION_H +#define CONNECTION_H + +#include "serviceflow.h" +#include "packet.h" +#include "queue.h" +#include "mac802_16pkt.h" + +/* CONSTANTS */ +#define INITIAL_RANGING_CID 0x0000 +#define BASIC_CID_START 0x0001 +#define BASIC_CID_STOP 0x2000 +#define PRIMARY_CID_START 0x2001 +#define PRIMARY_CID_STOP 0x4000 +#define TRANSPORT_SEC_CID_START 0x4001 +#define TRANSPORT_SEC_CID_STOP 0xFEFE +#define AAS_INIT_RANGIN_CID 0xFEFF +#define MULTICAST_CID_START 0xFF00 +#define MULTICAST_CID_STOP 0xFFFD +#define PADDING_CID 0xFFFE +#define BROADCAST_CID 0xFFFF + +/** + * Define the type of the connection + */ +enum ConnectionType_t { + CONN_INIT_RANGING, + CONN_AAS_INIT_RANGING, + CONN_MULTICAST_POLLING, + CONN_PADDING, + CONN_BROADCAST, + CONN_BASIC, + CONN_PRIMARY, + CONN_SECONDARY, + CONN_DATA +}; + +class PeerNode; +class ConnectionManager; +class Connection; +LIST_HEAD (connection, Connection); + +/** + * Class Connection + * The class supports LIST. + */ +class Connection { + public: + /** constructor */ + Connection (ConnectionType_t); + + /** constructor */ + Connection (ConnectionType_t, int cid); + + /** destructor */ + ~Connection (); + + /** + * Set the connection manager + * @param manager The Connection manager + */ + void setManager (ConnectionManager *manager); + + /** + * Enqueue the given packet + * @param p The packet to enqueue + */ + void enqueue (Packet * p); + + + +/// Added by Aymen +/** + * Enqueue the given packet at front of queue + * @param p The packet to enqueue + */ +void enqueueHead (Packet * p); +/// + + + /** + * Set the service flow for this connection + * @param sflow The service flow for this connection + */ + void setServiceFlow (ServiceFlow * sflow); + + /** + * Return the service flow for this connection + */ + ServiceFlow * getServiceFlow (); + + /** + * Get the value of cid + * The connection id + * @return the value of cid + */ + inline int get_cid ( ) { return cid_; } + + /** + * Get the value of category_ + * The connection id + * @return the value of category_ + */ + inline ConnectionType_t get_category ( ) { return category_; } + + /** + * Set the value of category_ + * The connection id + * @return the value of category_ + */ + inline void set_category (ConnectionType_t value ) { category_ = value; } + + /** + * Get the value of serviceflow_ + * The service flow associated with the connection + * @return the value of serviceflow_ + */ + inline ServiceFlow * get_serviceflow ( ) { return serviceflow_; } + + /** + * Set the value of serviceflow_ + * The service flow associated with the connection + * @return the value of serviceflow_ + */ + inline void set_serviceflow (ServiceFlow * value ) { serviceflow_ = value; } + + /** + * return the connection type + * @return The connection type + */ + inline ConnectionType_t getType () { return type_; } + + /** + * Get the value of queue_ + * The queue for this connection + * @return the value of queue_ + */ + inline PacketQueue * get_queue ( ) { return queue_; } + + /** + * Dequeue a packet from the queue + * @param p The packet to enqueue + */ + Packet * dequeue (); + + /** + * Return queue size in bytes + * @return The queue size in bytes + */ + int queueByteLength (); + + /** + * Return queue size in number of packets + * @return The number of packet in the queue + */ + int queueLength (); + + /** + * Flush the queue + */ + int flush_queue (); + + /** + * Enable/Disable fragmentation + */ + void enable_fragmentation (bool enable) { frag_enable_ = enable; } + + /** + * Indicates if the connection supports fragmentation + */ + bool isFragEnable () { return frag_enable_; } + + // Chain element to the list + inline void insert_entry(struct connection *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Return next element in the chained list + Connection* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + + /** + * Return the peer node for this connection + * @return the peer node for this connection + */ + inline PeerNode * getPeerNode () { return peer_; } + + /** + * Set the peer node for this connection + * @param the peer node for this connection + */ + inline void setPeerNode (PeerNode *peer) { peer_=peer; } + + /** + * Update the fragmentation information + * @param status The new fragmentation status + * @param index The new fragmentation index + * @param bytes The number of bytes + */ + void updateFragmentation (fragment_status status, int index, int bytes); + + fragment_status getFragmentationStatus () { return frag_status_; } + + int getFragmentNumber () { return frag_nb_; } + + int getFragmentBytes () { return frag_byte_proc_; } + + protected: + + /** + * Pointer to next in the list + */ + LIST_ENTRY(Connection) link; + //LIST_ENTRY(Connection); //for magic draw + + + private: + /** + * The connection manager + */ + ConnectionManager* manager_; + + /** + * The connection id + */ + int cid_; + + /** + * The category + */ + ConnectionType_t category_; + + /** + * The service flow associated with the connection + */ + ServiceFlow * serviceflow_; + + /** + * The queue for this connection + */ + PacketQueue * queue_; + + /** + * The connection type + */ + ConnectionType_t type_; + + /** + * Pointer to the peer node data + */ + PeerNode *peer_; + + /** + * Fragmentation status + */ + fragment_status frag_status_; + + /** + * Fragmentation number + */ + int frag_nb_; + + /** + * Bytes already processed (i.e sent or received) + */ + int frag_byte_proc_; + + /** + * Indicates if the connection can use fragmentation + */ + bool frag_enable_; + +}; +#endif //CONNECTION_H + diff -Naur ns-2.29-original/wimax/connectionmanager.cc ns-2.29-new/wimax/connectionmanager.cc --- ns-2.29-original/wimax/connectionmanager.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/connectionmanager.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,110 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "connectionmanager.h" +#include "mac802_16.h" + +/** + * Create the manager for the given mac + * @param mac The Mac where the manager is located + */ +ConnectionManager::ConnectionManager (Mac802_16 * mac) +{ + assert (mac!=NULL); + mac_ = mac; + + //init list + LIST_INIT (&up_con_list_); + LIST_INIT (&down_con_list_); +} + + +/** + * Add a connection to the list + * @param con The connection to add + * @param incoming true if it is an uplink connection + */ +void ConnectionManager::add_connection (Connection* con, bool uplink) { + assert (con!=NULL); + assert (!get_connection (con->get_cid(), uplink)); //check duplicate + mac_->debug ("At %f in %d adding %s connection %d\n", \ + NOW, mac_->addr(), uplink?"uplink":"downlink", con->get_cid()); + + if (uplink) + con->insert_entry (&up_con_list_); + else + con->insert_entry (&down_con_list_); + + con->setManager(this); +} + + + +/** + * Remove a connection + * @param The connection to remove + */ +void ConnectionManager::remove_connection (Connection* con) { + assert (con !=NULL); + mac_->debug ("At %f in %d removing connection %d\n", \ + NOW, mac_->addr(), con->get_cid()); + con->remove_entry (); +} + +/** + * Remove connection by CID, both directions. + * @param cid The connection id + */ +void ConnectionManager::remove_connection (int cid) +{ + Connection *con = get_connection (cid, true); + if (con) + remove_connection (con); + con = get_connection (cid, false); + if (con) + remove_connection (con); +} + + +/** + * Return the connection that has the given CID + * @param cid The connection ID + * @param uplink The direction + * @return the connection or NULL + */ +Connection* ConnectionManager::get_connection (int cid, bool uplink) { + //search throught the list + for (Connection *n=uplink?up_con_list_.lh_first:down_con_list_.lh_first; + n; n=n->next_entry()) { + if (n->get_cid ()==cid) + return n; + } + return NULL; +} + +/** + * Flush the queues. This can be called after switching BS. + */ +void ConnectionManager::flush_queues () { + mac_->debug ("At %f in %d Flushing queues\n", NOW, mac_->addr()); + for (Connection *n=down_con_list_.lh_first; n; n=n->next_entry()) { + int i = n->flush_queue(); + mac_->debug ("\tFreed %d packet in queue for connection %d\n", i, n->get_cid()); + } +} + diff -Naur ns-2.29-original/wimax/connectionmanager.h ns-2.29-new/wimax/connectionmanager.h --- ns-2.29-original/wimax/connectionmanager.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/connectionmanager.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,113 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef CONNECTIONMANAGER_H +#define CONNECTIONMANAGER_H + +#include "connection.h" + +class Mac802_16; + +/** + * Class ConnectionManager + * The class handles the list of connections for a Mac 802.16 + */ +class ConnectionManager { + friend class Connection; + public: + /** + * + * @param mac The mac where the manager belongs + */ + ConnectionManager (Mac802_16 * mac); + + /** + * Add a connection + * @param con The connection to add + * @param incoming true if it is an uplink connection + */ + void add_connection (Connection* con, bool uplink); + + /** + * Remove the given connection + * @param connection Remove the given connection + */ + void remove_connection (Connection* connection); + + /** + * Remove connection by CID, both directions. + * @param cid The connection id + */ + void remove_connection (int cid); + + /** + * Return the connection with the given cid and direction + * @param cid The connection id + * @param incoming specifies the direction of the connection + */ + Connection* get_connection (int cid, bool uplink); + + /** + * Return the head of the incoming connection list + */ + Connection* get_up_connection () { return up_con_list_.lh_first; } + + /** + * Return the head of the outgoing connection list + */ + Connection* get_down_connection () { return down_con_list_.lh_first; } + + + /** + * Flush the queues. This can be called after switching BS. + */ + void flush_queues (); + + protected: + /** + * Get the value of mac_ + * The Mac where this object is located + * @return the value of mac_ + */ + inline Mac802_16 * getMac ( ) { return mac_; } + + private: + /** + * The list of available connections + */ + Connection* connections_; + + /** + * The Mac where this object is located + */ + Mac802_16 * mac_; + + /** + * The list of uplink connections + */ + struct connection up_con_list_; + + /** + * The list of downlink connections + */ + struct connection down_con_list_; + + +}; +#endif //CONNECTIONMANAGER_H + diff -Naur ns-2.29-original/wimax/destclassifier.cc ns-2.29-new/wimax/destclassifier.cc --- ns-2.29-original/wimax/destclassifier.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/destclassifier.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,93 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "destclassifier.h" +#include "mac802_16.h" +#include "scheduling/wimaxscheduler.h" + +/** + * TCL Hooks for the simulator for classifier + */ +static class DestClassifierClass : public TclClass { +public: + DestClassifierClass() : TclClass("SDUClassifier/Dest") {} + TclObject* create(int, const char*const*) { + return (new DestClassifier()); + + } +} class_destclassifier; + +/** + * Create a classifier in the given mac + * Constructor to be used by TCL + */ +DestClassifier::DestClassifier (): SDUClassifier () { + +} + + +/** + * Classify a packet and return the CID to use (or -1 if unknown) + * @param p The packet to classify + * @return The CID or -1 + */ +int DestClassifier::classify (Packet * p) +{ + struct hdr_mac *dh = HDR_MAC(p); + int dst = dh->macDA(); + mac_->debug ("At %f in Mac %d DestClassifier classifying packet for %d(size=%d, type=%s)\n",\ + NOW, mac_->addr(), dst, HDR_CMN(p)->size(), packet_info.name(HDR_CMN(p)->ptype())); + //here we look at the list of peer nodes until we find the one with + //the same destination address. Then we return its data communication + + //if broadcast, then send to broadcast CID + if (dst == -1) { + if (mac_->getScheduler()->getNodeType ()==STA_BS) + return BROADCAST_CID; + else { + //I am a MN, check if I am connected + PeerNode *n = mac_->getPeerNode_head (); + //i should classify depending on the packet type.TBD + if (n && n->getSecondary()) + return n->getSecondary()->get_cid(); + } + } + + for (PeerNode *n = mac_->getPeerNode_head (); n ; n=n->next_entry()) { + //printf ("Checking peer %d for %d\n", n->getPeerNode(), dst); + if (dst == n->getPeerNode ()) { + switch (HDR_CMN(p)->ptype()) { + case PT_ARP: +#ifdef USE_802_21 + case PT_RRED: + case PT_RADS: + case PT_RSOL: +#endif + if (n->getSecondary()) + return n->getSecondary()->get_cid(); + break; + default: + if (n->getOutData()) + return n->getOutData()->get_cid(); + else //this node is not ready to send data + break; + } + } + } + return -1; +} diff -Naur ns-2.29-original/wimax/destclassifier.h ns-2.29-new/wimax/destclassifier.h --- ns-2.29-original/wimax/destclassifier.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/destclassifier.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,60 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef DESTCLASSIFIER_H +#define DESTCLASSIFIER_H + +#include "sduclassifier.h" + +/** + * This class classifies the packet based on the destination address + */ +class DestClassifier : public SDUClassifier +{ + public: + + /** + * Create a classifier in the given mac + */ + DestClassifier (); + + /** + * Create a classifier in the given mac + * @param mac The mac where it is located + */ + DestClassifier (Mac802_16 *mac); + + /** + * Create a classifier in the given mac + * @param mac The mac where it is located + * @param priority The classifier's priority + */ + DestClassifier (Mac802_16 *mac, int priority_); + + /** + * Classify a packet and return the CID to use (or -1 if unknown) + * @param p The packet to classify + * @return The CID or -1 + */ + int classify (Packet * p); + + protected: + +}; + +#endif diff -Naur ns-2.29-original/wimax/mac802_16.cc ns-2.29-new/wimax/mac802_16.cc --- ns-2.29-original/wimax/mac802_16.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/mac802_16.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,1184 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "mac802_16.h" +#include "scheduling/wimaxscheduler.h" +#include "scheduling/ssscheduler.h" //TBR +//we use mac 802_11 for trace +#include "mac-802_11.h" + +/* Defines frequencies for 3.5 GHz band and 7 Mhz freqency bandwidth */ +/* Will be removed when a dynamic way is added */ +static const int nbFreq = 5; +static const double frequencies[] = { 3.486e+9, 3.493e+9, 3.5e+9, 3.507e+9, 3.514e+9}; + + +int hdr_mac802_16::offset_; +/** + * TCL Hooks for the simulator for wimax packets + */ +static class Mac802_16HeaderClass : public PacketHeaderClass +{ +public: + Mac802_16HeaderClass() : PacketHeaderClass("PacketHeader/802_16", + sizeof(hdr_mac802_16)) + { + bind_offset(&hdr_mac802_16::offset_); + } +} class_hdr_mac802_16; + +/** + * TCL Hooks for the simulator for wimax mac + */ +static class Mac802_16Class : public TclClass { +public: + Mac802_16Class() : TclClass("Mac/802_16") {} + TclObject* create(int, const char*const*) { + return (new Mac802_16()); + + } +} class_mac802_16; + +Phy802_16MIB::Phy802_16MIB(Mac802_16 *parent) +{ + parent->bind ("channel_", &channel ); + parent->bind ("fbandwidth_", &fbandwidth ); + parent->bind ("ttg_", &ttg ); + parent->bind ("rtg_", &rtg ); +} + +Mac802_16MIB::Mac802_16MIB(Mac802_16 *parent) +{ + parent->bind ("queue_length_", &queue_length ); + parent->bind ("frame_duration_", &frame_duration ); + parent->bind ("dcd_interval_", &dcd_interval ); + parent->bind ("ucd_interval_", &ucd_interval ); + parent->bind ("init_rng_interval_", &init_rng_interval ); + parent->bind ("lost_dlmap_interval_", &lost_dlmap_interval ); + parent->bind ("lost_ulmap_interval_", &lost_ulmap_interval ); + parent->bind ("t1_timeout_", &t1_timeout ); + parent->bind ("t2_timeout_", &t2_timeout ); + parent->bind ("t3_timeout_", &t3_timeout ); + parent->bind ("t6_timeout_", &t6_timeout ); + parent->bind ("t12_timeout_", &t12_timeout ); + parent->bind ("t16_timeout_", &t16_timeout ); + parent->bind ("t17_timeout_", &t17_timeout ); + parent->bind ("t21_timeout_", &t21_timeout ); + parent->bind ("contention_rng_retry_", &contention_rng_retry ); + parent->bind ("invited_rng_retry_", &invited_rng_retry ); + parent->bind ("request_retry_", &request_retry ); + parent->bind ("reg_req_retry_", ®_req_retry ); + parent->bind ("tproc_", &tproc ); + parent->bind ("dsx_req_retry_", &dsx_req_retry ); + parent->bind ("dsx_rsp_retry_", &dsx_rsp_retry ); + + parent->bind ("rng_backoff_start_", &rng_backoff_start); + parent->bind ("rng_backoff_stop_", &rng_backoff_stop); + parent->bind ("bw_backoff_start_", &bw_backoff_start); + parent->bind ("bw_backoff_stop_", &bw_backoff_stop); + + //mobility extension + parent->bind ("scan_duration_", &scan_duration ); + parent->bind ("interleaving_interval_", &interleaving ); + parent->bind ("scan_iteration_", &scan_iteration ); + parent->bind ("t44_timeout_", &t44_timeout ); + parent->bind ("max_dir_scan_time_", &max_dir_scan_time ); + parent->bind ("nbr_adv_interval_", &nbr_adv_interval ); + parent->bind ("scan_req_retry_", &scan_req_retry ); + + parent->bind ("client_timeout_", &client_timeout ); + parent->bind ("rxp_avg_alpha_", &rxp_avg_alpha); + parent->bind ("lgd_factor_", &lgd_factor_); +} + +/** + * Creates a Mac 802.16 + */ +Mac802_16::Mac802_16() : Mac (), macmib_(this), phymib_(this), rxTimer_(this) +{ + //init variable + LIST_INIT(&classifier_list_); + peer_list_ = (struct peerNode *) malloc (sizeof(struct peerNode)); + LIST_INIT(peer_list_); + + collision_ = false; + pktRx_ = NULL; + pktBuf_ = NULL; + + connectionManager_ = new ConnectionManager (this); + scheduler_ = NULL; + /* the following will be replaced by dynamic adding of service flow */ + serviceFlowHandler_ = new ServiceFlowHandler (); + serviceFlowHandler_->setMac (this); + bs_id_ = BS_NOT_CONNECTED; + type_ = STA_UNKNOWN; + frame_number_ = 0; + state_ = MAC802_16_DISCONNECTED; + notify_upper_ = true; + + last_tx_time_ = 0; + last_tx_duration_ = 0; + + Tcl& tcl = Tcl::instance(); + tcl.evalf ("Phy/WirelessPhy set RXThresh_"); + macmib_.RXThreshold_ = atof (tcl.result()); + + + /* Initialize Stats variables */ + bind_bool ("print_stats_", &print_stats_); + + last_tx_delay_ = 0; + double tmp; + bind ("delay_avg_alpha_", &tmp); + delay_watch_.set_alpha(tmp); + bind ("jitter_avg_alpha_", &tmp); + jitter_watch_.set_alpha(tmp); + bind ("loss_avg_alpha_", &tmp); + loss_watch_.set_alpha(tmp); + bind ("throughput_avg_alpha_", &tmp); + rx_data_watch_.set_alpha(tmp); + rx_data_watch_.set_pos_gradient (false); + rx_traffic_watch_.set_alpha(tmp); + rx_traffic_watch_.set_pos_gradient (false); + tx_data_watch_.set_alpha(tmp); + tx_data_watch_.set_pos_gradient (false); + tx_traffic_watch_.set_alpha(tmp); + tx_traffic_watch_.set_pos_gradient (false); + bind ("throughput_delay_", &tmp); + rx_data_watch_.set_delay (tmp); + rx_traffic_watch_.set_delay (tmp); + tx_data_watch_.set_delay (tmp); + tx_traffic_watch_.set_delay (tmp); + //timers for stats + rx_data_timer_ = new StatTimer (this, &rx_data_watch_); + rx_traffic_timer_ = new StatTimer (this, &rx_traffic_watch_); + tx_data_timer_ = new StatTimer (this, &tx_data_watch_); + tx_traffic_timer_ = new StatTimer (this, &tx_traffic_watch_); + +} +/** + * Interface with the TCL script + * @param argc The number of parameter + * @param argv The list of parameters + */ +int Mac802_16::command(int argc, const char*const* argv) +{ + if (argc == 2) { + if (strcmp(argv[1], "dump-classifiers") == 0) { + for (SDUClassifier *n=classifier_list_.lh_first;n;n=n->next_entry()) { + //printf ("Classifier %x priority=%d\n", (int)n, n->getPriority()); + } + return TCL_OK; + } + } + else if (argc == 3) { + /* + if (strcmp(argv[1], "set-bs") == 0) { + bs_id_ = atoi (argv[2]); + } + else*/ + if (strcmp(argv[1], "add-classifier") == 0) { + SDUClassifier *clas = (SDUClassifier*) TclObject::lookup(argv[2]); + if (clas == 0) + return TCL_ERROR; + //add classifier to the list + addClassifier (clas); + return TCL_OK; + } else if (strcmp(argv[1], "set-scheduler") == 0) { + scheduler_ = (WimaxScheduler*) TclObject::lookup(argv[2]); + if (scheduler_ == 0) + return TCL_ERROR; + scheduler_->setMac (this); //register the mac + setStationType (scheduler_->getNodeType()); //get the node type (BS or MN) + return TCL_OK; + } else if (strcmp(argv[1], "set-servicehandler") == 0) { + serviceFlowHandler_ = (ServiceFlowHandler*) TclObject::lookup(argv[2]); + if (serviceFlowHandler_ == 0) + return TCL_ERROR; + serviceFlowHandler_->setMac (this); + return TCL_OK; + } else if (strcmp(argv[1], "set-channel") == 0) { + assert (netif_); //to make sure we can update the phy + phymib_.channel = atoi (argv[2]); + double tmp = frequencies[phymib_.channel]; + getPhy ()->setFrequency (tmp); + return TCL_OK; + } + } + return Mac::command(argc, argv); +} + +/** + * Set the type of STA. This will be called when adding the scheduler + * It is used to create the default connections + * @param type The station type + */ +void Mac802_16::setStationType (station_type_t type) +{ + assert (type_ == STA_UNKNOWN && type != STA_UNKNOWN); + type_ = type; + + init_default_connections (); +} + +/** + * Initialize default connections + */ +void Mac802_16::init_default_connections () +{ + Connection * con; + + //create initial ranging and padding connection + con = new Connection (CONN_INIT_RANGING); + connectionManager_->add_connection (con, true); //uplink + con = new Connection (CONN_INIT_RANGING); + connectionManager_->add_connection (con, false); //downlink + con = new Connection (CONN_PADDING); + connectionManager_->add_connection (con, true); + con = new Connection (CONN_PADDING); + connectionManager_->add_connection (con, false); + + if (type_ == STA_BS) { + //the BS is always connected + setMacState (MAC802_16_CONNECTED); + //we need to create a Broadcast connection and AAS init ranging CIDs + con = new Connection (CONN_BROADCAST); + connectionManager_->add_connection (con, false); + con = new Connection (CONN_AAS_INIT_RANGING); + connectionManager_->add_connection (con, true); + } else if (type_ == STA_MN) { + //create connection to receive broadcast packets from BS + con = new Connection (CONN_BROADCAST); + connectionManager_->add_connection (con, false); + } +} + +/** + * Return the peer node that has the given address + * @param index The address of the peer + * @return The peer node that has the given address + */ +PeerNode* Mac802_16::getPeerNode (int index) +{ + for (PeerNode *p=peer_list_->lh_first;p;p=p->next_entry()) { + if (p->getPeerNode ()==index) + return p; + } + return NULL; +} + +/** + * Add the peer node + * @param The peer node to add + */ +void Mac802_16::addPeerNode (PeerNode *node) +{ + node->insert_entry (peer_list_); + //update Rx time so for default value + node->setRxTime(NOW); + node->getStatWatch()->set_alpha(macmib_.rxp_avg_alpha); +} + +/** + * Remove the peer node + * @param The peer node to remove + */ +void Mac802_16::removePeerNode (PeerNode *peer) +{ + if (peer->getBasic()) { + getCManager()->remove_connection (peer->getBasic()->get_cid()); + delete (peer->getBasic()); + } + if (peer->getPrimary()) { + getCManager()->remove_connection (peer->getPrimary()->get_cid()); + delete (peer->getPrimary()); + } + if (peer->getSecondary()) { + getCManager()->remove_connection (peer->getSecondary()->get_cid()); + delete (peer->getSecondary()); + } + if (peer->getInData()) { + getCManager()->remove_connection (peer->getInData()->get_cid()); + delete (peer->getInData()); + } + if (peer->getOutData()) { + getCManager()->remove_connection (peer->getOutData()->get_cid()); + delete (peer->getOutData()); + } + peer->remove_entry (); + delete (peer); +} + +/** + * Set the mac state + * @param state The new mac state + */ +void Mac802_16::setMacState (Mac802_16State state) +{ + state_ = state; +} + +/** + * Return the mac state + * @return The new mac state + */ +Mac802_16State Mac802_16::getMacState () +{ + return state_; +} + +/** + * Return the PHY layer + * @return The PHY layer + */ +OFDMPhy* Mac802_16::getPhy () { + return (OFDMPhy*) netif_; +} + +/** + * Change the channel + * @param channel The new channel + */ +void Mac802_16::setChannel (int channel) +{ + assert (channel < nbFreq); + phymib_.channel = channel; + double tmp = frequencies[phymib_.channel]; + getPhy ()->setFrequency (tmp); +} + +/** + * Return the channel number for the given frequency + * @param freq The frequency + * @return The channel number of -1 if the frequency does not match + */ +int Mac802_16::getChannel (double freq) +{ + for (int i = 0 ; i < nbFreq ; i++) { + if (frequencies[i]==freq) + return i; + } + return -1; +} + +/** + * Return the channel index + * @return The channel + */ +int Mac802_16::getChannel () +{ + return phymib_.channel; +} + +/** + * Set the channel to the next from the list + * Used at initialisation and when loosing signal + */ +void Mac802_16::nextChannel () +{ + debug ("At %f in Mac %d Going to channel %d\n", NOW, index_, (phymib_.channel+1)%nbFreq); + setChannel ((phymib_.channel+1)%nbFreq); +} + +/** + * Add a flow + * @param qos The QoS required + * @param handler The entity that requires to add a flow + */ +void Mac802_16::addFlow (ServiceFlowQoS * qos, void * handler) +{ + +} + +/** + * Backup the state of the Mac + */ +state_info* Mac802_16::backup_state () +{ + state_info *backup_state = (state_info*) malloc (sizeof (state_info)); + backup_state->bs_id = bs_id_; + backup_state->state = state_; + backup_state->frameduration = getFrameDuration(); + backup_state->frame_number = frame_number_; + backup_state->channel = getChannel(); + backup_state->connectionManager = connectionManager_; + connectionManager_ = new ConnectionManager (this); + init_default_connections (); + backup_state->serviceFlowHandler = serviceFlowHandler_; + serviceFlowHandler_ = new ServiceFlowHandler(); + backup_state->peer_list = peer_list_; + peer_list_ = (struct peerNode *) malloc (sizeof(struct peerNode)); + LIST_INIT(peer_list_); + return backup_state; +} + +/** + * Restore the state of the Mac + */ +void Mac802_16::restore_state (state_info *backup_state) +{ + bs_id_ = backup_state->bs_id; + state_ = backup_state->state; + setFrameDuration(backup_state->frameduration); + frame_number_ = backup_state->frame_number; + setChannel (backup_state->channel); + delete (connectionManager_); + connectionManager_ = backup_state->connectionManager; + delete (serviceFlowHandler_); + serviceFlowHandler_ = backup_state->serviceFlowHandler; + while (getPeerNode_head()!=NULL) { + removePeerNode (getPeerNode_head()); + } + peer_list_ = backup_state->peer_list; +} + +/** + * Set the variable used to find out if upper layers + * must be notified to send packets. During scanning we + * do not want upper layers to send packet to the mac. + */ +void Mac802_16::setNotify_upper (bool notify) { + notify_upper_ = notify; + if (notify_upper_ && pktBuf_) { + sendDown (pktBuf_); + pktBuf_ = NULL; + } +} + +/**** Packet processing methods ****/ + +/** + * Process packets going out + * @param p The packet to send out + */ +void Mac802_16::sendDown(Packet *p) +{ + //We first send it through the CS + int cid = -1; + + if (!notify_upper_) { + assert (!pktBuf_); + pktBuf_ = p; + return; + } + + for (SDUClassifier *n=classifier_list_.lh_first; n && cid==-1; n=n->next_entry()) { + cid = n->classify (p); + } + + if (cid == -1) { + debug ("At %f in Mac %d drop packet because no classification were found\n", \ + NOW, index_); + drop(p, "CID"); + //Packet::free (p); + } else { + //enqueue the packet + Connection *connection = connectionManager_->get_connection (cid, type_ == STA_MN); + if (connection == NULL) { + debug ("Warning: At %f in Mac %d connection with cid = %d does not exist. Please check classifiers\n",\ + NOW, index_, cid); + //Packet::free (p); + update_watch (&loss_watch_, 1); + drop(p, "CID"); + } + else { + if (connection->queueLength ()==macmib_.queue_length) { + //queue full + update_watch (&loss_watch_, 1); + drop (p, "QWI"); + } else { + //update mac header information + //set header information + hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p); + wimaxHdr->header.ht = 0; + wimaxHdr->header.ec = 1; + wimaxHdr->header.type = 0; //no subheader + wimaxHdr->header.ci = 0; + wimaxHdr->header.eks = 0; + wimaxHdr->header.cid = cid; //default + wimaxHdr->header.hcs = 0; + HDR_CMN(p)->size() += HDR_MAC802_16_SIZE; + HDR_CMN(p)->timestamp() = NOW; //set timestamp for delay + connection ->enqueue (p); + + //printf ("At %f in Mac %d Enqueue packet to cid=%d queue size=%d(max=%d)\n", NOW, index_, cid,connection->queueLength (), macmib_.queue_length); + } + } + } + + //inform upper layer that it can send another packet + //if (notify_upper_) + resume (NULL); + +} + +/** + * Transmit a packet to the physical layer + * @param p The packet to send out + */ +void Mac802_16::transmit(Packet *p) +{ + if (NOW < last_tx_time_+last_tx_duration_) { + //still sending + //printf ("MAC is already transmitting. Drop packet.\n"); + Packet::free (p); + return; + } + + struct hdr_cmn *ch = HDR_CMN(p); + /* + debug ("At %f in Mac %d sending packet (type=%s, size=%d) ", NOW, index_, packet_info.name(ch->ptype()), ch->size()); + if (ch->ptype()==PT_MAC) { + if (HDR_MAC802_16(p)->header.ht == 0) + debug ("mngt=%d\n", ((mac802_16_dl_map_frame*) p->accessdata())->type); + else + debug ("bwreq\n"); + } else { + debug ("\n"); + } + */ + //update stats for delay and jitter + double delay = NOW-ch->timestamp(); + update_watch (&delay_watch_, delay); + double jitter = fabs (delay - last_tx_delay_); + update_watch (&jitter_watch_, jitter); + last_tx_delay_ = delay; + if (ch->ptype()!=PT_MAC) { + update_throughput (&tx_data_watch_, 8*ch->size()); + } + update_throughput (&tx_traffic_watch_, 8*ch->size()); + + last_tx_time_ = NOW; + last_tx_duration_ = ch->txtime(); + + downtarget_->recv (p, (Handler*)NULL); + +} + +/** + * Process incoming packets + * @param p The incoming packet + */ +void Mac802_16::sendUp (Packet *p) +{ + struct hdr_cmn *ch = HDR_CMN(p); + +#ifdef DEBUG_WIMAX + debug ("At %f in Mac %d receive first bit..over at %f(txtime=%f) (type=%s) ", NOW, index_, NOW+ch->txtime(),ch->txtime(), packet_info.name(ch->ptype())); + if (ch->ptype()==PT_MAC) { + if (HDR_MAC802_16(p)->header.ht == 0) + debug ("mngt=%d\n", ((mac802_16_dl_map_frame*) p->accessdata())->type); + else + debug ("bwreq\n"); + } else { + debug ("\n"); + } +#endif + + if (pktRx_ !=NULL) { + /* + * If the power of the incoming packet is smaller than the + * power of the packet currently being received by at least + * the capture threshold, then we ignore the new packet. + */ + if(pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) { + Packet::free(p); + } else { + /* + * Since a collision has occurred, figure out + * which packet that caused the collision will + * "last" the longest. Make this packet, + * pktRx_ and reset the Recv Timer if necessary. + */ + if(txtime(p) > rxTimer_.expire()) { + rxTimer_.stop(); + //printf ("\t drop pktRx..collision\n"); + drop(pktRx_, "COL"); + update_watch (&loss_watch_, 1); + pktRx_ = p; + //mark the packet with error + ch->error() = 1; + collision_ = true; + rxTimer_.start(ch->txtime()-0.000000001); + } + else { + //printf ("\t drop new packet..collision\n"); + drop(p, "COL"); + //mark the packet with error + HDR_CMN(pktRx_)->error() = 1; + collision_ = true; + } + } + return; + } + assert (pktRx_==NULL); + assert (rxTimer_.busy()==0); + pktRx_ = p; + //create a timer to wait for the end of reception + //since the packets are received by burst, the beginning of the new packet + //is the same time as the end of this packet..we process this packet 1ns + //earlier to make room for the new packet. + rxTimer_.start(ch->txtime()-0.000000001); +} + +/** + * Process the fully received packet + */ +void Mac802_16::receive () +{ + assert (pktRx_); + struct hdr_cmn *ch = HDR_CMN(pktRx_); + +#ifdef DEBUG_WIMAX + printf ("At %f in Mac %d packet received (type=%s) ", NOW, index_, packet_info.name(ch->ptype())); + if (ch->ptype()==PT_MAC) { + if (HDR_MAC802_16(pktRx_)->header.ht == 0) + printf ("mngt=%d\n", ((mac802_16_dl_map_frame*) pktRx_->accessdata())->type); + else + printf ("bwreq\n"); + } else { + printf ("\n"); + } +#endif + + + //drop the packet if corrupted + if (ch->error()) { + if (collision_) { + //printf ("\t drop new pktRx..collision\n"); + drop (pktRx_, "COL"); + collision_ = false; + } else { + //error in the packet, the Mac does not process + Packet::free(pktRx_); + } + //update drop stat + update_watch (&loss_watch_, 1); + pktRx_ = NULL; + return; + } + + //process packet + hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(pktRx_); + gen_mac_header_t header = wimaxHdr->header; + int cid = header.cid; + Connection *con = connectionManager_->get_connection (cid, type_==STA_BS); + mac802_16_dl_map_frame *frame; + + if (con == NULL) { + //This packet is not for us + //printf ("At %f in Mac %d Connection null\n", NOW, index_); + update_watch (&loss_watch_, 1); + Packet::free(pktRx_); + pktRx_=NULL; + return; + } + //printf ("CID=%d\n", cid); + + //update rx time of last packet received + PeerNode *peer; + if (type_ == STA_MN) + peer = getPeerNode_head(); //MN only has one peer + else + peer = con->getPeerNode(); //BS can have multiple peers + + if (peer) { + peer->setRxTime (NOW); + + //collect receive signal strength stats + peer->getStatWatch()->update(10*log10(pktRx_->txinfo_.RxPr*1e3)); + //debug ("At %f in Mac %d weighted RXThresh: %e rxp average %e\n", NOW, index_, macmib_.lgd_factor_*macmib_.RXThreshold_, pow(10,peer->getStatWatch()->average()/10)/1e3); + double avg_w = pow(10,(peer->getStatWatch()->average()/10))/1e3; + + if ( avg_w < (macmib_.lgd_factor_*macmib_.RXThreshold_)) { + if (!peer->isGoingDown () && type_ == STA_MN && state_==MAC802_16_CONNECTED) { + ((SSscheduler*) scheduler_)->send_scan_request (); + } + peer->setGoingDown (true); + debug ("At %f Mac %d link going down trigger\n", NOW, index_); +#ifdef USE_802_21 + double probability = 1; + if(type_ == STA_MN) { + Mac::send_link_going_down (addr(), getPeerNode_head()->getPeerNode(), -1, (int)(100*probability), eventId_++); + } else { + Mac::send_link_going_down (peer->getPeerNode(), addr(), -1, (int)(100*probability), eventId_++); + } +#endif + } + else { + if (peer->isGoingDown()) { +#ifdef USE_802_21 + Mac::send_link_rollback (addr(), eventId_-1); +#endif + peer->setGoingDown (false); + } + } + } + + //process reassembly + if (wimaxHdr->frag_subheader) { + bool drop_pkt = true; + //printf ("Frag type = %d\n",wimaxHdr->fc & 0x3); + switch (wimaxHdr->fc & 0x3) { + case FRAG_NOFRAG: + if (con->getFragmentationStatus()!=FRAG_NOFRAG) + con->updateFragmentation (FRAG_NOFRAG, 0, 0); //reset + drop_pkt = false; + break; + case FRAG_FIRST: + //when it is the first fragment, it does not matter if we previously + //received other fragments, since we reset the information + assert (wimaxHdr->fsn == 0); + //printf ("\tReceived first fragment\n"); + con->updateFragmentation (FRAG_FIRST, 0, ch->size()-(HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE)); + break; + case FRAG_CONT: + if ( (con->getFragmentationStatus()!=FRAG_FIRST + && con->getFragmentationStatus()!=FRAG_CONT) + || ((wimaxHdr->fsn&0x7) != (con->getFragmentNumber ()+1)%8) ) { + con->updateFragmentation (FRAG_NOFRAG, 0, 0); //reset + } else { + //printf ("\tReceived cont fragment\n"); + con->updateFragmentation (FRAG_CONT, wimaxHdr->fsn&0x7, con->getFragmentBytes()+ch->size()-(HDR_MAC802_16_SIZE+HDR_MAC802_16_FRAGSUB_SIZE)); + } + break; + case FRAG_LAST: + if ( (con->getFragmentationStatus()==FRAG_FIRST + || con->getFragmentationStatus()==FRAG_CONT) + && ((wimaxHdr->fsn&0x7) == (con->getFragmentNumber ()+1)%8) ) { + //printf ("\tReceived last fragment\n"); + ch->size() += con->getFragmentBytes()-HDR_MAC802_16_FRAGSUB_SIZE; + drop_pkt = false; + } else { + //printf ("Error with last frag seq=%d (expected=%d)\n", wimaxHdr->fsn&0x7, (con->getFragmentNumber ()+1)%8); + } + con->updateFragmentation (FRAG_NOFRAG, 0, 0); //reset + break; + default: + fprintf (stderr,"Error, unknown fragmentation type\n"); + exit (-1); + } + //if we got an error, or it is a fragment that is not the last, free the packet + if (drop_pkt) { + //update drop stat + update_watch (&loss_watch_, 1); + Packet::free(pktRx_); + pktRx_=NULL; + return; + } + } + + switch (con->getType()) { + case CONN_INIT_RANGING: + scheduler_->process (pktRx_); + break; + case CONN_AAS_INIT_RANGING: + break; + case CONN_MULTICAST_POLLING: + break; + case CONN_PADDING: + //padding is sent by a SS that does not have data + //to send is required to send a signal. + //TBD: Find the SS that sent the padding + scheduler_->process (pktRx_); + break; + case CONN_BROADCAST: + if (HDR_CMN(pktRx_)->ptype()==PT_MAC) + scheduler_->process (pktRx_); + else { + //Richard: only send to upper layer if connected + if (state_ == MAC802_16_CONNECTED) + goto send_upper; + else { + //update drop stat, could be used to detect deconnection + update_watch (&loss_watch_, 1); + Packet::free(pktRx_); + pktRx_=NULL; + return; + } + } + break; + case CONN_BASIC: + scheduler_->process (pktRx_); + break; + case CONN_PRIMARY: + assert (HDR_CMN(pktRx_)->ptype()==PT_MAC); + //we cast to this frame because all management frame start with a type + if (wimaxHdr->header.ht==1) { + //bw request + scheduler_->process (pktRx_); + } else { + frame = (mac802_16_dl_map_frame*) pktRx_->accessdata(); + switch (frame->type) { + case MAC_DSA_REQ: + case MAC_DSA_RSP: + case MAC_DSA_ACK: + serviceFlowHandler_->process (pktRx_); + break; + default: + scheduler_->process (pktRx_); + } + } + break; + case CONN_SECONDARY: + //fall through + case CONN_DATA: + //send to upper layer + goto send_upper; + break; + default: + fprintf (stderr,"Error: unknown connection type\n"); + exit (0); + } + goto sent_mac; //default jump + + send_upper: + update_throughput (&rx_data_watch_, 8*ch->size()); + update_throughput (&rx_traffic_watch_, 8*ch->size()); + ch->size() -= HDR_MAC802_16_SIZE; + uptarget_->recv(pktRx_, (Handler*) 0); + goto done; + + sent_mac: + update_throughput (&rx_traffic_watch_, 8*ch->size()); + //fall through + + //should not free it here because we don't know if other modules + //kept a copy of it. + //Packet::free(pktRx_); + //update Rx stat + done: + update_watch (&loss_watch_, 0); + pktRx_=NULL; +} + +/**** Helper methods ****/ + +/** + * Return the frame number + * @return the frame number + */ +int Mac802_16::getFrameNumber () { + return frame_number_; +} + +/* + * Return the code for the frame duration + * @return the code for the frame duration + */ +int Mac802_16::getFrameDurationCode () { + if (macmib_.frame_duration == 0.0025) + return 0; + else if (macmib_.frame_duration == 0.004) + return 1; + else if (macmib_.frame_duration == 0.005) + return 2; + else if (macmib_.frame_duration == 0.008) + return 3; + else if (macmib_.frame_duration == 0.01) + return 4; + else if (macmib_.frame_duration == 0.0125) + return 5; + else if (macmib_.frame_duration == 0.02) + return 6; + else { + fprintf (stderr, "Invalid frame duration %f\n", macmib_.frame_duration); + exit (1); + } +} + +/* + * Set the frame duration using code + * @param code The frame duration code + */ +void Mac802_16::setFrameDurationCode (int code) +{ + switch (code) { + case 0: + macmib_.frame_duration = 0.0025; + break; + case 1: + macmib_.frame_duration = 0.004; + break; + case 2: + macmib_.frame_duration = 0.005; + break; + case 3: + macmib_.frame_duration = 0.008; + break; + case 4: + macmib_.frame_duration = 0.01; + break; + case 5: + macmib_.frame_duration = 0.0125; + break; + case 6: + macmib_.frame_duration = 0.02; + break; + default: + fprintf (stderr, "Invalid frame duration code %d\n", code); + exit (1); + } +} + + +/** + * Return a packet + * @return a new packet + */ +Packet *Mac802_16::getPacket () +{ + Packet *p = Packet::alloc (); + + hdr_mac802_16 *wimaxHdr= HDR_MAC802_16(p); + + //set header information + wimaxHdr->header.ht = 0; + wimaxHdr->header.ec = 1; + wimaxHdr->header.type = 0; //no subheader + wimaxHdr->header.ci = 0; + wimaxHdr->header.eks = 0; + wimaxHdr->header.cid = BROADCAST_CID; //default + wimaxHdr->header.hcs = 0; + HDR_CMN(p)->ptype() = PT_MAC; + + HDR_CMN(p)->size() = HDR_MAC802_16_SIZE; + + return p; +} + +/**** Internal methods ****/ + + +/* + * Add a classifier + * @param clas The classifier to add + */ +void Mac802_16::addClassifier (SDUClassifier *clas) +{ + SDUClassifier *n=classifier_list_.lh_first; + SDUClassifier *prev=NULL; + int i = 0; + if (!n || (n->getPriority () >= clas->getPriority ())) { + //the first element + //debug ("Add first classifier\n"); + clas->insert_entry_head (&classifier_list_); + } else { + while ( n && (n->getPriority () < clas->getPriority ()) ) { + prev=n; + n=n->next_entry(); + i++; + } + //debug ("insert entry at position %d\n", i); + clas->insert_entry (prev); + } + //Register this mac with the classifier + clas->setMac (this); +} + +#ifdef USE_802_21 + +/* + * Configure/Request configuration + * The upper layer sends a config object with the required + * new values for the parameters (or PARAMETER_UNKNOWN_VALUE). + * The MAC tries to set the values and return the new setting. + * For examples if a MAC does not support a parameter it will + * return PARAMETER_UNKNOWN_VALUE + * @param config The configuration object + */ +void Mac802_16::link_configure (link_parameter_config_t* config) +{ + assert (config); + config->bandwidth = 15000000; //TBD use phy (but depend on modulation) + config->type = LINK_802_16; + //we set the rest to PARAMETER_UNKNOWN_VALUE + config->ber = PARAMETER_UNKNOWN_VALUE; + config->delay = PARAMETER_UNKNOWN_VALUE; + config->macPoA = PARAMETER_UNKNOWN_VALUE; +} + +/* + * Disconnect from the PoA + */ +void Mac802_16::link_disconnect () +{ + if (type_ == STA_MN) { + //force losing synchronization + ((SSscheduler*) scheduler_)->lost_synch (); + getPhy()->node_off(); + } +} + +/* + * Connect to the PoA + */ +void Mac802_16::link_connect (int poa) +{ + if (type_ == STA_MN) { + getPhy()->node_on(); + } +} + +/* + * Configure the threshold values for the given parameters + * @param numLinkParameter number of parameter configured + * @param linkThresholds list of parameters and thresholds + */ +struct link_param_th_status * Mac802_16::link_configure_thresholds (int numLinkParameter, struct link_param_th *linkThresholds) +{ + struct link_param_th_status *result = (struct link_param_th_status *) malloc(numLinkParameter * sizeof (struct link_param_th_status)); + StatWatch *watch=NULL; + for (int i=0 ; i < numLinkParameter ; i++) { + result[i].parameter = linkThresholds[i].parameter; + result[i].status = 1; //accepted..default + switch (linkThresholds[i].parameter){ + case LINK_PACKET_LOSS: + watch = &loss_watch_; + break; + case LINK_PACKET_DELAY: + watch = &delay_watch_; + break; + case LINK_PACKET_JITTER: + watch = &jitter_watch_; + break; + case LINK_RX_DATA_THROUGHPUT: + watch = &rx_data_watch_; + break; + case LINK_RX_TRAFFIC_THROUGHPUT: + watch = &rx_traffic_watch_; + break; + case LINK_TX_DATA_THROUGHPUT: + watch = &tx_data_watch_; + break; + case LINK_TX_TRAFFIC_THROUGHPUT: + watch = &tx_traffic_watch_; + break; + default: + fprintf (stderr, "Parameter type not supported %d\n", linkThresholds[i].parameter); + result[i].status = 0; //rejected + } + watch->set_thresholds (linkThresholds[i].initActionTh.data_d, + linkThresholds[i].rollbackActionTh.data_d , + linkThresholds[i].exectActionTh.data_d); + } + return result; +} + +#endif + +/** + * Update the given timer and check if thresholds are crossed + * @param watch the stat watch to update + * @param value the stat value + */ +void Mac802_16::update_watch (StatWatch *watch, double value) +{ + char *name; + +#ifdef USE_802_21 //Switch to activate when using 802.21 modules (external package) + threshold_action_t action = watch->update (value); + + if (action != NO_ACTION_TH) { + link_parameter_t param; + union param_value old_value, new_value; + + if (watch == &loss_watch_) { + param = LINK_PACKET_LOSS; + } else if (watch == &delay_watch_) { + param = LINK_PACKET_DELAY; + } else if (watch == &jitter_watch_) { + param = LINK_PACKET_JITTER; + } + old_value.data_d = watch->old_average(); + new_value.data_d = watch->average(); + send_link_parameter_change (addr(), param, old_value, new_value); + } +#endif + + if (watch == &loss_watch_) { + name = "loss"; + } else if (watch == &delay_watch_) { + name = "delay"; + } else if (watch == &jitter_watch_) { + name = "jitter"; + } else { + name = "other"; + } + if (print_stats_) + printf ("At %f in Mac %d, updating stats %s: %f\n", NOW, addr(), name, watch->average()); +} + +/** + * Update the given timer and check if thresholds are crossed + * @param watch the stat watch to update + * @param value the stat value + */ +void Mac802_16::update_throughput (ThroughputWatch *watch, double size) +{ + char *name; + +#ifdef USE_802_21 //Switch to activate when using 802.21 modules (external package) + threshold_action_t action = watch->update (size, NOW); + if (action != NO_ACTION_TH) { + link_parameter_t param; + union param_value old_value, new_value; + if (watch == &rx_data_watch_) { + param = LINK_RX_DATA_THROUGHPUT; + } else if (watch == &rx_traffic_watch_) { + param = LINK_RX_TRAFFIC_THROUGHPUT; + } else if (watch == &tx_data_watch_) { + param = LINK_TX_DATA_THROUGHPUT; + } else if (watch == &tx_traffic_watch_) { + param = LINK_TX_TRAFFIC_THROUGHPUT; + } + old_value.data_d = watch->old_average(); + new_value.data_d = watch->average(); + send_link_parameter_change (addr(), param, old_value, new_value); + } +#endif + + if (watch == &rx_data_watch_) { + name = "rx_data"; + rx_data_timer_->resched (watch->get_timer_interval()); + } else if (watch == &rx_traffic_watch_) { + rx_traffic_timer_->resched (watch->get_timer_interval()); + name = "rx_traffic"; + } else if (watch == &tx_data_watch_) { + tx_data_timer_->resched (watch->get_timer_interval()); + name = "tx_data"; + } else if (watch == &tx_traffic_watch_) { + tx_traffic_timer_->resched (watch->get_timer_interval()); + name = "tx_traffic"; + } + + if (print_stats_) + printf ("At %f in Mac %d, updating stats %s: %f\n", NOW, addr(), name, watch->average()); + +} + + + + /// Added by Aymen + /** + * Return the station type (MN, BS, unknown) + */ + int Mac802_16::getStationType(){ + return type_; + } + /// \ Pas de fin de ligne à la fin du fichier. diff -Naur ns-2.29-original/wimax/mac802_16.h ns-2.29-new/wimax/mac802_16.h --- ns-2.29-original/wimax/mac802_16.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/mac802_16.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,605 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef MAC802_16_H +#define MAC802_16_H + +#include "sduclassifier.h" +#include "connectionmanager.h" +#include "serviceflowhandler.h" +#include "serviceflowqos.h" +#include "peernode.h" +#include "mac.h" +#include "mac802_16pkt.h" +#include "mac802_16timer.h" + +//Define new debug function for cleaner code +#ifdef DEBUG_WIMAX +#define debug2 printf +#else +#define debug2(arg1,...) +#endif + +#define BS_NOT_CONNECTED -1 //bs_id when MN is not connected + +#define DL_PREAMBLE 3 //preamble+fch +#define INIT_RNG_PREAMBLE 2 +#define BW_REQ_PREAMBLE 1 + + +/** Defines different types of nodes */ +enum station_type_t { + STA_UNKNOWN, + STA_MN, + STA_BS +}; + +/** Defines the state of the MAC */ +enum Mac802_16State { + MAC802_16_DISCONNECTED, + MAC802_16_WAIT_DL_SYNCH, + MAC802_16_WAIT_DL_SYNCH_DCD, + MAC802_16_UL_PARAM, + MAC802_16_RANGING, + MAC802_16_WAIT_RNG_RSP, + MAC802_16_REGISTER, + MAC802_16_SCANNING, + MAC802_16_CONNECTED +}; + +/** Data structure to store MAC state */ +struct state_info { + Mac802_16State state; + int bs_id; + double frameduration; + int frame_number; + int channel; + ConnectionManager * connectionManager; + ServiceFlowHandler * serviceFlowHandler; + struct peerNode *peer_list; +}; + +/** Defines profiles */ +struct phyprofile { + int nb_channel; //number of valid channel in the array + int current; //index of the channel currently used + double freq[]; //list of channel frequencies +}; + +/** MAC MIB */ +class Mac802_16MIB { + public: + Mac802_16MIB (Mac802_16 *parent); + + int queue_length; + double frame_duration; + + double dcd_interval; + double ucd_interval; + double init_rng_interval; + double lost_dlmap_interval; + double lost_ulmap_interval; + + double t1_timeout; + double t2_timeout; + double t3_timeout; + double t6_timeout; + double t12_timeout; + double t16_timeout; + double t17_timeout; + double t21_timeout; + double t44_timeout; + + u_int32_t contention_rng_retry; + u_int32_t invited_rng_retry; + u_int32_t request_retry; + u_int32_t reg_req_retry; + double tproc; + u_int32_t dsx_req_retry; + u_int32_t dsx_rsp_retry; + + u_int32_t rng_backoff_start; + u_int32_t rng_backoff_stop; + u_int32_t bw_backoff_start; + u_int32_t bw_backoff_stop; + + //mobility extension + u_int32_t scan_duration; + u_int32_t interleaving; + u_int32_t scan_iteration; + u_int32_t max_dir_scan_time; + double nbr_adv_interval; + u_int32_t scan_req_retry; + + //miscalleous + double rxp_avg_alpha; //for measurements + double lgd_factor_; + double RXThreshold_; + double client_timeout; //used to clear information on BS side +}; + +/** PHY MIB */ +class Phy802_16MIB { + public: + Phy802_16MIB (Mac802_16 *parent); + + int channel; //current channel + double fbandwidth; + u_int32_t ttg; + u_int32_t rtg; +}; + +class WimaxScheduler; +class FrameMap; +class StatTimer; +/** + * Class implementing IEEE 802_16 + */ +class Mac802_16 : public Mac { + + friend class PeerNode; + friend class SDUClassifier; + friend class WimaxFrameTimer; + friend class FrameMap; + friend class WimaxScheduler; + friend class BSScheduler; + friend class SSscheduler; + friend class ServiceFlowHandler; + friend class Connection; + friend class StatTimer; + public: + + Mac802_16(); + + /** + * Return the connection manager + * @return the connection manager + */ + inline ConnectionManager * getCManager () { return connectionManager_; } + + /** + * Return The Service Flow handler + * @return The Service Flow handler + */ + inline ServiceFlowHandler * getServiceHandler () { return serviceFlowHandler_; } + + /** + * Return the Scheduler + * @return the Scheduler + */ + inline WimaxScheduler * getScheduler () { return scheduler_; } + + /** + * Return the frame duration (in s) + * @return the frame duration (in s) + */ + double getFrameDuration () { return macmib_.frame_duration; } + + /** + * Set the frame duration + * @param duration The frame duration (in s) + */ + void setFrameDuration (double duration) { macmib_.frame_duration = duration; } + + /** + * Return the current frame number + * @return the current frame number + */ + int getFrameNumber (); + + /** + * Add a flow + * @param qos The QoS required + * @param handler The entity that requires to add a flow + */ + void addFlow (ServiceFlowQoS * qos, void * handler); + + /** + * Return the head of the peer nodes list + * @return the head of the peer nodes list + */ + PeerNode * getPeerNode_head () { return peer_list_->lh_first; } + + /** + * Return the peer node that has the given address + * @param index The address of the peer + * @return The peer node that has the given address + */ + PeerNode *getPeerNode (int index); + + /** + * Add the peer node + * @param The peer node to add + */ + void addPeerNode (PeerNode *node); + + /** + * Remove a peer node + * @param The peer node to remove + */ + void removePeerNode (PeerNode *node); + + /** + * Interface with the TCL script + * @param argc The number of parameter + * @param argv The list of parameters + */ + int command(int argc, const char*const* argv); + + /** + * Set the mac state + * @param state The new mac state + */ + void setMacState (Mac802_16State state); + + /** + * Return the mac state + * @return The new mac state + */ + Mac802_16State getMacState (); + + /** + * Change the channel + * @param channel The new channel + */ + void setChannel (int channel); + + /** + * Return the channel index + * @return The channel + */ + int getChannel (); + + /** + * Return the channel number for the given frequency + * @param freq The frequency + * @return The channel number of -1 if the frequency does not match + */ + int getChannel (double freq); + + /** + * Set the channel to the next from the list + * Used at initialisation and when loosing signal + */ + void nextChannel (); + + /** + * Process packets going out + * @param p The packet to transmit + */ + void sendDown(Packet *p); + + /** + * Process packets going out + * @param p The packet to transmit + */ + void transmit(Packet *p); + + /** + * Process incoming packets + * @param p The received packet + */ + void sendUp(Packet *p); + + /** + * Process the packet after receiving last bit + */ + void receive(); + + /** + * Creates a snapshot of the MAC's state and reset it + * @return The snapshot of the MAC's state + */ + state_info *backup_state (); + + /** + * Restore the state of the Mac + * @param state The state to restore + */ + void restore_state (state_info *state); + + /** + * Set the variable used to find out if upper layers + * must be notified to send packets. During scanning we + * do not want upper layers to send packet to the mac. + * @param notify Value indicating if we want to receive packets + * from upper layers + */ + void setNotify_upper (bool notify); + + /** + * Return the PHY layer + * @return The physical layer + */ + OFDMPhy* getPhy (); + + /** + * The MAC MIB + */ + Mac802_16MIB macmib_; + + /** + * The Physical layer MIB + */ + Phy802_16MIB phymib_; + +#ifdef USE_802_21 //Switch to activate when using 802.21 modules (external package) + /* + * Configure/Request configuration + * The upper layer sends a config object with the required + * new values for the parameters (or PARAMETER_UNKNOWN_VALUE). + * The MAC tries to set the values and return the new setting. + * For examples if a MAC does not support a parameter it will + * return PARAMETER_UNKNOWN_VALUE + * @param config The configuration object + */ + void link_configure (link_parameter_config_t* config); + + /* + * Configure the threshold values for the given parameters + * @param numLinkParameter number of parameter configured + * @param linkThresholds list of parameters and thresholds + */ + struct link_param_th_status * link_configure_thresholds (int numLinkParameter, struct link_param_th *linkThresholds); //configure threshold + + /* + * Disconnect from the PoA + */ + void link_disconnect (); + + /* + * Connect to the PoA + * @param poa The address of PoA + */ + void link_connect (int poa); + +#endif + + + + /// Added by Aymen + /** + * Return the station type + */ + int getStationType(); + /// + + + + + protected: + /** + * Initialize default connection + */ + void init_default_connections (); + + /** + * The packet scheduler + */ + WimaxScheduler * scheduler_; + + /** + * Return a new allocated packet + * @return A newly allocated packet + */ + Packet * getPacket(); + + /* + * Return the code for the frame duration + * @return the code for the frame duration + */ + int getFrameDurationCode (); + + /* + * Set the frame duration using code + * @param code The frame duration code + */ + void setFrameDurationCode (int code); + + /** + * Current frame number + */ + int frame_number_; + + /** + * Statistics for queueing delay + */ + StatWatch delay_watch_; + + /** + * Delay for last packet + */ + double last_tx_delay_; + + /** + * Statistics for delay jitter + */ + StatWatch jitter_watch_; + + /** + * Stats for packet loss + */ + StatWatch loss_watch_; + + /** + * Stats for incoming data throughput + */ + ThroughputWatch rx_data_watch_; + + /** + * Stats for incoming traffic throughput (data+management) + */ + ThroughputWatch rx_traffic_watch_; + + + /** + * Stats for outgoing data throughput + */ + ThroughputWatch tx_data_watch_; + + /** + * Stats for outgoing traffic throughput (data+management) + */ + ThroughputWatch tx_traffic_watch_; + + /** + * Timers to continuously poll stats in case it is not updated by + * sending or receiving packets + */ + StatTimer *rx_data_timer_; + StatTimer *rx_traffic_timer_; + StatTimer *tx_data_timer_; + StatTimer *tx_traffic_timer_; + + /** + * Indicates if the stats must be printed + */ + int print_stats_; + + /** + * Update the given timer and check if thresholds are crossed + * @param watch the stat watch to update + * @param value the stat value + */ + void update_watch (StatWatch *watch, double value); + + /** + * Update the given timer and check if thresholds are crossed + * @param watch the stat watch to update + * @param size the size of packet received + */ + void update_throughput (ThroughputWatch *watch, double size); + +#ifdef USE_802_21 //Switch to activate when using 802.21 modules (external package) + /** + * Poll the given stat variable to check status + * @param type The link parameter type + */ + void poll_stat (link_parameter_t type); +#endif + + private: + /** + * The list of classifier + */ + struct sduClassifier classifier_list_; + + /** + * List of connected peer nodes. Only one for SSs. + */ + struct peerNode *peer_list_; + + /** + * The class to handle connections + */ + ConnectionManager * connectionManager_; + + /** + * The module that handles flow requests + */ + ServiceFlowHandler * serviceFlowHandler_; + + /** + * Packet being received + */ + Packet *pktRx_; + + /** + * A packet buffer used to temporary store a packet + * received by upper layer. Used during scanning + */ + Packet *pktBuf_; + + /** + * Add a classifier + */ + void addClassifier (SDUClassifier *); + + + + /** + * Set the node type + * @param type The station type + */ + void setStationType (station_type_t type); + + /* + * The type of station (MN or BS) + */ + station_type_t type_; + + /* + * Address of the Base Station. If STA is BS then equal index_ + */ + int bs_id_; + + /* + * The state of the MAC + */ + Mac802_16State state_; + + /** + * Receiving timer + */ + WimaxRxTimer rxTimer_; + + /** + * Indicates if a collision occured + */ + bool collision_; + + /** + * Indicate if upper layer must be notified to send more packets + */ + bool notify_upper_; + + /** + * Last time a packet was sent + */ + double last_tx_time_; + + /** + * Last transmission duration + */ + double last_tx_duration_; + +}; + +/** Class to poll stats */ +class StatTimer : public TimerHandler { + public: + StatTimer (Mac802_16 *mac, ThroughputWatch *watch) : TimerHandler() { + mac_ = mac; + watch_ = watch; + timer_interval_ = 0.1; //default 100ms + resched (timer_interval_); + } + void expire (Event *) { + mac_->update_throughput (watch_, 0); + //double tmp = watch_->get_timer_interval(); + //resched(tmp > 0? tmp: timer_interval_); + } + inline void set_timer_interval(double ti) { timer_interval_ = ti; } + private: + Mac802_16 *mac_; + ThroughputWatch *watch_; + double timer_interval_; +}; + +#endif //MAC802_16_H + diff -Naur ns-2.29-original/wimax/mac802_16pkt.cc ns-2.29-new/wimax/mac802_16pkt.cc --- ns-2.29-original/wimax/mac802_16pkt.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/mac802_16pkt.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,171 @@ +/* This class contains helpers for manipulating 802.16 messages + * and getting the packet size. + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "mac802_16pkt.h" + +/** + * Return the size of the MOB_NBR-ADV frame + * @param frame The frame + */ +int Mac802_16pkt::getMOB_NBR_ADV_size(mac802_16_mob_nbr_adv_frame *frame) +{ + int size = 4; //min size + if ((frame->skip_opt_field & 0x1) == 0) + size +=3; //add operator id + + for (int i = 0 ; i < frame->n_neighbors ; i++) { + size += 4; //min size for neighbor info + if (frame->nbr_info[i].phy_profile_id.FAindex & 0x1) + size++; + if (frame->nbr_info[i].phy_profile_id.bs_eirp & 0x1) + size++; + if ((frame->skip_opt_field & 0x2) == 0) + size +=3; //contain neighbor bs id + if ((frame->skip_opt_field & 0x4) == 0) + size ++; //contain HO process optimization + if ((frame->skip_opt_field & 0x8) == 0) + size ++; //contain neighbor bs id + if (frame->nbr_info[i].dcd_included) + size += 2+GET_DCD_SIZE (frame->nbr_info[i].dcd_settings.nb_prof); + if (frame->nbr_info[i].ucd_included) + size += 2+GET_UCD_SIZE (frame->nbr_info[i].ucd_settings.nb_prof); + if (frame->nbr_info[i].phy_included) + size += 2; + } + + return size; +} + +/** + * Return the size of the MOB_SCN-REQ + * @param frame The frame + */ +int Mac802_16pkt::getMOB_SCN_REQ_size(mac802_16_mob_scn_req_frame *frame) +{ + int size=6; + + if (frame->n_recommended_bs_index != 0) + size ++; + int tmp = 11*(frame->n_recommended_bs_index+frame->n_recommended_bs_full); + size += tmp/8; + if ((tmp%8)!=0) + size ++; + + return size; +} + +/** + * Return the size of the MOB_SCN-RSP + * @param frame The frame + */ +int Mac802_16pkt::getMOB_SCN_RSP_size(mac802_16_mob_scn_rsp_frame *frame) +{ + int size=6; + + if (frame->scan_duration!=0) { + size += 3; + if (frame->n_recommended_bs_index!=0) + size ++; + int tmp = 0; + for (int i = 0 ; i < frame->n_recommended_bs_index ; i++) { + tmp+=11; + if (frame->rec_bs_index[i].scanning_type==2 || + frame->rec_bs_index[i].scanning_type==3) + tmp+=24; + } + for (int i = 0 ; i < frame->n_recommended_bs_index ; i++) { + tmp+=51; + if (frame->rec_bs_index[i].scanning_type==2 || + frame->rec_bs_index[i].scanning_type==3) + tmp+=24; + } + size += tmp/8; + if ((tmp%8)!=0) + size ++; + } + + return size; +} + +/** + * Return the size of the MOB_MSHO-REQ + * @param frame The frame + */ +int Mac802_16pkt::getMOB_MSHO_REQ_size(mac802_16_mob_msho_req_frame *frame) +{ + int size=4; + int tmp, tmpB; + + tmp = 0; + tmpB = 0; + + if (frame->n_new_bs_index !=0) + size++; + + if (frame->report_metric & 0x1) tmp++; + if (frame->report_metric & 0x2) tmp++; + if (frame->report_metric & 0x4) tmp++; + + for (int i = 0 ; i < frame->n_new_bs_index ; i++) { + tmpB += 20 + 8*tmp; + if (frame->bs_index[i].arrival_time_diff_ind & 0x1) + tmpB += 4; + } + //n_new_bs_full + for (int i = 0 ; i < frame->n_new_bs_full ; i++) { + tmpB += 20 + 8*tmp; + if (frame->bs_full[i].arrival_time_diff_ind & 0x1) + tmpB += 4; + } + tmpB += 4; + //N_current + if (frame->report_metric & 0x8) tmp++; + for (int i = 0 ; i < frame->n_current_bs ; i++) { + tmpB += 4 + 8*tmp; + } + //increase size + size += tmp/8; + if ((tmp%8)!=0) + size ++; //includes padding + + return size; +} + +/** + * Return the size of the MOB_MSHO-REQ + * @param frame The frame + */ +int Mac802_16pkt::getMOB_BSHO_RSP_size(mac802_16_mob_bsho_rsp_frame *frame) +{ + int size=4; + + return size; +} + +/** + * Return the size of the MOB_HO-IND + * @param frame The frame + */ +int Mac802_16pkt::getMOB_HO_IND_size(mac802_16_mob_ho_ind_frame *frame) +{ + int size=4; + + return size; +} diff -Naur ns-2.29-original/wimax/mac802_16pkt.h ns-2.29-new/wimax/mac802_16pkt.h --- ns-2.29-original/wimax/mac802_16pkt.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/mac802_16pkt.h 2008-07-02 11:52:42.000000000 +0200 @@ -0,0 +1,931 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef MAC802_16PKT_H +#define MAC802_16PKT_H + +#include "packet.h" +#include "ofdmphy.h" +#include "serviceflow.h" + +//#define HDR_MAC802_16(p) ((hdr_mac802_16 *)hdr_mac::access(p)) +#define HDR_MAC802_16(p) (hdr_mac802_16::access(p)) +#define HDR_MAC802_16_SIZE 6 +#define HDR_MAC802_16_FRAGSUB_SIZE 2 + +/** Define fragmentation encoding */ +enum fragment_status { + FRAG_NOFRAG = 0, + FRAG_LAST, + FRAG_FIRST, + FRAG_CONT +}; + +/** Define Mac management type */ +enum mngmt_type { + MAC_UCD = 0, + MAC_DCD, + MAC_DL_MAP, + MAC_UL_MAP, + MAC_RNG_REQ, + MAC_RNG_RSP, + MAC_REG_REQ, + MAC_REG_RSP, + // 8: reserved + // 9-10: Privacy key, not used + MAC_DSA_REQ=11, + MAC_DSA_RSP, + MAC_DSA_ACK, + + MAC_MOB_NBR_ADV=53, + MAC_MOB_SCN_REQ, + MAC_MOB_SCN_RSP, + MAC_MOB_BSHO_REQ, + MAC_MOB_MSHO_REQ, + MAC_MOB_BSHO_RSP, + MAC_MOB_HO_IND, + MAC_MOB_SCN_REP, + MAC_MOB_ASC_REP=66 +}; + +/** Enumeration of scanning types */ +enum wimax_scanning_type { + SCAN_WITHOUT_ASSOC, + SCAN_ASSOC_LVL0, + SCAN_ASSOC_LVL1, + SCAN_ASSOC_LVL2 +}; + +/** Structure containing physical layer information */ +struct phy_info_t { + double freq_; //the frequency at which it is sent + Ofdm_mod_rate modulation_; //modulation at which the packet was sent + double g_; //The cyclic prefix information. Used for synchronization +}; + +/** Define generic MAC header */ +struct gen_mac_header_t { + u_char ht : 1; + u_char ec : 1; + u_char type : 6; + u_char rsv1: 1; + u_char ci: 1; + u_char eks: 2; + u_char rsv2: 1; + u_int16_t len: 11; + u_int16_t cid; + u_char hcs; +}; + +/** Define bandwidth request header */ +struct bw_req_header_t { + u_char ht : 1; + u_char ec : 1; + u_char type : 3; + u_int32_t br : 19; + u_int16_t cid; + u_char hcs; +}; + +/** Define structure for packet information */ +struct hdr_mac802_16 +{ + //virtual info for physical layer + phy_info_t phy_info; + + //generic mac header or bw request header + gen_mac_header_t header; + + //check how to put the subheaders (piggyback) + bool frag_subheader; //set to true if there is a fragmentation subheader + char fc : 2; //00:no fragmentation, 01:last, 10: first, 11: middle + char fsn : 3; //fragmentation number + + //for management frames, we put + //payload in the packet payload + //because the size changes + + //Packet header access functions + static int offset_; + inline static int& offset() {return offset_;} + inline static hdr_mac802_16* access(const Packet* p) + { + return (hdr_mac802_16*) p->access(offset_); + } +}; + +/**** Defines some constant for the maximum size of messages ****/ +/* When sending a packet, the message is copied for each + * destination. In that case, we need to store all the information + * in the packet itself and not use pointer. We then use arrays. + */ +#define MAX_MAP_IE 50 +#define MAX_PROFILE 10 +#define MAX_NBR 10 + +/**** Defines IEs ****/ +/** Defines DL_MAP IE (see p462.) */ +struct mac802_16_dlmap_ie { + u_int16_t cid; + u_char diuc : 4; //p463 + u_char preamble : 1; + u_int16_t start_time : 11; + //may contain extended info +}; +#define DL_MAP_IE_SIZE 4 + +/** fast Ranging IE (802.16e) */ +struct mac802_16_fast_ranging_ie { + int mac_addr; //48 bits + u_char uiuc : 4; + u_int16_t duration : 12; //in OFDM symbols +}; +#define FAST_RANGING_IE_SIZE 9 + +/** Defines UL_MAP IE (see p464.) */ +struct mac802_16_ulmap_ie { + u_int16_t cid; + u_int16_t start_time : 11; + u_char sub_channel_index : 5; + u_char uiuc : 4; + u_int16_t duration : 11; + u_char midamble_rep : 2; + //may contain additional info depending on uiuc + u_char extended_uiuc : 4; + u_char length : 4; + mac802_16_fast_ranging_ie fast_ranging; +}; +#define UL_MAP_IE_SIZE 6 + +/**** Defines burst profiles ****/ + +/* Burst profiles are TLV encoded...we just pick the info we + * are interested in. + */ +/** Defines DCD profile */ +struct mac802_16_dcd_profile { + u_char diuc : 4; + u_int32_t frequency; + u_char fec; + //may have more info +}; +#define DCD_PROFILE_SIZE 12 + +/** Defines UCD profile */ +struct mac802_16_ucd_profile { + u_char uiuc : 4; + u_char fec; + //may have more info +}; +#define UCD_PROFILE_SIZE 6 + +/**** Defines frames ****/ +/** DCD frame */ +struct mac802_16_dcd_frame { + u_char type; + u_char dcid; + u_char config_change_count; + //info for all channels: TLV encoded + u_char frame_duration_code; + u_int32_t frame_number : 24; + u_char ttg; + u_char rtg; + u_int32_t frequency; + //downlink burst profiles + u_int32_t nb_prof; + mac802_16_dcd_profile profiles[MAX_PROFILE]; +}; + +//+3 for the end of map profile +#define GET_DCD_SIZE(X) 22+X*DCD_PROFILE_SIZE+3 + +/** DL_MAP frame */ +struct mac802_16_dl_map_frame { + u_char type; + u_char dcd_count; + int bsid; //normaly 48 bits + //DL_MAP IEs + u_int32_t nb_ies; + mac802_16_dlmap_ie ies[MAX_MAP_IE]; +}; + +//there is X IEs +#define GET_DL_MAP_SIZE(X) 8+X*DL_MAP_IE_SIZE + +/** UCD frame */ +struct mac802_16_ucd_frame { + u_char type; + u_char config_change_count; + u_char rng_backoff_start; + u_char rng_backoff_end; + u_char req_backoff_start; + u_char req_backoff_end; + //info for overall channel + /* + u_int16_t rsv_timeout; + */ + u_int16_t bw_req_size; + u_int16_t rng_req_size; + //uplink burst profile + u_int32_t nb_prof; + mac802_16_ucd_profile profiles[MAX_PROFILE]; +}; + +//+3 for the end of map profile +#define GET_UCD_SIZE(X) 14+X*UCD_PROFILE_SIZE+3 + +/** UL_MAP frame */ +struct mac802_16_ul_map_frame { + u_char type; + u_char ucid; + u_char ucd_count; + u_int32_t allocation_start; + //UL_MAP IEs + u_int32_t nb_ies; + mac802_16_ulmap_ie ies[MAX_MAP_IE]; +}; + +#define GET_UL_MAP_SIZE(X) 7+X*UL_MAP_IE_SIZE + +/**** Defines ranging messages ****/ +/** Ranging request frame */ +struct mac802_16_rng_req_frame { + u_char type; + u_char dc_id; + /*TLV values*/ + /* Requested Downlink Burst Profile + * bits 0-3: DIUC of the downlink burst profile + * bits 4-7: LSB of Configuration Change Count value + * of DCD defining the burst profile assocciated with DIUC + */ + u_char req_dl_burst_profile; + int ss_mac_address; //should be 6 bytes + //u_char aas_bc_cap; //broadcast capability. optional +}; +#define RNG_REQ_SIZE 13 //max value + +/** Ranging status */ +enum ranging_status { + RNG_CONTINUE = 1, + RNG_ABORT, + RNG_SUCCESS, + RNG_RERANGE +}; + +/** Ranging response frame */ +struct mac802_16_rng_rsp_frame { + u_char type; + u_char uc_id; + /*TLV values*/ + u_char pw_adjust; + u_int32_t freq_adjust; + u_char rng_status; + /* byte 0: the least robust DIUC that may be used by BS for + * transmissions to the SS + * byte 1: Configuration Change Count of DCD defining the burst profile + * associated with DIUC + */ + u_int16_t dl_op_burst_profile; + int ss_mac_address; //6 bytes + u_int16_t basic_cid; + u_int16_t primary_cid; + u_char aas_bc_perm; +}; +#define RNG_RSP_SIZE 28 + +/**** Defines registration messages ****/ +/** Registration request frame */ +struct mac802_16_reg_req_frame { + u_char type; + /*TLV values*/ + u_char ss_mngmt_support; + u_char ip_mngmt_support; + u_int16_t uplink_cid_support; + +}; +#define REG_REQ_SIZE 12 + +/** Registration response frame */ +struct mac802_16_reg_rsp_frame { + u_char type; + u_char response; + /*TLV values*/ + u_char ss_mngmt_support; + u_int16_t sec_mngmt_cid; +}; +#define REG_RSP_SIZE 12 + +/**** Defines Dynamic Service Addition messages ****/ +/** DSA request frame */ +struct mac802_16_dsa_req_frame { + u_char type; //11 + u_int16_t transaction_id; + /*TLV values*/ + bool uplink; //direction of the flow, normaly coded in TLV with + //type 145 or 146 (see p647). + u_int16_t cid; + + + + /// Added by Aymen + ServiceFlow * serviceflow; + /// +}; +//parameter X indicates if cid is present (i.e request from BS) +#define GET_DSA_REQ_SIZE(X) 6+4*X + + +/// Added by Aymen +// type transaction_id service_flow_parameter uplink/downlink_encodings +#define GET_DSA_REQ_SIZE1 1+2+24+2 +// type transaction_id confirmation_code service_flow_parameter uplink/downlink_encodings +#define GET_DSA_RSP_SIZE1 1+2+1+24+2 +/// + + + +/** DSA response frame */ +struct mac802_16_dsa_rsp_frame { + u_char type; //12 + u_int16_t transaction_id; + u_char confirmation_code; + /*TLV values*/ + bool uplink; //direction of the flow, normaly coded in TLV with + //type 145 or 146 (see p647). + u_int16_t cid; + + + + /// Added by Aymen + ServiceFlow * serviceflow; + /// +}; +//parameter X indicates if cid is present (i.e response from BS) +#define GET_DSA_RSP_SIZE(X) 6+4*X + +/** DSA Acknowledgement frame */ +struct mac802_16_dsa_ack_frame { + u_char type; //13 + u_int16_t transaction_id; + u_char confirmation_code; + /*TLV values*/ + bool uplink; //direction of the flow, normaly coded in TLV with + //type 145 or 146 (see p647). +}; +#define DSA_ACK_SIZE 6 + + +/**** Defines Mobility messages (802.16e) ****/ +/** Structure of physical profile ID */ +struct mac802_16_phy_profile_id { + u_char colocatedFA: 1; + u_char FAconfig: 1; + u_char timefreq_synch: 2; + u_char bs_eirp: 1; + u_char dcducd_ref: 1; + u_char FAindex: 1; + u_char trigger_ref: 1; +}; + +/** Structure of physical mode ID */ +struct mac802_16_phy_mode_id { + u_char bandwidth: 7; + u_char fttsize: 3; + u_char cp: 2; + u_char duration_code: 4; +}; + +/** Information about a neighbor BS */ +struct mac802_16_nbr_adv_info { + u_char length; + mac802_16_phy_profile_id phy_profile_id; + u_char fa_index; //if FA index indicator=1 in phy_profile_id + u_char bs_eirp; + int nbr_bsid; + u_char preamble_index; //in OFDM, 5lsb= + u_char ho_process_opt; + u_char sched_srv_supported; + u_char dcd_ccc: 4; + u_char ucd_ccc: 4; + /* other TLV information */ + bool dcd_included; //tell if the dcd is included + mac802_16_dcd_frame dcd_settings; + bool ucd_included; //tell if the ucd is included + mac802_16_ucd_frame ucd_settings; + bool phy_included; //tell if the phy mode ID is included + mac802_16_phy_mode_id phy_mode_id; +}; + +/** Neighbor advertisment frame */ +struct mac802_16_mob_nbr_adv_frame { + u_char type; //53 + u_char skip_opt_field; + u_int32_t operatorID: 24; + u_char ccc; + u_char frag_index: 4; + u_char total_frag: 4; + u_char n_neighbors; //number of neighbors + mac802_16_nbr_adv_info nbr_info[MAX_NBR]; +}; + +/** Code BS using index in scan request */ +struct mac802_16_mob_scn_req_bs_index { + u_char neighbor_bs_index; + u_char scanning_type: 3; //0: scanning without association + //1: scanning+assoc level 0 + //2: scanning+assoc level 1 + //3: scanning+assoc level 2 + //4-7: reserved +}; + +/** Code BS using full address in scan request */ +struct mac802_16_mob_scn_req_bs_full { + int recommended_bs_id; /* 6 bytes */ + u_char scanning_type: 3; //0: scanning without association + //1: scanning+assoc level 0 + //2: scanning+assoc level 1 + //3: scanning+assoc level 2 + //4-7: reserved +}; + +/** Scan request frame */ +struct mac802_16_mob_scn_req_frame { + u_char type; //54 + u_char scan_duration; //units of frames + u_char interleaving_interval; //units of frames + u_char scan_iteration; //in frame + u_char n_recommended_bs_index; //number of BS recommended + u_char ccc; //present if n_recommended_bs_index!= 0 + mac802_16_mob_scn_req_bs_index rec_bs_index[MAX_NBR]; + u_char n_recommended_bs_full; + mac802_16_mob_scn_req_bs_full rec_bs_full[MAX_NBR]; + /* TLV info*/ +}; + +/** Code BS using index in scan response */ +struct mac802_16_mob_scn_rsp_bs_index { + u_char neighbor_bs_index; + u_char scanning_type: 3; //0: scanning without association + //1: scanning+assoc level 0 + //2: scanning+assoc level 1 + //3: scanning+assoc level 2 + //4-7: reserved + /* next present if scanning is 2 or 3*/ + u_char rdv_time; + u_char cdma_code; + u_char transmission_opp_offset; +}; + +/** Code BS using full address in scan response */ +struct mac802_16_mob_scn_rsp_bs_full { + int recommended_bs_id; /* 6 bytes */ + u_char scanning_type: 3; //0: scanning without association + //1: scanning+assoc level 0 + //2: scanning+assoc level 1 + //3: scanning+assoc level 2 + //4-7: reserved + /* next present if scanning is 2 or 3*/ + u_char rdv_time; + u_char cdma_code; + u_char transmission_opp_offset; +}; + +/** Scan response frame */ +struct mac802_16_mob_scn_rsp_frame { + u_char type; //55 + u_char scan_duration; //units of frames + u_char report_mode: 2; + u_char report_period; + u_char report_metric; + /*next information present only if scan duration !=0*/ + u_char start_frame: 4; + u_char interleaving_interval; + u_char scan_iteration; + u_char n_recommended_bs_index; + //next if n_recommended_bs_index !=0 + u_char ccc_mob_nbr_adv; + mac802_16_mob_scn_rsp_bs_index rec_bs_index[MAX_NBR]; + u_char n_recommended_bs_full; + mac802_16_mob_scn_rsp_bs_full rec_bs_full[MAX_NBR]; + /* end if scan duration !=0 */ + /* TLV information */ +}; + +/** Measurements about current BS */ +struct mac802_16_mob_scn_rep_current_bs { + u_char temp_bsid: 4; + u_char bs_cinr_mean; //if report_metric[0]==1 + u_char bs_rssi_mean; //if report_metric[1]==1 + u_char relative_delay; //if report_metric[2]==1 + u_char bs_rtd; //if report_metric[3]==1 +}; + +/** Measurements about neighbor BS using index */ +struct mac802_16_mob_scn_rep_bs_index { + u_char neighbor_bs_index; + u_char bs_cinr_mean; //if report_metric[0]==1 + u_char bs_rssi_mean; //if report_metric[1]==1 + u_char relative_delay; //if report_metric[2]==1 +}; + +/** Measurements about neighbor BS using full address */ +struct mac802_16_mob_scn_rep_bs_full { + int neighbor_bs_id; /* 6 bytes */ + u_char bs_cinr_mean; //if report_metric[0]==1 + u_char bs_rssi_mean; //if report_metric[1]==1 + u_char relative_delay; //if report_metric[2]==1 +}; + +/** Scan report frame */ +struct mac802_16_mob_scn_rep_frame { + u_char type; //60 + u_char report_mode: 1; + u_char comp_nbr_bsid_ind: 1; + u_char n_current_bs: 3; + u_char report_metric: 8; + mac802_16_mob_scn_rep_current_bs current_bs[MAX_NBR]; + u_char n_neighbor_bs_index; + //next if n_recommended_bs_index !=0 + u_char ccc_mob_nbr_adv; + mac802_16_mob_scn_rep_bs_index nbr_bs_index[MAX_NBR]; + u_char n_recommended_bs_full; + mac802_16_mob_scn_rep_bs_full nbr_bs_full[MAX_NBR]; + /* other TLV information */ +}; + +/** Code BS using index in association result report */ +struct mac802_16_mob_asc_rep_bs_index { + u_char neighbor_bs_index; + uint32_t timing_adjust; + u_char power_level_adjust; + uint32_t offset_freq_adjust; + u_char rng_status; + u_char service_level_prediction; +}; + +/** Code BS using address in association result report */ +struct mac802_16_mob_asc_rep_bs_full { + int neighbor_bs_id; /* 6 bytes */ + uint32_t timing_adjust; + u_char power_level_adjust; + uint32_t offset_freq_adjust; + u_char rng_status; + u_char service_level_prediction; +}; + +/** Association result report frame */ +struct mac802_16_mob_asc_rep_frame { + u_char type; //66 + u_char n_recommended_bs_index; + //next if n_recommended_bs_index !=0 + u_char ccc_mob_nbr_adv; + mac802_16_mob_asc_rep_bs_index rec_bs_index[MAX_NBR]; + u_char n_recommended_bs_full; + mac802_16_mob_asc_rep_bs_full rec_bs_full[MAX_NBR]; +}; + +/** Code request in mode 000 (HO request) */ +struct mac802_16_mob_bsho_req_mode_000 { + int neighbor_bsid; /* 6 bytes */ + u_char service_level_prediction; + u_char preamble_index; + u_char ho_process_optimization; + u_char net_assisted_ho_supported: 1; + u_char ho_id_included_indicator: 1; + u_char ho_autho_policy_indicator: 1; + //if ho_id_included_indicator==1 + u_char ho_id; + //if ho_autho_policy_indicator==1 + u_char ho_autho_policy_support; +}; + +/** Structure for BSHO request */ +struct mac802_16_mob_bsho_req_mode_new_bs { + int neighbor_bsid; /* 6 bytes */ + u_char temp_bsid: 3; + +}; + +/** Structure for BSHO request */ +struct mac802_16_mob_bsho_req_mode_new_bs2 { + int neighbor_bsid; /* 6 bytes */ + u_char temp_bsid: 3; + uint16_t new_cid[MAX_NBR]; + uint16_t new_said[MAX_NBR]; + +}; + +/** Structure for BSHO request */ +struct mac802_16_mob_bsho_req_mode_new_bs3 { + int neighbor_bsid; /* 6 bytes */ + u_char temp_bsid: 3; + uint16_t new_cid[MAX_NBR]; + uint16_t new_said[MAX_NBR]; + int cqich_id; //variable + u_char feedback_channel_off: 6; + u_char period: 2; + u_char frame_offset: 3; + u_char duration: 3; + u_char mimo_permutation_feedback: 2; +}; + +/** Structure for BSHO request */ +struct mac802_16_mob_bsho_req_mode_current_bs { + u_char temp_bsid: 3; +}; + +/** BSHO request frame */ +struct mac802_16_mob_bsho_req_frame { + u_char type; //56 + u_char net_assisted_ho_supported: 1; + u_char mode: 3; + //if mode == 0b000 + u_char ho_op_mode: 1; + u_char n_recommended; + u_char resource_retain_flag: 1; + mac802_16_mob_bsho_req_mode_000 n_rec[]; + //if mode == 0b001 + u_char tmp_bsid: 3; + u_char ak_change_indicator: 1; + u_char n_cids; + uint16_t cids[MAX_NBR]; + u_char n_saids; + uint16_t saids[MAX_NBR]; + + //if mode == 0b010: attribute defined in mode 0b001 + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + + //if mode == 0b011 + u_char n_new_bs: 3; + mac802_16_mob_bsho_req_mode_new_bs new_bs[MAX_NBR]; + u_char n_current_bs: 3; + mac802_16_mob_bsho_req_mode_current_bs current_bs[MAX_NBR]; + //also include the following elements defined in mode 0b001 + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + //u_char n_cids; + //uint16_t cids[MAX_NBR]; + //u_char n_saids; + //uint16_t saids[MAX_NBR]; + + //if mode == 0b100, include the following attributes (already defined) + //u_char n_new_bs: 3; + //mac802_16_mob_bsho_req_mode_new_bs new_bs[MAX_NBR]; + //u_char n_current_bs: 3; + //mac802_16_mob_bsho_req_mode_current_bs current_bs[MAX_NBR]; + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + + //if mode == 0b101 + //u_char n_new_bs: 3; + //u_char n_cids; + //u_char n_saids; + mac802_16_mob_bsho_req_mode_new_bs2 new_bs2[MAX_NBR]; + //u_char n_current_bs: 3; + //mac802_16_mob_bsho_req_mode_current_bs current_bs[]; + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + + //if mode == 0b110 + //u_char n_new_bs: 3; + //u_char n_cids; + //u_char n_saids; + mac802_16_mob_bsho_req_mode_new_bs3 new_bs3[MAX_NBR]; + //u_char n_current_bs: 3; + //mac802_16_mob_bsho_req_mode_current_bs current_bs[]; + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + + u_char action_time: 7; + /* TLV information */ +}; + +/** Structure for MSHO request */ +struct mac802_16_mob_msho_req_bs_index { + u_char neighbor_bs_index; + u_char preamble_index; + u_char bs_cinr_mean; //if report_metric[0]==1 + u_char bs_rssi_mean; //if report_metric[1]==1 + u_char relative_delay; //if report_metric[2]==1 + u_char service_level_prediction: 3; + u_char arrival_time_diff_ind: 1; + //next if arrival_time_diff_ind==1 + u_char arrival_time_diff: 4; +}; + +/** Structure for MSHO request */ +struct mac802_16_mob_msho_req_current_bs { + u_char temp_bsid: 4; + u_char bs_cinr_mean; //if report_metric[0]==1 + u_char bs_rssi_mean; //if report_metric[1]==1 + u_char relative_delay; //if report_metric[2]==1 + u_char bs_rtd; //if report_metric[3]==1 +}; + +/** MSHO request frame */ +struct mac802_16_mob_msho_req_frame { + u_char type; //57 + u_char report_metric; + u_char n_new_bs_index; + //next if n_recommended_bs_index !=0 + u_char ccc_mob_nbr_adv; + mac802_16_mob_msho_req_bs_index bs_index[MAX_NBR]; + //end + u_char n_new_bs_full; + mac802_16_mob_msho_req_bs_index bs_full[MAX_NBR]; + u_char n_current_bs; + mac802_16_mob_msho_req_current_bs bs_current[MAX_NBR]; + /* other TLV information */ +}; + +/** Structure for BSHO response */ +struct mac802_16_mob_bsho_rsp_rec { + int neighbor_bsid; /* 6 bytes */ + u_char preamble_index; + u_char service_level_prediction; + u_char ho_process_optimization; + u_char net_assisted_ho_supported: 1; + u_char ho_id_included_indicator: 1; + //if ho_id_included_indicator==1 + u_char ho_id; + //end if + u_char ho_autho_policy_indicator: 1; + //if ho_autho_policy_indicator==1 + u_char ho_autho_policy_support; + //end if + +}; + +/** Structure for BSHO response */ +struct mac802_16_mob_bsho_rsp_mode_new_bs2 { + int neighbor_bsid; /* 6 bytes */ + u_char temp_bsid: 3; + uint16_t new_cid[]; +}; + +/** BSHO response frame */ +struct mac802_16_mob_bsho_rsp_frame { + u_char type; //58 + u_char mode: 3; + + //if mode == 0b000 + u_char ho_operation_mode: 1; + u_char n_recommended; + u_char resource_retain_flag: 1; + mac802_16_mob_bsho_rsp_rec n_rec[MAX_NBR]; + + //if mode == 0b001 + u_char tmp_bsid: 3; + u_char ak_change_indicator: 1; + u_char n_cids; + uint16_t cids[MAX_NBR]; + u_char n_saids; + uint16_t saids[MAX_NBR]; + + //if mode == 0b010 + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + + //if mode == 0b011 + u_char n_new_bs: 3; + mac802_16_mob_bsho_req_mode_new_bs new_bs[MAX_NBR]; + u_char n_current_bs: 3; + mac802_16_mob_bsho_req_mode_current_bs current_bs[MAX_NBR]; + //also include the following elements defined in mode 0b001 + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + //u_char n_cids; + //uint16_t cids[MAX_NBR]; + //u_char n_saids; + //uint16_t saids[MAX_NBR]; + + //if mode == 0b100 + //u_char n_new_bs: 3; + //mac802_16_mob_bsho_req_mode_new_bs new_bs[MAX_NBR]; //same struct as req + //u_char n_current_bs: 3; + //mac802_16_mob_bsho_req_mode_current_bs current_bs[MAX_NBR]; //same as req + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + + //if mode == 0b101 + //u_char n_new_bs: 3; + //u_char n_cids; + mac802_16_mob_bsho_rsp_mode_new_bs2 new_bs2[MAX_NBR]; + //u_char n_current_bs: 3; + //mac802_16_mob_bsho_req_mode_current_bs current_bs[MAX_NBR]; + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + + //if mode == 0b110 + //u_char n_new_bs: 3; + //u_char n_cids; + //u_char n_saids; + mac802_16_mob_bsho_req_mode_new_bs3 new_bs3[MAX_NBR]; //same as request + //u_char n_current_bs: 3; + //mac802_16_mob_bsho_req_mode_current_bs current_bs[MAX_NBR]; + //u_char tmp_bsid: 3; + //u_char ak_change_indicator: 1; + + u_char action_time: 7; + /* TLV information */ + +}; + +/** Structure for Handover indication */ +struct mac802_16_mob_ho_ind_bs { + u_char temp_bsid: 3; +}; + +/** HO indication frame */ +struct mac802_16_mob_ho_ind_frame { + u_char type; //59 + u_char mode: 2; + //if mode==0b00 + u_char ho_ind_type: 2; + u_char rng_param_valid_ind: 2; + //next valid if ho_ind_type==0b00 + int target_bsid; /* 6 bytes */ + + //if mode==0b01 + u_char mdhofbss_ind_type: 2; + //next valid if mdhofbss_ind_type==0b00 + u_char bsid: 3; + u_char action_time; + //end valid if mdhofbss_ind_type==0b00 + + //if mode==0b10 + //u_char mdhofbss_ind_type: 2; + //next valid if mdhofbss_ind_type==0b00 + u_char diversity_set_included; + //next valid if diversity_set_included==1 + u_char anchor_bsid: 3; + u_char n_bs; + mac802_16_mob_ho_ind_bs bs[MAX_NBR]; + //end valid if diversity_set_included==1 + //u_char action_time; + //end valid if mdhofbss_ind_type==0b00 + u_char preamble_index; + + /* TLV information */ +}; + +/** This class contains helpers for manipulating 802.16 messages + * and getting the packet size + */ +class Mac802_16pkt { + public: + /** + * Return the size of the MOB_NBR-ADV frame + * @param frame The frame + */ + static int getMOB_NBR_ADV_size(mac802_16_mob_nbr_adv_frame *frame); + + /** + * Return the size of the MOB_SCN-REQ + * @param frame The frame + */ + static int getMOB_SCN_REQ_size(mac802_16_mob_scn_req_frame *frame); + + /** + * Return the size of the MOB_SCN-RSP + * @param frame The frame + */ + static int getMOB_SCN_RSP_size(mac802_16_mob_scn_rsp_frame *frame); + + /** + * Return the size of the MOB_MSHO-REQ + * @param frame The frame + */ + static int getMOB_MSHO_REQ_size(mac802_16_mob_msho_req_frame *frame); + + /** + * Return the size of the MOB_BSHO-RSP + * @param frame The frame + */ + static int getMOB_BSHO_RSP_size(mac802_16_mob_bsho_rsp_frame *frame); + + /** + * Return the size of the MOB_HO-IND + * @param frame The frame + */ + static int getMOB_HO_IND_size(mac802_16_mob_ho_ind_frame *frame); +}; + + +#endif diff -Naur ns-2.29-original/wimax/mac802_16timer.cc ns-2.29-new/wimax/mac802_16timer.cc --- ns-2.29-original/wimax/mac802_16timer.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/mac802_16timer.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,318 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "mac802_16timer.h" +#include "mac802_16.h" +#include "scheduling/wimaxscheduler.h" + +/* + * Starts a timer for the given duration + * @param time The timer duration + */ +void WimaxTimer::start(double time) +{ + Scheduler &s = Scheduler::instance(); + assert(busy_ == 0); + busy_ = 1; + paused_ = 0; + stime = s.clock(); + rtime = time; + assert(rtime >= 0.0); + s.schedule(this, &intr, rtime); //schedule the event +} + +/* + * Stop the timer + */ +void WimaxTimer::stop(void) +{ + Scheduler &s = Scheduler::instance(); + + assert(busy_); + + if(paused_ == 0) + s.cancel(&intr); //cancel the event + + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; +} + +void WimaxTimer::pause(void) +{ + Scheduler &s = Scheduler::instance(); + + assert(busy_ && ! paused_); + + paused_ = 1; + rtime -= s.clock()-stime; + + assert(rtime >= 0.0); + + s.cancel(&intr); +} + + +void WimaxTimer::resume(void) +{ + Scheduler &s = Scheduler::instance(); + + assert(busy_ && paused_); + + paused_ = 0; + stime = s.clock(); + + assert(rtime >= 0.0); + s.schedule(this, &intr, rtime ); +} + + + +/* + * Handling function for WimaxFrameTimer + * @param e The event that occured + */ +void WimaxRxTimer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->receive (); +} + +/* + * Handling function for WimaxFrameTimer + * @param e The event that occured + */ +void WimaxT1Timer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxT1TimerID); +} + +/* + * Handling function for WimaxFrameTimer + * @param e The event that occured + */ +void WimaxT2Timer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxT2TimerID); +} + +/* + * Handling function for WimaxT3Timer + * @param e The event that occured + */ +void WimaxT3Timer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxT3TimerID); +} + +/* + * Handling function for WimaxT6Timer + * @param e The event that occured + */ +void WimaxT6Timer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxT6TimerID); +} + +/* + * Handling function for WimaxT12Timer + * @param e The event that occured + */ +void WimaxT12Timer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxT12TimerID); +} + +/* + * Handling function for WimaxT17Timer + * @param e The event that occured + */ +void WimaxT17Timer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + /** The node did not send a registration: release and + * age out Basic and Primary CIDs + */ + PeerNode * peer = mac->getPeerNode (peerIndex_); + mac->debug ("At %f in Mac %d did not register on time...release CIDs\n", NOW, mac->addr(),peerIndex_); + mac->removePeerNode (peer); +} + + +/* + * Handling function for WimaxT21Timer + * @param e The event that occured + */ +void WimaxT21Timer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxT21TimerID); +} + +/* + * Handling function for WimaxFrameTimer + * @param e The event that occured + */ +void WimaxLostDLMAPTimer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxLostDLMAPTimerID); +} + +/* + * Handling function for WimaxFrameTimer + * @param e The event that occured + */ +void WimaxLostULMAPTimer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxLostULMAPTimerID); +} + +/* + * Handling function for WimaxDCDTimer + * @param e The event that occured + */ +void WimaxDCDTimer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxDCDTimerID); +} + +/* + * Handling function for WimaxUCDTimer + * @param e The event that occured + */ +void WimaxUCDTimer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxUCDTimerID); +} + +/* + * Handling function for WimaxScanIntervalTimer + * @param e The event that occured + */ +void WimaxScanIntervalTimer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxScanIntervalTimerID); +} + +/* + * Handling function for WimaxT44Timer + * @param e The event that occured + */ +void WimaxT44Timer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxT44TimerID); +} + +/* + * Handling function for WimaxMobNbrAdvTimer + * @param e The event that occured + */ +void WimaxMobNbrAdvTimer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxMobNbrAdvTimerID); +} + +/* + * Handling function for WimaxRdvTimer + * @param e The event that occured + */ +void WimaxRdvTimer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->getScheduler()->expire(WimaxRdvTimerID); + printf ("Rdv timeout going to channel %d\n", channel_); + mac->setChannel (channel_); +} + diff -Naur ns-2.29-original/wimax/mac802_16timer.h ns-2.29-new/wimax/mac802_16timer.h --- ns-2.29-original/wimax/mac802_16timer.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/mac802_16timer.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,243 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef MAC802_16TIMER_H +#define MAC802_16TIMER_H + +#include "scheduler.h" + +/** Define the ID for each timer **/ +enum timer_id { + WimaxFrameTimerID, + WimaxRxTimerID, + WimaxDCDTimerID, + WimaxUCDTimerID, + WimaxRngIntTimerID, + WimaxLostDLMAPTimerID, + WimaxLostULMAPTimerID, + WimaxT1TimerID, + WimaxT2TimerID, + WimaxT3TimerID, + WimaxT6TimerID, + WimaxT9TimerID, + WimaxT12TimerID, + WimaxT16TimerID, + WimaxT17TimerID, + WimaxT21TimerID, + WimaxT44TimerID, + //mobility extension + WimaxMobNbrAdvTimerID, + + WimaxScanIntervalTimerID, + WimaxRdvTimerID +}; + + +class Mac802_16; + +/** + * Super class for timers used in wimax + */ +class WimaxTimer : public Handler { +public: + WimaxTimer(Mac802_16* m) : mac(m) { + busy_ = paused_ = 0; stime = rtime = 0.0; + } + + virtual void handle(Event *e) = 0; + + virtual void start(double time); + virtual void stop(void); + void pause(void); /*{ assert(0); }*/ + void resume(void);/* { assert(0); }*/ + + inline int busy(void) { return busy_; } + inline int paused(void) { return paused_; } + inline double expire(void) { + return ((stime + rtime) - Scheduler::instance().clock()); + } + +protected: + Mac802_16 *mac; + int busy_; + int paused_; + Event intr; + double stime; // start time + double rtime; // remaining time +}; + +/** Timer for receiving a packet */ +class WimaxRxTimer : public WimaxTimer { + public: + WimaxRxTimer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for DCD interval */ +class WimaxDCDTimer : public WimaxTimer { + public: + WimaxDCDTimer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for UCD interval */ +class WimaxUCDTimer : public WimaxTimer { + public: + WimaxUCDTimer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for initial ranging regions interval */ +class WimaxRngIntTimer : public WimaxTimer { + public: + WimaxRngIntTimer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for Lost DL-MAP interval */ +class WimaxLostDLMAPTimer : public WimaxTimer { + public: + WimaxLostDLMAPTimer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for Lost UL-MAP interval */ +class WimaxLostULMAPTimer : public WimaxTimer { + public: + WimaxLostULMAPTimer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for T1 : wait for DCD timeout */ +class WimaxT1Timer : public WimaxTimer { + public: + WimaxT1Timer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for T2 : wait for broadcast ranging timeout */ +class WimaxT2Timer : public WimaxTimer { + public: + WimaxT2Timer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for T3 : ranging response timeout */ +class WimaxT3Timer : public WimaxTimer { + public: + WimaxT3Timer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for T6 : wait for registration response */ +class WimaxT6Timer : public WimaxTimer { + public: + WimaxT6Timer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for T9 : registration timeout */ +class WimaxT9Timer : public WimaxTimer { + public: + WimaxT9Timer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for T12 : wait for UCD descriptor */ +class WimaxT12Timer : public WimaxTimer { + public: + WimaxT12Timer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for T16 : wait for bw request grant */ +class WimaxT16Timer : public WimaxTimer { + public: + WimaxT16Timer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for T17 : wait for SS to register */ +class WimaxT17Timer : public WimaxTimer { + public: + WimaxT17Timer(Mac802_16 *m, int peerIndex) : WimaxTimer(m) { peerIndex_ = peerIndex;} + + void handle(Event *e); + private: + int peerIndex_; +}; + +/** Timer for T21 : time the station searches for DL-MAP on a channel */ +class WimaxT21Timer : public WimaxTimer { + public: + WimaxT21Timer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for T44 : wait for BS to send MOB_SCN-REP */ +class WimaxT44Timer : public WimaxTimer { + public: + WimaxT44Timer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for scan interval : timer for scanning */ +class WimaxScanIntervalTimer : public WimaxTimer { + public: + WimaxScanIntervalTimer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for neighbor advertisement interval */ +class WimaxMobNbrAdvTimer : public WimaxTimer { + public: + WimaxMobNbrAdvTimer(Mac802_16 *m) : WimaxTimer(m) {} + + void handle(Event *e); +}; + +/** Timer for rendez-vous with target BSs */ +class WimaxRdvTimer : public WimaxTimer { + public: + WimaxRdvTimer(Mac802_16 *m, int channel) : WimaxTimer(m) + { + channel_ = channel; + } + + void handle(Event *e); + private: + int channel_; +}; + +#endif diff -Naur ns-2.29-original/wimax/neighbordb.cc ns-2.29-new/wimax/neighbordb.cc --- ns-2.29-original/wimax/neighbordb.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/neighbordb.cc 2009-04-13 15:18:08.000000000 +0200 @@ -0,0 +1,103 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "neighbordb.h" + +/** + * Constructor + */ +NeighborDB::NeighborDB () +{ + nbentry_ = 0; + nbs_ = (WiMAXNeighborEntry **) malloc (DEFAULT_DB_SIZE*sizeof (WiMAXNeighborEntry *)); +} + +/** + * Destructor + */ +NeighborDB::~NeighborDB () +{ + for (int i=0 ; i < nbentry_ ; i++) { + delete (nbs_[i]); + } +} + +/** + * Add an entry in the database + * @param nb The neighbor to add + */ +void NeighborDB::addNeighbor (WiMAXNeighborEntry *nb) +{ + if (nbentry_ == DEFAULT_DB_SIZE) { + printf ("Default size for neighbor database is too small. Update DEFAULT_DB_SIZE attribute\n"); + exit (0); + } + nbs_[nbentry_++] = nb; +} + +/** + * Remove the entry associated with the given node + * @param nbid The neighbor id + */ +void NeighborDB::removeNeighbor (int nbid) +{ + assert (getNeighbor (nbid)==NULL); + + for (int i = 0 ; i < nbentry_ ; i++) { + if (nbs_[i]->getID() == nbid) { + delete (nbs_[i]); + for (int j = i+1 ; j < nbentry_ ; j++, i++) + nbs_[i]=nbs_[j]; + nbentry_--; + break; + } + } +} + +/** + * Return the number of neighbor in the list + * @return the number of neighbor in the list + */ +int NeighborDB::getNbNeighbor () +{ + return nbentry_; +} + +/** + * Return the entry associated with the given node + * @param nbid The neighbor id + * @return the entry for the given node or NULL + */ +WiMAXNeighborEntry * NeighborDB::getNeighbor (int nbid) +{ + for (int i = 0 ; i < nbentry_ ; i++) { + if (nbs_[i]->getID() == nbid) { + return (nbs_[i]); + } + } + return NULL; +} + +/** + * Return a pointer to the list of all neighbors + * @return a pointer to the list of all neighbors + */ +WiMAXNeighborEntry ** NeighborDB::getNeighbors () +{ + return nbs_; +} diff -Naur ns-2.29-original/wimax/neighbordb.h ns-2.29-new/wimax/neighbordb.h --- ns-2.29-original/wimax/neighbordb.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/neighbordb.h 2009-04-13 15:09:55.000000000 +0200 @@ -0,0 +1,93 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef NEIGHBORDB_H +#define NEIGHBORDB_H + +#include "WiMAXneighborentry.h" +#include "mac802_16pkt.h" + +/* This is the size of database allocated. Needs to be modified if + * a node could have more entries + */ +#define DEFAULT_DB_SIZE 10 + +/** + * The class is used to store and manipulate the list + * of neighbors in a given node + */ +class NeighborDB { + public: + /** + * Constructor + */ + NeighborDB (); + + /** + * Destructor + */ + ~NeighborDB (); + + /** + * Add an entry in the database + * @param nb The neighbor to add + */ + void addNeighbor (WiMAXNeighborEntry *nb); + + /** + * Remove the entry associated with the given node + * @param nbid The neighbor id + */ + void removeNeighbor (int nbid); + + /** + * Return the number of neighbor in the list + * @return the number of neighbor in the list + */ + int getNbNeighbor (); + + /** + * Return the entry associated with the given node + * @param nbid The neighbor id + * @return the entry for the given node or NULL + */ + WiMAXNeighborEntry * getNeighbor (int nbid); + + /** + * Return a pointer to the list of all neighbors + * @return a pointer to the list of all neighbors + */ + WiMAXNeighborEntry ** getNeighbors (); + + protected: + + private: + /** + * Current number of neighbor + */ + int nbentry_; + + /** + * Array of neighbors + */ + WiMAXNeighborEntry **nbs_; + +}; + + +#endif diff -Naur ns-2.29-original/wimax/ofdmphy.cc ns-2.29-new/wimax/ofdmphy.cc --- ns-2.29-original/wimax/ofdmphy.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/ofdmphy.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,304 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "ofdmphy.h" +#include "mac802_16pkt.h" + +//#define DEBUG_WIMAX 1 + +/** + * Tcl hook for creating the physical layer + */ +static class OFDMPhyClass: public TclClass { +public: + OFDMPhyClass() : TclClass("Phy/WirelessPhy/OFDM") {} + TclObject* create(int, const char*const*) { + return (new OFDMPhy); + } +} class_OfdmPhy; + +OFDMPhy::OFDMPhy() : WirelessPhy() +{ + //bind attributes + bind ("g_", &g_); + //bind ("rtg_", &rtg_); + //bind ("ttg_", &ttg_); + //bind ("fbandwidth_", &fbandwidth_); + + //default modulation is BPSK + modulation_ = OFDM_BPSK_1_2; + Tcl& tcl = Tcl::instance(); + tcl.evalf("Mac/802_16 set fbandwidth_"); + fbandwidth_ = atof (tcl.result()); + state_ = OFDM_IDLE; + activated_ = true; + + updateFs (); +} + +/* + * Activate node + */ +void OFDMPhy::node_on () +{ + activated_ = true; +} + +/* + * Deactivate node + */ +void OFDMPhy::node_off () +{ + activated_ = false; +} + + +/** + * Change the frequency at which the phy is operating + * @param freq The new frequency + */ +void OFDMPhy::setFrequency (double freq) +{ + freq_ = freq; + lambda_ = SPEED_OF_LIGHT / freq_; +} + +/** + * Set the new modulation for the physical layer + */ +void OFDMPhy::setModulation (Ofdm_mod_rate modulation) { + modulation_ = modulation; +} +/** + * Return the current modulation + */ +Ofdm_mod_rate OFDMPhy::getModulation () { + return modulation_; +} +/** + * Set the new transmitting power + */ +void OFDMPhy::setTxPower (double power) { + Pt_ = power; +} +/** + * Return the current transmitting power + */ +double OFDMPhy::getTxPower () { + return getPt(); +} + +/** + * Update the PS information + */ +void OFDMPhy::updateFs () { + /* The PS=4*Fs with Fs=floor (n.BW/8000)*8000 + * and n=8/7 is channel bandwidth multiple of 1.75Mhz + * n=86/75 is channel bandwidth multiple of 1.5Mhz + * n=144/125 is channel bandwidth multiple of 1.25Mhz + * n=316/275 is channel bandwidth multiple of 2.75Mhz + * n=57/50 is channel bandwidth multiple of 2.0Mhz + * n=8/7 for all other cases + */ + double n; + + if (((int) (fbandwidth_ / 1.75)) * 1.75 == fbandwidth_) { + n = 8.0/7; + } else if (((int) (fbandwidth_ / 1.5)) * 1.5 == fbandwidth_) { + n = 86.0/75; + } else if (((int) (fbandwidth_ / 1.25)) * 1.25 == fbandwidth_) { + n = 144.0/125; + } else if (((int) (fbandwidth_ / 2.75)) * 2.75 == fbandwidth_) { + n = 316.0/275; + } else if (((int) (fbandwidth_ / 2.0)) * 2.0 == fbandwidth_) { + n = 57.0/50; + } else { + n = 8.0/7; + } + + fs_ = floor (n*fbandwidth_/8000) * 8000; +#ifdef DEBUG_WIMAX + printf ("Fs updated. Bw=%f, n=%f, new value is %e\n", fbandwidth_, n, fs_); +#endif +} + +/* + * Compute the transmission time for a packet of size sdusize and + * using the given modulation + * @param sdusize Size in bytes of the data to send + * @param mod The modulation to use + */ +double OFDMPhy::getTrxTime (int sdusize, Ofdm_mod_rate mod) { + //we compute the number of symbols required + int nb_symbols, bpsymb; + + switch (mod) { + case OFDM_BPSK_1_2: + bpsymb = OFDM_BPSK_1_2_bpsymb; + break; + case OFDM_QPSK_1_2: + bpsymb = OFDM_QPSK_1_2_bpsymb; + break; + case OFDM_QPSK_3_4: + bpsymb = OFDM_QPSK_3_4_bpsymb; + break; + case OFDM_16QAM_1_2: + bpsymb = OFDM_16QAM_1_2_bpsymb; + break; + case OFDM_16QAM_3_4: + bpsymb = OFDM_16QAM_3_4_bpsymb; + break; + case OFDM_64QAM_2_3: + bpsymb = OFDM_64QAM_2_3_bpsymb; + break; + case OFDM_64QAM_3_4: + bpsymb = OFDM_64QAM_3_4_bpsymb; + break; + default: + printf ("Error: unknown modulation: method getTrxTime in file ofdmphy.cc\n"); + exit (1); + } + +#ifdef DEBUG_WIMAX + printf ("Nb symbols=%d\n", (int) (ceil(((double)sdusize*8)/bpsymb))); +#endif + + nb_symbols = (int) (ceil(((double)sdusize*8)/bpsymb)); + return (nb_symbols*getSymbolTime ()); +} + +/* + * Return the maximum size in bytes that can be sent for the given + * nb symbols and modulation + */ +int OFDMPhy::getMaxPktSize (double nbsymbols, Ofdm_mod_rate mod) +{ + int bpsymb; + + switch (mod) { + case OFDM_BPSK_1_2: + bpsymb = OFDM_BPSK_1_2_bpsymb; + break; + case OFDM_QPSK_1_2: + bpsymb = OFDM_QPSK_1_2_bpsymb; + break; + case OFDM_QPSK_3_4: + bpsymb = OFDM_QPSK_3_4_bpsymb; + break; + case OFDM_16QAM_1_2: + bpsymb = OFDM_16QAM_1_2_bpsymb; + break; + case OFDM_16QAM_3_4: + bpsymb = OFDM_16QAM_3_4_bpsymb; + break; + case OFDM_64QAM_2_3: + bpsymb = OFDM_64QAM_2_3_bpsymb; + break; + case OFDM_64QAM_3_4: + bpsymb = OFDM_64QAM_3_4_bpsymb; + break; + default: + printf ("Error: unknown modulation: method getTrxTime in file ofdmphy.cc\n"); + exit (1); + } + + return (int)(nbsymbols*bpsymb)/8; +} + +/** + * Return the OFDM symbol duration time + */ +double OFDMPhy::getSymbolTime () +{ + //printf ("fs=%e, Subcarrier spacing=%e\n", fs_, fs_/((double)NFFT)); + return (1+g_)*((double)NFFT)/fs_; +} + + +/* + * Set the mode for physical layer + * The Mac layer is in charge of know when to change the state by + * request the delay for the Rx2Tx and Tx2Rx + */ +void OFDMPhy::setMode (Ofdm_phy_state mode) +{ + state_ = mode; +} + +/* Redefine the method for sending a packet + * Add physical layer information + * @param p The packet to be sent + */ +void OFDMPhy::sendDown(Packet *p) +{ + hdr_mac802_16* wph = HDR_MAC802_16(p); + + /* Check phy status */ + if (state_ != OFDM_SEND) { + printf ("Warning: OFDM not in sending state. Drop packet.\n"); + Packet::free (p); + return; + } + +#ifdef DEBUG_WIMAX + printf ("OFDM phy sending packet. Modulation is %d, cyclic prefix is %f\n", + modulation_, g_); +#endif + + wph->phy_info.freq_ = freq_; + wph->phy_info.modulation_ = modulation_; + wph->phy_info.g_ = g_; + + //the packet can be sent + WirelessPhy::sendDown (p); +} + +/* Redefine the method for receiving a packet + * Add physical layer information + * @param p The packet to be sent + */ +int OFDMPhy::sendUp(Packet *p) +{ + hdr_mac802_16* wph = HDR_MAC802_16(p); + + if (!activated_) + return 0; + + if (freq_ != wph->phy_info.freq_) { +#ifdef DEBUG_WIMAX + printf ("drop packet because frequency is different (%f, %f)\n", freq_,wph->phy_info.freq_); +#endif + return 0; + } + + /* Check phy status */ + if (state_ != OFDM_RECV) { +#ifdef DEBUG_WIMAX + printf ("Warning: OFDM phy not in receiving state. Drop packet.\n"); +#endif + return 0; + } + +#ifdef DEBUG_WIMAX + printf ("OFDM phy receiving packet with mod=%d and cp=%f\n", wph->phy_info.modulation_,wph->phy_info.g_); +#endif + + //the packet can be received + return WirelessPhy::sendUp (p); +} + diff -Naur ns-2.29-original/wimax/ofdmphy.h ns-2.29-new/wimax/ofdmphy.h --- ns-2.29-original/wimax/ofdmphy.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/ofdmphy.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,214 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef OFDMPHY_H +#define OFDMPHY_H + +#include +#include "wireless-phy.h" + +/* Define subcarrier information */ +#define NFFT 256 +#define NUSED 200 //number of subcarrier used + +/** Status of physical layer */ +enum Ofdm_phy_state { + OFDM_IDLE, /* Module is not doing anything */ + OFDM_SEND, /* Module is ready to send or sending */ + OFDM_RECV, /* Module is can receive or is receiving */ + OFDM_RX2TX, /* Module is transitioning from receiving mode to sending mode */ + OFDM_TX2RX /* Module is transitioning from sending mode to receiving mode */ +}; + +/** Definition of supported rate */ +enum Ofdm_mod_rate { + OFDM_BPSK_1_2, /* Efficiency is 1 bps/Hz */ + OFDM_QPSK_1_2, /* Efficiency is 2 bps/Hz */ + OFDM_QPSK_3_4, /* Efficiency is 2 bps/Hz */ + OFDM_16QAM_1_2, /* Efficiency is 4 bps/Hz */ + OFDM_16QAM_3_4, /* Efficiency is 4 bps/Hz */ + OFDM_64QAM_2_3, /* Efficiency is 6 bps/Hz */ + OFDM_64QAM_3_4, /* Efficiency is 6 bps/Hz */ +}; + +/** + * How to compute the number of information bit per symbol: + * - Each symbol has 192 data subcarrier (200-8 for pilots) + * - A modulation has a coding rate (1/2, 2/3, or 3/4) + * - A modulation has an efficiency (1, 2, 4, or 6) + * - There is a 0x00 tail byte at the end of each OFDM symbol + * So for BPSK, 192*1*1/2-8=88 + */ +enum Ofdm_bit_per_symbol { + OFDM_BPSK_1_2_bpsymb = 88, + OFDM_QPSK_1_2_bpsymb = 184, + OFDM_QPSK_3_4_bpsymb = 280, + OFDM_16QAM_1_2_bpsymb = 376, + OFDM_16QAM_3_4_bpsymb = 578, + OFDM_64QAM_2_3_bpsymb = 760, + OFDM_64QAM_3_4_bpsymb = 856, +}; + +/** + * Class OFDMPhy + * Physical layer implementing OFDM + */ +class OFDMPhy : public WirelessPhy { + +public: + OFDMPhy(); + + /** + * Change the frequency at which the phy is operating + * @param freq The new frequency + */ + void setFrequency (double freq); + + /** + * Set the new modulation for the physical layer + * @param modulation The new physical modulation + */ + void setModulation (Ofdm_mod_rate modulation); + + /** + * Return the current modulation + */ + Ofdm_mod_rate getModulation (); + + /** + * Set the new transmitting power + * @param power The new transmitting power + */ + void setTxPower (double power); + + /** + * Return the current transmitting power + */ + double getTxPower (); + + /** + * Return the duration of a PS (physical slot), unit for allocation time. + * Use Frame duration / PS to find the number of available slot per frame + */ + inline double getPS () { return (4/fs_); } + + /** + * Return the OFDM symbol duration time + */ + double getSymbolTime (); + + /** + * Compute the transmission time for a packet of size sdusize and + * using the given modulation + */ + double getTrxTime (int, Ofdm_mod_rate); + + /** + * Return the maximum size in bytes that can be sent for the given + * nb of symbols and modulation + */ + int getMaxPktSize (double nbsymbols, Ofdm_mod_rate); + + /** + * Return the number of PS used by an OFDM symbol + */ + inline int getSymbolPS () { return (int) (ceil (getSymbolTime() / getPS())); } + + /** + * Set the mode for physical layer + */ + void setMode (Ofdm_phy_state mode); + + /** + * Activate node + */ + void node_on (); + + /** + * Deactivate node + */ + void node_off (); + +protected: + + /** + * Update the sampling frequency. Called after changing frequency BW + */ + void updateFs (); + + /* + * Return the delay required for switching for Rx to Tx mode + */ + //inline double getRx2TxDelay () { return getPS () * rtg_; } + + /* + * Return the delay required for switching for Tx to Rx mode + */ + //inline double getTx2RxDelay () { return getPS () * ttg_; } + + + /* Overwritten methods for handling packets */ + void sendDown(Packet *p); + int sendUp(Packet *p); + +private: + + /** + * The current modulation + */ + Ofdm_mod_rate modulation_; + /** + * The current transmitting power + */ + int tx_power_; + /** + * Ratio of CP time over useful time + */ + double g_; + /** + * The number of PS required to switch from Receiver to Transmitter + */ + //int rtg_; + /** + * The number of PS required to switch from Transmitter to Receiver + */ + //int ttg_; + + /** + * The sampling frequency + */ + double fs_; + + /** + * The frequency bandwidth (Hz) + */ + double fbandwidth_; + + /** + * The state of the OFDM + */ + Ofdm_phy_state state_; + + /** + * Indicates if the node is activated + */ + bool activated_; + +}; +#endif //OFDMPHY_H + diff -Naur ns-2.29-original/wimax/peernode.cc ns-2.29-new/wimax/peernode.cc --- ns-2.29-original/wimax/peernode.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/peernode.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,183 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "peernode.h" + +/** + * Constructor + * @param index The Mac address of the peer node + */ +PeerNode::PeerNode (int index): basic_(0), primary_(0), secondary_(0), indata_(0), + outdata_(0), rxtime_ (0.0), rxp_watch_() +{ + peerIndex_ = index; + going_down_ = false; + + /// Added by Aymen + /// Default SNR value + ReceivedSNR_ = SNR_QPSK_1_2; + /// +} + +/** + * Set the basic connection + * @param connection The basic connection + */ +void PeerNode::setBasic (Connection* connection ) +{ + assert (connection != NULL); + + basic_ = connection; + connection->set_category (CONN_BASIC); + connection->setPeerNode (this); +} + +/** + * Set the primary connection + * @param connection The primary connection + */ +void PeerNode::setPrimary (Connection* connection ) +{ + assert (connection != NULL); + + primary_ = connection; + connection->set_category (CONN_PRIMARY); + connection->setPeerNode (this); +} + +/** + * Set the secondary connection + * @param connection The secondary connection + */ +void PeerNode::setSecondary (Connection* connection ) +{ + assert (connection != NULL); + + secondary_ = connection; + connection->set_category (CONN_SECONDARY); + connection->setPeerNode (this); +} + +/** + * Set the incoming data connection + * @param connection The connection + */ +void PeerNode::setInData (Connection* connection ) +{ + assert (connection != NULL); + + indata_ = connection; + connection->set_category (CONN_DATA); + connection->setPeerNode (this); +} + +/** + * Set the outgoing data connection + * @param connection The connection + */ +void PeerNode::setOutData (Connection* connection ) +{ + assert (connection != NULL); + + outdata_ = connection; + connection->set_category (CONN_DATA); + connection->setPeerNode (this); +} + +/** + * Set the time the last packet was received + * @param time The time the last packet was received + */ +void PeerNode::setRxTime (double time) +{ + assert (time >=0.0); + rxtime_ = time; +} + +/** + * Get the time the last packet was received + * @return The time the last packet was received + */ +double PeerNode::getRxTime () +{ + return rxtime_; +} + +/** + * Return the stat watch + * @return The stat watch + */ +StatWatch * PeerNode::getStatWatch() +{ + return &rxp_watch_; +} + + + + /// Added by Aymen + /** + * Set the received SNR + * @param ReceivedSNR The received SNR + */ + void PeerNode::setReceivedSNR (float ReceivedSNR) + { + ReceivedSNR_ = ReceivedSNR; + } + + /** + * Get the received SNR + * @return The received SNR + */ + float PeerNode::getReceivedSNR () + { + return ReceivedSNR_; + } + + + + /** + * Get the corresponding MCS + * @return The corresponding MCS + */ + Ofdm_mod_rate PeerNode::getOfdm_mod_rate() + { + if (ReceivedSNR_ >= (float)SNR_64QAM_3_4) + return OFDM_64QAM_3_4; + else + if (ReceivedSNR_ >= SNR_64QAM_2_3) + return OFDM_64QAM_2_3; + else + if (ReceivedSNR_ >= SNR_16QAM_3_4) + return OFDM_16QAM_3_4; + else + if (ReceivedSNR_ >= SNR_16QAM_1_2) + return OFDM_16QAM_1_2; + else + if (ReceivedSNR_ >= SNR_QPSK_3_4) + return OFDM_QPSK_3_4; + else + if (ReceivedSNR_ >= SNR_QPSK_1_2) + return OFDM_QPSK_1_2; + else + if (ReceivedSNR_ >= SNR_BPSK_1_2) + return OFDM_BPSK_1_2; + else + return OFDM_BPSK_1_2; // to be modified + + } + /// \ Pas de fin de ligne à la fin du fichier. diff -Naur ns-2.29-original/wimax/peernode.h ns-2.29-new/wimax/peernode.h --- ns-2.29-original/wimax/peernode.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/peernode.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,250 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef PEERNODE_H +#define PEERNODE_H + +#include "connection.h" +#include "mac-stats.h" + + + +/// Added by Aymen +/* Defines the receiver SNR assumptions */ + #define SNR_BPSK_1_2 3.0 + #define SNR_QPSK_1_2 6.0 + #define SNR_QPSK_3_4 8.5 + #define SNR_16QAM_1_2 11.5 + #define SNR_16QAM_3_4 15.0 + #define SNR_64QAM_2_3 19.0 + #define SNR_64QAM_3_4 21.0 +/// + + + +class PeerNode; +LIST_HEAD (peerNode, PeerNode); +/** + * Class PeerNode + * Supports list + */ +class PeerNode { + +public: + + /** + * Constructor + * @param index The Mac address of the peer node + */ + PeerNode (int index); + + /** + * Return the address of the peer node + * @return The address of the peer node + */ + int getPeerNode () { return peerIndex_; } + + /** + * Set the connection for delay-intolerant management messages + * @param connection The connection used as basic + */ + void setBasic (Connection * connection); + + /** + * Return the connection used for delay-intolerant messages + */ + Connection* getBasic () { return basic_; } + + /** + * Set the connection for delay-tolerant management messages + * @param connection + */ + void setPrimary (Connection * connection); + + /** + * Return the connection used for delay-tolerant messages + */ + inline Connection* getPrimary () { return primary_; } + + /** + * Set the channel used for standard-based messages + * @param connection + */ + void setSecondary (Connection * connection); + + /** + * Return the connection used for standard-based messages + */ + Connection* getSecondary () { return secondary_; } + + /** + * Set the channel used for data messages + * @param connection + */ + void setInData (Connection * connection); + + /** + * Set the channel used for data messages + * @param connection + */ + void setOutData (Connection * connection); + + /** + * Return the connection used for data messages + */ + Connection* getOutData () { return outdata_; } + + /** + * Return the connection used for data messages + */ + Connection* getInData () { return indata_; } + + /** + * Set the time the last packet was received + * @param time The time the last packet was received + */ + void setRxTime (double time); + + /** + * Get the time the last packet was received + * @return The time the last packet was received + */ + double getRxTime (); + + /** + * Return the stat watch + * @return The stat watch + */ + StatWatch * getStatWatch(); + + /** + * Return true if the peer is going down + * @return true if the peer is going down + */ + inline bool isGoingDown () { return going_down_; } + + /** + * Set the status of going down + * @param status The link going down status + */ + inline void setGoingDown (bool status) { going_down_ = status; } + + // Chain element to the list + inline void insert_entry(struct peerNode *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Return next element in the chained list + PeerNode* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + + + + /// Added by Aymen + /** + * Set the received SNR + * @param ReceivedSNR The received SNR + */ + void setReceivedSNR (float ReceivedSNR); + + + + /** + * Get the received SNR + * @return The received SNR + */ + float getReceivedSNR (); + + + + /** + * Get the corresponding MCS + * @return The corresponding MCS + */ + Ofdm_mod_rate getOfdm_mod_rate(); + /// + + + + +protected: + + /* + * Pointer to next in the list + */ + LIST_ENTRY(PeerNode) link; + //LIST_ENTRY(PeerNode); //for magic draw + +private: + /** + * Mac address of peer node + */ + int peerIndex_; + + /** + * Used to send delay intolerant management messages + */ + Connection* basic_; + /** + * Used to send delay tolerant mac messages + */ + Connection* primary_; + /** + * Used to transport standard-based protocol (DHCP...) + */ + Connection* secondary_; + /** + * Incomfing data connection to this client + */ + Connection* indata_; + + /** + * Outgoing data connection to this client + */ + Connection* outdata_; + + /** + * Time last packet was received for this peer + */ + double rxtime_; + + /** + * Received signal strength stats + */ + StatWatch rxp_watch_; + + /** + * Inidicate the link going down status of the peer node + */ + bool going_down_; + + + + /// Added by Aymen + /** + * Received signal to noise rate + */ + float ReceivedSNR_; + /// +}; +#endif //PEERNODE_H + diff -Naur ns-2.29-original/wimax/plot-data ns-2.29-new/wimax/plot-data --- ns-2.29-original/wimax/plot-data 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/plot-data 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,17 @@ +reset +set terminal post eps +set output "synch.eps" +set nogrid +#set logscale y +set xlabel "dcd interval (s)" +set ylabel "Synchronization latency (s)" +set xrange [0:10] +set yrange [0:11] +#set key 45,0.45 +set title "Thoeratical synchronization latency" +plot "result1.dat" using 1:3 title "ucd interval=1s" with lp, \ +"result2.dat" using 1:3 title "ucd interval=2s" with lp, \ +"result5.dat" using 1:3 title "ucd interval=5s" with lp, \ +"result10.dat" using 1:3 title "ucd interval=10s" with lp + + diff -Naur ns-2.29-original/wimax/scheduling/bsscheduler.cc ns-2.29-new/wimax/scheduling/bsscheduler.cc --- ns-2.29-original/wimax/scheduling/bsscheduler.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/bsscheduler.cc 2008-10-27 15:33:54.000000000 +0100 @@ -0,0 +1,3448 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "bsscheduler.h" +#include "burst.h" +#include "dlburst.h" +#include "ulburst.h" +#include "random.h" +#include "wimaxctrlagent.h" + +/** + * Bridge to TCL for BSScheduler + */ +static class BSSchedulerClass : public TclClass { +public: + BSSchedulerClass() : TclClass("WimaxScheduler/BS") {} + TclObject* create(int, const char*const*) { + return (new BSScheduler()); + + } +} class_bsscheduler; + +/* + * Create a scheduler + */ +BSScheduler::BSScheduler () : cl_head_(0), cl_tail_(0), ctrlagent_(0) +{ + debug2 ("BSScheduler created\n"); + LIST_INIT (&t17_head_); + LIST_INIT (&scan_stations_); + LIST_INIT (&fast_ranging_head_); + bw_peer_ = NULL; + bw_node_index_ = 0; + default_mod_ = OFDM_BPSK_1_2; + contention_size_ = MIN_CONTENTION_SIZE; + sendDCD = false; + dlccc_ = 0; + sendUCD = false; + ulccc_ = 0; + + + + /// Added by Aymen + LIST_INIT (&ugsmanagement_head_); + LIST_INIT (&UnicastRequest_rtPSmanagement_head_); + LIST_INIT (&WRR_management_head_); + + LIST_INIT (&bandwidthtoallocate_head_); + //LIST_INIT (&rtPS_bandwidthtoallocate_head_); + //LIST_INIT (&BE_bandwidthtoallocate_head_); + + LIST_INIT (&trs_suspendprocedure_head_); + + //TRS_parameters(SNRth, Tr, Tp, L) + TRS_parameters_ = new TRS_parameters(3.0, 2, 3, 4); + + SymbolNumberForUnicastRequest_ = 1; + + last_rtPS_peer_RR_ = UNDEFINED_NODE; + last_BE_peer_RR_ = UNDEFINED_NODE; + + last_rtPS_peer_WRR_ = UNDEFINED_NODE; + last_BE_peer_WRR_ = UNDEFINED_NODE; + + first_peer_BEconnections_= UNDEFINED_NODE; + first_peer_AllConnections_ = UNDEFINED_NODE; + + rtPSscheduling_ = rtPS_SCHEDULING_RR; + + BEscheduling_ = BE_SCHEDULING_RR; + + SymbolsForPreamble_ = 1; + + SchedulingManagementSynch_ = 0; + + TRS_RR_counter_ = 0; + + pFile_rtPS = fopen ("nbSS_rtPS.txt", "w"); + pFile_BE = fopen ("nbSS_BE.txt", "w"); + /// +} + +/* + * Interface with the TCL script + * @param argc The number of parameter + * @param argv The list of parameters + */ +int BSScheduler::command(int argc, const char*const* argv) +{ + if (argc == 3) { + if (strcmp(argv[1], "set-default-modulation") == 0) { + if (strcmp(argv[2], "OFDM_BPSK_1_2") == 0) + default_mod_ = OFDM_BPSK_1_2; + else if (strcmp(argv[2], "OFDM_QPSK_1_2") == 0) + default_mod_ = OFDM_QPSK_1_2; + else if (strcmp(argv[2], "OFDM_QPSK_3_4") == 0) + default_mod_ = OFDM_QPSK_3_4; + else if (strcmp(argv[2], "OFDM_16QAM_1_2") == 0) + default_mod_ = OFDM_16QAM_1_2; + else if (strcmp(argv[2], "OFDM_16QAM_3_4") == 0) + default_mod_ = OFDM_16QAM_3_4; + else if (strcmp(argv[2], "OFDM_64QAM_2_3") == 0) + default_mod_ = OFDM_64QAM_2_3; + else if (strcmp(argv[2], "OFDM_64QAM_3_4") == 0) + default_mod_ = OFDM_64QAM_3_4; + else + return TCL_ERROR; + return TCL_OK; + } + else if (strcmp(argv[1], "set-contention-size") == 0) { + contention_size_ = atoi (argv[2]); + assert (contention_size_>=0); + return TCL_OK; + } + /// Added by Aymen + else + if (strcmp(argv[1], "set-SymbolNumberForUnicastRequest") == 0) + { + SymbolNumberForUnicastRequest_ = atoi(argv[2]); + return TCL_OK; + } + else + if (strcmp(argv[1], "set-rtPSscheduling") == 0) + { + if (strcmp(argv[2], "NIST_RR") == 0) + rtPSscheduling_ = rtPS_SCHEDULING_NIST_RR; + else + if (strcmp(argv[2], "RR") == 0) + rtPSscheduling_ = rtPS_SCHEDULING_RR; + else + if (strcmp(argv[2], "mSIR") == 0) + rtPSscheduling_ = rtPS_SCHEDULING_mSIR; + else + if (strcmp(argv[2], "mmSIR") == 0) + rtPSscheduling_ = rtPS_SCHEDULING_mmSIR; + else + if (strcmp(argv[2], "WRR") == 0) + {rtPSscheduling_ = rtPS_SCHEDULING_WRR;} + else + if (strcmp(argv[2], "TRS_RR") == 0) + {rtPSscheduling_ = rtPS_SCHEDULING_TRS_RR;} + else + if (strcmp(argv[2], "TRS_mSIR") == 0) + {rtPSscheduling_ = rtPS_SCHEDULING_TRS_mSIR;} + else + printf("\nError! Unknown rtPS scheduling algorithm"); + return TCL_OK; + } + else + if (strcmp(argv[1], "set-BEscheduling") == 0) + { + if (strcmp(argv[2], "RR") == 0) + BEscheduling_ = BE_SCHEDULING_RR; + else + if (strcmp(argv[2], "mSIR") == 0) + BEscheduling_ = BE_SCHEDULING_mSIR; + else + if (strcmp(argv[2], "WRR") == 0) + BEscheduling_ = BE_SCHEDULING_WRR; + //else + //if (strcmp(argv[2], "mmSIR") == 0) + //BEscheduling_ = BE_SCHEDULING_mmSIR; + //else + //if (strcmp(argv[2], "TRS_RR") == 0) + //{BEscheduling_ = BE_SCHEDULING_TRS_RR;} + //else + //if (strcmp(argv[2], "TRS_mSIR") == 0) + //{BEscheduling_ = BE_SCHEDULING_TRS_mSIR;} + else + printf("\nError! Unknown BE scheduling algorithm"); + return TCL_OK; + } + /// + } + /// Added by Aymen + else + if(argc == 4) { + if (strcmp(argv[1], "set-PeerNode-SNR") == 0){ + PeerNode * peer = mac_->getPeerNode(atoi(argv[2])); + if(peer) + peer->setReceivedSNR(atof(argv[3])); + else + printf("\nAt %f, node %d is not created",NOW,atoi(argv[2])); + return TCL_OK; + } + else + if (strcmp(argv[1], "set-PeerNode-UGSPeriodicity") == 0){ + if(!searchSchedulingManagement(ugsmanagement_head_, atoi(argv[2]))) + { + SchedulingManagementSynch_ = SchedulingManagementSynch_ % atoi(argv[3]); + SchedulingManagement *schedulingmanagemententry = new SchedulingManagement (atoi(argv[2]), atoi(argv[3]), SchedulingManagementSynch_); + //SchedulingManagementSynch_ ++; + schedulingmanagemententry->insert_entry (&ugsmanagement_head_); + } + else + { + SchedulingManagementSynch_ = SchedulingManagementSynch_ % atoi(argv[3]); + //SchedulingManagementSynch_ ++; + modifySchedulingManagement(ugsmanagement_head_, atoi(argv[2]), atoi(argv[3]), SchedulingManagementSynch_); + } + return TCL_OK; + } + else + if (strcmp(argv[1], "set-PeerNode-UnicastRequestPeriodicity") == 0){ + if(!searchSchedulingManagement(UnicastRequest_rtPSmanagement_head_, atoi(argv[2]))) + { + SchedulingManagementSynch_ = SchedulingManagementSynch_ % atoi(argv[3]); + SchedulingManagement *schedulingmanagemententry = new SchedulingManagement (atoi(argv[2]), atoi(argv[3]), SchedulingManagementSynch_); + SchedulingManagementSynch_ ++; + schedulingmanagemententry->insert_entry (&UnicastRequest_rtPSmanagement_head_); + } + else + { + SchedulingManagementSynch_ = SchedulingManagementSynch_ % atoi(argv[3]); + SchedulingManagementSynch_ ++; + modifySchedulingManagement(UnicastRequest_rtPSmanagement_head_, atoi(argv[2]), atoi(argv[3]), SchedulingManagementSynch_); + } + return TCL_OK; + } + else + if (strcmp(argv[1], "set-PeerNode-WRRscheduling") == 0){ + if(!searchSchedulingManagement(WRR_management_head_, atoi(argv[2]))) + { + SchedulingManagement *schedulingmanagemententry = new SchedulingManagement (atoi(argv[2]), atoi(argv[3]), 0); + schedulingmanagemententry->insert_entry (&WRR_management_head_); + } + else + { + modifySchedulingManagement(WRR_management_head_, atoi(argv[2]), atoi(argv[3]), 0); + } + return TCL_OK; + } + } + else + if(argc == 6) { + if (strcmp(argv[1], "set-TRSparameters-SNR-Tr-Tp-L") == 0){ + TRS_parameters_->setSNRth(atof(argv[2])); + TRS_parameters_->setTr(atoi(argv[3])); + TRS_parameters_->setTp(atoi(argv[4])); + TRS_parameters_->setL(atoi(argv[5])); + + return TCL_OK; + } + } + /// + return TCL_ERROR; +} + +/** + * Initializes the scheduler + */ +void BSScheduler::init () +{ + WimaxScheduler::init(); + /*print debug information */ + int nbPS = (int) round((mac_->getFrameDuration()/mac_->getPhy()->getPS())); + debug2 ("duration=%f, PStime=%f, nbPS=%d,Symbol time=%f, %d \n",mac_->getFrameDuration(), mac_->getPhy()->getPS(), nbPS, mac_->getPhy()->getSymbolTime (), mac_->getPhy()->getSymbolPS()); + + //At initialization, allocate one DL burst + //and contention windows + //1-create one profile to be used for broadcast + // packets (and DL_MAP...) + Profile *p = map_->getDlSubframe()->addProfile ((int)round((mac_->getPhy()->getFreq()/1000)), default_mod_); + p->setIUC (DIUC_PROFILE_1); + map_->getDlSubframe()->getPdu ()->setPreamble (DL_PREAMBLE); //preamble + fch + //2-add the burst to carry the broadcast message + DlBurst *b = (DlBurst*) map_->getDlSubframe()->getPdu ()->addBurst (0); + b->setCid ( BROADCAST_CID ); + b->setIUC (p->getIUC()); + b->setStarttime (0); //after preamble and fch + b->setDuration (INIT_DL_DURATION); //enough to send DL_MAP... + b->setPreamble(true); //this is the first burst after preamble + //3-Add the End of map element + b = (DlBurst*) map_->getDlSubframe()->getPdu ()->addBurst (1); + b->setIUC (DIUC_END_OF_MAP); + b->setStarttime (INIT_DL_DURATION); + + //create uplink + //start of UL subframe is after DL and TTG and unit is PS + int starttime = (INIT_DL_DURATION+DL_PREAMBLE)*mac_->getPhy()->getSymbolPS()+mac_->phymib_.ttg; + map_->getUlSubframe()->setStarttime (starttime); + int slotleft = nbPS - starttime - mac_->phymib_.rtg; + //duration is in unit of ofdm symbols + int rangingslot = slotleft/2; + int rangingduration =(int) round(((mac_->getPhy()->getPS()*rangingslot)/mac_->getPhy()->getSymbolTime())); + int bwduration = (int) round(((mac_->getPhy()->getPS()*(slotleft - rangingslot))/mac_->getPhy()->getSymbolTime())); + + //we open the uplink to initial ranging and bw requests + //add profile for the ranging burst + p = map_->getUlSubframe()->addProfile (0, default_mod_); + p->setIUC (UIUC_INITIAL_RANGING); + ContentionSlot *slot = map_->getUlSubframe()->getRanging (); + slot->setSize (getInitRangingopportunity ()); + slot->setBackoff_start (mac_->macmib_.rng_backoff_start); + slot->setBackoff_stop (mac_->macmib_.rng_backoff_stop); + //create burst to represent the contention slot + Burst* b2 = map_->getUlSubframe()->addPhyPdu (0,0)->addBurst (0); + b2->setIUC (UIUC_INITIAL_RANGING); + b2->setDuration (rangingduration); + b2->setStarttime (0); //we put the contention at the begining + + //now the bw request + //add profile for the bw burst + p = map_->getUlSubframe()->addProfile (0, default_mod_); + p->setIUC (UIUC_REQ_REGION_FULL); + slot = map_->getUlSubframe()->getBw_req (); + slot->setSize (getBWopportunity ()); + slot->setBackoff_start (mac_->macmib_.bw_backoff_start); + slot->setBackoff_stop (mac_->macmib_.rng_backoff_stop); + b2 = map_->getUlSubframe()->addPhyPdu (1,0)->addBurst (0); + b2->setIUC (UIUC_REQ_REGION_FULL); + b2->setDuration (bwduration); + b2->setStarttime (rangingduration); //start after the ranging slot + + //end of map + b2 = map_->getUlSubframe()->addPhyPdu (2,0)->addBurst (0); + b2->setIUC (UIUC_END_OF_MAP); + b2->setStarttime (rangingduration+bwduration); + + //schedule the first frame by using a random backoff to avoid + //synchronization between BSs. + double stime = Random::uniform(0, mac_->getFrameDuration ()); + dl_timer_->sched (stime); + + ul_timer_->sched (stime+starttime*mac_->getPhy()->getPS()); + + //also start the DCD and UCD timer + dcdtimer_ = new WimaxDCDTimer (mac_); + ucdtimer_ = new WimaxUCDTimer (mac_); + nbradvtimer_ = new WimaxMobNbrAdvTimer (mac_); + dcdtimer_->start (mac_->macmib_.dcd_interval); + ucdtimer_->start (mac_->macmib_.ucd_interval); + nbradvtimer_->start (mac_->macmib_.nbr_adv_interval+stime); + +} + +/** + * Compute and return the bandwidth request opportunity size + * @return The bandwidth request opportunity size + */ +int BSScheduler::getBWopportunity () +{ + int nbPS = BW_REQ_PREAMBLE * mac_->getPhy()->getSymbolPS(); + //add PS for carrying header + nbPS += (int) round((mac_->getPhy()->getTrxTime (HDR_MAC802_16_SIZE, map_->getUlSubframe()->getProfile(UIUC_REQ_REGION_FULL)->getEncoding())/mac_->getPhy()->getPS ())); + //printf ("BWopportunity size=%d\n", nbPS); + return nbPS; +} + +/** + * Compute and return the initial ranging opportunity size + * @return The initial ranging opportunity size + */ +int BSScheduler::getInitRangingopportunity () +{ + int nbPS = INIT_RNG_PREAMBLE * mac_->getPhy()->getSymbolPS(); + //add PS for carrying header + nbPS += (int) round((mac_->getPhy()->getTrxTime (RNG_REQ_SIZE+HDR_MAC802_16_SIZE, map_->getUlSubframe()->getProfile(UIUC_INITIAL_RANGING)->getEncoding())/mac_->getPhy()->getPS ())); + //printf ("Init ranging opportunity size=%d\n", nbPS); + +/*if(NOW>60 && NOW<65) +printf("\nnbPS=%d, initRNG=%d, rngsize=%d, hdr=%d, uiuc=%d, encoding=%d", nbPS, INIT_RNG_PREAMBLE, RNG_REQ_SIZE, HDR_MAC802_16_SIZE, UIUC_INITIAL_RANGING, map_->getUlSubframe()->getProfile(UIUC_INITIAL_RANGING)->getEncoding()); +*/ + return nbPS; +} + +/** + * Called when a timer expires + * @param The timer ID + */ +void BSScheduler::expire (timer_id id) +{ + switch (id) { + case WimaxDCDTimerID: + sendDCD = true; + mac_->debug ("At %f in Mac %d DCDtimer expired\n", NOW, mac_->addr()); + dcdtimer_->start (mac_->macmib_.dcd_interval); + break; + case WimaxUCDTimerID: + sendUCD = true; + mac_->debug ("At %f in Mac %d UCDtimer expired\n", NOW, mac_->addr()); + ucdtimer_->start (mac_->macmib_.ucd_interval); + break; + case WimaxMobNbrAdvTimerID: + send_nbr_adv(); + nbradvtimer_->start (mac_->macmib_.nbr_adv_interval); + break; + default: + mac_->debug ("Warning: unknown timer expired in BSScheduler\n"); + } +} + +/** + * Set the control agent + */ +void BSScheduler::setCtrlAgent (WimaxCtrlAgent *agent) +{ + assert (agent); + ctrlagent_ = agent; +} + +/** + * Process a packet received by the Mac. Only scheduling related packets should be sent here (BW request, UL_MAP...) + * @param p The packet to process + */ +void BSScheduler::process (Packet * p) +{ + //assert (mac_); + //debug2 ("BSScheduler received packet to process\n"); + + assert (mac_ && HDR_CMN(p)->ptype()==PT_MAC); + debug2 ("BSScheduler received packet to process\n"); + + hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p); + gen_mac_header_t header = wimaxHdr->header; + + //check if this is a bandwidth request + if (header.ht == 1) { + process_bw_req (p); + return; + } + + //we cast to this frame because all management frame start with + //a type + mac802_16_dl_map_frame *frame = (mac802_16_dl_map_frame*) p->accessdata(); + + switch (frame->type) { + case MAC_RNG_REQ: + process_ranging_req (p); + break; + case MAC_REG_REQ: + process_reg_req (p); + break; + case MAC_MOB_SCN_REQ: + if (ctrlagent_) + ctrlagent_->process_scan_request (p); + else + fprintf (stderr, "Warning: no controler to handle scan request in BS %d\n", mac_->addr()); + break; + case MAC_MOB_MSHO_REQ: + process_msho_req (p); + break; + case MAC_MOB_HO_IND: + process_ho_ind (p); + break; + default: + mac_->debug ("unknown packet in BS\n"); + } + + Packet::free (p); +} + + +/** + * Return the type of STA this scheduler is good for + * @return STA_BS + */ +station_type_t BSScheduler::getNodeType () +{ + return STA_BS; +} + +/** + * Start a new frame + */ +void BSScheduler::start_ulsubframe () +{ + //mac_->debug ("At %f in Mac %d BS scheduler ulsubframe expires\n", NOW, mac_->addr()); + + //change PHY state + mac_->getPhy()->setMode (OFDM_RECV); + + //start handler of ulsubframe + map_->getUlSubframe()->getTimer()->sched (0); + + //reschedule for next frame + ul_timer_->resched (mac_->getFrameDuration()); +} + +/** + * Start a new frame + */ +void BSScheduler::start_dlsubframe () +{ + + debug2 ("At %f in Mac %d BS scheduler dlsubframe expires (frame=%d)\n", + NOW, mac_->addr(), mac_->frame_number_+1); + + assert (map_); + + Packet *p; + Burst *b; + struct hdr_cmn *ch; + double txtime; + int txtime_s; + OFDMPhy *phy = mac_->getPhy(); + + //increment frame number + mac_->frame_number_ ++; + + //adjust frame start information + map_->setStarttime(NOW); + + /* First lets clear the peers we haven't heard of for long time */ + for (PeerNode *pn = mac_->getPeerNode_head() ; pn ; ) { + PeerNode *tmp = pn->next_entry(); //next elem + if (isPeerScanning(pn->getPeerNode())) { + //since a scanning node cannot send data we push the + //timeout while it is scanning + pn->setRxTime(NOW); + } else if (NOW-pn->getRxTime()>mac_->macmib_.client_timeout) { + mac_->debug ("Client timeout for node %d\n", pn->getPeerNode()); + mac_->removePeerNode(pn); + } + pn = tmp; + } + + /**** Step one : burst allocation ****/ + int nbPS = (int) round((mac_->getFrameDuration()/phy->getPS())); + int nbPS_left = nbPS - mac_->phymib_.rtg - mac_->phymib_.ttg; + int nbSymbols = (int) ((phy->getPS()*nbPS_left)/phy->getSymbolTime()); + + int dlduration = INIT_DL_DURATION+DL_PREAMBLE; + int ulduration = 0; + debug2 ("Frame: duration=%f, PSduration=%e, symboltime=%e, nbPS=%d, rtg=%d, ttg=%d, PSleft=%d, nbSymbols=%d, ", \ + mac_->getFrameDuration(), phy->getPS(), phy->getSymbolTime(), nbPS, mac_->phymib_.rtg, mac_->phymib_.ttg, nbPS_left, nbSymbols); + + //remove control messages + nbSymbols -= INIT_DL_DURATION+DL_PREAMBLE; + + nbSymbols -=10; + + for (Connection *c = mac_->getCManager()->get_down_connection (); c && nbSymbols>0 ; c=c->next_entry()) { + if (c->getPeerNode() && !isPeerScanning (c->getPeerNode()->getPeerNode())) { + int queuesize = c->queueByteLength(); + int tmp = (int) round((phy->getTrxTime (queuesize, map_->getDlSubframe()->getProfile (DIUC_PROFILE_1)->getEncoding())/phy->getSymbolTime())); + if (tmp < nbSymbols) { + dlduration += tmp; + nbSymbols -= tmp; + }else{ + dlduration +=nbSymbols; + nbSymbols -= nbSymbols; + break; + } + } + } + nbSymbols +=10; + + map_->getDlSubframe()->getPdu()->getBurst(0)->setDuration (dlduration); + map_->getUlSubframe()->setStarttime (dlduration*phy->getSymbolPS()+mac_->phymib_.rtg); + ul_timer_->resched (map_->getUlSubframe()->getStarttime()*mac_->getPhy()->getPS()); + + debug2 ("dlduration=%d, ", dlduration); + //update the END_OF_MAP start time + b = (DlBurst*) map_->getDlSubframe()->getPdu ()->getBurst (1); + b->setStarttime (dlduration); + + while (map_->getUlSubframe()->getNbPdu()>0) { + PhyPdu *pdu = map_->getUlSubframe()->getPhyPdu(0); + map_->getUlSubframe()->removePhyPdu(pdu); + delete (pdu); + } + + int rangingduration = 0; + int bwduration = 0; + int pduIndex = 0; + debug2 ("In Mac %d Nb symbols left before contention =%d\n", mac_->addr(), nbSymbols); + + int contentionslots = (int) round((contention_size_*((getBWopportunity()+getInitRangingopportunity())*mac_->getPhy()->getPS()/mac_->getPhy()->getSymbolTime()))); + + if (nbSymbols > contentionslots) { + int starttime, slotleft, rangingslot, bwslot; + //create uplink + //start of UL subframe is after DL and TTG and unit is PS + starttime = map_->getUlSubframe()->getStarttime(); + slotleft = nbPS - starttime - mac_->phymib_.rtg; + //if there is at least one peer, then use only contention_size_ symbols, + //otherwise use all the bw + + if (mac_->getPeerNode_head() || fast_ranging_head_.lh_first) { + rangingslot = contention_size_*getInitRangingopportunity(); + bwslot = contention_size_*getBWopportunity(); + nbSymbols -= contentionslots; + debug2 ("nbSymbols after contention=%d\n", nbSymbols); + } + else { + rangingslot = (int) (floor (slotleft/(2.0*getInitRangingopportunity()))*getInitRangingopportunity()); + bwslot = (int) (floor ((slotleft-rangingslot)/getBWopportunity())*getBWopportunity()); + nbSymbols = 0; + } + rangingduration =(int) round(((mac_->getPhy()->getPS()*rangingslot)/mac_->getPhy()->getSymbolTime())); + bwduration = (int) round (((mac_->getPhy()->getPS()*bwslot)/mac_->getPhy()->getSymbolTime())); + //we open the uplink to initial ranging and bw requests + ContentionSlot *slot = map_->getUlSubframe()->getRanging (); + //create burst to represent the contention slot + Burst* b2 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); + pduIndex++; + b2->setIUC (UIUC_INITIAL_RANGING); + b2->setDuration (rangingduration); + b2->setStarttime (ulduration); //we put the contention at the begining + ulduration += rangingduration; + + //now the bw request + slot = map_->getUlSubframe()->getBw_req (); + b2 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); + pduIndex++; + b2->setIUC (UIUC_REQ_REGION_FULL); + b2->setDuration (bwduration); + b2->setStarttime (ulduration); //start after the ranging slot + ulduration += bwduration; + } + + //check if there is Fast Ranging allocation to do + while (fast_ranging_head_.lh_first !=NULL + && fast_ranging_head_.lh_first->frame() == mac_->getFrameNumber()) { + //we need to include a fast ranging allocation + b = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); + pduIndex++; + int tmp =(int) round(((mac_->getPhy()->getPS()*getInitRangingopportunity())/mac_->getPhy()->getSymbolTime())); + b->setIUC (UIUC_EXT_UIUC); + b->setDuration (tmp); + b->setStarttime (ulduration); //start after previous slot + ((UlBurst*)b)->setFastRangingParam (fast_ranging_head_.lh_first->macAddr(), UIUC_INITIAL_RANGING); + ulduration += tmp; + mac_->debug ("At %f in Mac %d adding fast ranging for %d\n", NOW, mac_->addr(), fast_ranging_head_.lh_first->macAddr()); + fast_ranging_head_.lh_first->remove_entry(); + } + + //get the next node to allocate bw. + //PB: the node may have been removed. We need to check that + PeerNode *peer = mac_->getPeerNode_head(); + PeerNode *start_peer = mac_->getPeerNode_head(); + int i=0; + if (start_peer != NULL) { + //we have at least one element in the list + for (peer = mac_->getPeerNode_head(); peer->next_entry() ; peer=peer->next_entry()); + debug2 ("start_peer=%d, peer=%d\n", start_peer->getPeerNode(), peer->getPeerNode()); + while (start_peer != peer) { + if (!isPeerScanning(peer->getPeerNode())) { + debug2 ("peer %d not scanning take it\n", peer->getPeerNode()); + break; //we found next station + } + debug2 ("peer %d scanning move it\n", peer->getPeerNode()); + peer->remove_entry(); + mac_->addPeerNode (peer); //we put it at head of the list + for (peer = mac_->getPeerNode_head(); peer->next_entry() ; peer=peer->next_entry()); + } + } + if (peer) + debug2 ("final pick is %d\n", peer->getPeerNode()); + + //update variables + bw_node_index_ = i; + bw_peer_ = peer; + + + + /// Added by Aymen + if (rtPSscheduling_ != rtPS_SCHEDULING_NIST_RR) + { + +if(peer) +{ + peer->remove_entry(); + mac_->addPeerNode (peer); //we put it at head of the list +} + + /// schedule UGS connections + scheduleUGSconnections(&nbSymbols, &ulduration, &pduIndex); + + + /// schedule connections that have sent bw req and do not have data connection + scheduleNoDataConnections(&nbSymbols, &ulduration, &pduIndex); + + + /// provide unicast request opportunities to rtPS connections + provideUnicastRequest(&nbSymbols, &ulduration, &pduIndex); + + /// schedule rtPS connections + if(rtPSscheduling_ == rtPS_SCHEDULING_RR) + schedule_RR(&nbSymbols, &ulduration, &pduIndex, SERVICE_rtPS); + else + if(rtPSscheduling_ == rtPS_SCHEDULING_mSIR) + schedule_mSIR(&nbSymbols, &ulduration, &pduIndex, SERVICE_rtPS); + else + if(rtPSscheduling_ == rtPS_SCHEDULING_mmSIR) + schedulertPSconnections_mmSIR(&nbSymbols, &ulduration, &pduIndex); + else + if(rtPSscheduling_ == rtPS_SCHEDULING_WRR) + schedule_WRR(&nbSymbols, &ulduration, &pduIndex, SERVICE_rtPS); + else + if(rtPSscheduling_ == rtPS_SCHEDULING_TRS_RR) + schedule_TRS_RR(&nbSymbols, &ulduration, &pduIndex, SERVICE_rtPS); + else + if(rtPSscheduling_ == rtPS_SCHEDULING_TRS_mSIR) + schedule_TRS_mSIR(&nbSymbols, &ulduration, &pduIndex, SERVICE_rtPS); + + /// schedule BE connections + if(BEscheduling_ == BE_SCHEDULING_RR) + schedule_RR(&nbSymbols, &ulduration, &pduIndex, SERVICE_BE); + else + if(BEscheduling_ == BE_SCHEDULING_mSIR) + schedule_mSIR(&nbSymbols, &ulduration, &pduIndex, SERVICE_BE); + else + if(BEscheduling_ == BE_SCHEDULING_WRR) + schedule_WRR(&nbSymbols, &ulduration, &pduIndex, SERVICE_BE); + + //scheduleBEconnections(&nbSymbols, &ulduration, &pduIndex); + + } + /// + + + +/// Added by Aymen +if(rtPSscheduling_ == rtPS_SCHEDULING_NIST_RR) +/// + //the next peer node takes the rest of the bw + + if (nbSymbols > 0 && peer && !isPeerScanning(peer->getPeerNode())) { + + debug2 ("Allocate uplink for STA %d\n", peer->getPeerNode()); + peer->remove_entry(); + mac_->addPeerNode (peer); //we put it at head of the list + + + //add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); + pduIndex++; + b3->setIUC (UIUC_PROFILE_1); + b3->setCid (peer->getPrimary()->get_cid()); + b3->setDuration (nbSymbols); + b3->setStarttime (ulduration); + + /// Added by Aymen + ulduration+= nbSymbols; + /// + + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (UIUC_PROFILE_1); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, default_mod_); + p->setIUC (UIUC_PROFILE_1); + } + + } + + + + //end of map + + + Burst *b2 = map_->getUlSubframe()->addPhyPdu (pduIndex,0)->addBurst (0); + pduIndex++; + b2->setIUC (UIUC_END_OF_MAP); + + /// Was written by Richard + /// b2->setStarttime (rangingduration+bwduration+nbSymbols); + + /// Replaced by aymen + b2->setStarttime (ulduration); + /// + + + + //we need to fill up the outgoing queues + for (int index = 0 ; index < map_->getDlSubframe()->getPdu ()->getNbBurst() ; index++) { + b = map_->getDlSubframe()->getPdu ()->getBurst (index); + int duration = 0; + + if (b->getIUC()==DIUC_END_OF_MAP) { + //consistency check.. + assert (index == map_->getDlSubframe()->getPdu ()->getNbBurst()-1); + break; + } + + //we can get the next one after we check END_OF_MAP + //b2 = map_->getDlSubframe()->getPdu ()->getBurst (index+1); + + //if this is the first buffer, add DL_MAP...messages + if (index==0) { + p = map_->getDL_MAP(); + ch = HDR_CMN(p); + txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); + ch->txtime() = txtime; + txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol + assert ((duration+txtime_s) <= b->getDuration()); + b->enqueue(p); //enqueue into burst + duration += txtime_s; + p = map_->getUL_MAP(); + ch = HDR_CMN(p); + txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); + ch->txtime() = txtime; + txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol + assert ((duration+txtime_s) <= b->getDuration()); + b->enqueue(p); //enqueue into burst + duration += txtime_s; + + if (sendDCD || map_->getDlSubframe()->getCCC()!= dlccc_) { + p = map_->getDCD(); + ch = HDR_CMN(p); + txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); + ch->txtime() = txtime; + txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol + assert ((duration+txtime_s) <= b->getDuration()); + b->enqueue(p); //enqueue into burst + duration += txtime_s; + sendDCD = false; + dlccc_ = map_->getDlSubframe()->getCCC(); + //reschedule timer + dcdtimer_->stop(); + dcdtimer_->start (mac_->macmib_.dcd_interval); + } + + if (sendUCD || map_->getUlSubframe()->getCCC()!= ulccc_) { + p = map_->getUCD(); + ch = HDR_CMN(p); + txtime = phy->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); + ch->txtime() = txtime; + txtime_s = (int) round(txtime/phy->getSymbolTime ()); //in units of symbol + assert ((duration+txtime_s) <= b->getDuration()); + b->enqueue(p); //enqueue into burst + duration += txtime_s; + sendUCD = false; + ulccc_ = map_->getUlSubframe()->getCCC(); + //reschedule timer + ucdtimer_->stop(); + ucdtimer_->start (mac_->macmib_.ucd_interval); + } + } + + + //get the packets from the connection with the same CID + //Connection *c=mac_->getCManager ()->get_connection (b->getCid()); + int nb_down = 0; + for (Connection *c = mac_->getCManager()->get_down_connection (); c ; c=c->next_entry()){ nb_down++;} + + Connection **tmp_con = (Connection **) malloc (nb_down*sizeof (Connection *)); + int i=0; + + for (Connection *c = mac_->getCManager()->get_down_connection (); c ; c=c->next_entry()){ + tmp_con[i] = c; + i++; + } + + //we randomly pick the connection we'll start serving first + /// Was coded by Richard + ///int start_index = (int) round (Random::uniform(0, nb_down)); + + /// Replaced by Aymen + int start_index = 0; + /// + + debug2 ("Picked connection %d as first\n", start_index); + + //for (Connection *c = mac_->getCManager()->get_down_connection (); c ; c=c->next_entry()) { + for (i=0; i < nb_down ; i++) { + int index = (i+start_index)%nb_down; + Connection *c=tmp_con[index]; + + if (c->getPeerNode() && isPeerScanning (c->getPeerNode()->getPeerNode())) + continue; + duration = transfer_packets (c, b, duration); + } + + free(tmp_con); + + } + + //change PHY state + mac_->getPhy()->setMode (OFDM_SEND); + + //start handler of dlsubframe + map_->getDlSubframe()->getTimer()->sched (0); + + //reschedule for next time (frame duration) + dl_timer_->resched (mac_->getFrameDuration()); + +} + +/** Add a new Fast Ranging allocation + * @param time The time when to allocate data + * @param macAddr The MN address + */ +void BSScheduler::addNewFastRanging (double time, int macAddr) +{ + //compute the frame where the allocation will be located + int frame = int ((time-NOW)/mac_->getFrameDuration()) +2 ; + frame += mac_->getFrameNumber(); + //printf ("Added fast RA for frame %d (current=%d) for time (%f)\n", + // frame, mac_->getFrameNumber(), time); + FastRangingInfo *info= new FastRangingInfo (frame, macAddr); + info->insert_entry(&fast_ranging_head_); +} + + +/**** Packet processing methods ****/ + +/** + * Process a RNG-REQ message + * @param p The packet containing the ranging request information + */ +void BSScheduler::process_ranging_req (Packet *p) +{ + UlSubFrame *ulsubframe = map_->getUlSubframe(); + mac802_16_rng_req_frame *req = (mac802_16_rng_req_frame *) p->accessdata(); + + if (HDR_MAC802_16(p)->header.cid != INITIAL_RANGING_CID) { + //process request for DIUC + } else { + //here we can make decision to accept the SS or not. + //for now, accept everybody + //check if CID already assigned for the SS + PeerNode *peer = mac_->getPeerNode (req->ss_mac_address); + if (peer==NULL) { + mac_->debug ("New peer node requesting ranging (%d)\n",req->ss_mac_address); + //Assign Management CIDs + Connection *basic = new Connection (CONN_BASIC); + Connection *upbasic = new Connection (CONN_BASIC, basic->get_cid()); + Connection *primary = new Connection (CONN_PRIMARY); + Connection *upprimary = new Connection (CONN_PRIMARY, primary->get_cid()); + + //Create Peer information + peer = new PeerNode (req->ss_mac_address); + peer->setBasic (basic); + peer->setPrimary (primary); + upbasic->setPeerNode (peer); + upprimary->setPeerNode (peer); + mac_->addPeerNode (peer); + + mac_->getCManager()->add_connection (upbasic, true); + mac_->getCManager()->add_connection (basic, false); + mac_->getCManager()->add_connection (upprimary, true); + mac_->getCManager()->add_connection (primary, false); + //schedule timer in case the node never register + addtimer17 (req->ss_mac_address); + + //create packet for answers + Packet *rep = mac_->getPacket (); + struct hdr_cmn *ch = HDR_CMN(rep); + rep->allocdata (sizeof (struct mac802_16_rng_rsp_frame)); + mac802_16_rng_rsp_frame *frame = (mac802_16_rng_rsp_frame*) rep->accessdata(); + frame->type = MAC_RNG_RSP; + frame->uc_id = ulsubframe->getChannelID(); + frame->rng_status = RNG_SUCCESS; + frame->ss_mac_address = req->ss_mac_address; + frame->basic_cid = basic->get_cid(); + frame->primary_cid = primary->get_cid(); + ch->size() = RNG_RSP_SIZE; + //compute transmission time + Burst *b = map_->getDlSubframe()->getPdu ()->getBurst (0); + double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); + ch->txtime() = txtime; + //enqueue packet + mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (rep); + + if (cl_head_==NULL) { + cl_head_ = (new_client_t*)malloc (sizeof (new_client_t)); + cl_tail_ = cl_head_; + } else { + cl_tail_->next = (new_client_t*)malloc (sizeof (new_client_t)); + cl_tail_=cl_tail_->next; + } + cl_tail_->cid = primary->get_cid(); + cl_tail_->next = NULL; + +#ifdef USE_802_21 + mac_->send_link_detected (mac_->addr(), peer->getPeerNode(), 1); +#endif + + } else { + mac_->debug ("Received ranging for known station (%d)\n", req->ss_mac_address); + //reset invited ranging retries for SS + //create packet for answers + Connection *basic = peer->getBasic(); + Connection *primary = peer->getPrimary(); + Packet *rep = mac_->getPacket (); + struct hdr_cmn *ch = HDR_CMN(rep); + rep->allocdata (sizeof (struct mac802_16_rng_rsp_frame)); + mac802_16_rng_rsp_frame *frame = (mac802_16_rng_rsp_frame*) rep->accessdata(); + frame->type = MAC_RNG_RSP; + frame->uc_id = ulsubframe->getChannelID(); + frame->rng_status = RNG_SUCCESS; + frame->ss_mac_address = req->ss_mac_address; + frame->basic_cid = basic->get_cid(); + frame->primary_cid = primary->get_cid(); + ch->size() = RNG_RSP_SIZE; + //compute transmission time + Burst *b = map_->getDlSubframe()->getPdu ()->getBurst (0); + double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); + ch->txtime() = txtime; + //enqueue packet + mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (rep); + } + } +} + +/** + * Add a new timer17 in the list. It also performs cleaning of the list + * @param index The client address + */ +void BSScheduler::addtimer17 (int index) +{ + //clean expired timers + T17Element *entry; + for (entry = t17_head_.lh_first; entry ; ) { + if (entry->paused ()) { + T17Element *tmp = entry; + entry = entry->next_entry(); + tmp->remove_entry(); + free (tmp); + } + entry = entry->next_entry(); + } + + entry = new T17Element (mac_, index); + entry->insert_entry (&t17_head_); +} +/** + * Cancel and remove the timer17 associated with the node + * @param index The client address + */ +void BSScheduler::removetimer17 (int index) +{ + //clean expired timers + T17Element *entry; + for (entry = t17_head_.lh_first; entry ; entry = entry->next_entry()) { + if (entry->index ()==index) { + entry->cancel(); + entry->remove_entry(); + delete (entry); + break; + } + } +} + +/** + * Process bandwidth request + * @param p The request + */ +void BSScheduler::process_bw_req (Packet *p) +{ + hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p); + gen_mac_header_t header = wimaxHdr->header; + + bw_req_header_t *req; + req = (bw_req_header_t *)&header; + + mac_->debug ("received bandwidth request of %d bytes from %d\n", req->br, req->cid); + + /// Added by Aymen + //Get the peer that sends the bw req + PeerNode * peer; + peer = mac_->getCManager()->get_connection (req->cid, false)->getPeerNode(); + //Add a new bandwidth to allocate + if(peer) + { + BandwidthToAllocate * bandwidthToAllocate = getBandwidthToAllocate(bandwidthtoallocate_head_, peer->getPeerNode()); + if(!bandwidthToAllocate) + { + BandwidthToAllocate *bandwidthentry = new BandwidthToAllocate (peer->getPeerNode(), req->br); + bandwidthentry->insert_entry (&bandwidthtoallocate_head_); + bandwidthentry = NULL; + } + else + { + if(req->type == 0) + { + bandwidthToAllocate->setBWincremental(req->br); //incremental bw req + } + else + { + bandwidthToAllocate->setBWaggregate(req->br); //aggregate bw req + } + } + } + else + { + printf("\n!!!! n%d does not exist (process bw req)",peer->getPeerNode()); + } +} + +/** + * Process registration request + * @param p The request + */ +void BSScheduler::process_reg_req (Packet *req) +{ + hdr_mac802_16 *wimaxHdr_req = HDR_MAC802_16(req); + gen_mac_header_t header_req = wimaxHdr_req->header; + + mac_->debug ("received registration request from %d\n", header_req.cid); + + Packet *p; + struct hdr_cmn *ch; + hdr_mac802_16 *wimaxHdr; + mac802_16_reg_rsp_frame *reg_frame; + PeerNode *peer; + + //create packet for request + p = mac_->getPacket (); + ch = HDR_CMN(p); + wimaxHdr = HDR_MAC802_16(p); + p->allocdata (sizeof (struct mac802_16_reg_rsp_frame)); + reg_frame = (mac802_16_reg_rsp_frame*) p->accessdata(); + reg_frame->type = MAC_REG_RSP; + reg_frame->response = 0; //OK + peer = mac_->getCManager()->get_connection (header_req.cid, false)->getPeerNode(); + Connection *secondary = peer->getSecondary (); + if (secondary==NULL) { + //first time + secondary = new Connection (CONN_SECONDARY); + Connection *upsecondary = new Connection (CONN_SECONDARY, secondary->get_cid()); + mac_->getCManager()->add_connection (upsecondary, true); + mac_->getCManager()->add_connection (secondary, false); + peer->setSecondary (secondary); + upsecondary->setPeerNode (peer); + } + reg_frame->sec_mngmt_cid = secondary->get_cid(); + wimaxHdr->header.cid = header_req.cid; + ch->size() = REG_RSP_SIZE; + + //compute transmission time + Burst *b = map_->getDlSubframe()->getPdu ()->getBurst (0); + double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); + ch->txtime() = txtime; + //enqueue packet + mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (p); + //clear t17 timer for this node + removetimer17 (peer->getPeerNode()); + +#ifdef USE_802_21 + mac_->debug ("At %f in Mac %d, send link up\n", NOW, mac_->addr()); + mac_->send_link_up (peer->getPeerNode(),mac_->addr()); +#endif +} + +/** + * Send a neighbor advertisement message + */ +void BSScheduler::send_nbr_adv () +{ + mac_->debug ("At %f in BS %d send_nbr_adv (nb_neighbor=%d)\n", NOW, mac_->addr(), nbr_db_->getNbNeighbor()); + Packet *p; + struct hdr_cmn *ch; + hdr_mac802_16 *wimaxHdr; + mac802_16_mob_nbr_adv_frame *frame; + //PeerNode *peer; + + //create packet for request + p = mac_->getPacket (); + ch = HDR_CMN(p); + wimaxHdr = HDR_MAC802_16(p); + p->allocdata (sizeof (struct mac802_16_mob_nbr_adv_frame)); + frame = (mac802_16_mob_nbr_adv_frame*) p->accessdata(); + frame->type = MAC_MOB_NBR_ADV; + frame->n_neighbors = nbr_db_->getNbNeighbor(); + frame->skip_opt_field = 0; + for (int i = 0 ; i < frame->n_neighbors ; i++) { + frame->nbr_info[i].phy_profile_id.FAindex = 0; + frame->nbr_info[i].phy_profile_id.bs_eirp = 0; + frame->nbr_info[i].nbr_bsid= nbr_db_->getNeighbors()[i]->getID(); + frame->nbr_info[i].dcd_included = true; + memcpy (&(frame->nbr_info[i].dcd_settings), nbr_db_->getNeighbors ()[i]->getDCD(), sizeof(mac802_16_dcd_frame)); + frame->nbr_info[i].ucd_included = true; + memcpy (&(frame->nbr_info[i].ucd_settings), nbr_db_->getNeighbors ()[i]->getUCD(), sizeof(mac802_16_ucd_frame)); + frame->nbr_info[i].phy_included = false; + } + ch->size() = Mac802_16pkt::getMOB_NBR_ADV_size(frame); + mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (p); + +} + +/** + * Finds out if the given station is currently scanning + * @param nodeid The MS id + */ +bool BSScheduler::isPeerScanning (int nodeid) +{ + ScanningStation *sta; + for (sta = scan_stations_.lh_first; sta ; sta = sta->next_entry()) { + if (sta->getNodeId()==nodeid && sta->isScanning(mac_->frame_number_)) { + //printf ("station %d scanning\n", nodeid); + return true; + } + } + return false; +} + +/** + * Process handover request + * @param p The request + */ +void BSScheduler::process_msho_req (Packet *req) +{ + hdr_mac802_16 *wimaxHdr_req = HDR_MAC802_16(req); + gen_mac_header_t header_req = wimaxHdr_req->header; + mac802_16_mob_msho_req_frame *req_frame = + (mac802_16_mob_msho_req_frame*) req->accessdata(); + + mac_->debug ("At %f in Mac %d received handover request from %d\n", NOW, mac_->addr(), header_req.cid); + + //check the BS that has stronger power + int maxIndex = 0; + int maxRssi = 0; //max value + for (int i = 0; i < req_frame->n_new_bs_full ; i++) { + if (req_frame->bs_full[i].bs_rssi_mean >= maxRssi) { + maxIndex = i; + maxRssi = req_frame->bs_full[i].bs_rssi_mean; + } + } + //reply with one recommended BS + Packet *p; + struct hdr_cmn *ch; + hdr_mac802_16 *wimaxHdr; + mac802_16_mob_bsho_rsp_frame *rsp_frame; + + send_nbr_adv (); //to force update with latest information + + //create packet for request + p = mac_->getPacket (); + ch = HDR_CMN(p); + wimaxHdr = HDR_MAC802_16(p); + p->allocdata (sizeof (struct mac802_16_mob_bsho_rsp_frame)+sizeof (mac802_16_mob_bsho_rsp_rec)); + rsp_frame = (mac802_16_mob_bsho_rsp_frame*) p->accessdata(); + rsp_frame->type = MAC_MOB_BSHO_RSP; + + rsp_frame->mode = 0; //HO request + rsp_frame->ho_operation_mode = 1; //mandatory handover response + rsp_frame->n_recommended = 1; + rsp_frame->resource_retain_flag = 0; //release connection information + rsp_frame->n_rec[0].neighbor_bsid = req_frame->bs_full[maxIndex].neighbor_bs_index; + rsp_frame->n_rec[0].ho_process_optimization=0; //no optimization + + ch->size() += Mac802_16pkt::getMOB_BSHO_RSP_size(rsp_frame); + wimaxHdr->header.cid = header_req.cid; + mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (p); +} + +/** + * Process handover indication + * @param p The indication + */ +void BSScheduler::process_ho_ind (Packet *p) +{ + hdr_mac802_16 *wimaxHdr_req = HDR_MAC802_16(p); + gen_mac_header_t header_req = wimaxHdr_req->header; + //mac802_16_mob_ho_ind_frame *req_frame = + // (mac802_16_mob_ho_ind_frame*) p->accessdata(); + + mac_->debug ("At %f in Mac %d received handover indication from %d\n", NOW, mac_->addr(), header_req.cid); + + +} + +/** + * Send a scan response to the MN + * @param rsp The response from the control + */ +void BSScheduler::send_scan_response (mac802_16_mob_scn_rsp_frame *rsp, int cid) +{ + //create packet for request + Packet *p = mac_->getPacket (); + struct hdr_cmn *ch = HDR_CMN(p); + hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p); + p->allocdata (sizeof (struct mac802_16_mob_scn_rsp_frame)); + mac802_16_mob_scn_rsp_frame* rsp_frame = (mac802_16_mob_scn_rsp_frame*) p->accessdata(); + memcpy (rsp_frame, rsp, sizeof (mac802_16_mob_scn_rsp_frame)); + rsp_frame->type = MAC_MOB_SCN_RSP; + + wimaxHdr->header.cid = cid; + ch->size() += Mac802_16pkt::getMOB_SCN_RSP_size(rsp_frame); + + //add scanning station to the list + PeerNode *peer = mac_->getCManager()->get_connection (cid, false)->getPeerNode(); + + /* The request is received in frame i, the reply is sent in frame i+1 + * so the frame at which the scanning start is start_frame+2 + */ + ScanningStation *sta = new ScanningStation (peer->getPeerNode(), rsp_frame->scan_duration & 0xFF, + rsp_frame->start_frame+mac_->frame_number_+2, + rsp_frame->interleaving_interval & 0xFF, + rsp_frame->scan_iteration & 0xFF); + sta->insert_entry_head (&scan_stations_); + + //compute transmission time + Burst *b = map_->getDlSubframe()->getPdu ()->getBurst (0); + double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getDlSubframe()->getProfile (b->getIUC())->getEncoding()); + ch->txtime() = txtime; + //enqueue packet + mac_->getCManager()->get_connection (BROADCAST_CID, false)->enqueue (p); +} + + + +/// Added by Aymen +/** + * get the corresponding UIUC value + * @param ReceivedSNR The received signal-to-noise ratio + * @return The corresponding UIUC value + */ +uiuc_t BSScheduler::getUIUCvalue(float ReceivedSNR){ +if (ReceivedSNR >= SNR_64QAM_3_4) + return UIUC_PROFILE_8; + else + if (ReceivedSNR >= SNR_64QAM_2_3) + return UIUC_PROFILE_7; + else + if (ReceivedSNR >= SNR_16QAM_3_4) + return UIUC_PROFILE_6; + else + if (ReceivedSNR >= SNR_16QAM_1_2) + return UIUC_PROFILE_5; + else + if (ReceivedSNR >= SNR_QPSK_3_4) + return UIUC_PROFILE_4; + else + if (ReceivedSNR >= SNR_QPSK_1_2) + return UIUC_PROFILE_3; + else + if (ReceivedSNR >= SNR_BPSK_1_2) + return UIUC_PROFILE_2; + else + return UIUC_PROFILE_2; // to be modified +} + + + +/** + * get the peer number + * @return The peer number + */ +int BSScheduler::getPeerNumber(){ + int peernumber = 0; + for (PeerNode *pn = mac_->getPeerNode_head() ; pn ; ) + { + PeerNode *tmp = pn->next_entry(); //next elem + + peernumber ++; + + pn = tmp; + } + + return peernumber; +} + + + +/** + * get the peer number for a service flow scheduling type + * @param scheduling The service flow scheduling type + * @return The peer number for a service flow scheduling type + */ +int BSScheduler::getPeerNumber(SchedulingType_t scheduling){ + int peernumber = 0; + for (PeerNode *pn = mac_->getPeerNode_head() ; pn ; ) + { + PeerNode *tmp = pn->next_entry(); //next elem + + if(pn->getInData()) + { + if(pn->getInData()->get_serviceflow()->getScheduling() == scheduling) + { + peernumber ++; + } + } + + pn = tmp; + } + + return peernumber; +} + + + +/** + * get the peer set + * @return The peer set + */ +PeerNode ** BSScheduler::getPeerSet(){ + int peernumber = getPeerNumber(); + PeerNode **tmp_peer = (PeerNode **) malloc (peernumber*sizeof (PeerNode *)); + int i = 0; + for (PeerNode *pn = mac_->getPeerNode_head() ; pn ; ) + { + PeerNode *tmp = pn->next_entry(); //next elem + + tmp_peer[i] = pn; + i++; + + pn = tmp; + } + + return tmp_peer; +} + + + +/** + * get the peer set for a service flow scheduling type + * @param scheduling The service flow scheduling type + * @return The peer set for a service flow scheduling type + */ +PeerNode ** BSScheduler::getPeerSet(SchedulingType_t scheduling){ + int peernumber = getPeerNumber(scheduling); + PeerNode **tmp_peer = (PeerNode **) malloc (peernumber*sizeof (PeerNode *)); + int i = 0; + for (PeerNode *pn = mac_->getPeerNode_head() ; pn ; ) + { + PeerNode *tmp = pn->next_entry(); //next elem + + if(pn->getInData()) + { + if(pn->getInData()->get_serviceflow()->getScheduling() == scheduling) + { + tmp_peer[i] = pn; + i++; + } + } + + pn = tmp; + } + + return tmp_peer; +} + + + +/** + * Verify if the peer node exists in the scheduling management list + * @param head The scheduling management list + * @param peernode The peer node to look for + * @return true if the peer node exists in the scheduling management list, and false else + */ +bool BSScheduler::searchSchedulingManagement(struct schedulingmanagement head, int peernode){ + SchedulingManagement *entry; + for (entry = head.lh_first; entry ; ) { + if (entry->getNode () == peernode) { + return true; + } + entry = entry->next_entry(); + } + return false; +} + + +/** + * Modify the periodicity + * @param head The scheduling management list + * @param peernode The peer node + * @param periodicity The periodicity + */ +void BSScheduler::modifySchedulingManagement(struct schedulingmanagement head, int peernode, int periodicity){ + SchedulingManagement *entry; + for (entry = head.lh_first; entry ; ) { + if (entry->getNode () == peernode) { + entry->setPeriodicity(periodicity); + return; + } + entry = entry->next_entry(); + } +} + + + +/** + * Modify the periodicity + * @param head The scheduling management list + * @param peernode The peer node + * @param periodicity The periodicity + * @param iteration The iteration + */ +void BSScheduler::modifySchedulingManagement(struct schedulingmanagement head, int peernode, int periodicity, int iteration){ + SchedulingManagement *entry; + for (entry = head.lh_first; entry ; ) { + if (entry->getNode () == peernode) { + entry->setPeriodicity(periodicity); + entry->setIteration((iteration % periodicity)); + return; + } + entry = entry->next_entry(); + } +} + + + +/** + * increment the iteration of the peer node + * @param head The scheduling management list + * @param peernode The peer node + */ + void BSScheduler::incrementSchedulingManagement(struct schedulingmanagement head, int peernode){ + SchedulingManagement *entry; + for (entry = head.lh_first; entry ; ) { + if (entry->getNode () == peernode) { + entry->setIteration((entry->getIteration()+1)%entry->getPeriodicity()); + return; + } + entry = entry->next_entry(); + } + return; +} + + + +/** + * increment the iteration of the peer node without taking account the periodicity + * @param head The scheduling management list + * @param peernode The peer node + */ + void BSScheduler::incrementSchedulingManagement_NoPeriodicity(struct schedulingmanagement head, int peernode){ + SchedulingManagement *entry; + for (entry = head.lh_first; entry ; ) { + if (entry->getNode () == peernode) { + entry->setIteration((entry->getIteration()+1)); + return; + } + entry = entry->next_entry(); + } + return; +} + + + +/** + * get the connection management of the peer node + * @param head The scheduling management list + * @param peernode The peer node + * @return the connection management of the peer node + */ + SchedulingManagement *BSScheduler::getSchedulingManagement(struct schedulingmanagement head, int peernode){ + SchedulingManagement *entry; + for (entry = head.lh_first; entry ; ) { + if (entry->getNode () == peernode) { + return entry; + } + entry = entry->next_entry(); + } + return NULL; +} + + + +/** + * get the bandwidth request transmitted by the peer node + * @param head The list of the bandwidth to be allocated + * @param peernode The peer node + * @return the bandwidth request transmitted by the peer node + */ + BandwidthToAllocate *BSScheduler::getBandwidthToAllocate(struct bandwidthtoallocate head, int peernode){ + BandwidthToAllocate *entry; + for (entry = head.lh_first; entry ; ) { + if (entry->getNode () == peernode) { + return entry; + } + entry = entry->next_entry(); + } + return NULL; +} + + + +/** + * get the characteristics of the TRS Suspend Procedure + * @param head The list of nodes that are scheduled with the TRS scheduler + * @param peernode The peer node + * @return the characteristics of the TRS scheduler for the peer node + */ + TRS_SuspendProcedure *BSScheduler::getTRS_SuspendProcedure(struct trs_suspendprocedure head, int peernode){ + TRS_SuspendProcedure *entry; + for (entry = head.lh_first; entry ; ) { + if (entry->getNode () == peernode) { + return entry; + } + entry = entry->next_entry(); + } + return NULL; +} + + + +/** + * Schedule the UGS connections + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::scheduleUGSconnections(int *nbsymbols, int * ulduration, int * pduindex) +{ + + // determine the number of UGS connections + int UGS_connection_number = getPeerNumber(SERVICE_UGS); + + if(UGS_connection_number == 0) + return; + + // determine all peers that have UGS connections + PeerNode **tmp_peer_ugs = getPeerSet(SERVICE_UGS); + + //we randomly pick the connection we'll start serving first + int start_index = 0;//(int) round (Random::uniform(0, UGS_connection_number)); + + for (int i=0; i < UGS_connection_number ; i++) { + int index = (i+start_index)%UGS_connection_number; + PeerNode *pn = tmp_peer_ugs[index]; + + // verify if there is an entry for this peer in scheduling management list + if(!searchSchedulingManagement(ugsmanagement_head_, pn->getPeerNode())) + { + SchedulingManagement *ugsmanagemententry = new SchedulingManagement (pn->getPeerNode()); + ugsmanagemententry->insert_entry (&ugsmanagement_head_); + } + + // check the periodicity of the UGS connection + if(getSchedulingManagement(ugsmanagement_head_, pn->getPeerNode())->getIteration() != 0) + { + incrementSchedulingManagement(ugsmanagement_head_, pn->getPeerNode()); + continue; + } + else + { + incrementSchedulingManagement(ugsmanagement_head_, pn->getPeerNode()); + } + + // determine the transmission time for the UGS connection (take into account the periodicity) + double duration = mac_->getPhy()->getTrxTime(pn->getInData()->get_serviceflow()->getMaximumSustainedTrafficRate() * getSchedulingManagement(ugsmanagement_head_, pn->getPeerNode())->getPeriodicity(), pn->getOfdm_mod_rate()); + + // determine the number of symbols to be reserved for this UGS connection + int symbols = (int) ceil(duration / mac_->getPhy()->getSymbolTime()); + + // symbols are not enough + if((symbols + SymbolsForPreamble_) > *nbsymbols){ + //if(NOW > 2.0) + printf("\nAt %f, (UGS connection) insufficient resources for n%d (required symbols = %d remaining symbols = %d", NOW, pn->getPeerNode(), symbols, *nbsymbols); + continue; + } + + + // add preamble (SymbolsForPreamble_) + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p4->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + //addPreamble(nbsymbols, ulduration, pduindex); + + //add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (/*UIUC_PROFILE_1*/getUIUCvalue(pn->getReceivedSNR())); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, /*default_mod_*/pn->getOfdm_mod_rate()); + p->setIUC (/*UIUC_PROFILE_1*/getUIUCvalue(pn->getReceivedSNR())); + } + + if(*nbsymbols == 0) + { + free(tmp_peer_ugs); + return; + } + + } + + free(tmp_peer_ugs); + +} + + + +/** + * Provide periodic unicast request opportunities + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::provideUnicastRequest(int *nbsymbols, int * ulduration, int * pduindex) +{ + if(*nbsymbols == 0) + return; + + // determine the number of rtPS connections + int rtPS_connection_number = getPeerNumber(SERVICE_rtPS); + + if(rtPS_connection_number == 0) + return; + + // determine all peers that have rtPS connections + PeerNode **tmp_peer_rtPS = getPeerSet(SERVICE_rtPS); + + //we randomly pick the connection we'll start serving first + int start_index = 0;//(int) round (Random::uniform(0, rtPS_connection_number)); + + // allocate symbols for unicast request + for (int i=0; i < rtPS_connection_number ; i++) { + int index = (i+start_index)%rtPS_connection_number; + PeerNode *pn = tmp_peer_rtPS[index]; + + // verify if there is an entry for this peer in scheduling management list + if(!searchSchedulingManagement(UnicastRequest_rtPSmanagement_head_, pn->getPeerNode())) + { + SchedulingManagement *rtPSmanagemententry = new SchedulingManagement (pn->getPeerNode()); + rtPSmanagemententry->insert_entry (&UnicastRequest_rtPSmanagement_head_); + } + + // check the periodicity of the rtPS connection + if(getSchedulingManagement(UnicastRequest_rtPSmanagement_head_, pn->getPeerNode())->getIteration() != 0) + { + incrementSchedulingManagement(UnicastRequest_rtPSmanagement_head_, pn->getPeerNode()); + continue; + } + else + { + incrementSchedulingManagement(UnicastRequest_rtPSmanagement_head_, pn->getPeerNode()); + } + + + // determine the number of symbols to be allocated + int symbols = SymbolNumberForUnicastRequest_; + + // symbols are not enough (with preamble) + if((symbols + SymbolsForPreamble_) > *nbsymbols) + { + if(*nbsymbols < SymbolsForPreamble_) + { + free(tmp_peer_rtPS); + return; + } + + symbols = *nbsymbols - SymbolsForPreamble_; + } + + + // add Preamble + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p4->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + //addPreamble(nbsymbols, ulduration, pduindex); + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(UIUC_REQ_REGION_FOCUSED); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (UIUC_REQ_REGION_FOCUSED); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p->setIUC (UIUC_REQ_REGION_FOCUSED); + } + + + if(*nbsymbols == 0) + { + free(tmp_peer_rtPS); + return; + } + + } + + free(tmp_peer_rtPS); + +} + + + +/** + * Use the RR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::schedule_RR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type) +{ + if(*nbsymbols == 0) + return; + + // determine the number of connections (type) + int connection_number = getPeerNumber(type); + + if(connection_number == 0) + return; + + // determine the last peer served + int last_peer_RR; + if(type == SERVICE_rtPS) + last_peer_RR = last_rtPS_peer_RR_; + else + if(type == SERVICE_BE) + last_peer_RR = last_BE_peer_RR_; + else + { + printf("\nError, RR is applied only for rtPS and BE connections!"); + return; + } + + // determine all peers that have "type" connections + PeerNode **tmp_peer = getPeerSet(type); + + // initialize last_peer_RR + if(last_peer_RR == UNDEFINED_NODE) + last_peer_RR = tmp_peer[connection_number - 1]->getPeerNode(); + + // determine the address of the first served node in the last round + int indice = 0; + for (int i=0; i < connection_number ; i++) { + PeerNode *pn = tmp_peer[i]; + if(pn->getPeerNode() == last_peer_RR) + { + indice = i; + break; + } + } + + // serve the next node + indice++; + + // nb of served SS + int nbSS = 0; + + FILE * pFile; + if(type == SERVICE_rtPS) + pFile = pFile_rtPS; + else + pFile = pFile_BE; + + + for (int i=0; i < connection_number ; i++) { + int index = (i+indice)%connection_number; + PeerNode *pn = tmp_peer[index]; + + // save the first served node + if(i==0) + last_peer_RR = pn->getPeerNode(); + + if(type == SERVICE_rtPS) + last_rtPS_peer_RR_ = last_peer_RR; + else + if(type == SERVICE_BE) + last_BE_peer_RR_ = last_peer_RR; + + // determine the BR of the bandwidth request + BandwidthToAllocate * bandwidth = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + if(!bandwidth) + continue; + +/// There is no data to send +if(bandwidth->getRemindBW() <= 0) + continue; + + // determine the transmission time for the connection + double duration = mac_->getPhy()->getTrxTime(bandwidth->getRemindBW(), pn->getOfdm_mod_rate()); + + // determine the number of symbols to be reserved for this connection + int symbols = (int) ceil(duration / mac_->getPhy()->getSymbolTime()); + + + // symbols are not enough (with preamble) + if((symbols + SymbolsForPreamble_) > *nbsymbols) + { + if(*nbsymbols < SymbolsForPreamble_) + { + fprintf (pFile, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer); + return; + } + + symbols = *nbsymbols - SymbolsForPreamble_; + } + + + // add Preamble + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p4->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + //addPreamble(nbsymbols, ulduration, pduindex); + + // update the remind BW to allocate + bandwidth->setRemindBW(bandwidth->getRemindBW() - mac_->getPhy()->getMaxPktSize(symbols, pn->getOfdm_mod_rate())); + + // update "RemindBW" if there is no symbol to allocate + if(bandwidth->getRemindBW() <= 0) + { + bandwidth->setBWaggregate(0); + } + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + // increment the nb of served SS + nbSS++; + + if(*nbsymbols == 0) + { + fprintf (pFile, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer); + return; + } + + } + + fprintf (pFile, "%f\t%d\n",NOW,nbSS); + free(tmp_peer); + +} + + + +/** + * Use the maximum SIR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::schedule_mSIR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type) +{ + if(*nbsymbols == 0) + return; + + // determine the number of "type" connections + int connection_number = getPeerNumber(type); + + if(connection_number == 0) + return; + + // determine all peers that have "type" connections + PeerNode **tmp_peer = getPeerSet(type); + + // order peers using the received SIR + for(int j = 0; j < connection_number; j++) + for(int k = 0; k < (connection_number - 1); k++) + if(tmp_peer[k]->getReceivedSNR() < tmp_peer[k+1]->getReceivedSNR()) + { + PeerNode * tmp_p; + tmp_p = tmp_peer[k]; + tmp_peer[k] = tmp_peer[k+1]; + tmp_peer[k+1] = tmp_p; + tmp_p = NULL; + } + + + + // nb of served SS + int nbSS = 0; + + FILE * pFile; + if(type == SERVICE_rtPS) + pFile = pFile_rtPS; + else + pFile = pFile_BE; + + + for (int i=0; i < connection_number ; i++) { + PeerNode *pn = tmp_peer[i]; + + // determine the BR of the bandwidth request + BandwidthToAllocate * bandwidth = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + if(!bandwidth) + continue; + + // determine the transmission time for the connection + double duration = mac_->getPhy()->getTrxTime(bandwidth->getRemindBW(), pn->getOfdm_mod_rate()); + + // determine the number of symbols to be reserved for this connection + int symbols = (int) ceil(duration / mac_->getPhy()->getSymbolTime()); + +/* + // symbols are not enough (without preamble) + if(symbols > *nbsymbols) + { + symbols = *nbsymbols; + } +*/ + + + + // symbols are not enough (with preamble) + if((symbols + SymbolsForPreamble_) > *nbsymbols) + { + if(*nbsymbols < SymbolsForPreamble_) + { + fprintf (pFile, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer); + return; + } + symbols = *nbsymbols - SymbolsForPreamble_; + } + + + // add preamble + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p4->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + //addPreamble(nbsymbols, ulduration, pduindex); + + // update the remind BW to allocate + bandwidth->setRemindBW(bandwidth->getRemindBW() - mac_->getPhy()->getMaxPktSize(symbols, pn->getOfdm_mod_rate())); + + // delete the BW request if there are no symbols to allocate + if(bandwidth->getRemindBW() <= 0) + { + bandwidth->remove_entry(); + } + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + // increment the nb of served SS + nbSS++; + + if(*nbsymbols == 0) + { + fprintf (pFile, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer); + return; + } + + } + + fprintf (pFile, "%f\t%d\n",NOW,nbSS); + free(tmp_peer); + +} + + + +/** + * Schedule the rtPS connections using the modified maximum SIR (mmSIR) algorithm + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::schedulertPSconnections_mmSIR(int *nbsymbols, int * ulduration, int * pduindex) +{ + if(*nbsymbols == 0) + return; + + // determine the number of rtPS connections + int rtPS_connection_number = getPeerNumber(SERVICE_rtPS); + + if(rtPS_connection_number == 0) + return; + + // determine all peers that have rtPS connections + PeerNode **tmp_peer_rtPS = getPeerSet(SERVICE_rtPS); + + // order peers using the received SIR + for(int j = 0; j < rtPS_connection_number; j++) + for(int k = 0; k < (rtPS_connection_number - 1); k++) + if(tmp_peer_rtPS[k]->getReceivedSNR() < tmp_peer_rtPS[k+1]->getReceivedSNR()) + { + PeerNode * tmp_peer; + tmp_peer = tmp_peer_rtPS[k]; + tmp_peer_rtPS[k] = tmp_peer_rtPS[k+1]; + tmp_peer_rtPS[k+1] = tmp_peer; + tmp_peer = NULL; + } + + + // nb of served SS + int nbSS = 0; + + for (int i=0; i < rtPS_connection_number ; i++) { + PeerNode *pn = tmp_peer_rtPS[i]; + + // determine the BR of the bandwidth request + BandwidthToAllocate * bandwidth = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + if(!bandwidth) + continue; + + // determine the transmission time for the rtPS connection + double duration = mac_->getPhy()->getTrxTime(bandwidth->getRemindBW(), pn->getOfdm_mod_rate()); + + // determine the number of symbols to be reserved for this rtPS connection + int symbols = (int) ceil(duration / mac_->getPhy()->getSymbolTime()); + +/* + // symbols are not enough (without preamble) + if(symbols > *nbsymbols) + { + symbols = *nbsymbols; + } +*/ + + + /// mmSIR scheduler + // verify if there is an entry for this peer in scheduling management list + if(!searchSchedulingManagement(UnicastRequest_rtPSmanagement_head_, pn->getPeerNode())) + {printf("\n\nNo entry in BSScheduler::schedulertPS at %f", NOW); + SchedulingManagement *rtPSmanagemententry = new SchedulingManagement (pn->getPeerNode()); + rtPSmanagemententry->insert_entry (&UnicastRequest_rtPSmanagement_head_); + } + + // check the periodicity of the rtPS connection + if(getSchedulingManagement(UnicastRequest_rtPSmanagement_head_, pn->getPeerNode())->getIteration() == 1) + continue; + + + // symbols are not enough (with preamble) + if((symbols + SymbolsForPreamble_) > *nbsymbols) + { + if(*nbsymbols < SymbolsForPreamble_) + { + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer_rtPS); + return; + } + symbols = *nbsymbols - SymbolsForPreamble_; + } + + + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p4->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + //addPreamble(nbsymbols, ulduration, pduindex); + + // update the remind BW to allocate + bandwidth->setRemindBW(bandwidth->getRemindBW() - mac_->getPhy()->getMaxPktSize(symbols, pn->getOfdm_mod_rate())); + + // delete the BW request if there are no symbols to allocate + if(bandwidth->getRemindBW() <= 0) + { + bandwidth->remove_entry(); + } + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + // increment the nb of served SS + nbSS++; + + if(*nbsymbols == 0) + { + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer_rtPS); + return; + } + + } + + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + free(tmp_peer_rtPS); + +} + + + +/** + * Use the WRR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::schedule_WRR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type) +{ + if(*nbsymbols == 0) + return; + + // determine the number of connections + int connection_number = getPeerNumber(type); + + if(connection_number == 0) + return; + + // determine all peers that have "type" connections + PeerNode **tmp_peer = getPeerSet(type); + + // determine the last peer served + int last_peer_WRR; + if(type == SERVICE_rtPS) + last_peer_WRR = last_rtPS_peer_WRR_; + else + if(type == SERVICE_BE) + last_peer_WRR = last_BE_peer_WRR_; + else + { + printf("\nError, WRR is applied only for rtPS and BE connections!"); + return; + } + + // nb of served SS + int nbSS = 0; + + FILE * pFile; + if(type == SERVICE_rtPS) + pFile = pFile_rtPS; + else + pFile = pFile_BE; + + + // determine the address of the node served in the last round + int indice = 0; + + // initialize last_peer_WRR + if(last_peer_WRR == UNDEFINED_NODE) + { + last_peer_WRR = 1; + + for (int i=0; i < connection_number ; i++) + { + PeerNode *pn = tmp_peer[i]; + if(pn->getPeerNode() > last_peer_WRR) + { + indice = i; + } + } + last_peer_WRR = tmp_peer[indice]->getPeerNode(); + } + + + + for (int i=0; i < connection_number ; i++) { + PeerNode *pn = tmp_peer[i]; + if(pn->getPeerNode() == last_peer_WRR) + { + indice = i; + break; + } + } + + // serve the next node + indice++; + + + // verify if the cycle is complete + bool cycle = true; + for (int i=0; i < connection_number ; i++) { + PeerNode *pn = tmp_peer[i]; + + if(!searchSchedulingManagement(WRR_management_head_, pn->getPeerNode())) + { + SchedulingManagement *managemententry = new SchedulingManagement (pn->getPeerNode()); + managemententry->insert_entry (&WRR_management_head_); + } + + if(getSchedulingManagement(WRR_management_head_, pn->getPeerNode())->getIteration() < getSchedulingManagement(WRR_management_head_, pn->getPeerNode())->getPeriodicity()) + { + cycle = false; + break; + } + } + + // reset the WRR_management_head_ to begin a new cycle + if(cycle) + { + for (int i=0; i < connection_number ; i++) + { + PeerNode *pn = tmp_peer[i]; + getSchedulingManagement(WRR_management_head_, pn->getPeerNode())->setIteration(0); + } + + indice = 0; + + //last_peer_WRR = 1; + + for (int i=0; i < connection_number ; i++) + { + PeerNode *pn = tmp_peer[i]; + if(pn->getPeerNode() > last_peer_WRR) + { + indice = i; + } + } + last_peer_WRR = tmp_peer[indice]->getPeerNode(); + + //if(NOW>40.0&&NOW<40.5) + //printf("\nNew cycle at:%f, last peer = %d, indice=%d)",NOW, last_peer_WRR, indice); + + } + + + bool increment_once = true; + +/// css +/*if(NOW>40.0&&NOW<40.5) +{ + printf("\n\nAt %f:", NOW); + for (int i=0; i < connection_number ; i++) + { + PeerNode *pn = tmp_peer[i]; + BandwidthToAllocate * bandwidth = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + + + + if(bandwidth) + { + // determine the transmission time for the connection + double duration = mac_->getPhy()->getTrxTime(bandwidth->getRemindBW(), pn->getOfdm_mod_rate()); + + // determine the number of symbols to be reserved for this connection + int symbols = (int) ceil(duration / mac_->getPhy()->getSymbolTime()); + printf("\nNode %d demande %d symboles", pn->getPeerNode(), symbols); + } + else + printf("\nNode %d demande 0 symboles", pn->getPeerNode()); + } +}*/ +/// + + // schedule the connections + for (int i=0; i < connection_number ; i++) { + int index = (i+indice)%connection_number; + PeerNode *pn = tmp_peer[index]; + + // save the first served node + if(i==0) + last_peer_WRR = pn->getPeerNode(); + + if(type == SERVICE_rtPS) + last_rtPS_peer_WRR_ = last_peer_WRR; + else + if(type == SERVICE_BE) + last_BE_peer_WRR_ = last_peer_WRR; + + // verify if there is an entry for this peer in scheduling management list + if(!searchSchedulingManagement(WRR_management_head_, pn->getPeerNode())) + { + SchedulingManagement *managemententry = new SchedulingManagement (pn->getPeerNode()); + managemententry->insert_entry (&WRR_management_head_); + } + + // check the periodicity of the connection + if(getSchedulingManagement(WRR_management_head_, pn->getPeerNode())->getIteration() < getSchedulingManagement(WRR_management_head_, pn->getPeerNode())->getPeriodicity()) + { + + if(increment_once == true) + { + incrementSchedulingManagement_NoPeriodicity(WRR_management_head_, pn->getPeerNode()); + increment_once = false; + } + } + else + { + continue; + } + + + + // determine the BR of the bandwidth request + BandwidthToAllocate * bandwidth = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + if(!bandwidth) + continue; + + // determine the transmission time for the connection + double duration = mac_->getPhy()->getTrxTime(bandwidth->getRemindBW(), pn->getOfdm_mod_rate()); + + // determine the number of symbols to be reserved for this connection + int symbols = (int) ceil(duration / mac_->getPhy()->getSymbolTime()); + +/* + // symbols are not enough (without preamble) + if(symbols > *nbsymbols) + { + symbols = *nbsymbols; + } +*/ + + // symbols are not enough (with preamble) + if((symbols + SymbolsForPreamble_) > *nbsymbols) + { + if(*nbsymbols < SymbolsForPreamble_) + { + fprintf (pFile, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer); + return; + } + + symbols = *nbsymbols - SymbolsForPreamble_; + } + + + + // add Preamble + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p4->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + //addPreamble(nbsymbols, ulduration, pduindex); + + // update the remind BW to allocate + bandwidth->setRemindBW(bandwidth->getRemindBW() - mac_->getPhy()->getMaxPktSize(symbols, pn->getOfdm_mod_rate())); + + // delete the BW request if there are no symbols to allocate + if(bandwidth->getRemindBW() <= 0) + { + bandwidth->remove_entry(); + } + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + +/* +if(NOW>40.0&&NOW<40.5) +if(type == SERVICE_BE) +printf("\nAt %f, reserve %d symbols to n %d", NOW, symbols, pn->getPeerNode()); +*/ + + // increment the nb of served SS + nbSS++; + + if(*nbsymbols == 0) + { + fprintf (pFile, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer); + return; + } + + } + + fprintf (pFile, "%f\t%d\n",NOW,nbSS); + free(tmp_peer); + +} + + + +/** + * Use the TRS_RR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::schedule_TRS_RR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type) +{ + + if(*nbsymbols == 0) + return; + + // determine the number of rtPS connections + int rtPS_connection_number = getPeerNumber(SERVICE_rtPS); + + if(rtPS_connection_number == 0) + return; + + // determine all peers that have rtPS connections + PeerNode **tmp_peer_rtPS = getPeerSet(SERVICE_rtPS); + + // allocate a structure that contains the peers that will be scheduled at the current frame + PeerNode **tmp_peer_TRS = (PeerNode **) malloc (rtPS_connection_number*sizeof (PeerNode *)); + int ScheduledPeerNumber = 0; + + for (int i=0; i < rtPS_connection_number ; i++) { + PeerNode *pn = tmp_peer_rtPS[i]; + + // determine the BR of the bandwidth request + BandwidthToAllocate * bandwidth = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + if(!bandwidth) + continue; + + if(bandwidth->getRemindBW() <= 0) + continue; + + TRS_SuspendProcedure * trs_node = getTRS_SuspendProcedure(trs_suspendprocedure_head_, pn->getPeerNode()); + + // create a new entry if it did not exist + if(trs_node == NULL) + { + TRS_SuspendProcedure *SuspendProcedure_entry = new TRS_SuspendProcedure (pn->getPeerNode()); + SuspendProcedure_entry->insert_entry (&trs_suspendprocedure_head_); + trs_node = getTRS_SuspendProcedure(trs_suspendprocedure_head_, pn->getPeerNode()); + } + + // apply the TRS scheduling (Suspend procedure, ...) + + if(trs_node->getTr() == 0 && trs_node->getTp() == 0) + { + /// The peer is not suspended + if(pn->getReceivedSNR() < TRS_parameters_->getSNRth()) + { + /// The signal is not good => the peer will be suspended for Tr + trs_node->setTr(TRS_parameters_->getTr()); + trs_node->setTp(0); + trs_node->setIteration(0); + trs_node->setL(0); + + } + else + { + /// The signal is good => the peer is scheduled + tmp_peer_TRS[ScheduledPeerNumber] = pn; + ScheduledPeerNumber ++; + + } + } + else + if(trs_node->getTr() != 0 && trs_node->getTp() == 0) + { + /// The peer was suspended by Tr + trs_node->setIteration((trs_node->getIteration() + 1) % trs_node->getTr()); + + if(trs_node->getIteration() == 0) + { + /// The Tr is expired + + if(pn->getReceivedSNR() < TRS_parameters_->getSNRth()) + { + /// The signal is still not good + Tr is expired + trs_node->setL(trs_node->getL() + 1); + + if(trs_node->getL() == TRS_parameters_->getL()) + { + /// the suspend procedure is repeated L times => schedule the node and prevent it for Tp + tmp_peer_TRS[ScheduledPeerNumber] = pn; + ScheduledPeerNumber ++; + + trs_node->setIteration(0); + trs_node->setTr(0); + trs_node->setTp(TRS_parameters_->getTp()); + trs_node->setL(0); + + } + else + { + /// the procedure is not repeated L times => do nothing + } + } + else + { + /// the signal becomes good + Tr is expired + trs_node->setIteration(0); + trs_node->setTr(0); + trs_node->setL(0); + + tmp_peer_TRS[ScheduledPeerNumber] = pn; + ScheduledPeerNumber ++; + + } + } + } + else + { + /// The Tp was released + trs_node->setIteration((trs_node->getIteration() + 1) % trs_node->getTp()); + + if(trs_node->getIteration() == 0) + { + trs_node->setIteration(0); + trs_node->setTp(0); + + } + } + + + } + + free(tmp_peer_rtPS); + + // Apply the RR scheduler combined with TRS + + // nb of served SS + int nbSS = 0; + + if(ScheduledPeerNumber == 0) + { + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + free(tmp_peer_TRS); + return; + } + + + int excess = 0; + + int part = (int)floor((*nbsymbols - ScheduledPeerNumber * SymbolsForPreamble_) / ScheduledPeerNumber); + int max_part = part + *nbsymbols - ScheduledPeerNumber * SymbolsForPreamble_ - part * ScheduledPeerNumber; + + + TRS_RR_counter_ ++; + TRS_RR_counter_ = TRS_RR_counter_ % ScheduledPeerNumber; + int max_index = TRS_RR_counter_; //Random::uniform(0, ScheduledPeerNumber); + + for (int i=0; i < ScheduledPeerNumber ; i++) { + int indice = (i+max_index) % ScheduledPeerNumber; + PeerNode *pn = tmp_peer_TRS[indice]; + + int TRS_symbols; + if(i == 0) + TRS_symbols = max_part; + else + TRS_symbols = part; + + ///TRS_symbols = TRS_symbols + excess; + + /// + + // determine the BR of the bandwidth request + BandwidthToAllocate * bandwidth = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + + // determine the transmission time for the rtPS connection + double duration = mac_->getPhy()->getTrxTime(bandwidth->getRemindBW(), pn->getOfdm_mod_rate()); + + // determine the number of symbols to be reserved for this rtPS connection + int symbols = (int) ceil(duration / mac_->getPhy()->getSymbolTime()); + + if(symbols > TRS_symbols) + { + symbols = TRS_symbols; + excess = 0; + } + ///else + ///excess = TRS_symbols - symbols; + + // symbols are not enough (with preamble) + if((symbols + SymbolsForPreamble_) > *nbsymbols) + { + if(*nbsymbols < SymbolsForPreamble_) + { + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + free(tmp_peer_TRS); + return; + } + + symbols = *nbsymbols - SymbolsForPreamble_; + } + + // add Preamble + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p4->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + // update the remind BW to allocate + bandwidth->setRemindBW(bandwidth->getRemindBW() - mac_->getPhy()->getMaxPktSize(symbols, pn->getOfdm_mod_rate())); + + // delete the BW request if there are no symbols to allocate + if(bandwidth->getRemindBW() <= 0) + { + bandwidth->setRemindBW(0); + } + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + // increment the nb of served SS + nbSS++; + + if(*nbsymbols == 0) + { + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + free(tmp_peer_TRS); + return; + } + + } + + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + free(tmp_peer_TRS); + +} + + + +/** + * Use the TRS_mSIR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::schedule_TRS_mSIR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type) +{ + + if(*nbsymbols == 0) + return; + + // determine the number of rtPS connections + int rtPS_connection_number = getPeerNumber(SERVICE_rtPS); + + if(rtPS_connection_number == 0) + return; + + // determine all peers that have rtPS connections + PeerNode **tmp_peer_rtPS = getPeerSet(SERVICE_rtPS); + + // allocate a structure that contains the peers that can be scheduled at the current frame + PeerNode **tmp_peer_TRS = (PeerNode **) malloc (rtPS_connection_number*sizeof (PeerNode *)); + int ScheduledPeerNumber = 0; + + + for (int i=0; i < rtPS_connection_number ; i++) { + PeerNode *pn = tmp_peer_rtPS[i]; + + // determine the BR of the bandwidth request + BandwidthToAllocate * bandwidth = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + if(!bandwidth) + continue; + + TRS_SuspendProcedure * trs_node = getTRS_SuspendProcedure(trs_suspendprocedure_head_, pn->getPeerNode()); + + // create a new entry if it did not exist + if(trs_node == NULL) + { + TRS_SuspendProcedure *SuspendProcedure_entry = new TRS_SuspendProcedure (pn->getPeerNode()); + SuspendProcedure_entry->insert_entry (&trs_suspendprocedure_head_); + trs_node = getTRS_SuspendProcedure(trs_suspendprocedure_head_, pn->getPeerNode()); + } + + // apply the TRS scheduling (Suspend procedure, ...) + + if(trs_node->getTr() == 0 && trs_node->getTp() == 0) + { + /// The peer is not suspended + if(pn->getReceivedSNR() < TRS_parameters_->getSNRth()) + { + /// The signal is not good => the peer will be suspended for Tr + trs_node->setTr(TRS_parameters_->getTr()); + trs_node->setTp(0); + trs_node->setIteration(0); + trs_node->setL(0); + + } + else + { + /// The signal is good => the peer is scheduled + tmp_peer_TRS[ScheduledPeerNumber] = pn; + ScheduledPeerNumber ++; + + } + } + else + if(trs_node->getTr() != 0 && trs_node->getTp() == 0) + { + /// The peer was suspended by Tr + trs_node->setIteration((trs_node->getIteration() + 1) % trs_node->getTr()); + + if(trs_node->getIteration() == 0) + { + /// The Tr is expired + + if(pn->getReceivedSNR() < TRS_parameters_->getSNRth()) + { + /// The signal is still not good + Tr is expired + trs_node->setL(trs_node->getL() + 1); + + if(trs_node->getL() == TRS_parameters_->getL()) + { + /// the suspend procedure is repeated L times => schedule the node and prevent it for Tp + tmp_peer_TRS[ScheduledPeerNumber] = pn; + ScheduledPeerNumber ++; + + trs_node->setIteration(0); + trs_node->setTr(0); + trs_node->setTp(TRS_parameters_->getTp()); + trs_node->setL(0); + + } + else + { + /// the procedure is not repeated L times => do nothing + } + } + else + { + /// the signal becomes good + Tr is expired + trs_node->setIteration(0); + trs_node->setTr(0); + trs_node->setL(0); + + tmp_peer_TRS[ScheduledPeerNumber] = pn; + ScheduledPeerNumber ++; + + } + } + } // if(trs_node->getTr() != 0 && trs_node->getTp() == 0) + else + { + /// The Tp was released + trs_node->setIteration((trs_node->getIteration() + 1) % trs_node->getTp()); + + if(trs_node->getIteration() == 0) + { + trs_node->setIteration(0); + trs_node->setTp(0); + + } + } + + + } + + free(tmp_peer_rtPS); + + // nb of served SS + int nbSS = 0; + + if(ScheduledPeerNumber == 0) + { + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + free(tmp_peer_TRS); + return; + } + + + // order peers using the received SIR + for(int j = 0; j < ScheduledPeerNumber; j++) + for(int k = 0; k < (ScheduledPeerNumber - 1); k++) + if(tmp_peer_TRS[k]->getReceivedSNR() < tmp_peer_TRS[k+1]->getReceivedSNR()) + { + PeerNode * tmp_peer; + tmp_peer = tmp_peer_TRS[k]; + tmp_peer_TRS[k] = tmp_peer_TRS[k+1]; + tmp_peer_TRS[k+1] = tmp_peer; + tmp_peer = NULL; + } + + + for (int i=0; i < ScheduledPeerNumber ; i++) { + PeerNode *pn = tmp_peer_TRS[i]; + + // determine the BR of the bandwidth request + BandwidthToAllocate * bandwidth = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + + // determine the transmission time for the rtPS connection + double duration = mac_->getPhy()->getTrxTime(bandwidth->getRemindBW(), pn->getOfdm_mod_rate()); + + // determine the number of symbols to be reserved for this rtPS connection + int symbols = (int) ceil(duration / mac_->getPhy()->getSymbolTime()); + + // symbols are not enough (with preamble) + if((symbols + SymbolsForPreamble_) > *nbsymbols) + { + if(*nbsymbols < SymbolsForPreamble_) + { + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer_TRS); + return; + } + + symbols = *nbsymbols - SymbolsForPreamble_; + } + + + // add Preamble + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p4->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + //addPreamble(nbsymbols, ulduration, pduindex); + + // update the remind BW to allocate + bandwidth->setRemindBW(bandwidth->getRemindBW() - mac_->getPhy()->getMaxPktSize(symbols, pn->getOfdm_mod_rate())); + + // delete the BW request if there are no symbols to allocate + if(bandwidth->getRemindBW() <= 0) + { + bandwidth->remove_entry(); + } + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + // increment the nb of served SS + nbSS++; + + if(*nbsymbols == 0) + { + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + + free(tmp_peer_TRS); + return; + } + + } + + fprintf (pFile_rtPS, "%f\t%d\n",NOW,nbSS); + free(tmp_peer_TRS); +} + + + +/** + * Schedule the BE connections + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::scheduleBEconnections(int *nbsymbols, int * ulduration, int * pduindex) +{ + + if(*nbsymbols == 0) + return; + + + // determine the number of BE connections + int BE_connection_number = getPeerNumber(SERVICE_BE); + + + if(BE_connection_number == 0) + return; + + // determine all peers that have BE connections + PeerNode **tmp_peer_be = getPeerSet(SERVICE_BE); + + // initialize first_peer_BEconnections_ + if(first_peer_BEconnections_ == UNDEFINED_NODE) + first_peer_BEconnections_ = tmp_peer_be[BE_connection_number - 1]->getPeerNode(); + + // determine the address of the first served node in the last round + int indice = 0; + for (int i=0; i < BE_connection_number ; i++) { + PeerNode *pn = tmp_peer_be[i]; + if(pn->getPeerNode() == first_peer_BEconnections_) + { + indice = i; + break; + } + } + + // serve the next node + indice++; + + + for (int i=0; i < BE_connection_number ; i++) { + int index = (i+indice)%BE_connection_number; + PeerNode *pn = tmp_peer_be[index]; + + // save the first served node in each frame + if(i==0) + first_peer_BEconnections_ = pn->getPeerNode(); + + // determine the BR of the bandwidth request + BandwidthToAllocate * bandwidthToAllocate = getBandwidthToAllocate(bandwidthtoallocate_head_, pn->getPeerNode()); + + if(!bandwidthToAllocate) + continue; + + // determine the transmission time for the BE connection + double duration = mac_->getPhy()->getTrxTime(bandwidthToAllocate->getRemindBW(), pn->getOfdm_mod_rate()); + + // determine the number of symbols to be reserved for this BE connection + int symbols = (int) ceil(duration / mac_->getPhy()->getSymbolTime()); + + + +/* + // symbols are not enough (without preamble) + if(symbols > *nbsymbols) + { + symbols = *nbsymbols; + } +*/ + + + // symbols are not enough (with preamble) + if((symbols + SymbolsForPreamble_) > *nbsymbols) + { + if(*nbsymbols < SymbolsForPreamble_) + { + free(tmp_peer_be); + return; + } + + symbols = *nbsymbols - SymbolsForPreamble_; + } + + // update the remind BW to allocate + bandwidthToAllocate->setRemindBW(bandwidthToAllocate->getRemindBW() - mac_->getPhy()->getMaxPktSize(symbols, pn->getOfdm_mod_rate())); + + // delete the BW request if there are no symbols to allocate + if(bandwidthToAllocate->getRemindBW() <= 0) + { + bandwidthToAllocate->remove_entry(); + } + + + // add preamble + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p4->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + //addPreamble(nbsymbols, ulduration, pduindex); + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + + if(*nbsymbols == 0) + { + free(tmp_peer_be); + return; + } + + } + + free(tmp_peer_be); + +} + + + + +/** + * Schedule the connections that have no data connections + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::scheduleNoDataConnections(int *nbsymbols, int * ulduration, int * pduindex) +{ + if(*nbsymbols == 0) + return; + + // determine the number of connections + int connection_number = getPeerNumber(); + + if(connection_number == 0) + return; + + // determine all peers + PeerNode **tmp_peer = getPeerSet(); + + // determine the number of stations do not have data connection + int nodata_number = 0; + for (int i=0; i < connection_number ; i++) { + PeerNode *pn = tmp_peer[i]; + if(!pn->getInData()) + nodata_number ++; + } + + if(nodata_number == 0) + { + free(tmp_peer); + return; + } + + // determine the portion of symbols to conections having no data connections + int portion = (*nbsymbols) / nodata_number; + + int counter = 0; + + for (int i=0; i < connection_number ; i++) { + PeerNode *pn = tmp_peer[i]; + + if(pn->getInData()) + continue; + + counter ++; + + if(counter == nodata_number) + portion = *nbsymbols; + + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(UIUC_PROFILE_1); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (portion); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + portion; + *nbsymbols = *nbsymbols - portion; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (UIUC_PROFILE_1); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, default_mod_); + p->setIUC (UIUC_PROFILE_1); + } + + if(*nbsymbols == 0) + { + free(tmp_peer); + return; + } + + } + + free(tmp_peer); + +} + + + + + +/** + * Schedule all the connections + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::scheduleAllconnections(int *nbsymbols, int * ulduration, int * pduindex) +{ + if(*nbsymbols == 0) + return; + + // determine the number of connections + int connection_number = getPeerNumber(); + + if(connection_number == 0) + return; + + // determine all peers + PeerNode **tmp_peer = getPeerSet(); + + // initialize first_peer_Allconnections_ + if(first_peer_AllConnections_ == UNDEFINED_NODE) + first_peer_AllConnections_ = tmp_peer[connection_number - 1]->getPeerNode(); + + // determine the address of the first served node in the last round + int indice = 0; + for (int i=0; i < connection_number ; i++) { + PeerNode *pn = tmp_peer[i]; + if(pn->getPeerNode() == first_peer_AllConnections_) + { + indice = i; + break; + } + } + + // serve the next node + indice++; + + for (int i=0; i < connection_number ; i++) { + int index = (i+indice)%connection_number; + PeerNode *pn = tmp_peer[index]; + + // save the first served node + if(i==0) + first_peer_AllConnections_ = pn->getPeerNode(); + + int symbols; + symbols = *nbsymbols; + + + // add burst + Burst *b3 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + b3->setIUC(getUIUCvalue(pn->getReceivedSNR())); + b3->setCid (pn->getPrimary()->get_cid()); + b3->setDuration (symbols); + b3->setStarttime (*ulduration); + *ulduration = *ulduration + symbols; + *nbsymbols = *nbsymbols - symbols; + //add profile if not existing + Profile *p = map_->getUlSubframe()->getProfile (getUIUCvalue(pn->getReceivedSNR())); + if (p==NULL) { + p = map_->getUlSubframe()->addProfile (0, pn->getOfdm_mod_rate()); + p->setIUC (getUIUCvalue(pn->getReceivedSNR())); + } + + if(*nbsymbols == 0) + { + free(tmp_peer); + return; + } + + } + + free(tmp_peer); + +} + + + +/** + * Add a preamble + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::addPreamble(int *nbsymbols, int * ulduration, int * pduindex) +{ + + if(*nbsymbols > SymbolsForPreamble_) + { + Burst *b4 = map_->getUlSubframe()->addPhyPdu (*pduindex,0)->addBurst (0); + *pduindex = *pduindex + 1; + + int symbols4 = SymbolsForPreamble_; + b4->setIUC(UIUC_PROFILE_1); + b4->setCid (SPECIAL_GAP_CID); + b4->setDuration (symbols4); + b4->setStarttime (*ulduration); + *ulduration = *ulduration + symbols4; + *nbsymbols = *nbsymbols - symbols4; + //add profile if not existing + Profile *p4 = map_->getUlSubframe()->getProfile (UIUC_PROFILE_1); + if (p4==NULL) { + p4 = map_->getUlSubframe()->addProfile (0, default_mod_); + p4->setIUC (UIUC_PROFILE_1); + } + } +} + + +/// diff -Naur ns-2.29-original/wimax/scheduling/bsscheduler.h ns-2.29-new/wimax/scheduling/bsscheduler.h --- ns-2.29-original/wimax/scheduling/bsscheduler.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/bsscheduler.h 2008-06-06 16:51:08.000000000 +0200 @@ -0,0 +1,855 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef BSSCHEDULER_H +#define BSSCHEDULER_H + +#include "wimaxscheduler.h" +#include "scanningstation.h" + +#define INIT_DL_DURATION 20 //enough for DL_MAP, UL_MAP, DCD, UCD and some RNG-RSP +#define MIN_CONTENTION_SIZE 5 //minimum number of opportunity for allocation + + +/// Added by Aymen +#define UNDEFINED_NODE -3 + +#define SPECIAL_GAP_CID 1981 + + +/** Defines the supported rtPS scheduling algorithms */ +enum rtPS_SchedulingAlgorithm_t { + rtPS_SCHEDULING_NIST_RR, + rtPS_SCHEDULING_RR, + rtPS_SCHEDULING_mSIR, + rtPS_SCHEDULING_mmSIR, + rtPS_SCHEDULING_WRR, + rtPS_SCHEDULING_TRS_RR, + rtPS_SCHEDULING_TRS_mSIR +}; + + +/** Defines the supported BE scheduling algorithms */ +enum BE_SchedulingAlgorithm_t { + BE_SCHEDULING_RR, + BE_SCHEDULING_mSIR, + //BE_SCHEDULING_mmSIR, + BE_SCHEDULING_WRR, + //BE_SCHEDULING_TRS_RR, + //BE_SCHEDULING_TRS_mSIR +}; + + +class SchedulingManagement; +LIST_HEAD (schedulingmanagement, SchedulingManagement); +/** Object to handle connections management */ +class SchedulingManagement { + public: + SchedulingManagement (int node) { + node_ = node; + periodicity_ = 3; + iteration_ = 0; + } + + SchedulingManagement (int node, int periodicity, int iteration) { + node_ = node; + periodicity_ = periodicity; + iteration_ = iteration; + } + + SchedulingManagement (int node, int periodicity) { + node_ = node; + periodicity_ = periodicity; + iteration_ = 0; + } + + void setNode (int node){ node_ = node; } + int getNode () { return node_; } + + void setPeriodicity (int periodicity) { periodicity_ = periodicity; } + int getPeriodicity () { return periodicity_; } + + void setIteration (int iteration) { iteration_ = iteration; } + int getIteration () { return iteration_; } + + // Chain element to the list + inline void insert_entry(struct schedulingmanagement *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Return next element in the chained list + SchedulingManagement* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + protected: + + /* + * Pointer to next in the list + */ + LIST_ENTRY(SchedulingManagement) link; + //LIST_ENTRY(UGSManagement); //for magic draw + + private: + int node_; // The address of the node + int periodicity_; // The period for the allocation of symbols + int iteration_; // Only a value of 0 means that the BS must allocate symbols to the node +}; + + + + +class BandwidthToAllocate; +LIST_HEAD (bandwidthtoallocate, BandwidthToAllocate); +/** Object to handle bandwidth to allocate */ +class BandwidthToAllocate { + public: + BandwidthToAllocate (int Node, int BW) { + Node_ = Node; + BW_ = BW; + RemindBW_ = BW_ ; + } + + void setNode (int Node){ Node_ = Node; } + int getNode () { return Node_; } + + void setBWaggregate (int BW) { BW_ = BW; RemindBW_ = BW;} + void setBWincremental (int BW) { BW_ = BW_ + BW; RemindBW_ = RemindBW_ + BW;} + int getBW () { return BW_; } + + void setRemindBW (int RemindBW) { RemindBW_ = RemindBW; } + int getRemindBW () { return RemindBW_; } + + // Chain element to the list + inline void insert_entry(struct bandwidthtoallocate *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Chain element to the list + inline void insert_entry_after(BandwidthToAllocate *elem) { + LIST_INSERT_AFTER(elem, this, link); + } + + // Return next element in the chained list + BandwidthToAllocate* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + protected: + + /* + * Pointer to next in the list + */ + LIST_ENTRY(BandwidthToAllocate) link; + //LIST_ENTRY(BandwidthToAllocate); //for magic draw + + private: + int Node_; // The address of the node + int BW_; // The bandwidth request + int RemindBW_; // The remind bandwidth to be allocated +}; + + + +class TRS_SuspendProcedure; +LIST_HEAD (trs_suspendprocedure, TRS_SuspendProcedure); +/** Object to handle nodes that are scheduled by the TRS scheduler */ +class TRS_SuspendProcedure { + public: + TRS_SuspendProcedure (int Node) { + Node_ = Node; + Tr_ = 0; + Tp_ = 0; + Iteration_ = 0; + L_ = 0; + } + + void setNode (int Node){ Node_ = Node; } + int getNode () { return Node_; } + + void setIteration (int Iteration) { Iteration_ = Iteration;} + int getIteration () { return Iteration_; } + + void setTr (int Tr) { Tr_ = Tr; } + int getTr () { return Tr_; } + + void setTp (int Tp) { Tp_ = Tp; } + int getTp () { return Tp_; } + + void setL (int L) { L_ = L; } + int getL () { return L_; } + + // Chain element to the list + inline void insert_entry(struct trs_suspendprocedure *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Chain element to the list + inline void insert_entry_after(TRS_SuspendProcedure *elem) { + LIST_INSERT_AFTER(elem, this, link); + } + + // Return next element in the chained list + TRS_SuspendProcedure* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + protected: + + /* + * Pointer to next in the list + */ + LIST_ENTRY(TRS_SuspendProcedure) link; + //LIST_ENTRY(TRS_SuspendProcedure); //for magic draw + + private: + int Node_; // The address of the node + int Iteration_; // Only a value of 0 means that the BS must check the SIR of the Node again + int Tr_; // Number of iteration to wait when the signal is poor + int Tp_; // Number of iteration to wait when the procedure is repeated L times + int L_; // Maximum number of repetion of the suspend procedure (consecutive) +}; + + + +/** Parameters of TRS scheduler */ +class TRS_parameters { +public: + TRS_parameters(double SNRth, int Tr, int Tp, int L) + { + SNRth_ = SNRth; + Tr_ = Tr; + Tp_ = Tp; + L_ = L; + } + + void setSNRth (double SNRth) { SNRth_ = SNRth; } + double getSNRth () { return SNRth_; } + + void setTr (int Tr) { Tr_ = Tr; } + int getTr () { return Tr_; } + + void setTp (int Tp) { Tp_ = Tp; } + int getTp () { return Tp_; } + + void setL (int L) { L_ = L; } + int getL () { return L_; } + +private: + double SNRth_; // SNR threshold + int Tr_; // Tr parameter + int Tp_; // Tp parameter + int L_; // L parameter +}; +/// + + + +/** Information about a new client */ +struct new_client_t { + int cid; //primary cid of new client + new_client_t *next; +}; + +class T17Element; +LIST_HEAD (t17element, T17Element); +/** Object to handle timer t17 */ +class T17Element { + public: + T17Element (Mac802_16 *mac, int index) { + index_ = index; + timer = new WimaxT17Timer (mac, index); + timer->start (mac->macmib_.t17_timeout); + } + + ~T17Element () { delete (timer); } + + int index () { return index_; } + int paused () { return timer->paused(); } + void cancel () { timer->stop(); } + + // Chain element to the list + inline void insert_entry(struct t17element *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Return next element in the chained list + T17Element* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + protected: + + /* + * Pointer to next in the list + */ + LIST_ENTRY(T17Element) link; + //LIST_ENTRY(T17Element); //for magic draw + + private: + int index_; + WimaxT17Timer *timer; +}; + +class FastRangingInfo; +LIST_HEAD (fastRangingInfo, FastRangingInfo); +/** Store information about a fast ranging request to send */ +class FastRangingInfo { + public: + FastRangingInfo (int frame, int macAddr) { + frame_ = frame; + macAddr_ = macAddr; + } + + int frame () { return frame_; } + int macAddr () { return macAddr_; } + + // Chain element to the list + inline void insert_entry(struct fastRangingInfo *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Return next element in the chained list + FastRangingInfo* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + protected: + + /* + * Pointer to next in the list + */ + LIST_ENTRY(FastRangingInfo) link; + //LIST_ENTRY(FastRangingInfo); //for magic draw + + private: + int frame_; + int macAddr_; +}; + +class WimaxCtrlAgent; +/** + * Class BSScheduler + * Implement the packet scheduler on the BS side + */ +class BSScheduler : public WimaxScheduler { + //friend class SendTimer; + public: + /* + * Create a scheduler + */ + BSScheduler (); + + /* + * Interface with the TCL script + * @param argc The number of parameter + * @param argv The list of parameters + */ + int command(int argc, const char*const* argv); + + /** + * Process a packet received by the Mac. Only scheduling related packets should be sent here (BW request, UL_MAP...) + * @param p The packet to process + */ + void process (Packet * p); + + /** + * Return the type of STA this scheduler is good for + */ + virtual station_type_t getNodeType (); + + /** + * Initializes the scheduler + */ + virtual void init (); + + /** + * Called when a timer expires + * @param The timer ID + */ + virtual void expire (timer_id id); + + /** + * Start a new DL subframe + */ + virtual void start_dlsubframe (); + + /** + * Start a new UL subframe + */ + virtual void start_ulsubframe (); + + /** + * Finds out if the given station is currently scanning + * @param nodeid The MS id + */ + bool isPeerScanning (int nodeid); + + /** + * Set the control agent + * @param agent The control agent + */ + void setCtrlAgent (WimaxCtrlAgent *agent); + + /** Add a new Fast Ranging allocation + * @param time The time when to allocate data + * @param macAddr The MN address + */ + void addNewFastRanging (double time, int macAddr); + + /** + * Send a scan response to the MN + * @param rsp The response from the control + * @cid The CID for the MN + */ + void send_scan_response (mac802_16_mob_scn_rsp_frame *rsp, int cid); + + + +/// Added by Aymen +/** + * get the corresponding UIUC value + * @param ReceivedSNR The received signal-to-noise ratio + * @return The corresponding UIUC value + */ +uiuc_t getUIUCvalue(float ReceivedSNR); + + + +/** + * get the peer number + * @return The peer number + */ +int getPeerNumber(); + + + +/** + * get the peer number for a service flow scheduling type + * @param scheduling The service flow scheduling type + * @return The peer number for a service flow scheduling type + */ +int getPeerNumber(SchedulingType_t scheduling); + + + +/** + * get the peer set + * @return The peer set + */ +PeerNode ** BSScheduler::getPeerSet(); + + + +/** + * get the peer set for a service flow scheduling type + * @param scheduling The service flow scheduling type + * @return The peer set for a service flow scheduling type + */ +PeerNode ** getPeerSet(SchedulingType_t scheduling); + + + +/** + * Verify if the peer node exists in the scheduling management list + * @param head The scheduling management list + * @param peernode The peer node to look for + * @return true if the peer node exists in the scheduling management list, and false else + */ +bool searchSchedulingManagement(struct schedulingmanagement head, int peernode); + + + +/** + * Modify the periodicity + * @param head The scheduling management list + * @param peernode The peer node + * @param periodicity The periodicity + */ +void modifySchedulingManagement(struct schedulingmanagement head, int peernode, int periodicity); + + + +/** + * Modify the periodicity + * @param head The scheduling management list + * @param peernode The peer node + * @param periodicity The periodicity + * @param iteration The iteration + */ +void modifySchedulingManagement(struct schedulingmanagement head, int peernode, int periodicity, int iteration); + + + +/** + * increment the iteration of the peer node + * @param head The scheduling management list + * @param peernode The peer node + */ +void incrementSchedulingManagement(struct schedulingmanagement head, int peernode); + + + +/** + * increment the iteration of the peer node without taking account the periodicity + * @param head The scheduling management list + * @param peernode The peer node + */ + void incrementSchedulingManagement_NoPeriodicity(struct schedulingmanagement head, int peernode); + + +/** + * get the connection management of the peer node + * @param head The scheduling management list + * @param peernode The peer node + * @return the connection management of the peer node + */ +SchedulingManagement *getSchedulingManagement(struct schedulingmanagement head, int peernode); + + + +/** + * get the bandwidth request transmitted by the peer node + * @param head The list of the bandwidth to be allocated + * @param peernode The peer node + * @return the bandwidth request transmitted by the peer node + */ +BandwidthToAllocate *getBandwidthToAllocate(struct bandwidthtoallocate head, int peernode); + + + +/** + * get the characteristics of the TRS Suspend Procedure + * @param head The list of the nodes that are echeduled with the TRS scheduler + * @param peernode The peer node + * @return the characteristics of the TRS scheduler for the peer node + */ +TRS_SuspendProcedure *getTRS_SuspendProcedure(struct trs_suspendprocedure head, int peernode); + + + +/** + * Schedule the UGS connections + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::scheduleUGSconnections(int *nbsymbols, int * ulduration, int * pduindex); + + + +/** + * Provide periodic unicast request opportunities + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void provideUnicastRequest(int *nbsymbols, int * ulduration, int * pduindex); + + + +/** + * Use the RR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void schedule_RR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type); + + + +/** + * Use the maximum SIR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void schedule_mSIR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type); + + + +/** + * Use the modified maximum SIR (mmSIR) algorithm for rtPS QoS class + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void schedulertPSconnections_mmSIR(int *nbsymbols, int * ulduration, int * pduindex); + + + +/** + * Use the WRR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void schedule_WRR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type); + + + +/** + * Use the TRS_RR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void schedule_TRS_RR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type); + + + +/** + * Use the TRS_mSIR scheduler + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void schedule_TRS_mSIR(int *nbsymbols, int * ulduration, int * pduindex, SchedulingType_t type); + + + +/** + * Schedule the BE connections + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void BSScheduler::scheduleBEconnections(int *nbsymbols, int * ulduration, int * pduindex); + + + +/** + * Schedule the connections that have no data connections + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void scheduleNoDataConnections(int *nbsymbols, int * ulduration, int * pduindex); + + + + +/** + * Schedule all the connections + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void scheduleAllconnections(int *nbsymbols, int * ulduration, int * pduindex); + + + +/** + * Add a preamble + * @param nbsymbols The number of symbols that are not used + * @param ulduration The uplink duration + * @param pduindex The index of pdu + */ +void addPreamble(int *nbsymbols, int * ulduration, int * pduindex); + +/// + + + protected: + + /** + * Default modulation + */ + Ofdm_mod_rate default_mod_; + + /** + * Number of transmission opportunity for initial ranging + * and bw request (i.e contention slots) + */ + int contention_size_; + + /** + * Compute and return the bandwidth request opportunity size + * @return The bandwidth request opportunity size + */ + int getBWopportunity (); + + /** + * Compute and return the initial ranging opportunity size + * @return The initial ranging opportunity size + */ + int getInitRangingopportunity (); + + private: + + /** + * Process a RNG-REQ message + * @param frame The ranging request information + */ + void process_ranging_req (Packet *p); + + /** + * Process bandwidth request + * @param p The request + */ + void process_bw_req (Packet *p); + + /** + * Process bandwidth request + * @param p The request + */ + void process_reg_req (Packet *p); + + /** + * Process handover request + * @param req The request + */ + void process_msho_req (Packet *req); + + /** + * Process handover indication + * @param p The indication + */ + void process_ho_ind (Packet *p); + + /** + * Send a neighbor advertisement message + */ + void send_nbr_adv (); + + + /** + * Add a new timer 17 for client + * @param index The client address + */ + void addtimer17 (int index); + + /** + * Cancel and remove the timer17 associated with the node + * @param index The client address + */ + void removetimer17 (int index); + + struct new_client_t *cl_head_; + struct new_client_t *cl_tail_; + + struct t17element t17_head_; + + /** + * The index of the last SS that had bandwidth allocation + */ + int bw_node_index_; + + /** + * The node that had the last bandwidth allocation + */ + PeerNode *bw_peer_; + + /** + * Timer for DCD + */ + WimaxDCDTimer *dcdtimer_; + + /** + * Timer for UCD + */ + WimaxUCDTimer *ucdtimer_; + + /** + * Timer for MOB-NBR_ADV messages + */ + WimaxMobNbrAdvTimer *nbradvtimer_; + + /** + * Indicates if it is time to send a DCD message + */ + bool sendDCD; + int dlccc_; + bool sendUCD; + int ulccc_; + + /** + * List of station in scanning + */ + struct scanningStation scan_stations_; + + /** + * The Wimax control for BS synchronization + */ + WimaxCtrlAgent *ctrlagent_; + + /** + * List of the upcoming Fast Ranging allocation + */ + struct fastRangingInfo fast_ranging_head_; + + + + + /// Added by Aymen + struct schedulingmanagement ugsmanagement_head_; + struct schedulingmanagement UnicastRequest_rtPSmanagement_head_; + struct schedulingmanagement WRR_management_head_; + + struct bandwidthtoallocate bandwidthtoallocate_head_; // The list of the connections having bw to be allocated + //struct bandwidthtoallocate rtPS_bandwidthtoallocate_head_; // The list of the rtPS connections having bw to be allocated + //struct bandwidthtoallocate BE_bandwidthtoallocate_head_; // The list of the BE connections having bw to be allocated + + struct trs_suspendprocedure trs_suspendprocedure_head_; // The list of the nodes that are scheduled by TRS scheduler + + TRS_parameters * TRS_parameters_; + + int last_rtPS_peer_RR_; // The address of the last rtPS node served with RR scheduler + int last_BE_peer_RR_; // The address of the last BE node served with RR scheduler + + int last_rtPS_peer_WRR_; // The address of the last rtPS node served with WRR scheduler + int last_BE_peer_WRR_; // The address of the last BE node served with WRR scheduler + + int first_peer_BEconnections_; // The address of the first served node having a BE connection + int first_peer_AllConnections_; // The address of the first served node taking the rest of bw + + int SymbolNumberForUnicastRequest_; + + int SymbolsForPreamble_; + + int SchedulingManagementSynch_; + + /** + * The rtPS scheduling algorithm (RR, mSIR...) + */ + rtPS_SchedulingAlgorithm_t rtPSscheduling_; + + /** + * The BE scheduling algorithm (RR, mSIR, WRR...) + */ + BE_SchedulingAlgorithm_t BEscheduling_; + + int TRS_RR_counter_; + + FILE * pFile_rtPS; + FILE * pFile_BE; +/// +}; + +#endif //BSSCHEDULER_H + diff -Naur ns-2.29-original/wimax/scheduling/burst.cc ns-2.29-new/wimax/scheduling/burst.cc --- ns-2.29-original/wimax/scheduling/burst.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/burst.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,155 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "burst.h" + + +/** + * Creates a burst + * @param phypdu The PhyPdu where it is located + */ +Burst::Burst (PhyPdu *phypdu) : cid_(-1), duration_(0), + starttime_(0),iuc_(-1) +{ + assert (phypdu); + phypdu_ = phypdu; + queue_ = NULL; +} + +/* + * Delete the object + */ +Burst::~Burst () +{ + //delete packets in queue + if (queue_!=NULL) { + for (Packet *p = dequeue(); p ; p=dequeue()) { + Packet::free (p); + } + delete (queue_); + } +} + +/** + * Set burst CID + * @param cid The burst CID + */ +void Burst::setCid( int cid ) +{ + cid_ = cid; +} + +/** + * Return the CID for this burst + * @return the CID for this burst + */ +int Burst::getCid( ) +{ + return cid_; +} + +/** + * Return the burst duration in units of OFDM symbols + * @return the burst duration + */ +int Burst::getDuration( ) +{ + return duration_; +} + +/** + * Set the duration of the burst in units of OFDM symbols + * @param duration The burst duration + */ +void Burst::setDuration (int duration) +{ + duration_=duration; +} + +/** + * Set burst IUC + * @param iuc The burst IUC + */ +void Burst::setIUC( int iuc ) +{ + iuc_ = iuc; +} + +/** + * Return the Interval Usage Code + * @return the burst start time + */ +int Burst::getIUC( ) +{ + return iuc_; +} + +/** + * Set burst start time in units of symbol duration + * @param starttime the burst start time + */ +void Burst::setStarttime( int starttime ) +{ + assert (starttime >= 0); + starttime_ = starttime; +} + +/** + * Return the burst start time in units of symbol duration + * @return the burst start time + */ +int Burst::getStarttime( ) +{ + return starttime_; +} + +/** + * Enqueue the given packet + * @param p The packet to enqueue + */ +void Burst::enqueue (Packet * p) +{ + if (queue_ == NULL) { + //this is the first packet we enqueue, create queue + queue_ = new PacketQueue(); + } + queue_->enque (p); +} + +/** + * Dequeue a packet from the queue + * @param p The packet to enqueue + */ +Packet * Burst::dequeue () +{ + if (queue_==NULL) //in case there was never an enqueue + return NULL; + return queue_->deque (); +} + +/** + * Trigger the timer to send packets for this burst + * @param time The time the trigger expires + */ +/* +void Burst::trigger_timer (double time) +{ + //assert (NOW < time); + timer_.resched (time); +} +*/ diff -Naur ns-2.29-original/wimax/scheduling/burst.h ns-2.29-new/wimax/scheduling/burst.h --- ns-2.29-original/wimax/scheduling/burst.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/burst.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,189 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef BURST_H +#define BURST_H + +#include "queue.h" +#include "packet.h" + +class PhyPdu; + +class Burst; +LIST_HEAD (burst, Burst); + +/** + * This class describe a burst + */ +class Burst +{ + friend class WimaxBurstTimer; + + public: + /** + * Creates a burst + * @param phypdu The PhyPdu where it is located + */ + Burst (PhyPdu *phypdu); + + /** + * Delete the object + */ + ~Burst (); + + /** + * Return the CID for this burst + * @return the CID for this burst + */ + int getCid( ); + + /** + * Return the burst duration in units of OFDM symbols + * @return the burst duration + */ + int getDuration( ); + + /** + * Set the duration of the burst in units of OFDM symbols + * @param duration The burst duration + */ + void setDuration (int duration); + + /** + * Return the burst start time in units of symbol duration + * @return the burst start time + */ + int getStarttime( ); + + /** + * Return the Interval Usage Code + * @return the burst start time + */ + int getIUC( ); + + /** + * Set burst CID + * @param cid The burst CID + */ + void setCid( int cid ); + + /** + * Set burst start time in units of symbol duration + * @param starttime the burst start time + */ + void setStarttime( int starttime ); + + /** + * Set burst IUC + * @param iuc The burst IUC + */ + void setIUC( int iuc ); + + /** + * Enqueue a packet to be schedule in this burst + * @param p The packet to queue + */ + void enqueue (Packet *p); + + /** + * Dequeue a packet from the queue + * @param p The packet to enqueue + */ + Packet * dequeue (); + + /** + * Return the queue size in bytes + */ + int getQueueLength() { return queue_->byteLength();} + + /** + * Schedule the timer for this burst + * @param time The time the trigger expires + */ + //void trigger_timer (double time); + + // Chain element to the list + inline void insert_entry_head(struct burst *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Chain element to the list + inline void insert_entry(Burst *elem) { + LIST_INSERT_AFTER(elem, this, link); + } + + // Return next element in the chained list + Burst* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + +protected: + /** + * A timer use to transmit the burst + */ + //WimaxBurstTimer timer_; + + /** + * Packets to be sent during this burst + */ + PacketQueue* queue_; + + /** + * Return the PhyPdu + * @return the PhyPdu + */ + inline PhyPdu *getPhyPdu () { return phypdu_; } + + /* + * Pointer to next in the list + */ + LIST_ENTRY(Burst) link; + //LIST_ENTRY(Burst); //for magic draw + + private: + /** + * The CID for the burst. If a broadcast or multicast is used, then Mac SDUs for different SSs can be included in the burst. + */ + int cid_; + + /** + * The burst duration in units of OFDM Symbols + */ + int duration_; + + /** + * The start time of the burst in units of Symbol Duration + */ + int starttime_; + + /** + * The profile ID + */ + int iuc_; + + /** + * The PhyPdu where it is located + */ + PhyPdu *phypdu_; + +}; + +#endif diff -Naur ns-2.29-original/wimax/scheduling/contentionrequest.cc ns-2.29-new/wimax/scheduling/contentionrequest.cc --- ns-2.29-original/wimax/scheduling/contentionrequest.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/contentionrequest.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,218 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "contentionrequest.h" +#include "contentionslot.h" +#include "framemap.h" +#include "wimaxscheduler.h" +#include "random.h" + +/* + * Handling function for WimaxFrameTimer + * @param e The event that occured + */ +void WimaxBackoffTimer::handle(Event *e) +{ + busy_ = 0; + paused_ = 0; + stime = 0.0; + rtime = 0.0; + + mac->transmit (c_->p_->copy()); + + //start timeout trigger + c_->starttimeout (); +} + +void WimaxBackoffTimer::pause() +{ + Scheduler &s = Scheduler::instance(); + + //the caculation below make validation pass for linux though it + // looks dummy + + double st = s.clock(); + double rt = stime; + double sr = st - rt; + + assert(busy_ && ! paused_); + + paused_ = 1; + rtime -= sr; + + assert(rtime >= 0.0); + + s.cancel(&intr); +} + + +void WimaxBackoffTimer::resume() +{ + Scheduler &s = Scheduler::instance(); + + assert(busy_ && paused_); + + paused_ = 0; + stime = s.clock(); + + assert(rtime >= 0.0); + s.schedule(this, &intr, rtime); +} + +/* + * Creates a contention slot for the given frame + * @param s The contention slot + * @param p The packet to send + */ +ContentionRequest::ContentionRequest (ContentionSlot *s, Packet *p) +{ + assert (s); + assert (p); + s_=s; + mac_ = s_->map_->getMac(); + window_ = s_->getBackoff_start(); + nb_retry_ = 0; + p_=p; + backoff_timer_ = new WimaxBackoffTimer (this, mac_); + timeout_timer_ = new ContentionTimer (this); + int result = Random::random() % ((int)(pow (2, window_)+1)); + mac_->debug ("At %f in Mac %d Start contention in %f(backoff=%d, size=%d, ps=%f)\n", NOW, mac_->addr(), result*s_->getSize()*mac_->getPhy()->getPS(),result,s_->getSize(),mac_->getPhy()->getPS()); + backoff_timer_->start (result*s_->getSize()*mac_->getPhy()->getPS()); + backoff_timer_->pause(); +} + +ContentionRequest::~ContentionRequest () +{ + //printf ("canceling timeout\n"); + //the timeout timer need not be triggered + //this can happen when the STA received bw allocation + //when it is not waiting for one (or it's still in backoff) + if (timeout_timer_->status()!=TIMER_IDLE) + timeout_timer_->cancel(); + if (backoff_timer_->busy()) + backoff_timer_->stop(); + delete backoff_timer_; + delete timeout_timer_; + assert (p_); + Packet:: free (p_); +} + +/* + * Called when timeout expired + */ +void ContentionRequest::expire () +{ + +} + +/* + * Called when timeout expired + */ +void ContentionRequest::starttimeout () +{ + timeout_timer_->sched (timeout_); +} + +/* + * Pause the backoff timer + */ +void ContentionRequest::pause () +{ + if (backoff_timer_->busy() && !backoff_timer_->paused()) + backoff_timer_->pause(); +} + +/* + * Resume the backoff timer + */ +void ContentionRequest::resume () +{ + if (backoff_timer_->paused() && timeout_timer_->status()==TIMER_IDLE) + backoff_timer_->resume(); +} + +/* + * Creates a contention slot for the given frame + * @param frame The frame map + */ +RangingRequest::RangingRequest (ContentionSlot *s, Packet *p) : ContentionRequest (s,p) +{ + type_ = WimaxT3TimerID; + timeout_ = mac_->macmib_.t3_timeout; +} + +/* + * Called when timeout expired + */ +void RangingRequest::expire () +{ + mac_->debug ("Ranging request expires\n"); + if (nb_retry_ == (int)mac_->macmib_.contention_rng_retry) { + //max retries reached, inform the scheduler + mac_->getScheduler ()->expire (type_); + } else { + if (window_ < s_->getBackoff_stop()) + window_++; + nb_retry_++; + int result = Random::random() % ((int)(pow (2, window_)+1)); + mac_->debug ("Start Ranging contention in %f(backoff=%d, size=%d, ps=%f)\n", result*s_->getSize()*mac_->getPhy()->getPS(),result,s_->getSize(),mac_->getPhy()->getPS()); + backoff_timer_->start (result*s_->getSize()*mac_->getPhy()->getPS()); + backoff_timer_->pause(); + } +} + +/* + * Creates a contention slot for the given frame + * @param frame The frame map + */ +BwRequest::BwRequest (ContentionSlot *s, Packet *p, int cid, int len) : ContentionRequest (s,p) +{ + type_ = WimaxT16TimerID; + timeout_ = mac_->macmib_.t16_timeout; + cid_ = cid; + size_ = len; +} + +/* + * Called when timeout expired + */ +void BwRequest::expire () +{ + printf ("Bw request expires\n"); + if (nb_retry_ == (int)mac_->macmib_.request_retry) { + //max retries reached, delete the pdu that were waiting + Connection *c = mac_->getCManager()->get_connection (cid_, true); + int len = 0; + printf ("Dropping packet because bw req exceeded size=%d cid=%d c->len=%d\n",size_, cid_, c->queueByteLength()); + while (len < size_) { + Packet *p = c->dequeue(); + //len = size_ + 1; + assert (p); + len += HDR_CMN(p)->size(); + Packet::free (p); + } + } else { + if (window_ < s_->getBackoff_stop()) + window_++; + nb_retry_++; + int result = Random::random() % ((int)(pow (2, window_)+1)); + printf ("At %f, node %d Start BW contention in %f(backoff=%d, size=%d, ps=%f)\n",NOW, mac_->addr(), result*s_->getSize()*mac_->getPhy()->getPS(),result,s_->getSize(),mac_->getPhy()->getPS()); + backoff_timer_->start (result*s_->getSize()*mac_->getPhy()->getPS()); + backoff_timer_->pause(); + } +} diff -Naur ns-2.29-original/wimax/scheduling/contentionrequest.h ns-2.29-new/wimax/scheduling/contentionrequest.h --- ns-2.29-original/wimax/scheduling/contentionrequest.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/contentionrequest.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,211 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef CONTENTIONREQUEST_H +#define CONTENTIONREQUEST_H + +#include "mac802_16.h" +#include "mac802_16timer.h" + +class ContentionSlot; +class ContentionTimer; +class Mac802_16; + +class ContentionRequest; +/** Timer for backoff */ +class WimaxBackoffTimer : public WimaxTimer { + public: + WimaxBackoffTimer(ContentionRequest *c, Mac802_16 *m) : WimaxTimer(m) {c_=c;} + + void handle(Event *e); + void pause(void); + void resume(void); + private: + ContentionRequest *c_; +}; + + +class ContentionRequest; +LIST_HEAD (contentionRequest, ContentionRequest); + +/** + * This class is used to manage contention opportunities + * supports list + */ +class ContentionRequest +{ + friend class WimaxBackoffTimer; + public: + /** + * Creates a contention slot for the given frame + * @param s The contention slot + * @param p The packet to send + */ + ContentionRequest (ContentionSlot *s, Packet *p); + virtual ~ContentionRequest (); + /** + * Called when timeout expired + */ + virtual void expire (); + + /** + * Start the timeout timer + */ + void starttimeout(); + + /** + * Pause the backoff timer + */ + void pause (); + + /** + * Resume the backoff timer + */ + void resume (); + + /// Chain element to the list + inline void insert_entry_head(struct contentionRequest *head) { + LIST_INSERT_HEAD(head, this, link); + } + + /// Chain element to the list + inline void insert_entry(ContentionRequest *elem) { + LIST_INSERT_AFTER(elem, this, link); + } + + /// Return next element in the chained list + ContentionRequest* next_entry(void) const { return link.le_next; } + + /// Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + + protected: + + /** + * The contention slot information + */ + ContentionSlot *s_; + + /** + * The backoff timer + */ + WimaxBackoffTimer *backoff_timer_; + + /** + * The timeout timer + */ + ContentionTimer *timeout_timer_; + + /** + * Type of timer + */ + timer_id type_; + + /** + * Value for timeout + */ + double timeout_; + + /** + * The current window size + */ + int window_; + + /** + * Number of retry + */ + int nb_retry_; + + /** + * The scheduler to inform about timeout + */ + Mac802_16 *mac_; + + /** + * The packet to send when the backoff expires + */ + Packet *p_; + + /** + * Pointer to next in the list + */ + LIST_ENTRY(ContentionRequest) link; + //LIST_ENTRY(ContentionRequest); //for magic draw +}; + +/** + * Class to handle ranging opportunities + */ +class RangingRequest: public ContentionRequest +{ + public: + + /** + * Creates a contention slot for the given frame + * @param frame The frame map + */ + RangingRequest (ContentionSlot *s, Packet *p); + + /** + * Called when timeout expired + */ + void expire (); + + private: +}; + + +/** + * Class to handle bandwidth request opportunities + */ +class BwRequest: public ContentionRequest +{ + public: + + /** + * Creates a contention slot for the given frame + * @param frame The frame map + */ + BwRequest (ContentionSlot *s, Packet *p, int cid, int length); + + /** + * Called when timeout expired + */ + void expire (); + + /** + * Return the CID for this request + * @return the CID for this request + */ + inline int getCID () { return cid_; } + + private: + /** + * The CID for the request + */ + int cid_; + + /** + * The size in bytes of the bandwidth requested + */ + int size_; +}; + +#endif diff -Naur ns-2.29-original/wimax/scheduling/contentionslot.cc ns-2.29-new/wimax/scheduling/contentionslot.cc --- ns-2.29-original/wimax/scheduling/contentionslot.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/contentionslot.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,211 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "contentionslot.h" +#include +#include + +/* + * Creates a contention slot for the given frame + * @param frame The frame map + */ +ContentionSlot::ContentionSlot (FrameMap *map) +{ + assert (map); + map_ = map; +} + +/** + * Destructor + */ +ContentionSlot::~ContentionSlot() {} + +/* + * Set the initial contention slot window size + * @param backoff_start the initial contention slot window size + */ +void ContentionSlot::setBackoff_start( int backoff_start ) +{ + backoff_start_ = backoff_start; +} + +/* + * Set the final contention slot window size + * @param backoff_stop the final contention slot window size + */ +void ContentionSlot::setBackoff_stop( int backoff_stop ) +{ + backoff_stop_ = backoff_stop; +} + +/** + * Resume the timers for the requests + */ +void ContentionSlot::resumeTimers () {} + +/** + * Pause the timers for the requests + */ +void ContentionSlot::pauseTimers () {} + +/**** Methods for Ranging Contention slot ****/ + +/* + * Creates a contention slot for the given frame + * @param frame The frame map + */ +RngContentionSlot::RngContentionSlot (FrameMap *map) : ContentionSlot (map) +{ + request_ = NULL; +} + +/** + * Destructor + */ +RngContentionSlot::~RngContentionSlot() +{ + if (request_) + delete request_; +} + + +/* + * Add a ranging request + * @param p The packet to be sent during the ranging opportunity + */ +void RngContentionSlot::addRequest (Packet *p) +{ + assert (request_ == NULL); + request_ = new RangingRequest (this, p); +} + +/* + * Remove the pending request + */ +void RngContentionSlot::removeRequest () +{ + //assert (request_); + if (request_) { + delete request_; + request_ = NULL; + } +} + +/** + * Resume the timers for the requests + */ +void RngContentionSlot::resumeTimers () +{ + if (request_) + request_->resume(); +} + +/** + * Pause the timers for the requests + */ +void RngContentionSlot::pauseTimers () +{ + if (request_) + request_->pause(); +} + +/**** Methods for Bandwidth Contention slot ****/ + +/* + * Creates a contention slot for the given frame + * @param frame The frame map + */ +BwContentionSlot::BwContentionSlot (FrameMap *map) : ContentionSlot (map) +{ + LIST_INIT (&request_list_); +} + +/** + * Destructor + */ +BwContentionSlot::~BwContentionSlot() {} + +/* + * Add a bandwidth request + * @param p The packet to be sent during the ranging opportunity + * @param cid The CID of the bandwidth request + * @param len The size in bytes of the bandwidth request + */ +void BwContentionSlot::addRequest (Packet *p, int cid, int len) +{ + assert (getRequest (cid)==NULL); + BwRequest *b = new BwRequest (this, p, cid, len); + b->insert_entry_head (&request_list_); +} + +/* + * Remove the pending request + */ +void BwContentionSlot::removeRequest (int cid) +{ + BwRequest *b = getRequest (cid); + if (b!=NULL) { + b->remove_entry (); + delete b; + } +} + +/* + * Remove all pending reuquest + */ +void BwContentionSlot::removeRequests () +{ + for (BwRequest *c = (BwRequest *)request_list_.lh_first; c ; c=(BwRequest *)request_list_.lh_first) { + c->remove_entry(); + delete c; + } +} + + +/* + * Get the request for the given CID + * @param cid The CID for the request + */ +BwRequest* BwContentionSlot::getRequest (int cid) +{ + for (BwRequest *c = (BwRequest *)request_list_.lh_first; c ; c=(BwRequest *)(c->next_entry())) { + if (c->getCID()==cid) + return c; + } + return NULL; +} + +/** + * Resume the timers for the requests + */ +void BwContentionSlot::resumeTimers () +{ + for (BwRequest *c = (BwRequest *)request_list_.lh_first; c ; c=(BwRequest *)(c->next_entry())) { + c->resume(); + } +} + +/** + * Pause the timers for the requests + */ +void BwContentionSlot::pauseTimers () +{ + for (BwRequest *c = (BwRequest *)request_list_.lh_first; c ; c=(BwRequest *)(c->next_entry())) { + c->pause(); + } +} diff -Naur ns-2.29-original/wimax/scheduling/contentionslot.h ns-2.29-new/wimax/scheduling/contentionslot.h --- ns-2.29-original/wimax/scheduling/contentionslot.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/contentionslot.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,214 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef CONTENTIONSLOT_H +#define CONTENTIONSLOT_H + +#include "packet.h" +#include "queue.h" +#include "contentiontimer.h" + +class FrameMap; + +/** + * This class contains information about a contention slot + */ +class ContentionSlot +{ + friend class ContentionRequest; + + public: + /* + * Creates a contention slot for the given frame + * @param frame The frame map + */ + ContentionSlot (FrameMap *map); + + /** + * Destructor + */ + virtual ~ContentionSlot(); + + /* + * Return the initial contention slot window size + * @return the initial contention slot window size + */ + inline int getBackoff_start( ) { return backoff_start_; } + + /* + * Return the final contention slot window size + * @return the final contention slot window size + */ + inline int getBackoff_stop( ) { return backoff_stop_; } + + /* + * Return the opportunity size + * @return the opportunity size + */ + inline int getSize( ) { return size_; } + + /* + * Set the initial contention slot window size + * @param backoff_start the initial contention slot window size + */ + void setBackoff_start( int backoff_start ); + + /* + * Set the final contention slot window size + * @param backoff_stop the final contention slot window size + */ + void setBackoff_stop( int backoff_stop ); + + /* + * Set the opportunity size + * @param size The opportunity size + */ + inline void setSize( int size ) { size_ = size; } + + /** + * Resume the timers for the requests + */ + virtual void resumeTimers (); + + /** + * Pause the timers for the requests + */ + virtual void pauseTimers (); + + protected: + /** + * The frame map where this contention slot is located + */ + FrameMap *map_; + + /** + * Initial backoff window size. Must be power of 2 + */ + int backoff_start_; + + /** + * Final backoff window size + */ + int backoff_stop_; + + /** + * The duration in PS of the contention slot + */ + int size_; + private: + +}; + +/** + * Subclass used for ranging contention slot + */ +class RngContentionSlot: public ContentionSlot { + friend class RngContentionTimer; + public: + + /* + * Creates a contention slot for the given frame + * @param frame The frame map + */ + RngContentionSlot (FrameMap *map); + + /** + * Destructor + */ + virtual ~RngContentionSlot(); + + /* + * Add a ranging request + * @param p The packet to be sent during the ranging opportunity + */ + void addRequest (Packet *p); + + /* + * Remove the pending request + */ + void removeRequest (); + + /** + * Resume the timers for the requests + */ + void resumeTimers (); + + /** + * Pause the timers for the requests + */ + void pauseTimers (); + + private: + RangingRequest *request_; +}; + +/** + * Subclass used for ranging contention slot + */ +class BwContentionSlot: public ContentionSlot { + public: + /* + * Creates a contention slot for the given frame + * @param frame The frame map + */ + BwContentionSlot (FrameMap *map); + + /** + * Destructor + */ + virtual ~BwContentionSlot(); + + /* + * Add a bandwidth request + * @param p The packet to be sent during the ranging opportunity + * @param cid The CID of the bandwidth request + * @param len The size in bytes of the bandwidth request + */ + void addRequest (Packet *p, int cid, int len); + + /* + * Remove the pending request + */ + void removeRequest (int cid); + + /* + * Remove all pending reuquest + */ + void removeRequests (); + + /* + * Get the request for the given CID + * @param cid The CID for the request + */ + BwRequest * getRequest (int cid); + + /** + * Resume the timers for the requests + */ + void resumeTimers (); + + /** + * Pause the timers for the requests + */ + void pauseTimers (); + + private: + struct contentionRequest request_list_; +}; + +#endif diff -Naur ns-2.29-original/wimax/scheduling/contentiontimer.cc ns-2.29-new/wimax/scheduling/contentiontimer.cc --- ns-2.29-original/wimax/scheduling/contentiontimer.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/contentiontimer.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,40 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "contentiontimer.h" + +/** + * Creates a timer to handle the burst's transmission + * @param c The contention slot + */ +ContentionTimer::ContentionTimer( ContentionRequest* c ) : TimerHandler() +{ + assert (c); + c_ = c; +} + +/** + * When it expires, the timer will handle the next packet to send + * @param e not used + */ +void ContentionTimer::expire( Event* e ) +{ + c_->expire(); +} + + diff -Naur ns-2.29-original/wimax/scheduling/contentiontimer.h ns-2.29-new/wimax/scheduling/contentiontimer.h --- ns-2.29-original/wimax/scheduling/contentiontimer.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/contentiontimer.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,51 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef CONTENTIONTIMER_H +#define CONTENTIONTIMER_H + +#include "timer-handler.h" +#include "contentionrequest.h" + +/** + * Timer for contention window + */ +class ContentionTimer: public TimerHandler +{ + public: + /** + * Creates a timer to handle the burst's transmission + * @param c The contention slot + */ + ContentionTimer( ContentionRequest* c ); + + /** + * When it expires, the timer will handle the next packet to send + * @param e not used + */ + void expire( Event* e ); + + private: + + /** + * The contention slot containing the packets to send + */ + ContentionRequest* c_; +}; + +#endif diff -Naur ns-2.29-original/wimax/scheduling/dlburst.cc ns-2.29-new/wimax/scheduling/dlburst.cc --- ns-2.29-original/wimax/scheduling/dlburst.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/dlburst.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,28 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "dlburst.h" + +/** + * Creates a downlink burst + * @param phypdu The PhyPdu where it is located + */ +DlBurst::DlBurst (PhyPdu *phypdu) : Burst (phypdu) +{ + +} diff -Naur ns-2.29-original/wimax/scheduling/dlburst.h ns-2.29-new/wimax/scheduling/dlburst.h --- ns-2.29-original/wimax/scheduling/dlburst.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/dlburst.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,78 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef DLBURST_H +#define DLBURST_H + +#include "burst.h" + +/* Defines the OFDM DIUC values */ +enum diuc_t { + DIUC_STC_ZONE=0, + //1-11 reserved for burst profiles + DIUC_PROFILE_1, + DIUC_PROFILE_2, + DIUC_PROFILE_3, + DIUC_PROFILE_4, + DIUC_PROFILE_5, + DIUC_PROFILE_6, + DIUC_PROFILE_7, + DIUC_PROFILE_8, + DIUC_PROFILE_9, + DIUC_PROFILE_10, + DIUC_PROFILE_11, + //12 is reserved + DIUC_GAP=13, + DIUC_END_OF_MAP, + DIUC_EXT_DIUC +}; + +/** + * Downlink Burst Description + */ +class DlBurst : public Burst +{ + public: + + /** + * Default contructor + * @param phypdu The PhyPdu where it is located + */ + DlBurst (PhyPdu *phypdu); + + /** + * Return true if preamble is present in the burst + * @return true if preamble is present in the burst + */ + inline bool isPreamble( ) { return preamble_; } + + /** + * Set the preamble flag for the burst + * @param preamble The flag + */ + inline void setPreamble( bool preamble ) { preamble_ = preamble; } + + private: + /** + * Indicate if a preamble is included in the burst of not + */ + bool preamble_; + +}; + +#endif diff -Naur ns-2.29-original/wimax/scheduling/dlsubframetimer.cc ns-2.29-new/wimax/scheduling/dlsubframetimer.cc --- ns-2.29-original/wimax/scheduling/dlsubframetimer.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/dlsubframetimer.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,102 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "dlsubframetimer.h" +#include "framemap.h" +#include "subframe.h" +#include "wimaxscheduler.h" +#include "contentionslot.h" + +/** + * Creates a timer to handle the subframe transmission + * @param subframe The DlSubframe + */ +DlSubFrameTimer::DlSubFrameTimer (DlSubFrame *subframe): burstIndex_(0), newburst_(true), mac_(0) +{ + assert (subframe); + subframe_ = subframe; +} + +/** + * Reset the timer + */ +void DlSubFrameTimer::reset () +{ + burstIndex_ = 0; + newburst_ = true; + if (status()==TIMER_PENDING) + cancel(); +} + +/** + * When it expires, the timer will handle the next packet to send + * @param e not used + */ +void DlSubFrameTimer::expire( Event* e ) +{ + if (!mac_) { + mac_= subframe_->map_->getMac(); + } + + //printf ("At %f in Mac %d DlsubFrameTimer expires\n", NOW, mac_->addr()); + int iuc; + Burst *b = subframe_->getPdu()->getBurst(burstIndex_); + if (newburst_) { + //printf ("\tburst=%x type=%d\n", b,b->getIUC()); + if (b->getIUC()==DIUC_END_OF_MAP) { + //printf ("\tend of subframe\n"); + burstIndex_=0;//reset for next frame + if (mac_->getScheduler()->getNodeType()==STA_MN) { + mac_->getPhy()->setMode (OFDM_SEND); + } else { + mac_->getPhy()->setMode (OFDM_RECV); + } + return; //end of subframe + } + //change modulation + iuc = b->getIUC(); + Ofdm_mod_rate rate = subframe_->getProfile (iuc)->getEncoding(); + mac_->getPhy()->setModulation (rate); + } + //check if packet to send + Packet *p = b->dequeue(); + if (p) { + newburst_ = false; + double txtime = HDR_CMN(p)->txtime(); + //schedule for next packet + mac_->transmit (p); + + //printf ("\tNext packet at %f(in %f)\n", NOW+txtime, txtime); + if (b->getQueueLength()!=0) { + resched (txtime); //wait transmition time + return; + } + } + + //no packet to send...schedule for next phypdu + newburst_= true; + burstIndex_++; + double stime=0.0; + assert (b->next_entry()); + + stime = subframe_->map_->getStarttime(); + stime += b->next_entry()->getStarttime()*mac_->getPhy()->getSymbolTime(); + //printf ("\tNext burst at %f\n", stime); + resched (stime-NOW); + +} diff -Naur ns-2.29-original/wimax/scheduling/dlsubframetimer.h ns-2.29-new/wimax/scheduling/dlsubframetimer.h --- ns-2.29-original/wimax/scheduling/dlsubframetimer.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/dlsubframetimer.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,73 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef DLSUBFRAME_H +#define DLSUBFRAME_H + +#include "mac802_16.h" +#include "phypdu.h" + +class DlSubFrame; +/** + * This timer is used to handle the transmission of + * a UlSubframe. + */ +class DlSubFrameTimer: public TimerHandler +{ + public: + /** + * Creates a timer to handle the subframe transmission + * @param subframe The UlSubframe + */ + DlSubFrameTimer (DlSubFrame *subframe); + + /** + * When it expires, the timer will handle the next packet to send + * @param e not used + */ + void expire( Event* e ); + + /** + * Reset the timer + */ + void reset (); + + private: + /** + * The subframe + */ + DlSubFrame *subframe_; + + /** + * The current Burst being handled + */ + int burstIndex_; + + /** + * Tag to know if we are changing PhyPdu + */ + bool newburst_; + + /** + * Store local variables for faster access + */ + Mac802_16 *mac_; + +}; + +#endif diff -Naur ns-2.29-original/wimax/scheduling/framemap.cc ns-2.29-new/wimax/scheduling/framemap.cc --- ns-2.29-original/wimax/scheduling/framemap.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/framemap.cc 2008-07-02 11:50:25.000000000 +0200 @@ -0,0 +1,323 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + File * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + + +#include "framemap.h" +#include "wimaxscheduler.h" +#include "ulburst.h" +#include "dlburst.h" + +/* + * Creates a map of the frame + * @param mac Pointer to the mac layer + */ +FrameMap::FrameMap (Mac802_16 *mac): dlsubframe_(this), ulsubframe_(this) +{ + assert (mac); + mac_ = mac; + + //retreive information from mac + rtg_ = mac_->phymib_.rtg; + ttg_ = mac_->phymib_.ttg; + duration_ = mac_->getFrameDuration(); +} + +/** + * Compute the DL_MAP packet based on the information contained in the structure + */ +Packet* FrameMap::getDL_MAP( ) +{ + Packet *p = mac_->getPacket(); + hdr_cmn* ch = HDR_CMN(p); + + //printf ("Creating DL_MAP:"); + int nbies = dlsubframe_.getPdu()->getNbBurst(); + //printf ("nbies=%d\n",nbies); + + //allocate data for DL_MAP + p->allocdata (sizeof (struct mac802_16_dl_map_frame)); + mac802_16_dl_map_frame *frame = (mac802_16_dl_map_frame*) p->accessdata(); + + frame->type = MAC_DL_MAP; + frame->bsid = mac_->addr(); + frame->nb_ies = nbies; + + //allocate IEs + mac802_16_dlmap_ie *ies = frame->ies; + + for (int i = 0 ; i < nbies ; i++) { + Burst *b = dlsubframe_.getPdu()->getBurst(i); + ies[i].diuc = b->getIUC(); + ies[i].start_time = b->getStarttime(); + if (b->getIUC()!=DIUC_END_OF_MAP) { + ies[i].cid = b->getCid(); + if (i==0) + ies[i].preamble = dlsubframe_.getPdu()->getPreamble(); + else + ies[i].preamble = 0; + } + } + + ch->size() += GET_DL_MAP_SIZE(nbies); + + return p; +} + +/** + * Compute and return the DCD frame + */ +Packet* FrameMap::getDCD( ) +{ + Packet *p = mac_->getPacket (); + hdr_cmn* ch = HDR_CMN(p); + + //allocate data for DL_MAP + //printf ("getDCD...nbprofile=%d\n", dlsubframe_.getNbProfile()); + p->allocdata (sizeof (struct mac802_16_dcd_frame)); + mac802_16_dcd_frame *frame = (mac802_16_dcd_frame*) p->accessdata(); + + frame->type = MAC_DCD; + frame->dcid = mac_->addr(); //to check if needs to be different from ucid + frame->config_change_count = dlsubframe_.getCCC(); + frame->frame_duration_code = mac_->getFrameDurationCode (); + frame->frame_number = mac_->frame_number_; + frame->nb_prof = dlsubframe_.getNbProfile(); + frame->ttg = mac_->phymib_.ttg; + frame->rtg = mac_->phymib_.rtg; + frame->frequency = (int) (mac_->getPhy()->getFreq()/1000); + + //allocate IEs + mac802_16_dcd_profile *profiles = frame->profiles; + + int i=0; + for (Profile *p = dlsubframe_.getFirstProfile() ; p ; p=p->next_entry()) { + //set data for first burst + profiles[i].diuc = p->getIUC(); + profiles[i].frequency = p->getFrequency(); + profiles[i].fec = p->getEncoding(); + i++; + } + //the end of map is already included in the frame length + + ch->size() += GET_DCD_SIZE(dlsubframe_.getNbProfile()); + return p; +} + +/** + * Compute and return the UL_MAP frame + */ +Packet* FrameMap::getUL_MAP( ) +{ + Packet *p = mac_->getPacket (); + hdr_cmn* ch = HDR_CMN(p); + + int nbies = ulsubframe_.getNbPdu(); //there is one burst per UL phy PDU + //printf ("getUL_MAP, nbies=%d\n", nbies); + //allocate data for DL_MAP + p->allocdata (sizeof (struct mac802_16_ul_map_frame)); + mac802_16_ul_map_frame *frame = (mac802_16_ul_map_frame*) p->accessdata(); + + frame->type = MAC_UL_MAP; + frame->ucid = mac_->addr(); //set channel ID to index_ to be unique + frame->ucd_count = ulsubframe_.getCCC(); + frame->allocation_start = ulsubframe_.getStarttime(); //the subframe starts with the contention slot + frame->nb_ies = nbies; + + //allocate IEs + mac802_16_ulmap_ie *ies = frame->ies; + + int i=0; + for (PhyPdu *p = ulsubframe_.getFirstPdu(); p ; p= p ->next_entry()) { + UlBurst *b = (UlBurst*) p->getBurst(0); + ies[i].uiuc = b->getIUC(); //end of map + ies[i].start_time = b->getStarttime(); + if (b->getIUC()!=UIUC_END_OF_MAP) { + ies[i].cid = b->getCid(); + ies[i].midamble_rep = b->getMidamble(); + ies[i].duration = b->getDuration(); + if (b->getIUC() == UIUC_EXT_UIUC) { + ies[i].extended_uiuc = b->getExtendedUIUC(); + if (b->getExtendedUIUC ()== UIUC_FAST_RANGING) { + ies[i].fast_ranging.mac_addr = b->getFastRangingMacAddr (); + ies[i].fast_ranging.uiuc = b->getFastRangingUIUC (); + } + } + } + i++; + } + + ch->size() += GET_UL_MAP_SIZE(nbies); + return p; +} + +/** + * Compute and return the UCD frame + */ +Packet* FrameMap::getUCD( ) +{ + Packet *p = mac_->getPacket (); + hdr_cmn* ch = HDR_CMN(p); + + //allocate data for DL_MAP + p->allocdata (sizeof (struct mac802_16_ucd_frame)); + mac802_16_ucd_frame *frame = (mac802_16_ucd_frame*) p->accessdata(); + + frame->type = MAC_UCD; + frame->config_change_count = 0; //changed by scheduler + frame->rng_backoff_start = ulsubframe_.getRanging()->getBackoff_start(); + frame->rng_backoff_end = ulsubframe_.getRanging()->getBackoff_stop(); + frame->rng_req_size = ulsubframe_.getRanging()->getSize(); + frame->req_backoff_start = ulsubframe_.getBw_req()->getBackoff_start(); + frame->req_backoff_end = ulsubframe_.getBw_req()->getBackoff_stop()+1; + frame->bw_req_size = ulsubframe_.getBw_req()->getSize(); + + frame->nb_prof = ulsubframe_.getNbProfile(); + //allocate IEs + mac802_16_ucd_profile *profiles = frame->profiles; + + int i=0; + for (Profile *p = ulsubframe_.getFirstProfile() ; p ; p=p->next_entry()) { + //set data for first burst + profiles[i].uiuc = p->getIUC(); + profiles[i].fec = p->getEncoding(); + i++; + } + + //the end of map is already included in the frame length + ch->size() += GET_UCD_SIZE(ulsubframe_.getNbProfile()); + return p; +} + +/** + * Parse a DL_MAP message and create the data structure + * @param frame The DL frame information + */ +void FrameMap::parseDLMAPframe (mac802_16_dl_map_frame *frame) +{ + //printf ("parse DL-MAP in %d\n", mac_->addr()); + // Clear previous information + while (dlsubframe_.getPdu()->getNbBurst()>0) { + Burst *b = dlsubframe_.getPdu()->getBurst (0); + dlsubframe_.getPdu()->removeBurst (b); + delete b; + } + + int nbies = frame->nb_ies; + mac802_16_dlmap_ie *ies = frame->ies; + + for (int i = 0 ; i < nbies ; i++) { + Burst *b = dlsubframe_.getPdu()->addBurst(i); + b->setIUC(ies[i].diuc); + b->setStarttime(ies[i].start_time); + if (b->getIUC()!=DIUC_END_OF_MAP) { + b->setCid(ies[i].cid); + if (i==0) //first burst contains preamble + dlsubframe_.getPdu()->setPreamble(ies[i].preamble); + } + //printf ("\t Adding burst %d: cid=%d, iuc=%d start=%d\n", i, b->getCid(), b->getIUC(),b->getStarttime()); + } + //should we parse end of map too? +} + +/** + * Parse a DCD message and create the data structure + * @param frame The DL frame information + */ +void FrameMap::parseDCDframe (mac802_16_dcd_frame *frame) +{ + //clear previous profiles + dlsubframe_.removeProfiles(); + + int nb_prof = frame->nb_prof; + mac_->frame_number_ = frame->frame_number; + mac802_16_dcd_profile *profiles = frame->profiles; + mac_->setFrameDurationCode (frame->frame_duration_code); + + for (int i = 0 ; i < nb_prof ; i++) { + Profile *p = dlsubframe_.addProfile (profiles[i].frequency, (Ofdm_mod_rate)profiles[i].fec); + p->setIUC (profiles[i].diuc); + //printf ("\t Adding dl profile %i: f=%d, rate=%d, iuc=%d\n", i, p->getFrequency(), p->getEncoding(), p->getIUC()); + } +} + +/** + * Parse a UL_MAP message and create the data structure + * @param frame The UL frame information + */ +void FrameMap::parseULMAPframe (mac802_16_ul_map_frame *frame) +{ + //printf ("parse UL-MAP\n"); + // Clear previous information + for (PhyPdu *p = ulsubframe_.getFirstPdu(); p ; p = ulsubframe_.getFirstPdu()) { + ulsubframe_.removePhyPdu(p); + delete (p); + } + + int nbies = frame->nb_ies; + mac802_16_ulmap_ie *ies = frame->ies; + + ulsubframe_.setStarttime(frame->allocation_start); + //mac_->debug ("\tul start time = %d %f\n", frame->allocation_start, frame->allocation_start*mac_->getPhy()->getPS()); + + for (int i = 0 ; i < nbies ; i++) { + UlBurst *b = (UlBurst*)(ulsubframe_.addPhyPdu(i,0))->addBurst(0); + b->setIUC(ies[i].uiuc); + b->setStarttime(ies[i].start_time); + if (b->getIUC()!=UIUC_END_OF_MAP) { + b->setCid(ies[i].cid); + b->setMidamble(ies[i].midamble_rep); + b->setDuration(ies[i].duration); + if (b->getIUC() == UIUC_EXT_UIUC) { + if(ies[i].extended_uiuc== UIUC_FAST_RANGING) { + b->setFastRangingParam (ies[i].fast_ranging.mac_addr, ies[i].fast_ranging.uiuc); + } + } + } + /*mac_->debug ("\t Adding burst %d: cid=%d, iuc=%d start=%d (%f) duration=%d\n", \ + i, b->getCid(), b->getIUC(),b->getStarttime(), starttime_+frame->allocation_start*mac_->getPhy()->getPS()+b->getStarttime()*mac_->getPhy()->getSymbolTime(), b->getDuration());*/ + } +} + +/** + * Parse a UCD message and create the data structure + * @param frame The DL frame information + */ +void FrameMap::parseUCDframe (mac802_16_ucd_frame *frame) +{ + assert (frame); + //clear previous profiles + ulsubframe_.removeProfiles(); + + /*printf ("parse UCD..rng_start=%d, rng_stop=%d, req_start=%d, req_stop=%d\n",\ + frame->rng_backoff_start, frame->rng_backoff_end, frame->req_backoff_start, + frame->req_backoff_end);*/ + ulsubframe_.getRanging()->setBackoff_start(frame->rng_backoff_start); + ulsubframe_.getRanging()->setBackoff_stop(frame->rng_backoff_end); + ulsubframe_.getRanging()->setSize(frame->rng_req_size); + ulsubframe_.getBw_req()->setBackoff_start(frame->req_backoff_start); + ulsubframe_.getBw_req()->setBackoff_stop(frame->req_backoff_end); + ulsubframe_.getBw_req()->setSize(frame->bw_req_size); + + int nb_prof = frame->nb_prof; + mac802_16_ucd_profile *profiles = frame->profiles; + for (int i = 0 ; i < nb_prof ; i++) { + Profile *p = ulsubframe_.addProfile (0, (Ofdm_mod_rate)(profiles[i].fec)); + p->setIUC (profiles[i].uiuc); + //printf ("\t Adding ul profile %i: f=%d, rate=%d, iuc=%d\n", i, p->getFrequency(), p->getEncoding(), p->getIUC()); + } +} diff -Naur ns-2.29-original/wimax/scheduling/framemap.h ns-2.29-new/wimax/scheduling/framemap.h --- ns-2.29-original/wimax/scheduling/framemap.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/framemap.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,148 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef FRAMEMAP_H +#define FRAMEMAP_H + +#include "subframe.h" +#include "mac802_16.h" + +/** + * This class contains the datastructure to describe a frame + */ +class FrameMap +{ + public: + /* + * Creates a map of the frame + * @param mac Pointer to the mac layer + */ + FrameMap (Mac802_16 *mac); + + /** + * Compute and return the DCD frame + */ + Packet* getDCD( ); + /** + * Compute the DL_MAP packet based on the information contained in the structure + */ + Packet* getDL_MAP( ); + + /** + * Compute and return the UCD frame + */ + Packet* getUCD( ); + + /** + * Compute and return the UL_MAP frame + */ + Packet* getUL_MAP( ); + + /** + * Return the attached mac + * @return the mac + */ + inline Mac802_16 * getMac () { return mac_; } + + /** + * Return the DL subframe + * @return the DL subframe + */ + inline DlSubFrame * getDlSubframe () { return &dlsubframe_; } + + + /** + * Return the UL subframe + * @return the UL subframe + */ + inline UlSubFrame * getUlSubframe () { return &ulsubframe_; } + + + /** + * Parse a DL_MAP message and create the data structure + * @param frame The DL frame information + */ + void parseDLMAPframe (mac802_16_dl_map_frame *frame); + + /** + * Parse a DCD message and create the data structure + * @param frame The DL frame information + */ + void parseDCDframe (mac802_16_dcd_frame *frame); + + /** + * Parse a UL_MAP message and create the data structure + * @param frame The UL frame information + */ + void parseULMAPframe (mac802_16_ul_map_frame *frame); + + /** + * Parse a UCD message and create the data structure + * @param frame The DL frame information + */ + void parseUCDframe (mac802_16_ucd_frame *frame); + + /** + * Set the start time of the frame + */ + inline void setStarttime (double time) { starttime_ = time; } + + /** + * Return the time the frame started + * @return The time the frame started + */ + inline double getStarttime () { return starttime_; } + +private: + /** + * The mac layer + */ + Mac802_16 *mac_; + + /** + * The frame duration + */ + double duration_; + + /** + * Time the frame started. Used for synchronization + */ + double starttime_; + + /** + * The number of PS required to switch from receiver to transmitter + */ + int rtg_; + + /** + * The number of PS required to switch from sender to receiver + */ + int ttg_; + + /** + * The downlink subframe + */ + DlSubFrame dlsubframe_; + + /** + * The uplink subframe + */ + UlSubFrame ulsubframe_; +}; + +#endif diff -Naur ns-2.29-original/wimax/scheduling/phypdu.cc ns-2.29-new/wimax/scheduling/phypdu.cc --- ns-2.29-original/wimax/scheduling/phypdu.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/phypdu.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,174 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "phypdu.h" + +/** + * Create a phy pdu with the given preamble size + * @param preamble The preamble size in OFDM symbols + */ +PhyPdu::PhyPdu (FrameMap *map, int preamble) +{ + assert (preamble >=0 && map); + preamble_ = preamble; + map_ = map; + nb_burst_=0; + LIST_INIT(&burst_list_); +} + +/* + * Delete the object + */ +PhyPdu::~PhyPdu () +{ + for (Burst *b = burst_list_.lh_first; b ; b=burst_list_.lh_first) { + b->remove_entry (); + delete (b); + } +} + + +/** + * Set the preamble size for the PDU in unit of OFDM symbols + * @param preamble the preamble size for the PDU + */ +void PhyPdu::setPreamble( int preamble ) +{ + assert (preamble>=0); + preamble_ = preamble; +} + +/** + * Return the preamble size for the PDU in unit of OFDM symbols + * @return the preamble size for the PDU + */ +int PhyPdu::getPreamble( ) +{ + return preamble_; +} + +/** + * Add a burst in the PDU + * @param pos The position of the burst + */ +Burst* PhyPdu::addBurst(int pos) +{ + assert (pos >= 0 && pos <= nb_burst_ ); + Burst *b = new Burst (this); + if (pos==0) + b->insert_entry_head (&burst_list_); + else { + Burst *prev = burst_list_.lh_first ; + Burst *b2 = prev->next_entry(); + int index = 1; + while (index < pos) { + prev=b2; + b2=b2->next_entry(); + index++; + } + b->insert_entry (prev); + } + nb_burst_++; + return b; +} + +/** + * Remove a burst in the PDU + * @param burst The burst to remove + */ +void PhyPdu::removeBurst(Burst *b) +{ + b->remove_entry(); + nb_burst_--; +} + +/** + * Return the burst located at the given index + * @param pos The position of the burst + */ +Burst* PhyPdu::getBurst(int pos) +{ + assert (pos >= 0 && pos < nb_burst_ ); + Burst *b = burst_list_.lh_first ; + for (int i = 0 ; i < pos ; i++) { + b=b->next_entry(); + } + return b; +} + +/** Methods for class DlPhyPdu **/ + +/** + * Create a phy pdu with the given preamble size + * @param preamble The preamble size in OFDM symbols + */ +DlPhyPdu::DlPhyPdu (FrameMap *map, int preamble) : PhyPdu(map, preamble) +{ + +} + +/** + * Add a burst in the PDU + * @param pos The position of the burst + */ +Burst* DlPhyPdu::addBurst(int pos) +{ + assert (pos >= 0 && pos <= nb_burst_ ); + DlBurst *b = new DlBurst (this); + if (pos==0 || nb_burst_==0) + b->insert_entry_head (&burst_list_); + else { + Burst *prev = burst_list_.lh_first ; + Burst *b2 = prev->next_entry(); + int index = 1; + while (b2 && index < pos) { + prev=b2; + b2=b2->next_entry(); + index++; + } + b->insert_entry (prev); + } + nb_burst_++; + return b; +} + + +/** Methods for class UlPhyPdu **/ + +/** + * Create a phy pdu with the given preamble size + * @param preamble The preamble size in OFDM symbols + */ +UlPhyPdu::UlPhyPdu (FrameMap *map, int preamble) : PhyPdu(map, preamble) +{ + +} + +/** + * Add a burst in the PDU + * @param pos The position of the burst + */ +Burst* UlPhyPdu::addBurst(int pos) +{ + //UlPhyPdu only have one burst + assert (pos == 0 && nb_burst_==0 ); + UlBurst *b = new UlBurst (this); + b->insert_entry_head (&burst_list_); + nb_burst_++; + return b; +} diff -Naur ns-2.29-original/wimax/scheduling/phypdu.h ns-2.29-new/wimax/scheduling/phypdu.h --- ns-2.29-original/wimax/scheduling/phypdu.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/phypdu.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,175 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef PHYPDU_H +#define PHYPDU_H + +#include "burst.h" +#include "dlburst.h" +#include "ulburst.h" + +class FrameMap; +class PhyPdu; +LIST_HEAD (phyPdu, PhyPdu); +/** + * This class describte the content of a Phy PDU + */ +class PhyPdu +{ + public: + /** + * Create a phy pdu with the given preamble size + * @param preamble The preamble size in OFDM symbols + */ + PhyPdu (FrameMap *map, int preamble); + + /** + * Delete the object + */ + virtual ~PhyPdu (); + + /** + * Return the preamble size for the PDU in unit of OFDM symbols + * @return the preamble size for the PDU + */ + int getPreamble( ); + + /** + * Set the preamble size for the PDU in unit of OFDM symbols + * @param preamble the preamble size for the PDU + */ + void setPreamble( int preamble ); + + /** + * Create and return a burst in the PDU + * @param pos The position of the burst + * @return The burst created + */ + virtual Burst * addBurst(int pos); + + /** + * Remove a burst in the PDU + * @param burst The burst to remove + */ + void removeBurst(Burst *b); + + /** + * Return the burst located at the given index + * @param pos The position of the burst + */ + Burst* getBurst(int pos); + + /** + * Return the number of burst in the PhyPDU + */ + inline int getNbBurst () { return nb_burst_; } + + /** + * Return the FrameMap + */ + inline FrameMap * getMap() { return map_; } + + // Chain element to the list + inline void insert_entry_head(struct phyPdu *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Chain element to the list + inline void insert_entry(PhyPdu *elem) { + LIST_INSERT_AFTER(elem, this, link); + } + + // Return next element in the chained list + PhyPdu* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + protected: + /* + * Pointer to next in the list + */ + LIST_ENTRY(PhyPdu) link; + //LIST_ENTRY(PhyPdu); //for magic draw + + /** + * Curent number of bursts + */ + int nb_burst_; + + /** + * The list of burst contained in this PDU. + * For uplink Phy PDU, only one burst is allowed + */ + struct burst burst_list_; + + private: + /** + * Size of the preamble in units of OFDM symbols + */ + int preamble_; + + /** + * The frame map + */ + FrameMap *map_; + +}; + +/** + * Define subclass for downlink phy pdu + */ +class DlPhyPdu: public PhyPdu +{ + public: + /** + * Create a phy pdu with the given preamble size + * @param preamble The preamble size in OFDM symbols + */ + DlPhyPdu (FrameMap *map, int preamble); + + /** + * Create and return a burst in the PDU + * @param pos The position of the burst + * @return The burst created + */ + virtual Burst * addBurst(int pos); +}; + +/** + * Define subclass for uplink phy pdu + */ +class UlPhyPdu: public PhyPdu +{ + public: + /** + * Create a phy pdu with the given preamble size + * @param preamble The preamble size in OFDM symbols + */ + UlPhyPdu (FrameMap *map, int preamble); + + /** + * Create and return a burst in the PDU + * @param pos The position of the burst + * @return The burst created + */ + virtual Burst * addBurst(int pos); +}; + +#endif diff -Naur ns-2.29-original/wimax/scheduling/profile.cc ns-2.29-new/wimax/scheduling/profile.cc --- ns-2.29-original/wimax/scheduling/profile.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/profile.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,95 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "profile.h" +#include "subframe.h" + +/** + * Creates a profile with the given frequency and encoding + * @param f The frequency information for the profile + * @param enc The encoding type + */ +Profile::Profile (SubFrame *subframe, int f, Ofdm_mod_rate enc) : iuc_(0) +{ + assert (subframe); + subframe_ = subframe; + frequency_ = f; + encoding_ = enc; +} + +/** + * Return the encoding type + * @return the encoding type + */ +Ofdm_mod_rate Profile::getEncoding( ) +{ + return encoding_; +} + +/** + * Set the encoding type + * @param enc the encoding type + */ +void Profile::setEncoding( Ofdm_mod_rate enc ) +{ + if (encoding_ != enc) + subframe_->incrCCC(); + encoding_ = enc; +} + +/** + * Return the frequency in unit of kHz + * @return the frequency + */ +int Profile::getFrequency( ) +{ + return frequency_; +} + +/** + * Set the frequency in unit of kHz + * @param f the frequency + */ +void Profile::setFrequency( int f ) +{ + if (frequency_ != f) + subframe_->incrCCC(); + frequency_ = f; +} + +/** + * Return the frequency in unit of kHz + * @return the frequency + */ +int Profile::getIUC( ) +{ + return iuc_; +} + +/** + * Set the IUC number for this profile + * @param iuc The IUC number for this profile + */ +void Profile::setIUC( int iuc ) +{ + if (iuc_!=0 && iuc_!= iuc) + subframe_->incrCCC(); + iuc_ = iuc; +} + + diff -Naur ns-2.29-original/wimax/scheduling/profile.h ns-2.29-new/wimax/scheduling/profile.h --- ns-2.29-original/wimax/scheduling/profile.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/profile.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,121 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef PROFILE_H +#define PROFILE_H + +#include "ofdmphy.h" + +class SubFrame; + +class Profile; +LIST_HEAD (profile, Profile); + +/** + * This class contains information about burst such as modulation, frequency... + */ +class Profile +{ + public: + /** + * Creates a profile with the given frequency and encoding + * @param f The frequency information for the profile + * @param enc The encoding type + */ + Profile (SubFrame *subframe, int f, Ofdm_mod_rate enc); + + /** + * Set the IUC number for this profile + * @param iuc The IUC number for this profile + */ + void setIUC( int iuc ); + + /** + * Return the frequency in unit of kHz + * @return the frequency + */ + int getIUC(); + + /** + * Return the encoding type + * @return the encoding type + */ + Ofdm_mod_rate getEncoding( ); + + /** + * Return the frequency in unit of kHz + * @return the frequency + */ + int getFrequency( ); + + /** + * Set the encoding type + * @param enc the encoding type + */ + void setEncoding( Ofdm_mod_rate enc ); + + /** + * Set the frequency in unit of kHz + * @param f the frequency + */ + void setFrequency( int f ); + + // Chain element to the list + inline void insert_entry(struct profile *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Return next element in the chained list + Profile* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + + private: + /** + * The type of modulation used by the burst + */ + Ofdm_mod_rate encoding_; + + /** + * The downlink frequency in kHz + */ + int frequency_; + + /** + * The Interval Usage Code for the profile + */ + int iuc_; + + /** + * The subframe containing this profile + * Used to inform configuration change + */ + SubFrame *subframe_; + + /* + * Pointer to next in the list + */ + LIST_ENTRY(Profile) link; + //LIST_ENTRY(Profile); //for magic draw + +}; + +#endif diff -Naur ns-2.29-original/wimax/scheduling/scanningstation.cc ns-2.29-new/wimax/scheduling/scanningstation.cc --- ns-2.29-original/wimax/scheduling/scanningstation.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/scanningstation.cc 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,50 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "scanningstation.h" + +/** + * Create an data object with the given attributes + * @param nodeid The node + * @param duration The scanning duration + * @param start The frame at which the scanning start + * @param interleaving The interleaving interval + * @param iteration The number of iterations + */ +ScanningStation::ScanningStation (int nodeid, int duration, int start, int interleaving, int iteration) +{ + nodeid_ = nodeid; + duration_ = duration; + start_frame_ = start; + interleaving_ = interleaving; + iteration_ = iteration; +} + +/** + * Determines if the node is currently scanning + * @param frame The current frame + */ +bool ScanningStation::isScanning (int frame) +{ + //printf ("isScanning %d frame=%d, start_frame=%d, duration=%d, interleaving=%d iteration %d\n", nodeid_, frame, start_frame_, duration_, interleaving_, iteration_); + if ((frame < start_frame_)||(frame > (start_frame_ + (duration_+interleaving_)*iteration_))) + return false; + else { + return (((frame-start_frame_)%(duration_+interleaving_))-duration_)<0; + } +} diff -Naur ns-2.29-original/wimax/scheduling/scanningstation.h ns-2.29-new/wimax/scheduling/scanningstation.h --- ns-2.29-original/wimax/scheduling/scanningstation.h 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/scanningstation.h 2008-04-09 13:12:04.000000000 +0200 @@ -0,0 +1,112 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#ifndef SCANNINGSTATION_H +#define SCANNINGSTATION_H + +#include "packet.h" + +class ScanningStation; +LIST_HEAD (scanningStation, ScanningStation); + +/** + * Contains information about a scanning station and + * helps to determine if it is in a scanning or interleaving + * time. + */ +class ScanningStation +{ + public: + /** + * Create an data object with the given attributes + * @param nodeid The node + * @param duration The scanning duration + * @param start The frame at which the scanning start + * @param interleaving The interleaving interval + * @param iteration The number of iterations + */ + ScanningStation (int nodeid, int duration, int start, int interleaving, int iteration); + + /** + * Determines if the node is currently scanning + * @param frame The current frame + */ + bool isScanning (int frame); + + /** + * Return the node id + */ + int getNodeId () { return nodeid_; } + + // Chain element to the list + inline void insert_entry_head(struct scanningStation *head) { + LIST_INSERT_HEAD(head, this, link); + } + + // Chain element to the list + inline void insert_entry(ScanningStation *elem) { + LIST_INSERT_AFTER(elem, this, link); + } + + // Return next element in the chained list + ScanningStation* next_entry(void) const { return link.le_next; } + + // Remove the entry from the list + inline void remove_entry() { + LIST_REMOVE(this, link); + } + + protected: + + /** + * Pointer to next in the list + */ + LIST_ENTRY(ScanningStation) link; + //LIST_ENTRY(ScanningStation); //for magic draw + + + private: + /** + * Duration of scanning allocation in frames + */ + int duration_; + + /** + * Start frame (absolute) + */ + int start_frame_; + + /** + * interleaving in frames + */ + int interleaving_; + + /** + * number of iterations + */ + int iteration_; + + /** + * The node that is scanning + */ + int nodeid_; +}; + + + +#endif diff -Naur ns-2.29-original/wimax/scheduling/ssscheduler.cc ns-2.29-new/wimax/scheduling/ssscheduler.cc --- ns-2.29-original/wimax/scheduling/ssscheduler.cc 1970-01-01 01:00:00.000000000 +0100 +++ ns-2.29-new/wimax/scheduling/ssscheduler.cc 2009-04-13 15:19:27.000000000 +0200 @@ -0,0 +1,1804 @@ +/* This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of + * their official duties. Pursuant to title 17 Section 105 of the United + * States Code this software is not subject to copyright protection and + * is in the public domain. + * NIST assumes no responsibility whatsoever for its use by other parties, + * and makes no guarantees, expressed or implied, about its quality, + * reliability, or any other characteristic. + *
+ * We would appreciate acknowledgement if the software is used. + *
+ * NIST ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND + * DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING + * FROM THE USE OF THIS SOFTWARE. + *

+ * @author rouil + */ + +#include "ssscheduler.h" +#include "burst.h" + +/** + * Tcl hook for creating SS scheduler + */ +static class SSschedulerClass : public TclClass { +public: + SSschedulerClass() : TclClass("WimaxScheduler/SS") {} + TclObject* create(int, const char*const*) { + return (new SSscheduler()); + + } +} class_ssscheduler; + +/* + * Create a scheduler + */ +SSscheduler::SSscheduler (): t1timer_(0),t2timer_(0),t6timer_(0), t12timer_(0), + t21timer_(0), lostDLMAPtimer_(0), lostULMAPtimer_(0), + t44timer_(0), scan_info_(0) +{ + debug2 ("SSscheduler created\n"); +} + +/** + * Initializes the scheduler + */ +void SSscheduler::init () +{ + WimaxScheduler::init(); + + //At initialization, the SS is looking for synchronization + mac_->setMacState (MAC802_16_WAIT_DL_SYNCH); + mac_->getPhy()->setMode (OFDM_RECV); + //start timer for expiration + t21timer_ = new WimaxT21Timer (mac_); + t21timer_->start (mac_->macmib_.t21_timeout); + + //creates other timers + t1timer_ = new WimaxT1Timer (mac_); + t12timer_ = new WimaxT12Timer (mac_); + t2timer_ = new WimaxT2Timer (mac_); + lostDLMAPtimer_ = new WimaxLostDLMAPTimer (mac_); + lostULMAPtimer_ = new WimaxLostULMAPTimer (mac_); + + nb_scan_req_ = 0; + + scan_info_ = (struct scanning_structure *) malloc (sizeof (struct scanning_structure)); + memset (scan_info_, 0, sizeof (struct scanning_structure)); + scan_info_->nbr = NULL; + scan_info_->substate = NORMAL; + + /// Added by Aymen + BwRequestSendingParameter_ = 0; + BwRequestSendingPeriod_ = 10; + + SymbolNumberForUnicastRequest_ = 3; + /// +} + +/** + * Interface with the TCL script + * @param argc The number of parameter + * @param argv The list of parameters + */ +int SSscheduler::command(int argc, const char*const* argv) +{ + if (argc == 2) { + if (strcmp(argv[1], "send-scan") == 0) { + send_scan_request(); + return TCL_OK; + } + } + + + /// Added by Aymen + if(argc == 6) + { + if(strcmp(argv[1], "send-dsa") == 0) { + addFlow(atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), (SchedulingType_t) atoi (argv[5])); + sendFlowRequest(); + return TCL_OK; + } + else + if (strcmp(argv[1], "add-flow") == 0) { + addFlow(atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), (SchedulingType_t) atoi (argv[5])); + return TCL_OK; + } + } + + if(argc == 3) + { + if (strcmp(argv[1], "set-BwRequestSendingPeriod") == 0) + { + BwRequestSendingPeriod_ = atoi (argv[2]); + return TCL_OK; + } + else + if (strcmp(argv[1], "set-BandwidthBEconnections") == 0) + { + sendBwRequest(atoi (argv[2])); + return TCL_OK; + } + } + /// + + return TCL_ERROR; + +} + +/** + * Start a new frame + */ +void SSscheduler::start_dlsubframe () +{ + + //mac_->debug ("At %f in Mac %d SS scheduler dlsubframe expires %d\n", NOW, mac_->addr(), scan_info_->substate); + + mac_->frame_number_++; + + switch (scan_info_->substate) { + case SCAN_PENDING: + if (scan_info_->count == 0) { + resume_scanning(); + return; + } + scan_info_->count--; + break; + case HANDOVER_PENDING: + if (scan_info_->handoff_timeout == 0) { + assert (scan_info_->nbr); +#ifdef USE_802_21 + mac_->debug ("At %f in Mac %d link handoff proceeding\n", NOW, mac_->addr()); + mac_->send_link_handoff_proceeding (mac_->addr(), mac_->getPeerNode_head()->getPeerNode(), scan_info_->nbr->getID()); +#endif + scan_info_->substate = HANDOVER; + //restore previous state + //mac_->restore_state (scan_info_->nbr->getState()->state_info); + mac_->setChannel (scan_info_->nbr->getState()->state_info->channel); + lost_synch (); + //add target as peer + mac_->addPeerNode (new PeerNode(scan_info_->nbr->getID())); + return; + } + scan_info_->handoff_timeout--; + break; + default: + break; + } + + //change state of PHY + //mac_->getPhy()->setMode (OFDM_RECV); + + //this is the begining of new frame + map_->setStarttime (NOW); + + //start handler of dlsubframe + map_->getDlSubframe()->getTimer()->sched (0); + + //reschedule for next frame + dl_timer_->resched (mac_->getFrameDuration()); + + +} + + + +/** + * Start a new frame + */ +void SSscheduler::start_ulsubframe () +{ + + //mac_->debug ("At %f in Mac %d SS scheduler ulsubframe expires\n", NOW, mac_->addr()); + + //change state of PHY: even though it should have been done before + //there are some cases where it does not (during scanning) + mac_->getPhy()->setMode (OFDM_SEND); + + //1-Transfert the packets from the queues in Connections to burst queues + Burst *b; + OFDMPhy *phy = mac_->getPhy(); + //printf ("SS has %d ul bursts\n", map_->getUlSubframe()->getNbPdu ()); + + PeerNode *peer = mac_->getPeerNode_head(); //this is the BS + assert (peer!=NULL); + + + for (int index = 0 ; index < map_->getUlSubframe()->getNbPdu (); index++) { + b = map_->getUlSubframe()->getPhyPdu (index)->getBurst (0); + + if (b->getIUC()==UIUC_END_OF_MAP) { + //consistency check.. + assert (index == map_->getUlSubframe()->getNbPdu ()-1); + break; + } + + + if (b->getIUC()==UIUC_INITIAL_RANGING || b->getIUC()==UIUC_REQ_REGION_FULL) + continue; + + int duration = 0; + + //get the packets from the connection with the same CID + //printf ("\tBurst CID=%d\n", b->getCid()); + Connection *c=mac_->getCManager ()->get_connection (b->getCid(), true); + //assert (c); + if (!c) + continue; //I do not have this CID. Must be for another node + //transfert the packets until it reaches burst duration or no more packets + assert (c->getType()==CONN_PRIMARY); + + + +/// Added by Aymen +// receive an unicast poll +if(peer->getPrimary()) + if(b->getCid() == peer->getPrimary()->get_cid()) + if(b->getIUC() == UIUC_REQ_REGION_FOCUSED) + if(peer->getOutData()) + if(peer->getOutData()->get_queue()->head()) + if(peer->getOutData()->get_serviceflow()->getScheduling() == SERVICE_rtPS) + { + int duration_tmp = 0; + //addBwRequest(peer->getOutData(), max_data0); + addBwRequest(peer->getOutData()); + duration_tmp = transfer_packets (peer->getPrimary(), b, duration_tmp); + continue; + } + +/// + + + + + + if (peer->getBasic()!= NULL) + duration = transfer_packets (peer->getBasic(), b, duration); + if (peer->getPrimary()!= NULL) + duration = transfer_packets (peer->getPrimary(), b, duration); + if (peer->getSecondary()!= NULL) + duration = transfer_packets (peer->getSecondary(), b, duration); + if (peer->getOutData()!=NULL) + duration = transfer_packets (peer->getOutData(), b, duration); + + } + + /// Was added by Richard + //2-compute size of data left to create bandwidth requests +/* if (peer->getBasic()!= NULL) + create_request (peer->getBasic()); + if (peer->getPrimary()!= NULL) + create_request (peer->getPrimary()); + if (peer->getSecondary()!= NULL) + create_request (peer->getSecondary()); + if (peer->getOutData()!=NULL) + create_request (peer->getOutData()); +*/ + /// + + + + +// tempo /////////////////////////// + /*if (peer->getBasic()!= NULL) + create_request (peer->getBasic()); + if (peer->getPrimary()!= NULL) + create_request (peer->getPrimary()); + if (peer->getSecondary()!= NULL) + create_request (peer->getSecondary()); +*/ + +/*if(mac_->getServiceHandler()->get_flow_head_()->lh_first) + if(mac_->getServiceHandler()->get_flow_head_()->lh_first->getScheduling() == SERVICE_BE) + { + sendBwRequest(peer->getBasic()); + sendBwRequest(peer->getPrimary()); + sendBwRequest(peer->getSecondary()); + sendBwRequest(peer->getOutData()); + }*/ +/////////////////////////////////// + + + + /// Added by Aymen + // send bw request with contention (for BE connections) + if(peer->getOutData()) + if(peer->getOutData()->get_serviceflow()->getScheduling() == SERVICE_BE) + { + //Send immediately bw req for basic, primary, and secondary connections + sendBwRequest(peer->getBasic()); + sendBwRequest(peer->getPrimary()); + sendBwRequest(peer->getSecondary()); + + //Send periodically bw req for data connection + if(BwRequestSendingParameter_ == 0) + sendBwRequest(peer->getOutData()); + + BwRequestSendingParameter_ ++; + BwRequestSendingParameter_ = BwRequestSendingParameter_ % BwRequestSendingPeriod_; + } + /// + + + + + + //start handler for ulsubframe + b = map_->getUlSubframe()->getPhyPdu (0)->getBurst (0); + map_->getUlSubframe()->getTimer()->sched (b->getStarttime()*phy->getSymbolTime()); + + //reschedule for next frame + ul_timer_->resched (mac_->getFrameDuration()); + + +} + +/** + * Create a request for the given connection + * @param con The connection to check + */ +void SSscheduler::create_request (Connection *con) +{ + if (con->queueLength()==0) + return; //queue is empty + else if (map_->getUlSubframe()->getBw_req()->getRequest (con->get_cid())!=NULL) { + debug2 ("At %f in Mac %d already pending requests for cid=%d\n", NOW, mac_->addr(), con->get_cid()); + return; //there is already a pending request + } + + Packet *p= mac_->getPacket(); + hdr_cmn* ch = HDR_CMN(p); + bw_req_header_t *header = (bw_req_header_t *)&(HDR_MAC802_16(p)->header); + header->ht=1; + header->ec=1; + header->type = 0; //incremental..to check meaning + header->br = con->queueByteLength(); + header->cid = con->get_cid(); + + double txtime = mac_->getPhy()->getTrxTime (ch->size(), map_->getUlSubframe()->getProfile (UIUC_REQ_REGION_FULL)->getEncoding()); + ch->txtime() = txtime; + map_->getUlSubframe()->getBw_req()->addRequest (p, con->get_cid(), con->queueByteLength()); + debug2 ("SSscheduler enqueued request for cid=%d len=%d\n", con->get_cid(), con->queueByteLength()); + //start timeout for request +} +/** + * Process a packet received by the Mac. Only scheduling related packets should be sent here (BW request, UL_MAP...) + * @param p The packet to process + */ +void SSscheduler::process (Packet * p) +{ + assert (mac_ && HDR_CMN(p)->ptype()==PT_MAC); + debug2 ("SSScheduler received packet to process\n"); + + hdr_mac802_16 *wimaxHdr = HDR_MAC802_16(p); + gen_mac_header_t header = wimaxHdr->header; + + //we cast to this frame because all management frame start with + //a type + mac802_16_dl_map_frame *frame = (mac802_16_dl_map_frame*) p->accessdata(); + + switch (frame->type) { + case MAC_DL_MAP: + map_->setStarttime (NOW-HDR_CMN(p)->txtime()); + process_dl_map (frame); + break; + case MAC_DCD: + process_dcd ((mac802_16_dcd_frame*)frame); + break; + case MAC_UL_MAP: + process_ul_map ((mac802_16_ul_map_frame*)frame); + break; + case MAC_UCD: + process_ucd ((mac802_16_ucd_frame*)frame); + break; + case MAC_RNG_RSP: + process_ranging_rsp ((mac802_16_rng_rsp_frame*) frame); + break; + case MAC_REG_RSP: + process_reg_rsp ((mac802_16_reg_rsp_frame*) frame); + break; + case MAC_MOB_SCN_RSP: + process_scan_rsp ((mac802_16_mob_scn_rsp_frame *) frame); + break; + case MAC_MOB_BSHO_RSP: + process_bsho_rsp ((mac802_16_mob_bsho_rsp_frame *) frame); + break; + case MAC_MOB_NBR_ADV: + process_nbr_adv ((mac802_16_mob_nbr_adv_frame *) frame); + break; + default: + mac_->debug ("unknown packet in SS %d\n", mac_->addr()); + //exit (0); + } + + Packet::free (p); + +} + +/** + * Return the type of STA this scheduler is good for + * @return STA_SS + */ +station_type_t SSscheduler::getNodeType () +{ + return STA_MN; +} + +/** + * Called when lost synchronization + */ +void SSscheduler::lost_synch () +{ + //reset timers + if (t1timer_->busy()!=0) + t1timer_->stop(); + if (t12timer_->busy()!=0) + t12timer_->stop(); + if (t21timer_->busy()!=0) + t21timer_->stop(); + if (lostDLMAPtimer_->busy()!=0) + lostDLMAPtimer_->stop(); + if (lostULMAPtimer_->busy()!=0) + lostULMAPtimer_->stop(); + if (t2timer_->busy()!=0) + t2timer_->stop(); + if (t44timer_ && t44timer_->busy()!=0) + t44timer_->stop(); + //we need to go to receiving mode + //printf ("Set phy to recv %x\n", mac_->getPhy()); + mac_->getPhy()->setMode (OFDM_RECV); + if (mac_->getMacState()==MAC802_16_CONNECTED) { + //remove possible pending requests + map_->getUlSubframe()->getBw_req()->removeRequests(); + +#ifdef USE_802_21 + mac_->debug ("At %f in Mac %d, send link down\n", NOW, mac_->addr()); + mac_->send_link_down (mac_->addr(), RC_FAIL_NORESOURCE); +#endif + } + + //remove information about peer node + if (mac_->getPeerNode_head()) + mac_->removePeerNode (mac_->getPeerNode_head()); + + //start waiting for DL synch + mac_->setMacState (MAC802_16_WAIT_DL_SYNCH); + t21timer_->start (mac_->macmib_.t21_timeout); + if (dl_timer_->status()==TIMER_PENDING) + dl_timer_->cancel(); + map_->getDlSubframe()->getTimer()->reset(); + if (ul_timer_->status()==TIMER_PENDING) + ul_timer_->cancel(); + map_->getUlSubframe()->getTimer()->reset(); +} + +/** + * Called when a timer expires + * @param The timer ID + */ +void SSscheduler::expire (timer_id id) +{ + switch (id) { + case WimaxT21TimerID: + mac_->debug ("At %f in Mac %d, synchronization failed\n", NOW, mac_->addr()); + //go to next channel + mac_->nextChannel(); + t21timer_->start (mac_->macmib_.t21_timeout); + break; + case WimaxLostDLMAPTimerID: + mac_->debug ("At %f in Mac %d, lost synchronization (DL_MAP)\n", NOW, mac_->addr()); + lost_synch (); + break; + case WimaxT1TimerID: + mac_->debug ("At %f in Mac %d, lost synchronization (DCD)\n", NOW, mac_->addr()); + lost_synch (); + break; + case WimaxLostULMAPTimerID: + mac_->debug ("At %f in Mac %d, lost synchronization (UL_MAP)\n", NOW, mac_->addr()); + lost_synch (); + break; + case WimaxT12TimerID: + mac_->debug ("At %f in Mac %d, lost uplink param (UCD)\n", NOW, mac_->addr()); + lost_synch (); + break; + case WimaxT2TimerID: + mac_->debug ("At %f in Mac %d, lost synchronization (RNG)\n", NOW, mac_->addr()); + map_->getUlSubframe()->getRanging()->removeRequest (); + lost_synch (); + break; + case WimaxT3TimerID: + mac_->debug ("At %f in Mac %d, no response from BS\n", NOW, mac_->addr()); + //we reach the maximum number of retries + //mark DL channel usuable (i.e we go to next) + map_->getUlSubframe()->getRanging()->removeRequest (); + mac_->nextChannel(); + lost_synch (); + break; + case WimaxT6TimerID: + mac_->debug ("At %f in Mac %d, registration timeout (nbretry=%d)\n", NOW, mac_->addr(), + nb_reg_retry_); + if (nb_reg_retry_ == mac_->macmib_.reg_req_retry) { + mac_->debug ("\tmax retry excedeed\n"); + lost_synch (); + } else { + send_registration(); + } + break; + case WimaxT44TimerID: + mac_->debug ("At %f in Mac %d, did not receive MOB_SCN-RSP (nb_retry=%d)\n", NOW, mac_->addr(), nb_scan_req_); + if (nb_scan_req_ <= mac_->macmib_.scan_req_retry) { + send_scan_request (); + } else { //reset for next time + nb_scan_req_ = 0; + } + break; + case WimaxScanIntervalTimerID: + pause_scanning (); + break; + case WimaxRdvTimerID: + //we need to meet at another station. We cancel the current scanning + //lost_synch (); + mac_->debug ("At %f in Mac %d Rdv timer expired\n", NOW, mac_->addr()); + break; + default: + mac_->debug ("Trigger unkown\n"); + } +} + +/**** Packet processing methods ****/ + +/** + * Process a DL_MAP message + * @param frame The dl_map information + */ +void SSscheduler::process_dl_map (mac802_16_dl_map_frame *frame) +{ + assert (frame); + + //create an entry for the BS + if (mac_->getPeerNode (frame->bsid)==NULL) + mac_->addPeerNode (new PeerNode (frame->bsid)); + + map_->parseDLMAPframe (frame); + + if (mac_->getMacState()==MAC802_16_WAIT_DL_SYNCH) { + mac_->debug ("At %f in %d, received DL_MAP for synch from %d (substate=%d)\n", + NOW, mac_->addr(), frame->bsid,scan_info_->substate); + assert (t21timer_->busy()!=0); + //synchronization is done + t21timer_->stop(); + //start lost_dl_map + lostDLMAPtimer_->start (mac_->macmib_.lost_dlmap_interval); + //start T1: DCD + t1timer_->start (mac_->macmib_.t1_timeout); + //start T12: UCD + t12timer_->start (mac_->macmib_.t12_timeout); + +#ifdef USE_802_21 + mac_->debug ("At %f in Mac %d, send link detected\n", NOW, mac_->addr()); + mac_->send_link_detected (mac_->addr(), frame->bsid, 1); +#endif + + mac_->setMacState(MAC802_16_WAIT_DL_SYNCH_DCD); + + //if I am doing handoff and we have dcd/ucd information + //from scanning, use it + if (scan_info_->substate == HANDOVER || scan_info_->substate == SCANNING) { + if (scan_info_->substate == SCANNING) { + if (scan_info_->nbr == NULL || scan_info_->nbr->getID()!=frame->bsid) { + //check if an entry already exist in the database + scan_info_->nbr = nbr_db_->getNeighbor (frame->bsid); + if (scan_info_->nbr == NULL) { + //create entry + debug2 ("Creating nbr info for node %d\n", frame->bsid); + scan_info_->nbr = new WiMAXNeighborEntry (frame->bsid); + nbr_db_->addNeighbor (scan_info_->nbr); + } else { + debug2 ("loaded nbr info\n"); + if (scan_info_->nbr->isDetected ()) { + //we already synchronized with this AP...skip channel + mac_->nextChannel(); + lost_synch (); + return; + } + } + } + }//if HANDOVER, scan_info_->nbr is already set + + bool error = false; + //we check if we can read the DL_MAP + mac802_16_dcd_frame *dcd = scan_info_->nbr->getDCD(); + if (dcd!=NULL) { + debug2 ("Check if we can decode stored dcd\n"); + //check if we can decode dl_map with previously acquired dcd + bool found; + for (int i = 0 ; !error && i < map_->getDlSubframe()->getPdu()->getNbBurst() ; i++) { + int diuc = map_->getDlSubframe()->getPdu()->getBurst(i)->getIUC(); + if (diuc == DIUC_END_OF_MAP) + continue; + found = false; + for (u_int32_t j = 0 ; !found && j < dcd->nb_prof; j++) { + found = dcd->profiles[j].diuc==diuc; + } + error = !found; + } + if (!error) + process_dcd (dcd); + } else { + debug2 ("No DCD information found\n"); + } + } + } else { + //maintain synchronization + assert (lostDLMAPtimer_->busy()); + lostDLMAPtimer_->stop(); + //printf ("update dlmap timer\n"); + lostDLMAPtimer_->start (mac_->macmib_.lost_dlmap_interval); + + if (mac_->getMacState()!= MAC802_16_WAIT_DL_SYNCH_DCD + && mac_->getMacState()!=MAC802_16_UL_PARAM) { + + //since the map may have changed, we need to adjust the timer + //for the DLSubframe + double stime = map_->getStarttime(); + stime += map_->getDlSubframe()->getPdu()->getBurst(1)->getStarttime()*mac_->getPhy()->getSymbolTime(); + //printf ("received dl..needs to update expiration to %f, %f,%f\n", stime, NOW,map_->getStarttime()); + map_->getDlSubframe()->getTimer()->resched (stime-NOW); + dl_timer_->resched (map_->getStarttime()+mac_->getFrameDuration()-NOW); + } + } +} + +/** + * Process a DCD message + * @param frame The dcd information + */ +void SSscheduler::process_dcd (mac802_16_dcd_frame *frame) +{ + if (mac_->getMacState()==MAC802_16_WAIT_DL_SYNCH) { + //we are waiting for DL_MAP,