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,