Compare commits
3017
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
370c7f7215 | ||
|
|
d0696fd776 | ||
|
|
a7f445f460 | ||
|
|
f5bb4c3302 | ||
|
|
d82bf3abd6 | ||
|
|
75cba72257 | ||
|
|
7c2c80af1b | ||
|
|
a4aeb6e815 | ||
|
|
f13ffe2ed2 | ||
|
|
7fb1cd3b38 | ||
|
|
0d8bed8b04 | ||
|
|
9f901c8ef1 | ||
|
|
9f2e63f535 | ||
|
|
ffe65494c4 | ||
|
|
b0f7bbf060 | ||
|
|
cb9b816af0 | ||
|
|
c8929f34e6 | ||
|
|
311955363b | ||
|
|
72d3e7353a | ||
|
|
6f10c6c828 | ||
|
|
e5870d73cb | ||
|
|
808a874b45 | ||
|
|
cd64cbad48 | ||
|
|
69aa96cfe8 | ||
|
|
18f4a0f940 | ||
|
|
9b48ec2c9c | ||
|
|
d654a7c67a | ||
|
|
6f2fba35ab | ||
|
|
356b8a4d5c | ||
|
|
f75a46a16c | ||
|
|
b62d2131d5 | ||
|
|
b024a19fe1 | ||
|
|
17adb4fab8 | ||
|
|
320dcbbfee | ||
|
|
8bb361bcba | ||
|
|
986a63bbb4 | ||
|
|
e1f187d38a | ||
|
|
8b080ef574 | ||
|
|
ae217b0eaa | ||
|
|
61947e25a7 | ||
|
|
1b605147ce | ||
|
|
48ac0501a0 | ||
|
|
d8dc981267 | ||
|
|
e84289cff4 | ||
|
|
2284d3d545 | ||
|
|
dcce81147d | ||
|
|
fd149a38f3 | ||
|
|
80ba473c52 | ||
|
|
9e629d895f | ||
|
|
fb24a25673 | ||
|
|
618313f44c | ||
|
|
d8ec3bb638 | ||
|
|
f4ea04de0b | ||
|
|
a618b8efaa | ||
|
|
55279b18b4 | ||
|
|
b9a4eaca8e | ||
|
|
f77da8c755 | ||
|
|
e4bd4773e8 | ||
|
|
453dd8a294 | ||
|
|
6e375eee8e | ||
|
|
d2dd9c358f | ||
|
|
f759d0c1d2 | ||
|
|
b641c0d9b2 | ||
|
|
ca8ec27fdc | ||
|
|
4b5aa5ccca | ||
|
|
2c7865d6f2 | ||
|
|
a8dca1e3d3 | ||
|
|
18b6ad7263 | ||
|
|
fd7fc3f80e | ||
|
|
c0dcf4a2cd | ||
|
|
bf1e64236f | ||
|
|
9d1d6b890e | ||
|
|
d801092405 | ||
|
|
aafd298bde | ||
|
|
720a407b59 | ||
|
|
b3525f35af | ||
|
|
ea0a5cf285 | ||
|
|
51d62156f5 | ||
|
|
d24895bdd1 | ||
|
|
0dc8bc3e86 | ||
|
|
f423b864b0 | ||
|
|
9c48b2460c | ||
|
|
21dcddef88 | ||
|
|
cd39d96f2b | ||
|
|
c063465ce6 | ||
|
|
1a78f415ce | ||
|
|
76147944c3 | ||
|
|
7d81d3a381 | ||
|
|
d7fb97eac0 | ||
|
|
4cfeba2bf7 | ||
|
|
39daae1374 | ||
|
|
79f85cdf94 | ||
|
|
65206529fb | ||
|
|
2ef4eeb41a | ||
|
|
5788fe5e8f | ||
|
|
77b1692293 | ||
|
|
c5710262c4 | ||
|
|
c7406f3722 | ||
|
|
3f1514a867 | ||
|
|
9b5145b5a0 | ||
|
|
8f7b450103 | ||
|
|
5fd19292ea | ||
|
|
87dc4f304d | ||
|
|
67313dc308 | ||
|
|
732bc9d257 | ||
|
|
1ace78069a | ||
|
|
0adbfb8047 | ||
|
|
7570be25c5 | ||
|
|
e8cc479c4f | ||
|
|
3878eac508 | ||
|
|
05b8fed716 | ||
|
|
d6dd23547b | ||
|
|
235ac2801f | ||
|
|
4591673b99 | ||
|
|
11c4bec9e8 | ||
|
|
64e7d5cd17 | ||
|
|
168361462f | ||
|
|
90c70d1a39 | ||
|
|
b88b399635 | ||
|
|
caa878e725 | ||
|
|
15766219de | ||
|
|
a54f875690 | ||
|
|
08833cb918 | ||
|
|
c466a1d098 | ||
|
|
3ba8dce954 | ||
|
|
c0ee4eb2a0 | ||
|
|
8027faacca | ||
|
|
dab7ef6871 | ||
|
|
bf3ad68c92 | ||
|
|
8cdde7b8f2 | ||
|
|
cb5d18a929 | ||
|
|
0500b5353e | ||
|
|
3ba086cef6 | ||
|
|
bd37d93222 | ||
|
|
f5f3b3f057 | ||
|
|
5f63fe35ba | ||
|
|
cfdb301bee | ||
|
|
21b5431c24 | ||
|
|
abd6647112 | ||
|
|
cd95f66344 | ||
|
|
fd774c3fb6 | ||
|
|
097f338632 | ||
|
|
433c4e2eea | ||
|
|
7c7b4e12fb | ||
|
|
f051f8fb19 | ||
|
|
0717db6ed0 | ||
|
|
a128c2f70a | ||
|
|
0335beed14 | ||
|
|
c71981e5a2 | ||
|
|
35c5966c45 | ||
|
|
471112db7e | ||
|
|
a55316e4f7 | ||
|
|
4ad7f52f7c | ||
|
|
2231b56ebe | ||
|
|
d0ff359d01 | ||
|
|
66c9294134 | ||
|
|
f9cb0f5a7e | ||
|
|
524435da19 | ||
|
|
728f6ad65d | ||
|
|
b591ee4053 | ||
|
|
222c989f79 | ||
|
|
68f0b97baa | ||
|
|
404cdb6f49 | ||
|
|
f6044dc0b4 | ||
|
|
39f080feba | ||
|
|
3ca49e8f39 | ||
|
|
1327e45a41 | ||
|
|
bfd084bde7 | ||
|
|
29151f4ec2 | ||
|
|
161adc2a4e | ||
|
|
bf060fddf8 | ||
|
|
3883a5e095 | ||
|
|
1eecaa6abd | ||
|
|
2d872a846d | ||
|
|
2966ca33b9 | ||
|
|
162194c37f | ||
|
|
13bdfdf131 | ||
|
|
6116a532db | ||
|
|
6c7bdf5845 | ||
|
|
b6a0e35db1 | ||
|
|
3a519a71da | ||
|
|
7a711ae53e | ||
|
|
1e654fa962 | ||
|
|
27df0a5c92 | ||
|
|
af0efdeab3 | ||
|
|
4ba6e58745 | ||
|
|
172db792a8 | ||
|
|
51d31554c4 | ||
|
|
660c536a49 | ||
|
|
317878411a | ||
|
|
3af1dc7235 | ||
|
|
caaae1c1dd | ||
|
|
1f86e826e5 | ||
|
|
5857618635 | ||
|
|
89cb48c524 | ||
|
|
36f196a9a0 | ||
|
|
8d844b7502 | ||
|
|
b157853a0c | ||
|
|
91f0ef0320 | ||
|
|
c95c773d17 | ||
|
|
5e24aed9dd | ||
|
|
fbf681955e | ||
|
|
565483bc09 | ||
|
|
2aceead32f | ||
|
|
ca2fef3bd8 | ||
|
|
732b7994de | ||
|
|
f573eaa47a | ||
|
|
c51f635cfb | ||
|
|
dbb7f0f738 | ||
|
|
0ad768c938 | ||
|
|
5a71f60c7a | ||
|
|
b9722796d7 | ||
|
|
c415957dfc | ||
|
|
f890b8e138 | ||
|
|
fd2cf07d30 | ||
|
|
d711e853d0 | ||
|
|
44c48d41e3 | ||
|
|
9c8ee223b3 | ||
|
|
a303c4bfad | ||
|
|
ae074d9e03 | ||
|
|
0632b05ed9 | ||
|
|
06a4d72721 | ||
|
|
b1af5815b0 | ||
|
|
d369fc0c61 | ||
|
|
e567e5fec5 | ||
|
|
4144eccd4f | ||
|
|
f7fc598240 | ||
|
|
4914c4afcb | ||
|
|
8cc54510ba | ||
|
|
a8d461f29e | ||
|
|
c33568c079 | ||
|
|
ccb5ec4d4d | ||
|
|
6b9023ebf4 | ||
|
|
ef5b621566 | ||
|
|
36a4bc8c40 | ||
|
|
db748a0000 | ||
|
|
2ca65219de | ||
|
|
65d4f0972c | ||
|
|
41fab0b441 | ||
|
|
cfa12b46c4 | ||
|
|
ff82231ef4 | ||
|
|
6afc4f8d7f | ||
|
|
f1e627aec7 | ||
|
|
69dc042ec7 | ||
|
|
d1a7261479 | ||
|
|
2aff99d749 | ||
|
|
10ee9b9e01 | ||
|
|
1132bcbd99 | ||
|
|
90e5f8cf0e | ||
|
|
7fb6a81b59 | ||
|
|
8356645d0a | ||
|
|
9b8db57a00 | ||
|
|
9d5d168444 | ||
|
|
7dce1174ba | ||
|
|
6911a69356 | ||
|
|
14beae6e8d | ||
|
|
731a76246f | ||
|
|
7f07acc254 | ||
|
|
7b34f76ef7 | ||
|
|
fb17731cab | ||
|
|
c3a8ec5555 | ||
|
|
be9e5ced39 | ||
|
|
ee19e57741 | ||
|
|
1f1ffe7372 | ||
|
|
5f9b651ba8 | ||
|
|
a6ccafbed7 | ||
|
|
fd2cdaf7ac | ||
|
|
3ff7e83dd0 | ||
|
|
0f045371a3 | ||
|
|
3d6e4532ae | ||
|
|
5f994081d5 | ||
|
|
178567b32b | ||
|
|
11ddb61d96 | ||
|
|
24693d3bbd | ||
|
|
5a35637ab9 | ||
|
|
b07781eead | ||
|
|
7f8fcbc547 | ||
|
|
c1f8cff710 | ||
|
|
864923164b | ||
|
|
8e0738b5ba | ||
|
|
8b1b7b25a2 | ||
|
|
dfc7509dd6 | ||
|
|
3c16c7d6d0 | ||
|
|
d236aad5e5 | ||
|
|
eb3d502a49 | ||
|
|
fe73953148 | ||
|
|
c5ec154ea1 | ||
|
|
cb491541ac | ||
|
|
bcae4f9ea1 | ||
|
|
95be482f24 | ||
|
|
ab714db3a9 | ||
|
|
1c8622e4f8 | ||
|
|
a97acf9ac0 | ||
|
|
df677111d4 | ||
|
|
f3d8a5eb6d | ||
|
|
d00d6e123c | ||
|
|
f8a561c16a | ||
|
|
8a0bcd18ba | ||
|
|
629a5b02da | ||
|
|
45334ff8de | ||
|
|
d8a6c6f336 | ||
|
|
26b91a3c6c | ||
|
|
b2b5de9d22 | ||
|
|
12c6c43d57 | ||
|
|
0f27dc1b81 | ||
|
|
74e8ce7845 | ||
|
|
cf37954b04 | ||
|
|
7c7cfcc865 | ||
|
|
ab3a728ba5 | ||
|
|
f7c6438560 | ||
|
|
94ee9fd47e | ||
|
|
925136697a | ||
|
|
2d76aafcfb | ||
|
|
056c8a7855 | ||
|
|
ff8c38b5ac | ||
|
|
7e12d28439 | ||
|
|
572ee9e3c9 | ||
|
|
7f91bd111e | ||
|
|
b93a9aeef4 | ||
|
|
67c5dfa611 | ||
|
|
75fab6d1b0 | ||
|
|
fbc3554c2c | ||
|
|
5b9d211ab9 | ||
|
|
a52bde7d46 | ||
|
|
46dced7f48 | ||
|
|
4196578e98 | ||
|
|
89f5373c27 | ||
|
|
b271ea5c87 | ||
|
|
31417e808d | ||
|
|
d714797804 | ||
|
|
bf513e45d2 | ||
|
|
8a6ed9603e | ||
|
|
03975f8102 | ||
|
|
26972f3917 | ||
|
|
1d5803e8f3 | ||
|
|
24e907d036 | ||
|
|
2f840a4f54 | ||
|
|
df2984b28c | ||
|
|
ee9129e71e | ||
|
|
bdb123bbc4 | ||
|
|
c094200ef6 | ||
|
|
28117fd049 | ||
|
|
73e368454d | ||
|
|
45f203f09f | ||
|
|
133bf0b651 | ||
|
|
d5423b88a2 | ||
|
|
898ce6b375 | ||
|
|
20865bfde0 | ||
|
|
9bb182aa54 | ||
|
|
9f205e0fba | ||
|
|
f201618a5f | ||
|
|
eb848bb719 | ||
|
|
5cf2aa1ebf | ||
|
|
f58dda2fcb | ||
|
|
246b544cb3 | ||
|
|
500b5c1fd4 | ||
|
|
31fc532913 | ||
|
|
8869dc9630 | ||
|
|
62c2e46c37 | ||
|
|
89e20b56c9 | ||
|
|
2b1bc24321 | ||
|
|
cb19bb1404 | ||
|
|
92c9208ea6 | ||
|
|
8c7759dc6b | ||
|
|
b9aeaf3650 | ||
|
|
87c68d5a58 | ||
|
|
77d2f50c2f | ||
|
|
ddef596d2f | ||
|
|
fcf9b4cf5b | ||
|
|
bdf0896c2a | ||
|
|
3aa9ce9efd | ||
|
|
73f7efb2f2 | ||
|
|
e10db3d576 | ||
|
|
daaed2d5e6 | ||
|
|
f1019e4026 | ||
|
|
398ffd3d58 | ||
|
|
ae661f53e0 | ||
|
|
4b3b79be2f | ||
|
|
2fb03d7aa3 | ||
|
|
14c3cac1d1 | ||
|
|
c4ea047cb9 | ||
|
|
6746cc48eb | ||
|
|
1fe76d94f1 | ||
|
|
6d739bf2b5 | ||
|
|
c3fb9059ac | ||
|
|
0c35c2b60f | ||
|
|
9008e089ae | ||
|
|
ad46f21982 | ||
|
|
8a78bf66ae | ||
|
|
da514b5edb | ||
|
|
4743c2ff7c | ||
|
|
7c05c10381 | ||
|
|
544f9d1a81 | ||
|
|
c7e37d1a18 | ||
|
|
b357866655 | ||
|
|
aefd3e3371 | ||
|
|
4587183489 | ||
|
|
6f2e42050f | ||
|
|
a86ec45ec9 | ||
|
|
d99df782e9 | ||
|
|
e1d52991b6 | ||
|
|
2d2675e6f8 | ||
|
|
d4a0ae2a74 | ||
|
|
b5cfed2178 | ||
|
|
a6aed94fe8 | ||
|
|
9da2bfa832 | ||
|
|
098186e7e6 | ||
|
|
452bb57c9f | ||
|
|
1b8812d558 | ||
|
|
4a73b2abd0 | ||
|
|
c11554b553 | ||
|
|
da05aa1327 | ||
|
|
2edda56a6f | ||
|
|
9ed0f04944 | ||
|
|
1aef4543cc | ||
|
|
9ccd6dadcb | ||
|
|
8ae203ce50 | ||
|
|
1e4c17bc9f | ||
|
|
cbc938e2bf | ||
|
|
cdb5cc083f | ||
|
|
de189d447c | ||
|
|
aebdb9fbfd | ||
|
|
82e92545aa | ||
|
|
8559d575f5 | ||
|
|
5a3fbf3637 | ||
|
|
9ca1253956 | ||
|
|
de69fcb842 | ||
|
|
88d12f80eb | ||
|
|
a37b419abd | ||
|
|
6c4692ea55 | ||
|
|
97d98fa1ce | ||
|
|
6bcd10f205 | ||
|
|
36ac76b49c | ||
|
|
d003d6a34f | ||
|
|
3b217b603e | ||
|
|
43263bc0e7 | ||
|
|
525969ca64 | ||
|
|
fb9ca8f381 | ||
|
|
1f9b7723b8 | ||
|
|
60c2ddafa8 | ||
|
|
64e2c2bb8f | ||
|
|
b469955b1e | ||
|
|
c3557faf08 | ||
|
|
4d144c5ec8 | ||
|
|
2b7b6628f3 | ||
|
|
de2475ddc3 | ||
|
|
4d2bbed418 | ||
|
|
7ef64dd6ce | ||
|
|
90bbabf52f | ||
|
|
c43918d4c2 | ||
|
|
14562c914d | ||
|
|
017b3b191d | ||
|
|
49a48f01e8 | ||
|
|
12ae07ddab | ||
|
|
d86a521ff1 | ||
|
|
3e3f102d62 | ||
|
|
45f9ff0ddc | ||
|
|
44478e378d | ||
|
|
1eb07aeaef | ||
|
|
10a7924d63 | ||
|
|
d3b35a295c | ||
|
|
1a5577bc3d | ||
|
|
92f2ed110a | ||
|
|
8b7d6955e6 | ||
|
|
1ae7ba74b9 | ||
|
|
94b7fd9434 | ||
|
|
1ca824b340 | ||
|
|
94587dd4f3 | ||
|
|
6495130641 | ||
|
|
d1cc848f30 | ||
|
|
39b7522f4c | ||
|
|
1840dfe6b1 | ||
|
|
5307dcfd48 | ||
|
|
9dfc592a26 | ||
|
|
be9d919a58 | ||
|
|
937f78e7bc | ||
|
|
d9a606c58d | ||
|
|
d3942cd4d0 | ||
|
|
6badc137d9 | ||
|
|
2eafd4b9b1 | ||
|
|
add091ea23 | ||
|
|
92ebbd036d | ||
|
|
f08ea71825 | ||
|
|
a5c312cb1c | ||
|
|
e20525cad9 | ||
|
|
00d36e836c | ||
|
|
312b8da3a3 | ||
|
|
05a27250c1 | ||
|
|
a7a0a3de70 | ||
|
|
26d46a960d | ||
|
|
2a323473e4 | ||
|
|
4904c44f15 | ||
|
|
e4ec46dd52 | ||
|
|
a947ff3967 | ||
|
|
bbf1d7cce3 | ||
|
|
dfb9b7360a | ||
|
|
554fcfda0d | ||
|
|
16d1d635a0 | ||
|
|
62d8743f1c | ||
|
|
5872949e0a | ||
|
|
f173b434dd | ||
|
|
48fa3d344c | ||
|
|
b9d448c83b | ||
|
|
6152ba1a89 | ||
|
|
08f2b87daa | ||
|
|
39c1412e3e | ||
|
|
41b7eadd33 | ||
|
|
b851cc5b0b | ||
|
|
08961f4883 | ||
|
|
c9ccce91ed | ||
|
|
76dd4d1db4 | ||
|
|
27e5640201 | ||
|
|
fdc3e27c11 | ||
|
|
709f6a6d5b | ||
|
|
45793c3a02 | ||
|
|
137ff47a46 | ||
|
|
ab01dd65a4 | ||
|
|
31870b3bc0 | ||
|
|
0c34dea05b | ||
|
|
b135ced7aa | ||
|
|
16018e8d7e | ||
|
|
0ef25b59c4 | ||
|
|
20b1d65d07 | ||
|
|
eaf4fb4a6d | ||
|
|
f86b2de0af | ||
|
|
4182edbc93 | ||
|
|
6af434b9f9 | ||
|
|
f79ac9e373 | ||
|
|
c352b35d3f | ||
|
|
b91e3b0e4c | ||
|
|
0d86d03be0 | ||
|
|
9a94ef7a2d | ||
|
|
791e9ae464 | ||
|
|
c2a543f568 | ||
|
|
b3390aaa3e | ||
|
|
3d0264e3a3 | ||
|
|
42fbffdbdb | ||
|
|
f83b6c7ab1 | ||
|
|
2f1e4574c0 | ||
|
|
de351e9388 | ||
|
|
20f5f62292 | ||
|
|
0008eeebce | ||
|
|
ca7b76ef27 | ||
|
|
a41edb2fa1 | ||
|
|
ffd1766adc | ||
|
|
f9e025ad81 | ||
|
|
b62c394703 | ||
|
|
4ba092f3aa | ||
|
|
93126f3a55 | ||
|
|
62ff82d0ca | ||
|
|
e62a059f05 | ||
|
|
5f94a4cf59 | ||
|
|
888a3bdad6 | ||
|
|
72dba0d456 | ||
|
|
3bd417f4e5 | ||
|
|
72d054a867 | ||
|
|
e9e87c3232 | ||
|
|
ef99300eff | ||
|
|
49d5404bfc | ||
|
|
c21d79a87b | ||
|
|
8dc2460416 | ||
|
|
e6bd2a7a6a | ||
|
|
3a34c3fff1 | ||
|
|
ad374c8d87 | ||
|
|
935532822b | ||
|
|
45d6dcd5f4 | ||
|
|
e4c1b22090 | ||
|
|
2a14b1c408 | ||
|
|
5b119aa40d | ||
|
|
25de2ff3c4 | ||
|
|
4c4ef85a93 | ||
|
|
67d54a7f8a | ||
|
|
0a476b4f04 | ||
|
|
2c57f536e3 | ||
|
|
a1882f8e10 | ||
|
|
7c509777e5 | ||
|
|
d5a75f0cec | ||
|
|
91c4ef481f | ||
|
|
d034ec3e08 | ||
|
|
dd4979ef89 | ||
|
|
84c9dd96db | ||
|
|
18011ba4eb | ||
|
|
aa7b91f890 | ||
|
|
0e05b107fd | ||
|
|
05c3383610 | ||
|
|
43c64f656b | ||
|
|
2b4b265b60 | ||
|
|
0efe19fe76 | ||
|
|
1a990a1877 | ||
|
|
6547b9222c | ||
|
|
a4a8086580 | ||
|
|
8d3dfb1df9 | ||
|
|
3226ce7f09 | ||
|
|
1b12b95ee9 | ||
|
|
ffdff79112 | ||
|
|
4b7bfc9b77 | ||
|
|
ccb704ffc7 | ||
|
|
ce87f97994 | ||
|
|
8a7187fba3 | ||
|
|
3a8df9f3d6 | ||
|
|
31a31ffc07 | ||
|
|
63dccc1973 | ||
|
|
36e6b69aaf | ||
|
|
dc624d46b3 | ||
|
|
1cecfe5548 | ||
|
|
a54122b4e8 | ||
|
|
693099a950 | ||
|
|
ae1fed72b1 | ||
|
|
b5e22fdc37 | ||
|
|
47e58be578 | ||
|
|
833506428b | ||
|
|
ca3c48f8e8 | ||
|
|
b00892cae7 | ||
|
|
2e116e5f74 | ||
|
|
9eb007fd26 | ||
|
|
6be343530f | ||
|
|
9ee8930726 | ||
|
|
0add09088e | ||
|
|
006ac07f97 | ||
|
|
5d5fd895f1 | ||
|
|
a042d0bbef | ||
|
|
3ebec1046c | ||
|
|
4340da4ca6 | ||
|
|
6ec88588f1 | ||
|
|
32bc3d3664 | ||
|
|
ee62b6d04e | ||
|
|
fc73accacd | ||
|
|
9da8e1bb03 | ||
|
|
515183caae | ||
|
|
0f55fefaba | ||
|
|
ddda864b77 | ||
|
|
5a16ff1df4 | ||
|
|
53841f6170 | ||
|
|
3c8bfe6ae6 | ||
|
|
2e699a4704 | ||
|
|
7089f682d6 | ||
|
|
371ed54dc9 | ||
|
|
0b6e955a24 | ||
|
|
f5bb823415 | ||
|
|
83cd996471 | ||
|
|
418a3fae42 | ||
|
|
66229167d2 | ||
|
|
164e8c83bc | ||
|
|
2865203612 | ||
|
|
f2a37c6ca4 | ||
|
|
6236cbf9a3 | ||
|
|
58ab30c53c | ||
|
|
beaf8569c0 | ||
|
|
9679a25783 | ||
|
|
aaccadb46a | ||
|
|
4c424da911 | ||
|
|
623d9898b7 | ||
|
|
1c05220bba | ||
|
|
ccd72825dd | ||
|
|
29169d42b6 | ||
|
|
43ecf40b5a | ||
|
|
119cf2035b | ||
|
|
73aec9c9b1 | ||
|
|
04c8831510 | ||
|
|
fbabf8129a | ||
|
|
08511f30c5 | ||
|
|
daddd90d07 | ||
|
|
bfe0533aa3 | ||
|
|
f8a2add627 | ||
|
|
af58cc3026 | ||
|
|
c6f7bb2d3e | ||
|
|
075851985f | ||
|
|
e4eeeb18f5 | ||
|
|
b61d0ff5f2 | ||
|
|
288d193daa | ||
|
|
0996a38b84 | ||
|
|
18ee064a79 | ||
|
|
96c43a7e26 | ||
|
|
5c7b34db46 | ||
|
|
d3623e2142 | ||
|
|
062a2dcc42 | ||
|
|
2d581766fd | ||
|
|
d7a038431f | ||
|
|
e17282f995 | ||
|
|
78829ba702 | ||
|
|
4a78ce68d1 | ||
|
|
ad54b2ce62 | ||
|
|
f79e7581b6 | ||
|
|
aeffbb31d7 | ||
|
|
b998a05cce | ||
|
|
3752943c22 | ||
|
|
9fd7fbb86c | ||
|
|
829a6dd8bb | ||
|
|
1f0dd55d8d | ||
|
|
28bf2500e9 | ||
|
|
63d6b14d45 | ||
|
|
815f3721b7 | ||
|
|
0dab5235c9 | ||
|
|
eb9fa68703 | ||
|
|
7be1b92968 | ||
|
|
d1ddd3c89b | ||
|
|
9b153c313b | ||
|
|
ea6e067812 | ||
|
|
6a93edb24e | ||
|
|
a6321aac60 | ||
|
|
450b10b597 | ||
|
|
f91e2ff5a4 | ||
|
|
35170aed54 | ||
|
|
2c1b7db441 | ||
|
|
a557f1c064 | ||
|
|
f2b7b1795b | ||
|
|
3b711f9852 | ||
|
|
a890500150 | ||
|
|
7468230ede | ||
|
|
6a3326e529 | ||
|
|
4ff40c4a07 | ||
|
|
254057bd80 | ||
|
|
f5f32e0ea3 | ||
|
|
39ef17d6a4 | ||
|
|
505de0c685 | ||
|
|
bb10734d66 | ||
|
|
edb480ad29 | ||
|
|
f4cff0e194 | ||
|
|
78a2df8963 | ||
|
|
f8ec434cdb | ||
|
|
1649c1dc65 | ||
|
|
5c5ab1f1f0 | ||
|
|
53be11fe6f | ||
|
|
6fd8b6c572 | ||
|
|
61375f8ef5 | ||
|
|
8a32b1e369 | ||
|
|
22d1a6046d | ||
|
|
db81db32a8 | ||
|
|
c9d422bbb6 | ||
|
|
bd1ef984cc | ||
|
|
6d53b47cae | ||
|
|
09f00c5b34 | ||
|
|
fbe5e3949f | ||
|
|
43dbc0b4d1 | ||
|
|
5e9344d2d4 | ||
|
|
2b0056553c | ||
|
|
6cf0d2e645 | ||
|
|
822e13a7df | ||
|
|
a62f9d7771 | ||
|
|
112b278854 | ||
|
|
14c60f7ad3 | ||
|
|
e855838ed1 | ||
|
|
8a4b416428 | ||
|
|
ca687b56f6 | ||
|
|
556d973168 | ||
|
|
42282f5512 | ||
|
|
0e65d73baa | ||
|
|
f7691237f5 | ||
|
|
ed0dcc982b | ||
|
|
a390b13f86 | ||
|
|
5d91e8c2d2 | ||
|
|
0789c9b435 | ||
|
|
03b4114b20 | ||
|
|
fda39900e3 | ||
|
|
9167a8b308 | ||
|
|
60c81de8b5 | ||
|
|
3211fbb0bf | ||
|
|
3327b9da92 | ||
|
|
72b496b9ef | ||
|
|
8bfd88b80b | ||
|
|
c456128c6d | ||
|
|
dd283f6ead | ||
|
|
271ea4bc75 | ||
|
|
e7c2292d7b | ||
|
|
c883517a1d | ||
|
|
696859e936 | ||
|
|
267a3ca69d | ||
|
|
27c1fab7fc | ||
|
|
be27a1c03d | ||
|
|
ba319c457d | ||
|
|
4a556dbf91 | ||
|
|
923b1180f9 | ||
|
|
f6ba778fc9 | ||
|
|
cff773b8d2 | ||
|
|
776a594c3c | ||
|
|
a75e91cc03 | ||
|
|
dc271270a8 | ||
|
|
cc927f907f | ||
|
|
53fb65aea7 | ||
|
|
560a34ba97 | ||
|
|
e0570ec0b0 | ||
|
|
e110fea8ff | ||
|
|
d4cd3c92fd | ||
|
|
b807dfa090 | ||
|
|
5a16b2cad8 | ||
|
|
9ea56ac66a | ||
|
|
478e810ad5 | ||
|
|
bf90dded3c | ||
|
|
c22d5c5733 | ||
|
|
bb5f9f1a50 | ||
|
|
3f1c2d2653 | ||
|
|
f6dcb76287 | ||
|
|
6740fc4627 | ||
|
|
edc7af8a02 | ||
|
|
80c8937a01 | ||
|
|
4400054ebe | ||
|
|
3a43bd4987 | ||
|
|
c140066890 | ||
|
|
c3f0505ddc | ||
|
|
8501ca807c | ||
|
|
75643a53ef | ||
|
|
b6471a7749 | ||
|
|
0c393e38c4 | ||
|
|
05019b6214 | ||
|
|
737bc7cd00 | ||
|
|
31d26c1e84 | ||
|
|
ec7c5d2dd6 | ||
|
|
b34fbc477b | ||
|
|
a8acd5c5f0 | ||
|
|
621f07f0d2 | ||
|
|
11468a4235 | ||
|
|
441b674f96 | ||
|
|
2c273b86cd | ||
|
|
d4347bc1b5 | ||
|
|
5a8c75187d | ||
|
|
36049254af | ||
|
|
18dd6edda3 | ||
|
|
c802635595 | ||
|
|
56b59c5905 | ||
|
|
6490c81cf8 | ||
|
|
ec3d666f3b | ||
|
|
8dc44fbfaf | ||
|
|
5a8d264371 | ||
|
|
3faceb9149 | ||
|
|
aad4e224e5 | ||
|
|
5bd019aba0 | ||
|
|
9fe0c49344 | ||
|
|
bcc362cd11 | ||
|
|
34c057c351 | ||
|
|
9c1922aebe | ||
|
|
058f508927 | ||
|
|
24863d5368 | ||
|
|
e103bc0ded | ||
|
|
766efc6d0e | ||
|
|
e4fa093d5f | ||
|
|
cb1e1d0023 | ||
|
|
dc96b531b1 | ||
|
|
a4a18943f7 | ||
|
|
a87eed74c2 | ||
|
|
5a614715ea | ||
|
|
27d2380327 | ||
|
|
d1d683ee21 | ||
|
|
812fc3be75 | ||
|
|
ae4529b819 | ||
|
|
2c1c5afe91 | ||
|
|
b41554c18f | ||
|
|
40349f92d8 | ||
|
|
6935a997e6 | ||
|
|
41f6573c8d | ||
|
|
2b44913a70 | ||
|
|
64f72686aa | ||
|
|
d06c2b4fae | ||
|
|
889e333a35 | ||
|
|
379c3d5390 | ||
|
|
02273c7da7 | ||
|
|
2bb663d011 | ||
|
|
0dfe8fa5df | ||
|
|
e173bb868d | ||
|
|
c5ffe4c9dc | ||
|
|
a053ff6896 | ||
|
|
537e375fe1 | ||
|
|
879b2cb91d | ||
|
|
c0d60678d9 | ||
|
|
521c43eb23 | ||
|
|
627813fe6c | ||
|
|
16f7931992 | ||
|
|
76847a02ca | ||
|
|
935a7896e1 | ||
|
|
7f6f6ba6a7 | ||
|
|
8977a827b2 | ||
|
|
11608c6b16 | ||
|
|
6ac2042e55 | ||
|
|
4ff7264001 | ||
|
|
9bcf1cdac5 | ||
|
|
f2769ba5a5 | ||
|
|
db02706e4c | ||
|
|
78bfd610d9 | ||
|
|
20726f8201 | ||
|
|
4fc3138b1e | ||
|
|
b6932288ae | ||
|
|
6397957980 | ||
|
|
8810ebfe02 | ||
|
|
7771ab6562 | ||
|
|
27615d70d1 | ||
|
|
1a443df051 | ||
|
|
ff4dfc3009 | ||
|
|
a349c602db | ||
|
|
62308cf1ce | ||
|
|
511e11e9be | ||
|
|
6de12cc9d2 | ||
|
|
9ad6948605 | ||
|
|
7e17f8d7e1 | ||
|
|
67c8f12b67 | ||
|
|
e0346ac124 | ||
|
|
46cc3fab6d | ||
|
|
02dc54f597 | ||
|
|
a7677d77de | ||
|
|
e963c05aeb | ||
|
|
cb475c1750 | ||
|
|
4202275d10 | ||
|
|
e9c67a3ada | ||
|
|
ba70c90271 | ||
|
|
8d084573dc | ||
|
|
9644e5ee88 | ||
|
|
74541b0d23 | ||
|
|
fa2983e8a4 | ||
|
|
a280c30a20 | ||
|
|
a85420cd34 | ||
|
|
982fe8454b | ||
|
|
b5cfd48e9a | ||
|
|
b7f945f750 | ||
|
|
942f3404a3 | ||
|
|
fd49891782 | ||
|
|
6191bda098 | ||
|
|
ac7ef5158d | ||
|
|
c61932afc5 | ||
|
|
473ea28f10 | ||
|
|
2158f87125 | ||
|
|
b4aaac11c6 | ||
|
|
1d78ea62e8 | ||
|
|
37f1478f00 | ||
|
|
2fe2751c9e | ||
|
|
80e0d082b4 | ||
|
|
011e2bbb70 | ||
|
|
26fba17dc2 | ||
|
|
4e2a41ae85 | ||
|
|
cb3bcff3a6 | ||
|
|
72f7ffdb6d | ||
|
|
050af31b95 | ||
|
|
89d089c506 | ||
|
|
3d0e59cd05 | ||
|
|
83dea96517 | ||
|
|
e1d6ca18e1 | ||
|
|
7020d1611e | ||
|
|
0a3da46adc | ||
|
|
ed271f5954 | ||
|
|
a3628b44c1 | ||
|
|
23edc105e2 | ||
|
|
44afb107ba | ||
|
|
5fe039c6a6 | ||
|
|
cabb264eef | ||
|
|
ab8a395c49 | ||
|
|
da1d232338 | ||
|
|
08eb0aef35 | ||
|
|
d869416a92 | ||
|
|
77bf878ea8 | ||
|
|
4966231237 | ||
|
|
1724e3ceec | ||
|
|
58dd143df7 | ||
|
|
a6979a7bb9 | ||
|
|
7b8b8e8de3 | ||
|
|
7f56378951 | ||
|
|
b21f71e568 | ||
|
|
8872354a55 | ||
|
|
69dfbe8707 | ||
|
|
5117b61f63 | ||
|
|
bb59c6a9fb | ||
|
|
c6868e0961 | ||
|
|
ff02feb0b7 | ||
|
|
991e83fe2c | ||
|
|
0a9ad0c47c | ||
|
|
dafc9f88ae | ||
|
|
9b4661c799 | ||
|
|
69ddf50d98 | ||
|
|
386b5fe6eb | ||
|
|
25374b7325 | ||
|
|
da3541e88d | ||
|
|
3bf71817cf | ||
|
|
8acd8baa33 | ||
|
|
7c1cda0ccb | ||
|
|
a12b08bd3a | ||
|
|
341ef1908c | ||
|
|
18bfce3a97 | ||
|
|
35729f1717 | ||
|
|
f44690e9af | ||
|
|
14690d8553 | ||
|
|
44d0c56680 | ||
|
|
3a19364b1b | ||
|
|
9ad409452b | ||
|
|
47775d87da | ||
|
|
41bbee50af | ||
|
|
80fec1898e | ||
|
|
0ccf783437 | ||
|
|
35d9ec1c8e | ||
|
|
4e5eab77e2 | ||
|
|
29f19e164e | ||
|
|
e1c0003987 | ||
|
|
4404c371af | ||
|
|
83ac55585c | ||
|
|
e9a8648ae9 | ||
|
|
f17df2c2dc | ||
|
|
18c92e855d | ||
|
|
048ffbe7d3 | ||
|
|
e5818f9865 | ||
|
|
09b0afe3d5 | ||
|
|
4f3921d1bf | ||
|
|
48a799a6ac | ||
|
|
08ce187c6b | ||
|
|
d3fb648979 | ||
|
|
2759411565 | ||
|
|
fa8f4bf528 | ||
|
|
eeaea6f03b | ||
|
|
8125fab8c3 | ||
|
|
7fe3f102ff | ||
|
|
53b38a05ea | ||
|
|
8aada40095 | ||
|
|
621b84064a | ||
|
|
91cf6bfccd | ||
|
|
c9785a0ef0 | ||
|
|
73ea5d6192 | ||
|
|
752658119f | ||
|
|
53b3d2bb1f | ||
|
|
e22584cd79 | ||
|
|
05b6cf11a8 | ||
|
|
960bc0d1ba | ||
|
|
745520c03d | ||
|
|
de80ab4910 | ||
|
|
c995c98e85 | ||
|
|
fc3824059b | ||
|
|
ef44869539 | ||
|
|
4ef540a4e6 | ||
|
|
56299308b6 | ||
|
|
f7aa0eb745 | ||
|
|
881590b6d7 | ||
|
|
c78d5b071a | ||
|
|
6974ce4f24 | ||
|
|
627a2048f1 | ||
|
|
5cd592fe06 | ||
|
|
295c1cd3d5 | ||
|
|
931e5140e2 | ||
|
|
574ed67011 | ||
|
|
5b42ef5b02 | ||
|
|
c6aa4c8fb4 | ||
|
|
6534020b54 | ||
|
|
a3ed490b7f | ||
|
|
10bbdc4176 | ||
|
|
26f046edd5 | ||
|
|
cabfd83031 | ||
|
|
1518a1dbd1 | ||
|
|
e5b7c28375 | ||
|
|
2f666d9622 | ||
|
|
30525bef9a | ||
|
|
e14aaceabe | ||
|
|
c8f4d234ea | ||
|
|
8dc5510518 | ||
|
|
6b9fc231e1 | ||
|
|
a0a7c6d88c | ||
|
|
f6438556ef | ||
|
|
5d4ecfc62c | ||
|
|
de502593ef | ||
|
|
b5bfc150e3 | ||
|
|
bcf92901ac | ||
|
|
c7be59d0c1 | ||
|
|
218c66592a | ||
|
|
96e4874bdb | ||
|
|
0ef1e6b866 | ||
|
|
0bfc594407 | ||
|
|
fd014845f7 | ||
|
|
660e414f36 | ||
|
|
1806cbede9 | ||
|
|
3aa9706150 | ||
|
|
939cee7ac3 | ||
|
|
0f79c7d754 | ||
|
|
6a96f3f3ea | ||
|
|
ef0a14d093 | ||
|
|
b66b302a6a | ||
|
|
b685071f5a | ||
|
|
2ea43c9729 | ||
|
|
eb89e875f7 | ||
|
|
7ecce753a6 | ||
|
|
8ab25173a1 | ||
|
|
ac16151d22 | ||
|
|
b68fa9919b | ||
|
|
516eb971a3 | ||
|
|
22a66ef917 | ||
|
|
9cf6137916 | ||
|
|
36995793fb | ||
|
|
0ddbe50a61 | ||
|
|
0d839a85c0 | ||
|
|
be10286ae5 | ||
|
|
4163debdfb | ||
|
|
c4b1bff412 | ||
|
|
848cb7cfb5 | ||
|
|
6df47b4d19 | ||
|
|
c09319cab9 | ||
|
|
175518d248 | ||
|
|
14ccd72505 | ||
|
|
fb452286e6 | ||
|
|
aa3db11715 | ||
|
|
250eed3667 | ||
|
|
5a7be54e31 | ||
|
|
4227fc706d | ||
|
|
3e4aa96665 | ||
|
|
b97dfc9450 | ||
|
|
3c32879211 | ||
|
|
5d2044ae93 | ||
|
|
b5a8d46096 | ||
|
|
7a1c14372c | ||
|
|
9cac5c71ee | ||
|
|
ef8ee7e7ef | ||
|
|
ae62a57f4e | ||
|
|
e3fe5ec788 | ||
|
|
bd1c208097 | ||
|
|
56c82ac742 | ||
|
|
321b953877 | ||
|
|
603615d2d0 | ||
|
|
a4c5f55812 | ||
|
|
517c5e5bfd | ||
|
|
514685e9a6 | ||
|
|
9b1a38aa42 | ||
|
|
9af9500a0c | ||
|
|
eb4fb0cb5d | ||
|
|
415eb2496a | ||
|
|
bb5e793580 | ||
|
|
fcc2066d01 | ||
|
|
ad625de65a | ||
|
|
6f26975964 | ||
|
|
9a8cbe189f | ||
|
|
782dd6d45b | ||
|
|
5ed6f37ad9 | ||
|
|
fceeaca439 | ||
|
|
f46a1041b8 | ||
|
|
90a26d4d51 | ||
|
|
90a367e2e1 | ||
|
|
5273535527 | ||
|
|
c777a6802f | ||
|
|
267b3e487b | ||
|
|
4ca05b7aad | ||
|
|
b1d7592e34 | ||
|
|
b6d8a11148 | ||
|
|
8ca8824655 | ||
|
|
59df24f63f | ||
|
|
81b8f0f159 | ||
|
|
e4a7b6e868 | ||
|
|
773b4d80a5 | ||
|
|
b14aab2fe4 | ||
|
|
a02c29d25b | ||
|
|
ec5c7742d9 | ||
|
|
6916fd5c3b | ||
|
|
06e1a61fab | ||
|
|
93f5de21b1 | ||
|
|
8350d5d0af | ||
|
|
0fa7cbe6a3 | ||
|
|
45d5f42ca3 | ||
|
|
f15c11d440 | ||
|
|
20d6fdf375 | ||
|
|
c3d5b77c96 | ||
|
|
9b37416720 | ||
|
|
163c32fc28 | ||
|
|
a786828ddf | ||
|
|
23bfe3fe09 | ||
|
|
732c7f1d0b | ||
|
|
ce83863f87 | ||
|
|
713c893939 | ||
|
|
7951713874 | ||
|
|
42c7a8c6ab | ||
|
|
99f4928d7c | ||
|
|
356b89e672 | ||
|
|
7b79b4cdef | ||
|
|
db4e999d61 | ||
|
|
346b857c6c | ||
|
|
936b124ff7 | ||
|
|
ed22af820c | ||
|
|
a5e8bdf451 | ||
|
|
8b2caa1a2a | ||
|
|
c43e0ecb14 | ||
|
|
4c40782b30 | ||
|
|
5c83be026b | ||
|
|
0a3b46fdf5 | ||
|
|
af58f11739 | ||
|
|
58d05259cb | ||
|
|
662bf63f87 | ||
|
|
947e86f4fa | ||
|
|
a0f5714f8a | ||
|
|
b7ab54776d | ||
|
|
4a1cb62fce | ||
|
|
bf1aad6a7d | ||
|
|
93ee85a925 | ||
|
|
69a95852ba | ||
|
|
8e4605294a | ||
|
|
289cf2170e | ||
|
|
8f6d84e669 | ||
|
|
21466b9afe | ||
|
|
de39c3b77a | ||
|
|
374362b25c | ||
|
|
7965ccd65c | ||
|
|
893a2d0859 | ||
|
|
fea84ff0f2 | ||
|
|
e06e3096cb | ||
|
|
0c586271e5 | ||
|
|
1d4187bd0f | ||
|
|
fe07d43e5d | ||
|
|
9e40bb3bfd | ||
|
|
4704c9d427 | ||
|
|
49087105ad | ||
|
|
dd0ae959fe | ||
|
|
8f8639aa7a | ||
|
|
e5e35f6545 | ||
|
|
1ae525bf0e | ||
|
|
fb2f498e54 | ||
|
|
cf2466f185 | ||
|
|
5ea4a79c06 | ||
|
|
ed32045dc6 | ||
|
|
1fe93d4e86 | ||
|
|
e933b3091d | ||
|
|
0a8fd09acf | ||
|
|
200a9c69ff | ||
|
|
bfc21a4e47 | ||
|
|
276147ac65 | ||
|
|
9094ef8b1b | ||
|
|
b4ca4f9cf3 | ||
|
|
a5c397f21b | ||
|
|
d5221dcfe4 | ||
|
|
847f7587ff | ||
|
|
061f5a8426 | ||
|
|
6a2d2601fc | ||
|
|
0d49574056 | ||
|
|
10d2a5b770 | ||
|
|
9b0290012f | ||
|
|
9db1cd07e3 | ||
|
|
5b36ba86ad | ||
|
|
f38dfb4e28 | ||
|
|
38d882d889 | ||
|
|
4e598bde94 | ||
|
|
702a31b06e | ||
|
|
b5664b575d | ||
|
|
0ffaf38602 | ||
|
|
2eae2f926c | ||
|
|
96b47442ea | ||
|
|
93ae3cea51 | ||
|
|
6895e23eca | ||
|
|
b744916fb8 | ||
|
|
0febad916b | ||
|
|
7b44a35460 | ||
|
|
5e08c5cb5b | ||
|
|
c4238a2fb7 | ||
|
|
2aa6ff8d7d | ||
|
|
6d05a9e061 | ||
|
|
f8ca997175 | ||
|
|
377f70de36 | ||
|
|
0dbeed4691 | ||
|
|
ca3a3794bf | ||
|
|
1bcb523456 | ||
|
|
68a81eed0b | ||
|
|
f9538ea708 | ||
|
|
03cc15ebdd | ||
|
|
37b0481304 | ||
|
|
c1d4c1d4c5 | ||
|
|
a7f4957c02 | ||
|
|
e039942a02 | ||
|
|
1706273d74 | ||
|
|
23d972d9dd | ||
|
|
3b50a66d0b | ||
|
|
969a41048d | ||
|
|
5fc7981de6 | ||
|
|
d041abd435 | ||
|
|
9a0f0f438f | ||
|
|
baca67f7a3 | ||
|
|
cb069a418f | ||
|
|
ae4e6226cf | ||
|
|
fda20b8236 | ||
|
|
c5dc486e2c | ||
|
|
144e84154b | ||
|
|
5de083e234 | ||
|
|
e4529f9217 | ||
|
|
b511f31d39 | ||
|
|
4d6e41a185 | ||
|
|
73740bdbc6 | ||
|
|
b30c9ee4b3 | ||
|
|
386b63ceb9 | ||
|
|
ebbea8ae40 | ||
|
|
ad7d70ae34 | ||
|
|
c182f4d479 | ||
|
|
6353d911c0 | ||
|
|
8c4ce99b89 | ||
|
|
6c34a2f48e | ||
|
|
f95a872d12 | ||
|
|
95c59da336 | ||
|
|
78a151d337 | ||
|
|
cccdb1f6d6 | ||
|
|
4dce1b28b8 | ||
|
|
8bac0c2ba3 | ||
|
|
c194579f5e | ||
|
|
2a3e635cd1 | ||
|
|
82c3fa3aaa | ||
|
|
2830225b2c | ||
|
|
cf9ed2855f | ||
|
|
b4edd36ec5 | ||
|
|
49d1a39d16 | ||
|
|
23a8d8bf1b | ||
|
|
1e70c7ac38 | ||
|
|
bf0d4e7154 | ||
|
|
e8fc6ec946 | ||
|
|
be2b52ac8f | ||
|
|
7bb06e0661 | ||
|
|
b56cad3cbc | ||
|
|
5bec43f720 | ||
|
|
25bb76ce20 | ||
|
|
e94efb4a11 | ||
|
|
de438d035b | ||
|
|
88c9b123ee | ||
|
|
2c234e63e7 | ||
|
|
bd94258500 | ||
|
|
ee5f2a5475 | ||
|
|
2806d0edbe | ||
|
|
c51821715f | ||
|
|
85cbeccd3e | ||
|
|
147510bb00 | ||
|
|
450ca7325d | ||
|
|
3f5fa2d889 | ||
|
|
2e4860e39e | ||
|
|
392c7581eb | ||
|
|
81f0d2464c | ||
|
|
58a93485de | ||
|
|
23c4395731 | ||
|
|
0a20822e64 | ||
|
|
cdc9002e41 | ||
|
|
f8ae534480 | ||
|
|
c6f3793178 | ||
|
|
96451fdb37 | ||
|
|
feb47b3bb1 | ||
|
|
4f02439cb1 | ||
|
|
b0e8f9ff56 | ||
|
|
74a7f5d065 | ||
|
|
8cc988f172 | ||
|
|
a14e1de6cc | ||
|
|
a30e3a7e94 | ||
|
|
450f9db5c6 | ||
|
|
eca7dc5b27 | ||
|
|
e51df22a48 | ||
|
|
fa3b613148 | ||
|
|
d4a6b3ab85 | ||
|
|
c295b15d7e | ||
|
|
cf48df0f49 | ||
|
|
16a94230d2 | ||
|
|
d226ebb036 | ||
|
|
2c658704eb | ||
|
|
ea1eacc952 | ||
|
|
161ff1c6b0 | ||
|
|
eec4df655d | ||
|
|
bd0ca7917a | ||
|
|
5af34cc0da | ||
|
|
69f491c008 | ||
|
|
1f848288d8 | ||
|
|
9cd8e34252 | ||
|
|
5137b37f86 | ||
|
|
16086b3349 | ||
|
|
153e0f6d48 | ||
|
|
f44a019aed | ||
|
|
f826fbc2d9 | ||
|
|
f03f1c237b | ||
|
|
b4c23f8ebf | ||
|
|
dd8985b92d | ||
|
|
bf9d59fe21 | ||
|
|
9fcd20505c | ||
|
|
a142d30a9d | ||
|
|
c3658bd810 | ||
|
|
6e7d9062cb | ||
|
|
a6438d91b4 | ||
|
|
d2d16360c1 | ||
|
|
3b277785c0 | ||
|
|
c94bc0c5c8 | ||
|
|
b1495e485e | ||
|
|
6d6ba0c668 | ||
|
|
0bc09d7d86 | ||
|
|
563f2e3594 | ||
|
|
6ba83d0891 | ||
|
|
f21962defc | ||
|
|
c3719a2eca | ||
|
|
3b58cf8c0e | ||
|
|
b390f1ef73 | ||
|
|
02fd903228 | ||
|
|
52ca0dd3f6 | ||
|
|
6a874b283c | ||
|
|
fd238f3e40 | ||
|
|
438036550f | ||
|
|
a0e14bd523 | ||
|
|
c8a76b7dd5 | ||
|
|
c86c3ce16d | ||
|
|
dd48772c9e | ||
|
|
53833582b7 | ||
|
|
f262b76a41 | ||
|
|
441e17174d | ||
|
|
defd58bc77 | ||
|
|
38f2897c29 | ||
|
|
d9d019c5d4 | ||
|
|
f23152d7a7 | ||
|
|
d625837eb9 | ||
|
|
cecd35e20b | ||
|
|
5ade799440 | ||
|
|
2786b195ee | ||
|
|
ad6f51646d | ||
|
|
328190ca63 | ||
|
|
5b5649de74 | ||
|
|
78003d863a | ||
|
|
71c635dedc | ||
|
|
5f5518e05b | ||
|
|
bd33305e5b | ||
|
|
aa8bd8a8ba | ||
|
|
84cdad7f7d | ||
|
|
3c38ca5a1b | ||
|
|
ffaf3e7d91 | ||
|
|
a81a6fc0ec | ||
|
|
6c3559792c | ||
|
|
6292ead1f7 | ||
|
|
9a15ceadf6 | ||
|
|
f61e9a9941 | ||
|
|
21a113f38f | ||
|
|
4f3bd6f9dd | ||
|
|
d2c80f4d1a | ||
|
|
2949d86908 | ||
|
|
0fcbdbf0fe | ||
|
|
1dc22a9e8f | ||
|
|
5c769d2d24 | ||
|
|
a2e63b7f0b | ||
|
|
44c33f1618 | ||
|
|
4730d7087f | ||
|
|
3b31a0234e | ||
|
|
cac5b2ca97 | ||
|
|
3b08f13bf3 | ||
|
|
e51bb180d4 | ||
|
|
4e97b6b47c | ||
|
|
ed6ee71ded | ||
|
|
6c69295696 | ||
|
|
fb72939392 | ||
|
|
b61692f121 | ||
|
|
9ff2549315 | ||
|
|
3a4eb97315 | ||
|
|
4f58be6548 | ||
|
|
33bd62d32f | ||
|
|
c547c88e89 | ||
|
|
2a4dcce444 | ||
|
|
b41d008223 | ||
|
|
a144ad9a1e | ||
|
|
93be0562cc | ||
|
|
64bb988613 | ||
|
|
3fcff1b1b3 | ||
|
|
6150ba4860 | ||
|
|
676307027c | ||
|
|
976f16c4d9 | ||
|
|
b88e90fec3 | ||
|
|
2103459845 | ||
|
|
348eb1e187 | ||
|
|
1fb6ad5488 | ||
|
|
328aa2cc45 | ||
|
|
2deb2ea0f0 | ||
|
|
bc1ab2d79b | ||
|
|
f3e77eea3d | ||
|
|
6b0e717a19 | ||
|
|
906a9748b5 | ||
|
|
414c33ffc9 | ||
|
|
77f8c5cbf2 | ||
|
|
3f5d7030cb | ||
|
|
c53c3afd46 | ||
|
|
33fd7f0c67 | ||
|
|
853f0a13e9 | ||
|
|
9569ad645b | ||
|
|
3a98117aa5 | ||
|
|
42092bc91e | ||
|
|
2d6f46dfa8 | ||
|
|
f1f400bcee | ||
|
|
a6e289c8ef | ||
|
|
a83ec513a1 | ||
|
|
f043a8789c | ||
|
|
30bbef4b14 | ||
|
|
26fb62c748 | ||
|
|
77c0e85775 | ||
|
|
ac45276835 | ||
|
|
cfa242a6a5 | ||
|
|
26599981a0 | ||
|
|
8fe2191d04 | ||
|
|
35b4c6c6b8 | ||
|
|
e42ccef4a7 | ||
|
|
8449139061 | ||
|
|
16e7e60cab | ||
|
|
c53988d01e | ||
|
|
1fea8b38fc | ||
|
|
7d6cd9ae7c | ||
|
|
bd70c33606 | ||
|
|
f2a0ca2b0e | ||
|
|
282543b759 | ||
|
|
15748575d8 | ||
|
|
cc9655af45 | ||
|
|
465bf1c10a | ||
|
|
eb1200a2cd | ||
|
|
c1a71e53f9 | ||
|
|
f5fe661c13 | ||
|
|
f42e5c4814 | ||
|
|
135a4ab58c | ||
|
|
b192207132 | ||
|
|
3464e84e90 | ||
|
|
a0ee98cb4b | ||
|
|
01d7a64670 | ||
|
|
cbafcb5aa6 | ||
|
|
b604bf2d7a | ||
|
|
05efca8430 | ||
|
|
007f125e46 | ||
|
|
83dd618e5b | ||
|
|
ffc992893f | ||
|
|
b04e3d6cd6 | ||
|
|
5e19f9707b | ||
|
|
457d07a50f | ||
|
|
3262a4e103 | ||
|
|
df27c80c72 | ||
|
|
bc54e34375 | ||
|
|
49deb08b81 | ||
|
|
b8fbe8341f | ||
|
|
07e46fb8aa | ||
|
|
0ee86b72fb | ||
|
|
b54c43b966 | ||
|
|
1b82e5cba7 | ||
|
|
8a825ee775 | ||
|
|
c91b667c13 | ||
|
|
32611749b2 | ||
|
|
dd9e29c425 | ||
|
|
8debe6ef1d | ||
|
|
bab56b0d88 | ||
|
|
0b43b4fdc2 | ||
|
|
210fb3539c | ||
|
|
026f3f2aef | ||
|
|
9b5d0a50f7 | ||
|
|
d3df13225d | ||
|
|
fb2ebab793 | ||
|
|
2f71efe6a7 | ||
|
|
7813d6fdd7 | ||
|
|
8ce92e1bc2 | ||
|
|
9316a5c23f | ||
|
|
64684b6b71 | ||
|
|
f133bfaf9f | ||
|
|
3f174e0bd0 | ||
|
|
39a0e3b29c | ||
|
|
ac8e86643e | ||
|
|
6a51ea96c0 | ||
|
|
94e2d9059a | ||
|
|
85c67ca048 | ||
|
|
99a5a8370f | ||
|
|
284ebcc23f | ||
|
|
c156f29c86 | ||
|
|
e075fcd4f3 | ||
|
|
49a8c459a8 | ||
|
|
1e45a4c9f5 | ||
|
|
dd825831c7 | ||
|
|
1b17161758 | ||
|
|
908971e48b | ||
|
|
ca76e83370 | ||
|
|
4774f44062 | ||
|
|
f198acda79 | ||
|
|
86a564094c | ||
|
|
f2c5dd8d71 | ||
|
|
ed8ef96a61 | ||
|
|
87a1ae56d7 | ||
|
|
63331e705a | ||
|
|
6f447c2b6a | ||
|
|
f415e99a36 | ||
|
|
b699ad9ae1 | ||
|
|
632a762654 | ||
|
|
a4a3bc72fc | ||
|
|
b809739d8c | ||
|
|
7ad2a4c3f2 | ||
|
|
4c4332c88b | ||
|
|
6c0ef59a30 | ||
|
|
83714d4d03 | ||
|
|
7498ef647c | ||
|
|
321dfcf741 | ||
|
|
bdc6fcf5dd | ||
|
|
50cd61e7c3 | ||
|
|
125796fec7 | ||
|
|
d1d0e1c732 | ||
|
|
820fd1c13a | ||
|
|
577373aed9 | ||
|
|
d1865a2c1e | ||
|
|
60efef0caf | ||
|
|
71c53d9f3d | ||
|
|
11a58a55c3 | ||
|
|
fc099a35ab | ||
|
|
f992fe0b8d | ||
|
|
ac99f9e46c | ||
|
|
225df7593f | ||
|
|
5ecad32251 | ||
|
|
cfd44fc50c | ||
|
|
20f47863bf | ||
|
|
c6cfbd4e8c | ||
|
|
8422056873 | ||
|
|
80ba651375 | ||
|
|
18e5bf9c07 | ||
|
|
0394180213 | ||
|
|
b52be989ed | ||
|
|
b15597dbe7 | ||
|
|
6aa4ae880a | ||
|
|
01d2d77a76 | ||
|
|
640a49e1ce | ||
|
|
c8cf6df4cd | ||
|
|
7f0a1a1caf | ||
|
|
d9942c0c32 | ||
|
|
587d573a04 | ||
|
|
391adea516 | ||
|
|
aad088e588 | ||
|
|
ed31e39491 | ||
|
|
34345b47d0 | ||
|
|
873a2c8dda | ||
|
|
838bef63b3 | ||
|
|
6d97118181 | ||
|
|
c1544ba7c4 | ||
|
|
008e02b03c | ||
|
|
2e68155c6d | ||
|
|
a53e880346 | ||
|
|
79f4bb679e | ||
|
|
21baa41ccf | ||
|
|
d20ccf186e | ||
|
|
3128aadfe0 | ||
|
|
03da97b0b8 | ||
|
|
2d39b3c2d0 | ||
|
|
dada8dc1db | ||
|
|
5b47785ae4 | ||
|
|
c18e92df67 | ||
|
|
8828ac5d30 | ||
|
|
83d717bcae | ||
|
|
21f9524b3e | ||
|
|
c7078a3e10 | ||
|
|
1bbd9675b6 | ||
|
|
87db306da0 | ||
|
|
c41da878f9 | ||
|
|
0a17e5ab7f | ||
|
|
2f356fd916 | ||
|
|
1bf52bda9e | ||
|
|
89117a326c | ||
|
|
51bc877b4e | ||
|
|
f5772f0423 | ||
|
|
95596a53b0 | ||
|
|
c114ad9aa7 | ||
|
|
bb9c35ffea | ||
|
|
6b426b5f83 | ||
|
|
9e215a3493 | ||
|
|
3321873fc6 | ||
|
|
fc57cac746 | ||
|
|
dbdd00fef8 | ||
|
|
0986cb46d9 | ||
|
|
e55384067b | ||
|
|
c905f0658d | ||
|
|
99fca41f02 | ||
|
|
eb666a62ac | ||
|
|
6e660e4c27 | ||
|
|
00bf89e1d2 | ||
|
|
48a98d8b1f | ||
|
|
1a8421bbfe | ||
|
|
ecc4bab8f2 | ||
|
|
b5a64f2fae | ||
|
|
7e11cfb891 | ||
|
|
cdcfbd8ab2 | ||
|
|
9964005525 | ||
|
|
3dd8898aaf | ||
|
|
d3acfdfa07 | ||
|
|
cb0eeaeb32 | ||
|
|
b114ba4ec6 | ||
|
|
688683fdaf | ||
|
|
f0740d8235 | ||
|
|
bf33ac89eb | ||
|
|
baeee68d27 | ||
|
|
25d1f542d7 | ||
|
|
1b919575f2 | ||
|
|
f7e49cfb04 | ||
|
|
c3cbbcacd7 | ||
|
|
d030b978ab | ||
|
|
1acb811437 | ||
|
|
1bf7be4d2a | ||
|
|
44096d2f95 | ||
|
|
136cb036b4 | ||
|
|
a1bfcd1216 | ||
|
|
277173ae0f | ||
|
|
28e6e63c5d | ||
|
|
a49623136a | ||
|
|
9041f3ed1f | ||
|
|
bc759b5bb3 | ||
|
|
0d70b12c75 | ||
|
|
b471e74ef8 | ||
|
|
745412ffb8 | ||
|
|
680c125dde | ||
|
|
d072cdd527 | ||
|
|
570126f8ff | ||
|
|
5de828fa15 | ||
|
|
32f3411eca | ||
|
|
7509e66617 | ||
|
|
92d65a529f | ||
|
|
51590ad30f | ||
|
|
7af70745f3 | ||
|
|
936c25c98b | ||
|
|
fcbfa307ef | ||
|
|
534b655291 | ||
|
|
5a0fa236cb | ||
|
|
d17845d767 | ||
|
|
ecd20983e8 | ||
|
|
66b200178f | ||
|
|
7dca6e0b04 | ||
|
|
60b6fb3d39 | ||
|
|
9d1a3eff16 | ||
|
|
e560f2329d | ||
|
|
d58602289d | ||
|
|
8845f347d3 | ||
|
|
d6611f02ba | ||
|
|
3ed9dc6a94 | ||
|
|
dbfc58c5ed | ||
|
|
aedad2ccb0 | ||
|
|
1aa79965c7 | ||
|
|
a7ec5d9b71 | ||
|
|
4afb2919fa | ||
|
|
52d6092ffd | ||
|
|
4bef99703a | ||
|
|
1afa21922f | ||
|
|
d3cb3eccff | ||
|
|
937d727011 | ||
|
|
ca7f175fb7 | ||
|
|
81f5e4c039 | ||
|
|
2f4ed00c93 | ||
|
|
cb1b1daacd | ||
|
|
6862cc0ce9 | ||
|
|
6ff8bda568 | ||
|
|
8e78937160 | ||
|
|
d7bfb88be9 | ||
|
|
46654ba28a | ||
|
|
34889dfb6a | ||
|
|
e2a3b89175 | ||
|
|
6a51a05171 | ||
|
|
09bfa883ac | ||
|
|
6f0268171d | ||
|
|
e0da616e37 | ||
|
|
224f0a0684 | ||
|
|
f928f6c161 | ||
|
|
4e5203a3dd | ||
|
|
58363c9dab | ||
|
|
0e7024488d | ||
|
|
6310a6040b | ||
|
|
ec31e714d6 | ||
|
|
a80d3bcf38 | ||
|
|
ad9b41e45e | ||
|
|
9d643387fb | ||
|
|
c570beefbd | ||
|
|
6f97972582 | ||
|
|
736368f441 | ||
|
|
8975be38ae | ||
|
|
7aede726ca | ||
|
|
228150cd72 | ||
|
|
9f4f9e7b2f | ||
|
|
629de5c931 | ||
|
|
30af256bb6 | ||
|
|
7340c86c61 | ||
|
|
187c6692d8 | ||
|
|
0c5de08870 | ||
|
|
36a6d0c93c | ||
|
|
2d66b73e34 | ||
|
|
18517c1fe5 | ||
|
|
69dfc4fe32 | ||
|
|
d7fe272673 | ||
|
|
40add040f9 | ||
|
|
766d7138ac | ||
|
|
dc3fb38cbb | ||
|
|
eb1e734628 | ||
|
|
ba95d49a67 | ||
|
|
a90aee32a0 | ||
|
|
8a9502ce01 | ||
|
|
8d46c4debc | ||
|
|
fe2ab99c52 | ||
|
|
a5467f201c | ||
|
|
976c3bbe98 | ||
|
|
551de62f42 | ||
|
|
860df74295 | ||
|
|
eca4117497 | ||
|
|
434226dd01 | ||
|
|
e770997d09 | ||
|
|
52d42bca30 | ||
|
|
3b5eba1c85 | ||
|
|
76af0aa6ed | ||
|
|
4a6e000a07 | ||
|
|
cf2fbcb6e3 | ||
|
|
11c2f8c991 | ||
|
|
0d3182c278 | ||
|
|
1d2a21fa1f | ||
|
|
c6763e76ee | ||
|
|
818c1ea9e9 | ||
|
|
0b4d0fcf67 | ||
|
|
384c4b998e | ||
|
|
449bd78db7 | ||
|
|
5d2227d3a6 | ||
|
|
0058449576 | ||
|
|
2059a57d96 | ||
|
|
8bb9ab629f | ||
|
|
73c536fa04 | ||
|
|
2d07bbdf2c | ||
|
|
83e7cf54f4 | ||
|
|
54725d30b1 | ||
|
|
e688cc520b | ||
|
|
ec5e79f86b | ||
|
|
87d56eb866 | ||
|
|
2922488eb9 | ||
|
|
b8230bf5e6 | ||
|
|
e66a3625b4 | ||
|
|
61ed256846 | ||
|
|
31bafccb6c | ||
|
|
db709dc4dc | ||
|
|
9461d8ec13 | ||
|
|
834eb4c1b6 | ||
|
|
21ab738c72 | ||
|
|
620a465f84 | ||
|
|
0c760dc107 | ||
|
|
ad7ea01ee8 | ||
|
|
1026821e33 | ||
|
|
302bdd366c | ||
|
|
e5241d93e5 | ||
|
|
6804f40bc4 | ||
|
|
a18fc4fd93 | ||
|
|
315dfd2041 | ||
|
|
f5513abfc8 | ||
|
|
0296999ec8 | ||
|
|
b2a44942a8 | ||
|
|
268e4d5ec9 | ||
|
|
4f562dbbfb | ||
|
|
e9127c0427 | ||
|
|
b2545f4d89 | ||
|
|
9c922e0c73 | ||
|
|
d6721ea8ef | ||
|
|
c8503d149e | ||
|
|
cd045df1c3 | ||
|
|
20b226769f | ||
|
|
8460428f2e | ||
|
|
d7f63afae7 | ||
|
|
6ad1a5b57f | ||
|
|
a2388cc4b4 | ||
|
|
f79ee4b582 | ||
|
|
03fd848f18 | ||
|
|
258a44de1a | ||
|
|
20a04408a6 | ||
|
|
662356311a | ||
|
|
806cba6352 | ||
|
|
b42e00961b | ||
|
|
fc0089c0f4 | ||
|
|
2c9b70a674 | ||
|
|
0bb0cb7b93 | ||
|
|
0e9a8e6c3d | ||
|
|
c7d39c7975 | ||
|
|
86abaf4009 | ||
|
|
382c3d1787 | ||
|
|
2ac8e7e496 | ||
|
|
2425ad39ef | ||
|
|
6b5b86f343 | ||
|
|
230645ffa5 | ||
|
|
3861eada88 | ||
|
|
a1691fda9b | ||
|
|
ec7d64d30d | ||
|
|
8cda08d41c | ||
|
|
05fe040f88 | ||
|
|
756cc86a23 | ||
|
|
9e470dffc3 | ||
|
|
6e2080f092 | ||
|
|
24a0b73ce3 | ||
|
|
473c0eecb1 | ||
|
|
10baa77dbc | ||
|
|
dec333d063 | ||
|
|
61d85c75d3 | ||
|
|
8dab22328c | ||
|
|
ac0991a7cc | ||
|
|
bc276b2bc1 | ||
|
|
1e6415ce45 | ||
|
|
e4f6408939 | ||
|
|
497bb74d5a | ||
|
|
dee939e78c | ||
|
|
79aa1535f3 | ||
|
|
9f2902e9d2 | ||
|
|
ace6574179 | ||
|
|
8ac82843af | ||
|
|
3e4acb6921 | ||
|
|
3a41b51160 | ||
|
|
c0ed9be287 | ||
|
|
bb9a9fb06d | ||
|
|
1a0edab86e | ||
|
|
673ac3faa9 | ||
|
|
3833b9b585 | ||
|
|
6ba9224f32 | ||
|
|
d138a49895 | ||
|
|
0e434f0212 | ||
|
|
f807067337 | ||
|
|
5e5800363e | ||
|
|
d643cf8c1d | ||
|
|
7a37ee7c30 | ||
|
|
d42e7a6d0a | ||
|
|
115506476b | ||
|
|
fab9df7825 | ||
|
|
0873562023 | ||
|
|
ca890b509a | ||
|
|
59fc14c57c | ||
|
|
907ad64f96 | ||
|
|
c96ad24a35 | ||
|
|
9a7694f32a | ||
|
|
73e9110b64 | ||
|
|
90439fc8c4 | ||
|
|
1a480445c9 | ||
|
|
adf066acdd | ||
|
|
a2d11d8100 | ||
|
|
f77b8a9137 | ||
|
|
ad0241047d | ||
|
|
6218b00486 | ||
|
|
4585f14b5f | ||
|
|
c0af9c2bf1 | ||
|
|
bf2adc6861 | ||
|
|
743a4eaf02 | ||
|
|
4df07ae61f | ||
|
|
6c1d1db4b4 | ||
|
|
11ac94d449 | ||
|
|
a84a41bc75 | ||
|
|
5f61c348c2 | ||
|
|
ffdc440926 | ||
|
|
3457fcb48b | ||
|
|
f70700c330 | ||
|
|
b28727ef8c | ||
|
|
3af33c8b75 | ||
|
|
9059dd7e3e | ||
|
|
2d0f686964 | ||
|
|
cf896e8064 | ||
|
|
2422ec276d | ||
|
|
c00aa2d807 | ||
|
|
ab400de069 | ||
|
|
829a28c986 | ||
|
|
666850a6bc | ||
|
|
89ff51cc09 | ||
|
|
c0ea316f44 | ||
|
|
7fae03e300 | ||
|
|
728d858f15 | ||
|
|
2029981f00 | ||
|
|
3e2e67d88d | ||
|
|
4fd5e3dc74 | ||
|
|
17a02b8fbb | ||
|
|
75a174bc7b | ||
|
|
086e01fcb8 | ||
|
|
a219428887 | ||
|
|
ca86b0acf9 | ||
|
|
f20df8a492 | ||
|
|
d742b306d7 | ||
|
|
119c647097 | ||
|
|
64c6fa6525 | ||
|
|
5a7965468d | ||
|
|
855ccbf300 | ||
|
|
855d52908b | ||
|
|
1440302ab3 | ||
|
|
9e055bd52f | ||
|
|
d4a36c2e0f | ||
|
|
ef9c8a4716 | ||
|
|
cd21a5ed8a | ||
|
|
1d0c9511a5 | ||
|
|
cd73b37673 | ||
|
|
f970ede20b | ||
|
|
9308382295 | ||
|
|
caf0a2c143 | ||
|
|
06cb649b55 | ||
|
|
e216675ca1 | ||
|
|
fec546e939 | ||
|
|
e7fb2a2c7c | ||
|
|
1bc6f6eeda | ||
|
|
afc46ac1d3 | ||
|
|
636e47d219 | ||
|
|
9c219d647d | ||
|
|
99da16b834 | ||
|
|
d8e5697bfe | ||
|
|
b504a88459 | ||
|
|
3745686f38 | ||
|
|
fda2e2d34d | ||
|
|
2f4da0f0b0 | ||
|
|
327e60b275 | ||
|
|
2450bac944 | ||
|
|
46fe0fbc29 | ||
|
|
8f30f628a0 | ||
|
|
27ba7608db | ||
|
|
d2cd341615 | ||
|
|
978e3e6e81 | ||
|
|
5099bebba5 | ||
|
|
6951f13ce4 | ||
|
|
ea76a9f88e | ||
|
|
35ed9727d3 | ||
|
|
b7ddc30244 | ||
|
|
e525cd4465 | ||
|
|
3898752f67 | ||
|
|
c0b11f6eab | ||
|
|
b6d9bf7319 | ||
|
|
16e4a3c10e | ||
|
|
4b00999550 | ||
|
|
c5797b916f | ||
|
|
7a6385b614 | ||
|
|
5391aa0fa2 | ||
|
|
06659f1dfc | ||
|
|
eec001cad4 | ||
|
|
d953614fe4 | ||
|
|
82070b999c | ||
|
|
cbf46c9ec4 | ||
|
|
13347878df | ||
|
|
343d9fd63f | ||
|
|
4d1ab8f4ba | ||
|
|
f7ff4d6cc7 | ||
|
|
c1717498f4 | ||
|
|
74a57d9e12 | ||
|
|
df3bfb2771 | ||
|
|
76dc77106f | ||
|
|
265df9d0f2 | ||
|
|
e4352e3c5a | ||
|
|
da44de59b9 | ||
|
|
8180ca7a9d | ||
|
|
71125e4833 | ||
|
|
5408c387ba | ||
|
|
8df3425a2e | ||
|
|
eb4e4b6b05 | ||
|
|
166563d343 | ||
|
|
f6dcef3b49 | ||
|
|
299015ae5d | ||
|
|
dbc4beb71a | ||
|
|
7d23d0c5b0 | ||
|
|
ac9d618188 | ||
|
|
87cd21f1f8 | ||
|
|
a54dc98fad | ||
|
|
392b535cf0 | ||
|
|
eecce3f414 | ||
|
|
bea31d6487 | ||
|
|
bd51ec2c87 | ||
|
|
75c461c8f9 | ||
|
|
c8d4f578af | ||
|
|
4b242b57c8 | ||
|
|
6a5e3bf70d | ||
|
|
43bb81fd82 | ||
|
|
1f6d0347cc | ||
|
|
0826d6de53 | ||
|
|
df5905ace6 | ||
|
|
acadb46e6c | ||
|
|
ccee2254e0 | ||
|
|
e26b497ccc | ||
|
|
5e49ae47a9 | ||
|
|
1d79c8dc53 | ||
|
|
7bf7f4bbe5 | ||
|
|
bba1cb3859 | ||
|
|
36b77224c5 | ||
|
|
b310b6745d | ||
|
|
9ef345f02d | ||
|
|
8649c899db | ||
|
|
ed9f98bda1 | ||
|
|
2e1dcf1479 | ||
|
|
90b02a4f6c | ||
|
|
16b634a7fc | ||
|
|
873176a3e6 | ||
|
|
6c30d76401 | ||
|
|
9bc6fe4e7a | ||
|
|
013a31afdb | ||
|
|
57b0050ae7 | ||
|
|
61a105af21 | ||
|
|
51a6c25e16 | ||
|
|
0e3ff45eb9 | ||
|
|
77e7c6f60f | ||
|
|
d09deab2f1 | ||
|
|
3e77a6301d | ||
|
|
3e89ecfdf6 | ||
|
|
644fffd69f | ||
|
|
a84dd0068c | ||
|
|
eb05af8e74 | ||
|
|
7c6c5fe445 | ||
|
|
191c80211b | ||
|
|
b13164b2c0 | ||
|
|
28456d5486 | ||
|
|
eb99e12003 | ||
|
|
058529526c | ||
|
|
49cf104a12 | ||
|
|
b639466adb | ||
|
|
1cf86b9641 | ||
|
|
f894771e7d | ||
|
|
451a4762df | ||
|
|
92313a2d64 | ||
|
|
94743678a9 | ||
|
|
4a6e5ee331 | ||
|
|
b284eab745 | ||
|
|
6969cf239a | ||
|
|
2b3b68605e | ||
|
|
738735b808 | ||
|
|
c1034b9344 | ||
|
|
42e6c413b6 | ||
|
|
4e75362d4b | ||
|
|
9bbfa99b4c | ||
|
|
1f49f40faa | ||
|
|
69735ce1a5 | ||
|
|
8d1ac59134 | ||
|
|
3407a01845 | ||
|
|
485a114a2d | ||
|
|
4ae082bfc7 | ||
|
|
cbd6277844 | ||
|
|
96f04b41cb | ||
|
|
ba9338c522 | ||
|
|
b39cf878a0 | ||
|
|
20bf1d71bb | ||
|
|
313a167729 | ||
|
|
ca342d8de2 | ||
|
|
0c2dd78f3b | ||
|
|
3c81d0423e | ||
|
|
3fcc420e08 | ||
|
|
65c099c02a | ||
|
|
c197a4a62c | ||
|
|
60fbe881c1 | ||
|
|
e96365a4bc | ||
|
|
1e865deaaf | ||
|
|
df98467eaf | ||
|
|
7265a5f3c0 | ||
|
|
0ac1983b66 | ||
|
|
a0e8906575 | ||
|
|
f13dc2777d | ||
|
|
0f588a8d97 | ||
|
|
6ce3443a34 | ||
|
|
1e448915d1 | ||
|
|
a9124f0a4a | ||
|
|
bd1adba17e | ||
|
|
39cb30a4be | ||
|
|
6ced31f8b5 | ||
|
|
74ceb06336 | ||
|
|
ee35d8ada2 | ||
|
|
4e92674be7 | ||
|
|
a39d25f6c1 | ||
|
|
0147e59899 | ||
|
|
a08faa038f | ||
|
|
42189e5c52 | ||
|
|
6c05ba06ff | ||
|
|
1a75a82523 | ||
|
|
8b5b6d3636 | ||
|
|
fd8b0ba57d | ||
|
|
187ae2fe0e | ||
|
|
4a6a601b5a | ||
|
|
5631c4d214 | ||
|
|
6be5ea55ce | ||
|
|
b43e2f9190 | ||
|
|
eb81a302b0 | ||
|
|
6b8f9a0d07 | ||
|
|
7d8b071049 | ||
|
|
e143b5d142 | ||
|
|
929e23b74e | ||
|
|
07fb4b1e5b | ||
|
|
f652969936 | ||
|
|
65c0b60e5f | ||
|
|
5b76e3e70f | ||
|
|
99d7c597b6 | ||
|
|
5e7e0d7b2a | ||
|
|
e377cbad38 | ||
|
|
0824ceacd9 | ||
|
|
4ddb327597 | ||
|
|
e068eb8bd1 | ||
|
|
0a9cb8d248 | ||
|
|
bb1711de60 | ||
|
|
8c85cc598d | ||
|
|
5883e3db52 | ||
|
|
2894f50005 | ||
|
|
87a9c29cf7 | ||
|
|
471e30d85e | ||
|
|
3330ba77b1 | ||
|
|
62df1e933b | ||
|
|
d23b3123ba | ||
|
|
2d73bd9927 | ||
|
|
ca379f0814 | ||
|
|
c5b3ed12a0 | ||
|
|
0e177e766a | ||
|
|
15234069fe | ||
|
|
45c531c463 | ||
|
|
01d0b1767c | ||
|
|
45f247393e | ||
|
|
c8967b4b5e | ||
|
|
cd40e70901 | ||
|
|
ec3c5c7774 | ||
|
|
69c4f021c9 | ||
|
|
a2fb5d5cbe | ||
|
|
0261a0b795 | ||
|
|
3b2ffd1a07 | ||
|
|
e20b40ee61 | ||
|
|
a882435757 | ||
|
|
afbb95d987 | ||
|
|
74f9163b24 | ||
|
|
cda26929bd | ||
|
|
f9a6120685 | ||
|
|
979da57982 | ||
|
|
33e923540a | ||
|
|
c384b746f7 | ||
|
|
4d9cf433ff | ||
|
|
380cdf687a | ||
|
|
722fb64245 | ||
|
|
67b0c98578 | ||
|
|
9f6f56f3ff | ||
|
|
91a6beb749 | ||
|
|
a5cf22af80 | ||
|
|
cc6d4c0c06 | ||
|
|
0b0a187967 | ||
|
|
966643a542 | ||
|
|
04569d27b7 | ||
|
|
f55a3c0b3d | ||
|
|
579a173fbf | ||
|
|
fa4bcd0cd4 | ||
|
|
8acd0300cd | ||
|
|
65f12f1df5 | ||
|
|
551fe6ebc5 | ||
|
|
95c06276cf | ||
|
|
403ece5588 | ||
|
|
fce27dc4de | ||
|
|
b41cef3631 | ||
|
|
3eeae90472 | ||
|
|
e366a6eed4 | ||
|
|
90c8be1fa3 | ||
|
|
669ce539dd | ||
|
|
ccef3f6d9f | ||
|
|
c1b38a9203 | ||
|
|
3f159872c0 | ||
|
|
9a836af0d0 | ||
|
|
4e486b1f59 | ||
|
|
217edad33c | ||
|
|
89a326ebc5 | ||
|
|
bce75ae3a8 | ||
|
|
9bf17256fb | ||
|
|
027cd21aa1 | ||
|
|
391b3eef11 | ||
|
|
4bf8491d01 | ||
|
|
a62ac4df3a | ||
|
|
9a7206b971 | ||
|
|
e23f26a8f3 | ||
|
|
490d38c9f1 | ||
|
|
02418f7498 | ||
|
|
ca21c26638 | ||
|
|
00a9973ca8 | ||
|
|
2ee1d5fca6 | ||
|
|
d8b046a69f | ||
|
|
08bcb4249d | ||
|
|
35f5503e26 | ||
|
|
c0b90df335 | ||
|
|
bea15392ec | ||
|
|
52de20c3b6 | ||
|
|
365e662472 | ||
|
|
89758558cf | ||
|
|
8d5ddc0ddf | ||
|
|
9d2617d9a0 | ||
|
|
6b17652197 | ||
|
|
6c2a73ebda | ||
|
|
ad45701790 | ||
|
|
ad3b6a04cc | ||
|
|
caab4a3f41 | ||
|
|
aecc283cb5 | ||
|
|
87c9e523c7 | ||
|
|
90451d9635 | ||
|
|
e567af9b24 | ||
|
|
dfae0be7d0 | ||
|
|
d62a38e533 | ||
|
|
bc8ee80491 | ||
|
|
915e34b32b | ||
|
|
5099a91a21 | ||
|
|
6f9ab0dea5 | ||
|
|
f90c3d0350 | ||
|
|
66d375b3b3 | ||
|
|
233d71fec7 | ||
|
|
14f3f82555 | ||
|
|
22fec82616 | ||
|
|
fcfdb18914 | ||
|
|
23d17d56e9 | ||
|
|
4d50d21f78 | ||
|
|
722285bd8f | ||
|
|
2bd8f97709 | ||
|
|
b4aae47556 | ||
|
|
1d546dbd83 | ||
|
|
9fbb2607a1 | ||
|
|
442d4c9e35 | ||
|
|
de7999c932 | ||
|
|
03cf88211e | ||
|
|
ec4d9bbcb9 | ||
|
|
2df1260c87 | ||
|
|
6e762c1ae3 | ||
|
|
2db3a828d6 | ||
|
|
c62cf3c82d | ||
|
|
5da9cd2205 | ||
|
|
883d92940f | ||
|
|
f53e19589d | ||
|
|
8e6b694d6e | ||
|
|
c298892833 | ||
|
|
971997fbc1 | ||
|
|
8b87d39c72 | ||
|
|
1124cf3a03 | ||
|
|
3691c3cc98 | ||
|
|
072734f7e8 | ||
|
|
0b34c336f7 | ||
|
|
6b64959309 | ||
|
|
704cab010d | ||
|
|
3153bfd916 | ||
|
|
493c34dfb9 | ||
|
|
346cdbfb18 | ||
|
|
cb9fdc66e3 | ||
|
|
07aedd4bb2 | ||
|
|
8881f8bd91 | ||
|
|
ee2b9fc885 | ||
|
|
250109b215 | ||
|
|
aaa8a45658 | ||
|
|
e683e1ab1c | ||
|
|
23a116b96e | ||
|
|
29014acd87 | ||
|
|
c4ccb4a8ca | ||
|
|
b392b2a867 | ||
|
|
a7de7bcf31 | ||
|
|
371b1b01cb | ||
|
|
08062bc3c5 | ||
|
|
bac11af00e | ||
|
|
69ccebd108 | ||
|
|
7f3f471f12 | ||
|
|
9f7eb9eecb | ||
|
|
86f50b36d6 | ||
|
|
0eca73234a | ||
|
|
f346815b18 | ||
|
|
5e9325fad1 | ||
|
|
d668f7749f | ||
|
|
a34d15da01 | ||
|
|
7bc4564029 | ||
|
|
f302d055e9 | ||
|
|
9cb258d920 | ||
|
|
4b8e9cf7d1 | ||
|
|
9b33c46995 | ||
|
|
6ae06014c5 | ||
|
|
32cd28829a | ||
|
|
aceebd88bb | ||
|
|
7ad0b27460 | ||
|
|
635374075f | ||
|
|
d3672ded33 | ||
|
|
b5f68770a3 | ||
|
|
1bd35c2b55 | ||
|
|
1242430e2f | ||
|
|
771bf92f78 | ||
|
|
042f455113 | ||
|
|
57464209b8 | ||
|
|
d6f35d7c5c | ||
|
|
1f73d0d258 | ||
|
|
7f9545754c | ||
|
|
1e22e6d203 | ||
|
|
496f1d91d0 | ||
|
|
5a38178db2 | ||
|
|
55b4291df0 | ||
|
|
5c419ea37f | ||
|
|
02ccad8fbc | ||
|
|
9a8e9dc34b | ||
|
|
e6aae4aa5f | ||
|
|
b8458246b8 | ||
|
|
287416006a | ||
|
|
1a1dda1796 | ||
|
|
3fd0b3ba42 | ||
|
|
77712a63ad | ||
|
|
caf9c39afa | ||
|
|
0db07e14d6 | ||
|
|
988d512b77 | ||
|
|
06c632fa50 | ||
|
|
f750bcefab | ||
|
|
4946bbcf97 | ||
|
|
dcdca3338d | ||
|
|
fbbd5dc9a6 | ||
|
|
913319d9e3 | ||
|
|
3919d03f97 | ||
|
|
5c19b67791 | ||
|
|
a55fa0d833 | ||
|
|
8e1489d85b | ||
|
|
797d537cb8 | ||
|
|
b6618577c7 | ||
|
|
0cb76eb275 | ||
|
|
93cea27ad8 | ||
|
|
263326ecbe | ||
|
|
61c85465b9 | ||
|
|
25c33df302 | ||
|
|
7d5a47afe9 | ||
|
|
fc7802ea0f | ||
|
|
b2ddd93191 | ||
|
|
d9a9624c6c | ||
|
|
aff09e3e34 | ||
|
|
6db993b589 | ||
|
|
a454a51939 | ||
|
|
6a1e38d831 | ||
|
|
cb6943010a | ||
|
|
6929464500 | ||
|
|
6e956f6cc3 | ||
|
|
b080a339a6 | ||
|
|
5de2add9c3 | ||
|
|
de77db64fc | ||
|
|
555885a3b0 | ||
|
|
f6ec749e96 | ||
|
|
a5b8f5af68 | ||
|
|
fce7c3cc39 | ||
|
|
4050d495ed | ||
|
|
3378f0de19 | ||
|
|
c05e7134ed | ||
|
|
f8a6287322 | ||
|
|
6c6a9a073f | ||
|
|
9c309707a7 | ||
|
|
9c1e4a0e70 | ||
|
|
7298cd1110 | ||
|
|
e672f9711f | ||
|
|
740ad8c1b2 | ||
|
|
62310f6b21 | ||
|
|
9c2de843b5 | ||
|
|
a905bf35a7 | ||
|
|
bd1932f12c | ||
|
|
d272bd4e05 | ||
|
|
67e42e8600 | ||
|
|
078d8b607c | ||
|
|
7c001bf468 | ||
|
|
2eef3ac5fb | ||
|
|
63cc2150a0 | ||
|
|
2476dd4474 | ||
|
|
b954d65b8f | ||
|
|
1b62aa5a79 | ||
|
|
48d1219f5c | ||
|
|
210e88b511 | ||
|
|
21960157ae | ||
|
|
73322272fe | ||
|
|
4d12a0bfdf | ||
|
|
b632880fde | ||
|
|
707b722c36 | ||
|
|
dd3ca3aa63 | ||
|
|
a4c3028881 | ||
|
|
b4b0d52ffb | ||
|
|
492afc0f9d | ||
|
|
38b3f73a85 | ||
|
|
2319629592 | ||
|
|
802ac99d0d | ||
|
|
e91a1198a0 | ||
|
|
b835a6b564 | ||
|
|
2687579986 | ||
|
|
e05f635db5 | ||
|
|
d3f1f2a341 | ||
|
|
4886a7c0fe | ||
|
|
93ad9161ec | ||
|
|
39633a0f09 | ||
|
|
f8baaaf617 | ||
|
|
354e017a33 | ||
|
|
3d9d4ce7be | ||
|
|
530b65e51d | ||
|
|
af6bed4995 | ||
|
|
f7f981d549 | ||
|
|
1454050eef | ||
|
|
8c80e6c2f8 | ||
|
|
b4237e51dc | ||
|
|
7af432c313 | ||
|
|
833462a84e | ||
|
|
222eea66fa | ||
|
|
072626d390 | ||
|
|
e4dedb226f | ||
|
|
acde0b6311 | ||
|
|
8cb57d43d6 | ||
|
|
f597f96152 | ||
|
|
0f5b5f1f6c | ||
|
|
ea0a9ae7ab | ||
|
|
98abf1d812 | ||
|
|
f1b9327123 | ||
|
|
497b9deadc | ||
|
|
2e723a700d | ||
|
|
5b558714de | ||
|
|
2641f7fe88 | ||
|
|
80bf1491e1 | ||
|
|
22cf3afdfa | ||
|
|
f2084098e2 | ||
|
|
00e998e5f9 | ||
|
|
df7f115415 | ||
|
|
0467d48201 | ||
|
|
41074331ed | ||
|
|
034469197c | ||
|
|
c80acdf88f | ||
|
|
7b9fbc36e1 | ||
|
|
ecd4f30e41 | ||
|
|
8682d0293a | ||
|
|
28ddc5db69 | ||
|
|
9e23045867 | ||
|
|
08758e9129 | ||
|
|
14404dff66 | ||
|
|
7b0e63b123 | ||
|
|
3b52247058 | ||
|
|
4c5fe41f2b | ||
|
|
b4ebd87229 | ||
|
|
d5086e07a0 | ||
|
|
b4698b7cca | ||
|
|
510083f0ea | ||
|
|
e7f300bc7c | ||
|
|
45773a987d | ||
|
|
9f8910c258 | ||
|
|
ef462dbb5e | ||
|
|
d38da7ae3d | ||
|
|
a9fe0f2d23 | ||
|
|
5e4dbc66dc | ||
|
|
e85f337b2f | ||
|
|
a7d36f9f9f | ||
|
|
e6ef4109c8 | ||
|
|
fc7b62e329 | ||
|
|
3cfda55a69 | ||
|
|
64a8418674 | ||
|
|
c3e1f137e1 | ||
|
|
0b1819cdc8 | ||
|
|
dcf642ffb0 | ||
|
|
21be3e3912 | ||
|
|
d6cb167a0c | ||
|
|
1177dc94b8 | ||
|
|
daa9c3c13c | ||
|
|
9d5184bae4 | ||
|
|
c7906b2d61 | ||
|
|
0b1ddb45a2 | ||
|
|
3cec6af4a8 | ||
|
|
8474486b74 | ||
|
|
695119b3a5 | ||
|
|
863de62880 | ||
|
|
c716994cab | ||
|
|
db6a90d956 | ||
|
|
4d847a04a7 | ||
|
|
a60ac679a0 | ||
|
|
8a5f927d8d | ||
|
|
073e685b0d | ||
|
|
a7089873e9 | ||
|
|
c2c7f7d71c | ||
|
|
c2c923ba11 | ||
|
|
e45d934cb6 | ||
|
|
f35ff8f583 | ||
|
|
6b29b3c817 | ||
|
|
317f336c76 | ||
|
|
ddd0dc6dff | ||
|
|
1da64ebbd6 | ||
|
|
48cf146a6f | ||
|
|
ccd6240e23 | ||
|
|
41c4b6453a | ||
|
|
fda49d72c1 | ||
|
|
230b3840ad | ||
|
|
31530c7311 | ||
|
|
ad5f36f2ac | ||
|
|
718ec64593 | ||
|
|
b078d91894 | ||
|
|
0e21d85be1 | ||
|
|
54af49fe40 | ||
|
|
2d950869f8 | ||
|
|
d3ec8f8791 | ||
|
|
9033830375 | ||
|
|
35e5c48814 | ||
|
|
b16efc8c0b | ||
|
|
bdf28a79fc | ||
|
|
bc634975d4 | ||
|
|
2f682ca9f8 | ||
|
|
bb8c8e5fa8 | ||
|
|
014bc9ed79 | ||
|
|
a89dbfad01 | ||
|
|
b53716bd7f | ||
|
|
6e9b3d811b | ||
|
|
3fa85ade3a | ||
|
|
1bd05e4561 | ||
|
|
a38a0d5b81 | ||
|
|
efcf28b96b | ||
|
|
6b827886a0 | ||
|
|
f6712c7cbd | ||
|
|
3e11da04df | ||
|
|
56d6ee9a1c | ||
|
|
897a518750 | ||
|
|
c9b7590dd9 | ||
|
|
4d3d250d5e | ||
|
|
43d93b87bc | ||
|
|
f0a90a46ed | ||
|
|
d379c41d72 | ||
|
|
57688559b1 | ||
|
|
fa26073882 | ||
|
|
b37ca7868a | ||
|
|
767621d2cb | ||
|
|
ab93e1f56d | ||
|
|
f3523e8381 | ||
|
|
0eeaf31270 | ||
|
|
5703b95d0e | ||
|
|
7acaffa841 | ||
|
|
ea7652677d | ||
|
|
b239441ff9 | ||
|
|
8bea90280f | ||
|
|
4fef0935fb | ||
|
|
421e19ca4b | ||
|
|
3e00c2d842 | ||
|
|
3fe8f75d1b | ||
|
|
8e0837b6a1 | ||
|
|
347b7238dc | ||
|
|
fdb89d13ef | ||
|
|
f3060d8a33 | ||
|
|
be743da973 | ||
|
|
de8d7725be | ||
|
|
7033df8c0c | ||
|
|
2e6e200962 | ||
|
|
b7a44adca0 | ||
|
|
e831a050cd | ||
|
|
4e2af32bcf | ||
|
|
198b031d03 | ||
|
|
5ec60a6a2c | ||
|
|
eadaabbe62 | ||
|
|
b2d7640a1d | ||
|
|
39ba117abf | ||
|
|
7a3849ffdb | ||
|
|
9a367b2be7 | ||
|
|
f671c11773 | ||
|
|
bb7208b754 | ||
|
|
3ae6f849ac | ||
|
|
e682be574b | ||
|
|
ab084a9399 | ||
|
|
3f4edebda6 | ||
|
|
a59e3bb3cd | ||
|
|
e62ea4cdb4 | ||
|
|
e3283739ce | ||
|
|
600aa2ec16 | ||
|
|
0921355a74 | ||
|
|
1ac757bd60 | ||
|
|
9c46074145 | ||
|
|
2ad239b6c9 | ||
|
|
9bc8eb952b | ||
|
|
83cbc1f450 | ||
|
|
5ef0970789 | ||
|
|
41920cc74f | ||
|
|
bda63626d2 | ||
|
|
d0d364d729 | ||
|
|
e896c2576b | ||
|
|
8b417ebd25 | ||
|
|
6d93d700bb | ||
|
|
88b0af83b5 | ||
|
|
5e3d0126e3 | ||
|
|
aef4192d6a | ||
|
|
30b8b3c61f | ||
|
|
7a1c6388c2 | ||
|
|
a694ccb39e | ||
|
|
a85bcfc0d7 | ||
|
|
5cc787f648 | ||
|
|
a011792fb6 | ||
|
|
2bd88ed300 | ||
|
|
bd234eafe3 | ||
|
|
0405be5bb0 | ||
|
|
f8616ba0b5 | ||
|
|
c40b0f6f63 | ||
|
|
b10c76a3a6 | ||
|
|
683b301fb7 | ||
|
|
76223227ba | ||
|
|
04e59f26b9 | ||
|
|
ba0f81e65c | ||
|
|
204352ca8b | ||
|
|
8b07f89d13 | ||
|
|
2f01154847 | ||
|
|
24458b4bf1 | ||
|
|
52049833fd | ||
|
|
3ec27d06ec | ||
|
|
2c813805e7 | ||
|
|
0583ab3bc8 | ||
|
|
510d234611 | ||
|
|
3006bcb3f7 | ||
|
|
b9c2580f22 | ||
|
|
2684031ff2 | ||
|
|
ae8f10ae47 | ||
|
|
de2866fe38 | ||
|
|
2f2b10d22b | ||
|
|
2065013a04 | ||
|
|
57b3448019 | ||
|
|
65faee4e7b | ||
|
|
e1c4bbed1d | ||
|
|
420fb5f6cc | ||
|
|
c4ee764dd8 | ||
|
|
3e0167a9e9 | ||
|
|
be74b3dca8 | ||
|
|
ba94df76e1 | ||
|
|
6361dd3f6e | ||
|
|
9f44a9d6a4 | ||
|
|
b6c0155487 | ||
|
|
42d93b9872 | ||
|
|
534ab7a030 | ||
|
|
e0399adca9 | ||
|
|
33a0cc3759 | ||
|
|
9ff955496e | ||
|
|
9424ed9669 | ||
|
|
248122670f | ||
|
|
9dc9be484f | ||
|
|
3fc88faa51 | ||
|
|
8168ddcb40 | ||
|
|
d57291777f | ||
|
|
e47dd4f054 | ||
|
|
4e86f62a64 | ||
|
|
711276e62b | ||
|
|
a2acacebe0 | ||
|
|
40e70fc6e9 | ||
|
|
f4d5687704 | ||
|
|
3adfd850c7 | ||
|
|
42019fca7c | ||
|
|
0fc2f3d86d | ||
|
|
b10355c846 | ||
|
|
05d649ef54 | ||
|
|
71d55ebf18 | ||
|
|
dc80efa426 | ||
|
|
0068da44d4 | ||
|
|
d757f69479 | ||
|
|
5629eae3ae | ||
|
|
496313f56b | ||
|
|
3640d302e1 | ||
|
|
d07e17d85c | ||
|
|
a87c498af8 | ||
|
|
75070e1bfa | ||
|
|
5487c20beb | ||
|
|
bcedf25ebf | ||
|
|
7ce874f5d0 | ||
|
|
bd0cbfb5b8 | ||
|
|
67fa3a8c82 | ||
|
|
3ce169b4e2 | ||
|
|
441a8868a0 | ||
|
|
dfb744bdf1 | ||
|
|
849c347d2e | ||
|
|
9c3fa17ce2 | ||
|
|
37783c3446 | ||
|
|
2447ea37ca | ||
|
|
4d0e208a2e | ||
|
|
65f894b7ac | ||
|
|
de608e90c1 | ||
|
|
3aa83b20ff | ||
|
|
1194823a73 | ||
|
|
60685f35d8 | ||
|
|
4d9b0f6157 | ||
|
|
e2428486b1 | ||
|
|
5a7dd75687 | ||
|
|
42bc462559 | ||
|
|
d0ff4c3306 | ||
|
|
2f5acd74d9 | ||
|
|
7979a01371 | ||
|
|
59633b8ba6 | ||
|
|
1eecfd24f6 | ||
|
|
fdda9161fe | ||
|
|
4156e28d78 | ||
|
|
418275589c | ||
|
|
0b32b0109f | ||
|
|
0f246d7f69 | ||
|
|
d30f4d66de | ||
|
|
be946aab50 | ||
|
|
2aca908685 | ||
|
|
99ec33418a | ||
|
|
c416887542 | ||
|
|
dd0ff29f66 | ||
|
|
3e22f47624 | ||
|
|
bda20507bd | ||
|
|
9111697a0b | ||
|
|
97ac1394fa | ||
|
|
6966d2633a | ||
|
|
58d341cea3 | ||
|
|
f27587f391 | ||
|
|
ce6536c1d8 | ||
|
|
c0420dfa2a | ||
|
|
0c77aa5a69 | ||
|
|
96698c5783 | ||
|
|
038bc809cb | ||
|
|
71d559e1f2 | ||
|
|
184d929521 | ||
|
|
5e975db36e | ||
|
|
9a89cf1978 | ||
|
|
94c1f03300 | ||
|
|
872df4e54e | ||
|
|
5fdde955b3 | ||
|
|
826d8e0303 | ||
|
|
3f87b85886 | ||
|
|
af6777397c | ||
|
|
2f29b73496 | ||
|
|
7bed39940e | ||
|
|
5625551898 | ||
|
|
fd479088ec | ||
|
|
c14499b211 | ||
|
|
57b5993f8d | ||
|
|
2f8fdae0db | ||
|
|
e57869a38e | ||
|
|
e4d291802b | ||
|
|
77eb4ec65a | ||
|
|
d27798e797 | ||
|
|
fca6b52fba | ||
|
|
04ebac2279 | ||
|
|
fb968dccdf | ||
|
|
1271ada6e1 | ||
|
|
7a86a8a8e7 | ||
|
|
e9ee638ae9 | ||
|
|
965e14c3f9 | ||
|
|
a2ca638f47 | ||
|
|
0197e59eb1 | ||
|
|
418adb52a4 | ||
|
|
8894524474 | ||
|
|
8b7716b380 | ||
|
|
96a92d230e | ||
|
|
6ec6318d5f | ||
|
|
bedbfd18d7 | ||
|
|
a5e90a8dea | ||
|
|
b22e98aa01 | ||
|
|
89ea0a9911 | ||
|
|
2756732458 | ||
|
|
3bb28c049f | ||
|
|
ce57b5d156 | ||
|
|
23f4e85f87 | ||
|
|
b937ec5a87 | ||
|
|
103a2527ce | ||
|
|
18e53720d1 | ||
|
|
35f80fc5c3 | ||
|
|
993dc85f8f | ||
|
|
99bd5418bc | ||
|
|
7c1e148ffa | ||
|
|
ffa52a935a | ||
|
|
4b4b121366 | ||
|
|
2964b90925 | ||
|
|
50f2fc5a16 | ||
|
|
d879c3c54a | ||
|
|
3012f74206 | ||
|
|
7fec46aecf | ||
|
|
91aa5250de | ||
|
|
75d762c0b9 | ||
|
|
67454b117b | ||
|
|
3b96881ba2 | ||
|
|
87c5cb5706 | ||
|
|
f4911e544b | ||
|
|
10d053a838 | ||
|
|
c4ab5ba8ff | ||
|
|
75bc2e9b0b | ||
|
|
c2fda9ce09 | ||
|
|
8e2ee88b93 | ||
|
|
d27fe9ac8e | ||
|
|
0d7b0e26ee | ||
|
|
da531b4aef | ||
|
|
4772e79fee | ||
|
|
72622c0755 | ||
|
|
55f2084e86 | ||
|
|
f34463d1cc | ||
|
|
76b31adc2f | ||
|
|
641ecb2736 | ||
|
|
3dbf735aeb | ||
|
|
33a493fe5d | ||
|
|
1ec3ab4a1f | ||
|
|
005d9c9877 | ||
|
|
102dcfd4bc | ||
|
|
e89ad0a86b | ||
|
|
b7ded4e595 | ||
|
|
b61417101f | ||
|
|
6e2d898443 | ||
|
|
1ba5c01281 | ||
|
|
c6f42b1cff | ||
|
|
2b3882fb1a | ||
|
|
12476595ad | ||
|
|
8435bfc4fe | ||
|
|
9cec524f88 | ||
|
|
fb3786c137 | ||
|
|
40e654dd22 | ||
|
|
d5087e2d90 | ||
|
|
adf49bbc32 | ||
|
|
8361cbab71 | ||
|
|
49abdbd009 | ||
|
|
4b95d67bea | ||
|
|
a6382422df | ||
|
|
e77c211955 | ||
|
|
8a3e4b7b14 | ||
|
|
a0901958a8 | ||
|
|
8e0ccbb45a | ||
|
|
1608934b89 | ||
|
|
02763bf7cb | ||
|
|
e5b63ce34d | ||
|
|
4ed6463d22 | ||
|
|
f348fc4fbc | ||
|
|
07489e7e9c | ||
|
|
eb6eea0f72 | ||
|
|
b0a30b32bb | ||
|
|
2caaf90037 | ||
|
|
929ea4dab0 | ||
|
|
f5ce4791d2 | ||
|
|
5698e745c9 | ||
|
|
8c03ce9e0c | ||
|
|
113e6255ea | ||
|
|
cbac246ffb | ||
|
|
e829515b02 | ||
|
|
3e511d1457 | ||
|
|
aabed928b1 | ||
|
|
6816e303ec | ||
|
|
1bbf7ce1a2 | ||
|
|
969ff1267e | ||
|
|
3634046dc7 | ||
|
|
c3ff0ad584 | ||
|
|
ebfe75384c | ||
|
|
bd1dcf3f97 | ||
|
|
d5e147d400 | ||
|
|
35dbade0a9 | ||
|
|
dc62fabc0b | ||
|
|
47f2db1e23 | ||
|
|
967b3f34e9 | ||
|
|
09ed1c9575 | ||
|
|
f71d6fd74f | ||
|
|
b9c4fa85f1 | ||
|
|
c32fa46161 | ||
|
|
d0bd4ea161 | ||
|
|
7b6d5c4e97 | ||
|
|
0459737b00 | ||
|
|
372ecb8430 | ||
|
|
9a852e442e | ||
|
|
92757ef5c3 | ||
|
|
297692d88b | ||
|
|
4ead4618e6 | ||
|
|
96f1c67bfe | ||
|
|
9db1449b4b | ||
|
|
9421bfcfee | ||
|
|
a5a1152e95 | ||
|
|
3a97fce182 | ||
|
|
e8ab5afb41 | ||
|
|
1d0658dc85 | ||
|
|
01f37ccb65 | ||
|
|
4d5a66d6e5 | ||
|
|
c4234041bc | ||
|
|
359a2f98a8 | ||
|
|
1225b1623e | ||
|
|
62aa29999b | ||
|
|
a4f727f68d | ||
|
|
a6c8a11881 | ||
|
|
ce4bcba2e6 | ||
|
|
a88ff1f2c4 | ||
|
|
a986e81353 | ||
|
|
b9899de6df | ||
|
|
bebb4eb281 | ||
|
|
03ca60cd50 | ||
|
|
1c46ed54e5 | ||
|
|
34c6957f95 | ||
|
|
8a62c228b2 | ||
|
|
4c92dfe914 | ||
|
|
5f2b952521 | ||
|
|
3485d9829c | ||
|
|
00d6bb5c8a | ||
|
|
89fc9310db | ||
|
|
26e52f0da4 | ||
|
|
99c235760e | ||
|
|
0dfdcfbdc3 | ||
|
|
5f48c4e7f3 | ||
|
|
5e703c70f7 | ||
|
|
e9ae18f809 | ||
|
|
396c76892c | ||
|
|
c329d7dd4e | ||
|
|
ca3871e4f6 | ||
|
|
d1c6c9a348 | ||
|
|
d5260811dc | ||
|
|
ce155b4d35 | ||
|
|
65aca43f3f | ||
|
|
96418f577d | ||
|
|
2ee9064175 | ||
|
|
4042681e83 | ||
|
|
cdf13df87d | ||
|
|
50037ae611 | ||
|
|
e38244e7c0 | ||
|
|
4f0eae4a6d | ||
|
|
438e58cc1c | ||
|
|
4bfd1c4a2a | ||
|
|
abfdb4befc | ||
|
|
5a1ffabd03 | ||
|
|
66bf48b6e6 | ||
|
|
bf7acebc30 | ||
|
|
975c1dc46f | ||
|
|
8cf2162121 | ||
|
|
9980528f1e | ||
|
|
0e34f6cfb8 | ||
|
|
581b34b586 | ||
|
|
20581afe80 | ||
|
|
3861a96d5a | ||
|
|
af44bde349 | ||
|
|
4736067ed2 | ||
|
|
2e686bcca7 | ||
|
|
8eef599aa6 | ||
|
|
afb85320bf | ||
|
|
4b8dabddae | ||
|
|
ab5c0a43bd | ||
|
|
65f215eee2 | ||
|
|
e7abed2def | ||
|
|
66c3a25fe1 | ||
|
|
d9f03cafbe | ||
|
|
639231388c | ||
|
|
fe44d27cde | ||
|
|
b71248e0f3 | ||
|
|
4db6e9a69a | ||
|
|
a6d6859aab | ||
|
|
55f8e04570 | ||
|
|
a1f206804c | ||
|
|
18c3f768a3 | ||
|
|
0e277a28d8 | ||
|
|
081e70c7f3 | ||
|
|
44007809fd | ||
|
|
827e1c879e | ||
|
|
1a7e6629fb | ||
|
|
4164903d0e | ||
|
|
5bedcf0a1c | ||
|
|
f1db331e5d | ||
|
|
3df39a1f78 | ||
|
|
59459fc6ca | ||
|
|
83dcd91223 | ||
|
|
ca530216ec | ||
|
|
c2ac40ca00 | ||
|
|
14e59ca91a | ||
|
|
643522774e | ||
|
|
cb3ec490a5 | ||
|
|
4358b2fd71 | ||
|
|
6c6a0073bf | ||
|
|
f86cf8b9c3 | ||
|
|
0444eb1f80 | ||
|
|
45d2ebfc69 | ||
|
|
acbfbc29b3 | ||
|
|
923f4aeb8f | ||
|
|
381103678d | ||
|
|
80247a993d | ||
|
|
29026f00db | ||
|
|
25c6350a88 | ||
|
|
c0af811d13 | ||
|
|
01d21b3ea2 | ||
|
|
df1cd3d5da | ||
|
|
1bab5a3625 | ||
|
|
911daba417 | ||
|
|
9b4e7f4cfc | ||
|
|
8c4e057c91 | ||
|
|
cd0c502986 | ||
|
|
7436c51592 | ||
|
|
95863b81a3 | ||
|
|
49fbbec138 | ||
|
|
cc2d1399ab | ||
|
|
fcf02a427c | ||
|
|
73a66e5b1a | ||
|
|
8b48c39675 | ||
|
|
055f6d06ae | ||
|
|
23ab5ba436 | ||
|
|
a655f02fcc | ||
|
|
92aa47e0bc | ||
|
|
8cdcda24e1 | ||
|
|
a28dd7dbc3 | ||
|
|
cd7fdcf026 | ||
|
|
81b081c67d | ||
|
|
fb07f84709 | ||
|
|
b1bc31ae0e | ||
|
|
b3d1e90132 | ||
|
|
f2c02fe3bb |
No files matched your search
@@ -1,9 +1,29 @@
|
||||
.*.orig$
|
||||
.*\.o$
|
||||
.*~$
|
||||
build-dir
|
||||
build
|
||||
.*\.sconsign
|
||||
doc/html.*
|
||||
doc/latex.*
|
||||
.lock-wscript
|
||||
\.rej$
|
||||
\.orig$
|
||||
\.o$
|
||||
~$
|
||||
^build-dir
|
||||
^build
|
||||
^doc/html
|
||||
^doc/latex
|
||||
^\.lock-wscript
|
||||
^\.waf
|
||||
^doc/introspected-doxygen\.h$
|
||||
.*\.py[co]$
|
||||
\.pcap$
|
||||
^doc/manual/manual/
|
||||
doc/manual/manual.aux
|
||||
doc/manual/manual.cp
|
||||
doc/manual/manual.fn
|
||||
doc/manual/manual.html
|
||||
doc/manual/manual.ky
|
||||
doc/manual/manual.log
|
||||
doc/manual/manual.pdf
|
||||
doc/manual/manual.pg
|
||||
doc/manual/manual.toc
|
||||
doc/manual/manual.tp
|
||||
doc/manual/manual.vr
|
||||
^doc/manual/figures/.*eps
|
||||
^doc/manual/figures/.*pdf
|
||||
^doc/manual/figures/.*png
|
||||
^bindings/python/pybindgen/
|
||||
@@ -1 +1,20 @@
|
||||
56928998e05c9c11f5f3aefe79be8d2843e0db88 release ns-3.0.1
|
||||
56928998e05c9c11f5f3aefe79be8d2843e0db88 ns-3.0.1
|
||||
7ac5a4b0969b255c4824c926c2b37ef450136ce9 ns-3.0.2
|
||||
38099dd26e9467b8f49f8632f22789858149a6e7 ns-3.0.3
|
||||
5701e60bf01a8ac1308945e69001e0cc07948faf ns-3.0.4
|
||||
08046b6aef37932507696a2f2f427b42d693781e ns-3.0.5
|
||||
606df29888e7573b825fc891a002f0757166b616 ns-3.0.6
|
||||
36472385a1cc7c44d34fb7a5951b930010f4e8d2 ns-3.0.7
|
||||
560a5091e0e6ded47d269e2f2dee780f13950a63 ns-3.0.8
|
||||
4db981a0d9eb135e3e1c07765cff8d66f7a55cca ns-3.0.9
|
||||
b5bf2588cde2f1273b1095cc5c83a0c272e55370 ns-3.0.10
|
||||
ee5e1da76ecc52337f097cd90ebb50a3d49ec541 ns-3.0.11
|
||||
b17f2928291eec5bf5b1c59a4a5fd583f704ac40 ns-3.0.12
|
||||
79dba133b5f8a2d6f6f678a22e8519bc155e6a4e ns-3.0.13
|
||||
8869a79a391f49d0c787f0558cc9329b4e7ee40e ns-3.1-RC1
|
||||
951296e9a277e14113a0d3ba86a9688b222569ae ns-3.1-RC2
|
||||
ea16c44eb90db579c83d3434fc8a960be506a7f5 ns-3.1-RC3
|
||||
42504fb1f7be7817b8be513cdcd3d9bc8f3660e8 ns-3.1
|
||||
5768685f9fdba9fbf2e9561a840f085142c73575 ns-3.1
|
||||
dfd634417b8d1896d981b6f44d8f71030611596a ns-3.2-RC1
|
||||
319eb29611b18998abbad01548825643a8017bcb ns-3.2-RC2
|
||||
@@ -1,6 +1,12 @@
|
||||
Raj Bhattarcharjea (raj.b@gatech.edu)
|
||||
Gustavo Carneiro (gjcarneiro@gmail.com)
|
||||
Raj Bhattacharjea (raj.b@gatech.edu)
|
||||
Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com)
|
||||
Craig Dowell (craigdo@ee.washington.edu)
|
||||
Tom Henderson (tomhend@u.washington.edu)
|
||||
Joe Kopena (tjkopena@cs.drexel.edu)
|
||||
Mathieu Lacage (mathieu.lacage@sophia.inria.fr)
|
||||
Emmanuelle Laprise (emmmanuelle.laprise@bluekazoo.ca)
|
||||
Federico Maguolo (maguolof@dei.unipd.it)
|
||||
George F. Riley (riley@ece.gatech.edu)
|
||||
Guillaume Vu-Brugier (gvubrugier@gmail.com)
|
||||
Florian Westphal (fw@strlen.de)
|
||||
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<title>ns-3 Change Log</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>
|
||||
ns-3: API and model change history</h1>
|
||||
<!--
|
||||
This ChangeLog is updated in the reverse order
|
||||
with the most recent changes coming first. Date format: DD-MM-YYYY
|
||||
-->
|
||||
<p>
|
||||
ns-3 is an evolving system and there will be API or behavioral changes
|
||||
from time to time. Users who try to use scripts or models across
|
||||
versions of ns-3 may encounter problems at compile time, run time, or
|
||||
may see the simulation output change. </p>
|
||||
<p>
|
||||
We have adopted the development policy that we are going to try to ease
|
||||
the impact of these changes on users by documenting these changes in a
|
||||
single place (this file), and not by providing a temporary or permanent
|
||||
backward-compatibility software layer. </p>
|
||||
<p>
|
||||
The goal is that users who encounter a problem when trying to use older
|
||||
code with newer code should be able to consult this file to find
|
||||
guidance as to how to fix the problem. For instance, if a method name
|
||||
or signature has changed, it should be stated what the new replacement
|
||||
name is. </p>
|
||||
<p>
|
||||
Note that users who upgrade the simulator across versions, or who work
|
||||
directly out of the development tree, may find that simulation output
|
||||
changes even when the compilation doesn't break, such as when a
|
||||
simulator default value is changed. Therefore, it is good practice for
|
||||
_anyone_ using code across multiple ns-3 releases to consult this file,
|
||||
as well as the RELEASE_NOTES, to understand what has changed over time.
|
||||
</p>
|
||||
<p>
|
||||
This file is a best-effort approach to solving this issue; we will do
|
||||
our best but can guarantee that there will be things that fall through
|
||||
the cracks, unfortunately. If you, as a user, can suggest improvements
|
||||
to this file based on your experience, please contribute a patch or drop
|
||||
us a note on ns-developers mailing list. </p>
|
||||
|
||||
<hr>
|
||||
<h1>changes from ns-3.1 to ns-3.2</h1>
|
||||
|
||||
<h2>new API:</h2>
|
||||
|
||||
<li>26-08-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/5aa65b1ea001">5aa65b1ea001</a></li>
|
||||
<ul>
|
||||
<li>
|
||||
Add multithreaded and real-time simulator implementation. Allows for emulated
|
||||
net devices running in threads other than the main simulation thread to schedule
|
||||
events. Allows for pacing the simulation clock at 1x real-time.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li>26-08-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/c69779f5e51e">c69779f5e51e</a></li>
|
||||
<ul>
|
||||
<li>
|
||||
Add threading and synchronization primitives. Enabling technology for
|
||||
multithreaded simulator implementation.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<h2>new API in existing classes:</h2>
|
||||
|
||||
<ul>
|
||||
<li>01-08-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/a18520551cdf">a18520551cdf</a></li>
|
||||
<ul>
|
||||
<li>class ArpCache has two new attributes: MaxRetries
|
||||
and a Drop trace. It also has some new public methods but these are
|
||||
mostly for internal use.
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>changes to existing API:</h2>
|
||||
|
||||
<li>05-09-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/aa1fb0f43571">aa1fb0f43571</a></li>
|
||||
<ul>
|
||||
<li>
|
||||
Change naming of MTU and packet size attributes in CSMA and Point-to-Point devices<br>
|
||||
After much discussion it was decided that the preferred way to think about
|
||||
the different senses of transmission units and encapsulations was to call the
|
||||
MAC MTU simply MTU and to use the overall packet size as the PHY-level attribute
|
||||
of interest. See the Doxygen of CsmaNetDevice::SetFrameSize and
|
||||
PointToPointNetDevice::SetFrameSize for a detailed description.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<ul>
|
||||
<li>25-08-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/e5ab96db540e">e5ab96db540e</a></li>
|
||||
<ul>
|
||||
<li>
|
||||
bug 273: constify packet pointers.<br>
|
||||
The normal and the promiscuous receive callbacks of the NetDevice API
|
||||
have been changed from:
|
||||
<pre>
|
||||
Callback<bool,Ptr<NetDevice>,Ptr<Packet>,uint16_t,const Address &>
|
||||
Callback<bool,Ptr<NetDevice>, Ptr<Packet>, uint16_t,
|
||||
const Address &, const Address &, enum PacketType >
|
||||
</pre>
|
||||
to:
|
||||
<pre>
|
||||
Callback<bool,Ptr<NetDevice>,Ptr<const Packet>,uint16_t,const Address &>
|
||||
Callback<bool,Ptr<NetDevice>, Ptr<const Packet>, uint16_t,
|
||||
const Address &, const Address &, enum PacketType >
|
||||
</pre>
|
||||
to avoid the kind of bugs reported in
|
||||
<a href="http://www.nsnam.org/bugzilla/show_bug.cgi?id=273">bug 273</a>.
|
||||
Users who implement a subclass of the NetDevice base class need to change the signature
|
||||
of their SetReceiveCallback and SetPromiscReceiveCallback methods.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li>04-08-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/cba7b2b80fe8">cba7b2b80fe8</a></li>
|
||||
<ul>
|
||||
<li>
|
||||
Cleanup of MTU confusion and initialization in CsmaNetDevice<br>
|
||||
The MTU of the CsmaNetDevice defaulted to 65535. This did not correspond with
|
||||
the expected MTU found in Ethernet-like devices. Also there was not clear
|
||||
documentation regarding which MTU was being set. There are two MTU here, one
|
||||
at the MAC level and one at the PHY level. We split out the MTU setting to make
|
||||
this more clear and set the default PHY level MTU to 1500 to be more like
|
||||
Ethernet. The encapsulation mode defaults to LLC/SNAP which then puts the
|
||||
MAC level MTU at 1492 by default. We allow users to now set the encapsulation
|
||||
mode, MAC MTU and PHY MTU while keeping the three values consistent. See the
|
||||
Doxygen of CsmaNetDevice::SetMaxPayloadLength for a detailed description of the
|
||||
issues and solution.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li>21-07-2008; changeset
|
||||
<a href="
|
||||
http://code.nsnam.org/ns-3-dev/rev/99698bc858e8">99698bc858e8</a></li>
|
||||
<ul>
|
||||
<li> class NetDevice has added a pure virtual method that
|
||||
must be implemented by all subclasses:
|
||||
<pre>
|
||||
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb) = 0;
|
||||
</pre>
|
||||
All NetDevices must support this method, and must call this callback
|
||||
when processing packets in the receive direction (the appropriate place
|
||||
to call this is device-dependent). An approach to stub this out
|
||||
temporarily, if you do not care about immediately enabling this
|
||||
functionality, would be to add this to your device:
|
||||
<pre>
|
||||
void
|
||||
ExampleNetDevice::SetPromiscReceiveCallback
|
||||
(NetDevice::PromiscReceiveCallback cb)
|
||||
{
|
||||
NS_ASSERT_MSG (false, "No implementation yet for
|
||||
SetPromiscReceiveCallback");
|
||||
}
|
||||
</pre>
|
||||
To implement this properly, consult the CsmaNetDevice for examples of
|
||||
when the m_promiscRxCallback is called.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li>03-07-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/d5f8e5fae1c6">d5f8e5fae1c6</a></li>
|
||||
<ul>
|
||||
<li>
|
||||
Miscellaneous cleanup of Udp Helper API, to fix bug 234
|
||||
<pre>
|
||||
class UdpEchoServerHelper
|
||||
{
|
||||
public:
|
||||
- UdpEchoServerHelper ();
|
||||
- void SetPort (uint16_t port);
|
||||
+ UdpEchoServerHelper (uint16_t port);
|
||||
+
|
||||
+ void SetAttribute (std::string name, const AttributeValue &value);
|
||||
ApplicationContainer Install (NodeContainer c);
|
||||
|
||||
class UdpEchoClientHelper
|
||||
{
|
||||
public:
|
||||
- UdpEchoClientHelper ();
|
||||
+ UdpEchoClientHelper (Ipv4Address ip, uint16_t port);
|
||||
- void SetRemote (Ipv4Address ip, uint16_t port);
|
||||
- void SetAppAttribute (std::string name, const AttributeValue &value);
|
||||
+ void SetAttribute (std::string name, const AttributeValue &value);
|
||||
ApplicationContainer Install (NodeContainer c);
|
||||
</pre>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li>03-07-2008; changeset
|
||||
<a href="
|
||||
http://code.nsnam.org/ns-3-dev/rev/3cdd9d60f7c7">3cdd9d60f7c7</a></li>
|
||||
<ul>
|
||||
<li>
|
||||
Rename all instances method names using "Set..Parameter" to "Set..Attribute"
|
||||
(bug 232)
|
||||
</li>
|
||||
<li> How to fix your code: Any use of helper API that was using a method
|
||||
"Set...Parameter()" should be changed to read "Set...Attribute()". e.g.
|
||||
<pre>
|
||||
- csma.SetChannelParameter ("DataRate", DataRateValue (5000000));
|
||||
- csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
|
||||
+ csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
|
||||
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
|
||||
</pre>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>changed behavior:</h2>
|
||||
<ul>
|
||||
|
||||
<li>07-09-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/5d836ab1523b">5d836ab1523b</a></li>
|
||||
<ul>
|
||||
<li>
|
||||
Implement a finite receive buffer for TCP<br>
|
||||
The native TCP model in TcpSocketImpl did not support a finite receive buffer.
|
||||
This changeset adds the following functionality in this regard:
|
||||
<ul>
|
||||
<li>
|
||||
Being able to set the receiver buffer size through the attributes system.
|
||||
</li>
|
||||
<li>
|
||||
This receiver buffer size is now correctly exported in the TCP header as the
|
||||
advertised window. Prior to this changeset, the TCP header advertised window
|
||||
was set to the maximum size of 2^16 bytes.
|
||||
window
|
||||
</li>
|
||||
<li>
|
||||
The aforementioned window size is correctly used for flow control, i.e. the
|
||||
sending TCP will not send more data than available space in the receiver's
|
||||
buffer.
|
||||
</li>
|
||||
<li>
|
||||
In the case of a receiver window collapse, when a advertised zero-window
|
||||
packet is received, the sender enters the persist probing state in which
|
||||
it sends probe packets with one payload byte at exponentially backed-off
|
||||
intervals up to 60s. The reciever will continue to send advertised
|
||||
zero-window ACKs of the old data so long as the receiver buffer remains full.
|
||||
When the receiver window clears up due to an application read, the TCP
|
||||
will finally ACK the probe byte, and update its advertised window appropriately.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
See
|
||||
<a href="http://www.nsnam.org/bugzilla/show_bug.cgi?id=239"> bug 239 </a> for
|
||||
more.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>07-09-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/7afa66c2b291">7afa66c2b291</a></li>
|
||||
<ul>
|
||||
<li>
|
||||
Add correct FIN exchange behavior during TCP closedown<br>
|
||||
The behavior of the native TcpSocketImpl TCP model was such that the final
|
||||
FIN exchange was not correct, i.e. calling Socket::Close didn't send a FIN
|
||||
packet, and even if it had, the ACK never came back, and even if it had, the
|
||||
ACK would have incorrect sequence number. All these various problems have been
|
||||
addressed by this changeset. See
|
||||
<a href="http://www.nsnam.org/bugzilla/show_bug.cgi?id=242"> bug 242 </a> for
|
||||
more.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li> 28-07-2008; changeset
|
||||
<a href="http://code.nsnam.org/ns-3-dev/rev/6f68f1044df1">6f68f1044df1</a>
|
||||
<ul>
|
||||
<li>
|
||||
OLSR: HELLO messages hold time changed to 3*hello
|
||||
interval from hello interval. This is an important bug fix as
|
||||
hold time == refresh time was never intentional, as it leads to
|
||||
instability in neighbor detection.
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -23,7 +23,7 @@ will be contributed by the community in an open collaboration
|
||||
process.
|
||||
|
||||
Contributing to the ns-3 project is still a very informal
|
||||
process because that process depends heavily on the personality
|
||||
process because that process depends heavily on the background
|
||||
of the people involved, the amount of time they can invest
|
||||
and the type of model they want to work on.
|
||||
|
||||
@@ -34,27 +34,28 @@ project. These steps are described in doc/contributing.txt
|
||||
2) An overview of the ns-3 project
|
||||
----------------------------------
|
||||
|
||||
This package contains the latest version of ns-3 which is aims
|
||||
This package contains the latest version of ns-3 which aims
|
||||
at being a replacement for ns-2. Currently, ns-3 provides a
|
||||
number of very simple network simulation models:
|
||||
- an ipv4 and udp stack
|
||||
number of simple network simulation models:
|
||||
- an ipv4 and tcp and udp stack
|
||||
- arp support at the bottom of the stack
|
||||
- point-to-point physical-layer links
|
||||
- static global and OLSR unicast routing
|
||||
- point-to-point, CSMA, and Wifi links
|
||||
- mobility
|
||||
- OnOff traffic generator
|
||||
|
||||
Our focus to date has been on getting an overall software
|
||||
framework in place. The framework is there to make adding
|
||||
new models as simple as possible:
|
||||
- an extensive tracing system can be used to connect
|
||||
any number of arbitrary trace sources to any number
|
||||
of trace sinks. This tracing system is decoupled
|
||||
from the act of serializing the trace events to a
|
||||
file: users can and should provide their own
|
||||
trace handling routines.
|
||||
|
||||
- an extensive callback-based tracing system
|
||||
|
||||
- simple file trace serialization support is included
|
||||
to both text and pcap files.
|
||||
|
||||
- an attribute system for configuring parameters in the
|
||||
models
|
||||
|
||||
- adding new MAC-level models simply requires subclassing
|
||||
the pair of classes NetDevice and Channel.
|
||||
|
||||
@@ -71,32 +72,36 @@ use of these ns-3 libraries.
|
||||
|
||||
To build the set of default libraries and the example
|
||||
programs included in this package, you need to use the
|
||||
tool 'scons'. Detailed information on how to install
|
||||
and use scons is included in the file doc/build.txt
|
||||
tool 'waf'. Detailed information on how use waf is
|
||||
included in the file doc/build.txt
|
||||
|
||||
However, the real quick and dirty way to get started is to
|
||||
type the command "scons" the the directory which contains
|
||||
type the command "./waf" the the directory which contains
|
||||
this README file. The files built will be copied in the
|
||||
build-dir/dbg-shared/bin and build-dir/dbg-shared/lib
|
||||
directories. build-dir/dbg-shared/bin will contain
|
||||
one binary for each of the sample code in the 'samples'
|
||||
directory and one binary for each of the detailed examples
|
||||
found in the 'examples' directory.
|
||||
build/debug or build/optimized.
|
||||
|
||||
The current codebase is expected to build and run on the
|
||||
following set of platforms:
|
||||
- linux x86 gcc 4.2, 4.1, and, 3.4.
|
||||
- linux x86_64 gcc 4.0
|
||||
- linux x86 gcc 4.2, 4.1, and, 3.4.6.
|
||||
- linux x86_64 gcc 4.1.3, 4.2.1, 3.4.6
|
||||
- MacOS X ppc and x86
|
||||
- mingw gcc 3.4.5 (debug only)
|
||||
- cygwin gcc 3.4.4 (debug only)
|
||||
|
||||
The current codebase is expected to fail to build on
|
||||
the following platforms:
|
||||
- gcc 3.3 and earlier
|
||||
- optimized builds on gcc 3.4.4 and 3.4.5
|
||||
- optimized builds on linux x86 gcc 4.0
|
||||
- msvc
|
||||
|
||||
Other platforms may or may not work: we welcome
|
||||
patches to improve the portability of the code to these
|
||||
other platforms.
|
||||
The following optional features are known to not work on
|
||||
these platforms:
|
||||
- mingw: nsc, realtime scheduler
|
||||
- cygwin: python bindings, nsc
|
||||
|
||||
Other platforms may or may not work: we welcome patches to
|
||||
improve the portability of the code to these other platforms.
|
||||
|
||||
4) Running ns-3
|
||||
---------------
|
||||
@@ -105,22 +110,17 @@ On recent Linux systems, once you have built ns-3, it
|
||||
should be easy to run the sample programs with the
|
||||
following command:
|
||||
|
||||
./build-dir/dbg-shared/bin/simple-p2p
|
||||
./waf --run simple-global-routing
|
||||
|
||||
or:
|
||||
|
||||
cd build-dir/dbg-shared/bin
|
||||
./simple-p2p
|
||||
|
||||
That program should generate a simple-p2p.tr text
|
||||
trace file and a set of simple-p2p-xx-xx.pcap binary
|
||||
pcap trace files, which can be read by tcpdump.
|
||||
That program should generate a simple-global-routing.tr text
|
||||
trace file and a set of simple-global-routing-xx-xx.pcap binary
|
||||
pcap trace files, which can be read by tcpdump -tt -r filename.pcap
|
||||
|
||||
5) Getting access to the ns-3 documentation
|
||||
-------------------------------------------
|
||||
|
||||
Once you have verified that your build of ns-3 works by running
|
||||
the simple-p2p example as outlined in 4) above, it is
|
||||
the simple-point-to-point example as outlined in 4) above, it is
|
||||
quite likely that you will want to get started on reading
|
||||
some ns-3 documentation.
|
||||
|
||||
@@ -130,12 +130,7 @@ include some of it in this release for ease of use.
|
||||
|
||||
This documentation includes:
|
||||
|
||||
- an architecture document which describes a very
|
||||
high-level view of ns-3: it tries to explain the
|
||||
use-cases the ns-3 developers really focused on when
|
||||
doing the initial design and then goes on to explain
|
||||
the structure of the resulting framework.
|
||||
See the file doc/architecture.pdf
|
||||
- a tutorial
|
||||
|
||||
- a wiki for user-contributed tips: http://www.nsnam.org/wiki/
|
||||
|
||||
@@ -144,17 +139,6 @@ This documentation includes:
|
||||
as introductory text:
|
||||
http://www.nsnam.org/doxygen/index.html
|
||||
|
||||
If you want to re-generate this documentation, you can
|
||||
easily do so:
|
||||
|
||||
- doc/architecture.pdf is generated from the architecture.tex
|
||||
file in http://code.nsnam.org/docs
|
||||
|
||||
- the doxygen documentation is generated from the doc/doxygen.conf
|
||||
configuration file. The command "scons doc" will generate it
|
||||
as doc/html/index.html if you have installed the doxygen tools
|
||||
(see http://www.doxygen.org)
|
||||
|
||||
6) Working with the development version of ns-3
|
||||
-----------------------------------------------
|
||||
|
||||
@@ -166,6 +150,5 @@ mercurial website is usually a good idea if you are not
|
||||
familiar with it.
|
||||
|
||||
If you have successfully installed mercurial, you can get
|
||||
a copy of the development version with the following
|
||||
command:
|
||||
a copy of the development version with the following command:
|
||||
"hg clone http://code.nsnam.org/ns-3-dev"
|
||||
+268
-2
@@ -3,9 +3,275 @@
|
||||
|
||||
This file contains ns-3 release notes (most recent releases first).
|
||||
|
||||
Release 3.0.2 (2007/05/18)
|
||||
Release 3.2 (pending)
|
||||
=====================
|
||||
|
||||
Availability
|
||||
------------
|
||||
|
||||
This release is immediately available from:
|
||||
http://www.nsnam.org/releases/ns-3.2.tar.bz2
|
||||
|
||||
What is ns-3 ?
|
||||
--------------
|
||||
|
||||
ns-3 is a new discrete-event network simulator designed for supporting network
|
||||
research and education. ns-3 features a solid, well documented C++ core and
|
||||
models for TCP/IP (IPv4), several link types including WiFi, and mobility
|
||||
models.
|
||||
|
||||
ns-3 is an open source project released under the GNU GPLv2 license which
|
||||
allows anyone to use ns-3 without having to pay any license fee or royalties.
|
||||
ns-3 is actively seeking new contributors to extend the range of supported
|
||||
models and/or to maintain existing models.
|
||||
|
||||
New user-visible features
|
||||
-------------------------
|
||||
a) Learning bridge (IEEE 802.1D)
|
||||
It is now possible to bridge together multiple layer 2 devices to
|
||||
create larger layer 2 networks. The Wifi and Csma models support
|
||||
this new mode of operation. (contributed by Gustavo Carneiro)
|
||||
|
||||
b) Python bindings
|
||||
It is now possible to write simulation scripts in python using our
|
||||
python bindings (contributed by Gustavo Carneiro).
|
||||
|
||||
c) Real-time simulator
|
||||
It is now possible to run simulations synchronized on the real-world
|
||||
wall-clock time (contributed by Craig Dowell).
|
||||
|
||||
d) Network Simulation Craddle
|
||||
It is now possible to use the Network Simulation Craddle
|
||||
(http://www.wand.net.nz/~stj2/nsc/) in ns-3 and run simulations
|
||||
using various versions of kernel TCP network stacks. (contributed
|
||||
by Florian Westphal as part of his Google Summer of Code work)
|
||||
|
||||
e) A statistics framework
|
||||
Joseph Kopena contributed a statistics framework which can be used
|
||||
keep track of simulation data in persistent storage across multiple
|
||||
runs (database and ascii file backends are available).
|
||||
More information on the wiki:
|
||||
http://www.nsnam.org/wiki/index.php/Statistical_Framework_for_Network_Simulation
|
||||
|
||||
Where to get more information about ns-3
|
||||
----------------------------------------
|
||||
|
||||
All the ns-3 documentation, is accessible from the ns-3 website:
|
||||
http://www.nsnam.org
|
||||
|
||||
Including, tutorials:
|
||||
http://www.nsnam.org/tutorials.html
|
||||
|
||||
Supported platforms
|
||||
-------------------
|
||||
|
||||
ns-3 is regularly tested on the following platforms:
|
||||
- linux x86 gcc 4.2, 4.1, and, 3.4.6.
|
||||
- linux x86_64 gcc 4.1.3, 4.2.1, 3.4.6
|
||||
- MacOS X ppc and x86
|
||||
- cygwin gcc 3.4.4 (debug only)
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
ns-3 is known to fail on the following platforms:
|
||||
- gcc 3.3 and earlier
|
||||
- optimized builds on gcc 3.4.4 and 3.4.5
|
||||
- optimized builds on linux x86 gcc 4.0.x
|
||||
- optimized builds on Ubuntu 8.10 alpha 5 x86 gcc4.3.2
|
||||
- MinGW
|
||||
|
||||
The IPv4 API defined in src/node/ipv4.h is expected to undergo major changes
|
||||
in preparation of the merge of the IPv6 API and implementation.
|
||||
|
||||
API changes for this release are documented in CHANGES.html
|
||||
|
||||
Future releases
|
||||
---------------
|
||||
|
||||
Our next release, which is expected to happen in 2 to 4 months from now, will
|
||||
feature the merging of some of our projects currently in development: IPv6,
|
||||
emulation, and synchronous posix sockets.
|
||||
|
||||
Release 3.1 (2008/06/30)
|
||||
========================
|
||||
|
||||
The first ns-3 stable release
|
||||
-----------------------------
|
||||
|
||||
This release is immediately available from:
|
||||
http://www.nsnam.org/releases/ns-3.1.tar.bz2
|
||||
|
||||
We dedicate this initial ns-3 release to our late contributor and friend,
|
||||
Federico Maguolo.
|
||||
|
||||
What is ns-3 ?
|
||||
--------------
|
||||
|
||||
ns-3 is a new discrete-event network simulator designed for supporting network
|
||||
research and education. ns-3 features a solid, well documented C++ core and
|
||||
models for TCP/IP (IPv4), several link types including WiFi, and mobility
|
||||
models.
|
||||
|
||||
ns-3 is an open source project released under the GNU GPLv2 license which
|
||||
allows anyone to use ns-3 without having to pay any license fee or royalties.
|
||||
ns-3 is actively seeking new contributors to extend the range of supported
|
||||
models and/or to maintain existing models.
|
||||
|
||||
Where to get more information about ns-3
|
||||
----------------------------------------
|
||||
|
||||
All the ns-3 documentation, is accessible from the ns-3 website:
|
||||
http://www.nsnam.org
|
||||
|
||||
Including, tutorials:
|
||||
http://www.nsnam.org/tutorials.html
|
||||
|
||||
Supported platforms
|
||||
-------------------
|
||||
|
||||
ns-3 is regularly tested on the following platforms:
|
||||
- linux x86 gcc 4.2, 4.1, and, 3.4.6.
|
||||
- linux x86_64 gcc 4.1.3, 4.2.1, 3.4.6
|
||||
- MacOS X ppc and x86
|
||||
- cygwin gcc 3.4.4 (debug only)
|
||||
|
||||
Known issues
|
||||
------------
|
||||
|
||||
ns-3 is known to fail on the following platforms:
|
||||
- gcc 3.3 and earlier
|
||||
- optimized builds on gcc 3.4.4 and 3.4.5
|
||||
- optimized builds on linux x86 gcc 4.0.x
|
||||
|
||||
The IPv4 API defined in src/node/ipv4.h is expected to undergo major changes
|
||||
in preparation of the merge of the IPv6 API and implementation.
|
||||
|
||||
Future releases
|
||||
---------------
|
||||
|
||||
Our next release, which is expected to happen in 2 to 4 months from now, will
|
||||
feature the merging of some of our projects currently in development: python
|
||||
scripting, IPv6, emulation, a statistics framework and synchronous posix
|
||||
sockets.
|
||||
|
||||
Release 3.0.13 (2008/06/02)
|
||||
===========================
|
||||
- point to point links generate ppp pcap traces
|
||||
- point to point links support asymmetrical data rates.
|
||||
- generate doxygen documentation for all attributes and trace sources
|
||||
- add ConfigStore and GtkConfigStore to contrib module
|
||||
- socket API now support tx and rx buffers: implemented for UDP and TCP
|
||||
- ARP cache now supports per-entry pending queues
|
||||
- lots of bugfixes and implementation and API cleanups
|
||||
|
||||
Warning: among API changes in this release, Application::Start and
|
||||
Application::Stop now interprets the time argument as a relative
|
||||
instead of absolute simulation time, to align with how Simulator::Schedule
|
||||
behaves. Any code that calls these APIs in the middle of the simulation
|
||||
will need to be adapted.
|
||||
|
||||
The API of Simulator::StopAt (time) has also changed. Now it is
|
||||
called Simulator::Stop (time), and takes a relative time, instead of
|
||||
absolute.
|
||||
|
||||
Release 3.0.12 (2008/04/07)
|
||||
===========================
|
||||
- Add Attribute support to the TypeId metadata system and add
|
||||
attribute support to all in-tree models
|
||||
- Add a mid-level helper API to build simulation topologies
|
||||
and perform simple ascii and pcap link-level tracing.
|
||||
- Large amount of structural changes to accomodate the needs
|
||||
of the upcoming python bindings
|
||||
- new rate control algorithm (RRAA) and a jakes propagation model
|
||||
in the 802.11 model (Federico Maguolo).
|
||||
- regression test framework added
|
||||
- TCP delayed acknowledgements and multitasking server
|
||||
|
||||
Release 3.0.11 (2008/02/15)
|
||||
===========================
|
||||
- Initial port of GTNetS TCP implementation (initial version
|
||||
that does not support multitasking or delayed acknowledgments yet,
|
||||
but supports a reliable stream service)
|
||||
- Changes to the ns-3 object model to create a TypeId-based
|
||||
metadata system
|
||||
- lots of bug fixes throughout the system
|
||||
- tutorial updates
|
||||
|
||||
Release 3.0.10 (2008/01/15)
|
||||
===========================
|
||||
- Add tutorial document content;
|
||||
- Valgrind option for "waf" tool;
|
||||
- Doxygen organization changes.
|
||||
|
||||
Release 3.0.9 (2007/12/15)
|
||||
==========================
|
||||
- A 802.11 model ported from Yans. This model supports:
|
||||
* a rather extensive PHY model
|
||||
* log-distance and friis propagation model
|
||||
* a simple set of rate control algorithms (ARF, Ideal,
|
||||
AARF, constant-rate)
|
||||
* adhoc and infrastructure mode (beacon+assoc)
|
||||
- Use smart pointer for Packet in the APIs
|
||||
- A new contrib directory with helper classes:
|
||||
EventGarbageCollector, Gnuplot
|
||||
- Tracing support for Applications
|
||||
- many bugs fixed
|
||||
|
||||
Release 3.0.8 (2007/11/15)
|
||||
==========================
|
||||
- A simple error model
|
||||
- Source files for ns-3 tutorial
|
||||
|
||||
Release 3.0.7 (2007/10/15)
|
||||
==========================
|
||||
- OLSR routing protocol
|
||||
- A timer class
|
||||
- Additional mobility models (random waypoint, random 2D walk)
|
||||
- A mobility visualization tool
|
||||
|
||||
Release 3.0.6 (2007/09/15)
|
||||
==========================
|
||||
- Static multicast IPv4 routing
|
||||
- Logging overhaul (NS_LOG macros)
|
||||
- Refactoring of tracing subsystem
|
||||
- Tutorial document started
|
||||
|
||||
Release 3.0.5 (2007/08/15)
|
||||
==========================
|
||||
|
||||
- Refactoring to support win32-based unix environments (Cygwin, mingw)
|
||||
- "Packet socket" for allowing applications to access NetDevices directly
|
||||
- Generalized, polymorphic Address class
|
||||
- Add CSMA NetDevice model (from Emmanuelle Laprise)
|
||||
- Modularize IPv4 routing support (from Gustavo Carneiro)
|
||||
- Add mobility framework and basic mobility models
|
||||
- Global unicast centralized routing
|
||||
|
||||
Release 3.0.4 (2007/07/15)
|
||||
==========================
|
||||
|
||||
- Enable waf as the default build system.
|
||||
- Per-packet metadata: a system to track which headers and trailers
|
||||
are added to a packet
|
||||
- Simplifications to point-to-point devices and channel
|
||||
|
||||
Release 3.0.3 (2007/06/15)
|
||||
==========================
|
||||
|
||||
- Enable Waf for release tarballs: users can now build ns-3
|
||||
with the "waf" tool. See doc/build-waf.txt.
|
||||
- Add support for variable time precision: it is now possible
|
||||
to run a simulation with an accuracy which is higher or lower
|
||||
than a nanosecond: seconds, milliseconds, microseconds,
|
||||
femtoseconds and picoseconds are supported.
|
||||
- Optimize and rework the COM framework, solidify the component
|
||||
manager
|
||||
- Many small API cleanups
|
||||
|
||||
Release 3.0.2 (2007/05/18)
|
||||
==========================
|
||||
|
||||
- Implement a new memory management infrastructure based
|
||||
on reference counting and smart pointers (the latter being
|
||||
optional)
|
||||
@@ -16,7 +282,7 @@ Release 3.0.2 (2007/05/18)
|
||||
- Add support for a BSD-style socket API for user applications
|
||||
|
||||
Release 3.0.1 (2007/03/31)
|
||||
========================
|
||||
==========================
|
||||
|
||||
- First public release; not yet pre-alpha.
|
||||
|
||||
|
||||
-435
@@ -1,435 +0,0 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
import os.path
|
||||
import build
|
||||
|
||||
version_file = open ('VERSION', 'r')
|
||||
version = version_file.readline ()
|
||||
version_file.close ()
|
||||
version = version.strip ()
|
||||
|
||||
ns3 = build.Ns3()
|
||||
ns3.build_dir = 'build-dir'
|
||||
ns3.version = version
|
||||
ns3.name = 'ns3'
|
||||
ns3.distname = 'ns'
|
||||
ns3.doxygen_config = os.path.join('doc', 'doxygen.conf')
|
||||
ns3.add_extra_dist(os.path.join('doc', 'main.txt'))
|
||||
ns3.add_extra_dist ('doc/architecture.pdf')
|
||||
ns3.add_extra_dist ('doc/contributing.txt')
|
||||
ns3.add_extra_dist ('doc/build.txt')
|
||||
ns3.add_extra_dist ('doc/codingstd.txt')
|
||||
ns3.add_extra_dist ('doc/mercurial.txt')
|
||||
ns3.add_extra_dist ('README')
|
||||
ns3.add_extra_dist ('RELEASE_NOTES')
|
||||
ns3.add_extra_dist ('AUTHORS')
|
||||
ns3.add_extra_dist ('VERSION')
|
||||
|
||||
|
||||
#
|
||||
# The Core module
|
||||
#
|
||||
core = build.Ns3Module('core', 'src/core')
|
||||
ns3.add(core)
|
||||
core.add_sources([
|
||||
'reference-list-test.cc',
|
||||
'callback-test.cc',
|
||||
'debug.cc',
|
||||
'assert.cc',
|
||||
'ptr.cc',
|
||||
'object.cc',
|
||||
'test.cc',
|
||||
'random-variable.cc',
|
||||
'rng-stream.cc',
|
||||
'interface.cc',
|
||||
'uid-manager.cc',
|
||||
'default-value.cc',
|
||||
'command-line.cc',
|
||||
'type-name.cc',
|
||||
'component-manager.cc',
|
||||
])
|
||||
env = Environment()
|
||||
if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] == 'cygwin':
|
||||
core.add_external_dep('pthread')
|
||||
core.add_sources([
|
||||
'unix-system-wall-clock-ms.cc',
|
||||
])
|
||||
elif env['PLATFORM'] == 'win32':
|
||||
core.add_sources([
|
||||
'win32-system-wall-clock-ms.cc',
|
||||
])
|
||||
core.add_headers ([
|
||||
'uid-manager.h',
|
||||
'singleton.h',
|
||||
])
|
||||
core.add_inst_headers([
|
||||
'system-wall-clock-ms.h',
|
||||
'reference-list.h',
|
||||
'callback.h',
|
||||
'ptr.h',
|
||||
'object.h',
|
||||
'debug.h',
|
||||
'assert.h',
|
||||
'fatal-error.h',
|
||||
'test.h',
|
||||
'random-variable.h',
|
||||
'rng-stream.h',
|
||||
'interface.h',
|
||||
'default-value.h',
|
||||
'command-line.h',
|
||||
'type-name.h',
|
||||
'component-manager.h',
|
||||
])
|
||||
|
||||
def config_core (env, config):
|
||||
retval = []
|
||||
# XXX This check is primitive but it should be
|
||||
# good enough for now.
|
||||
if config.CheckCHeader ('stdlib.h') == 1:
|
||||
retval.append ('#define HAVE_STDLIB_H 1')
|
||||
retval.append ('#define HAVE_GETENV 1')
|
||||
else:
|
||||
retval.append ('#undef HAVE_STDLIB_H')
|
||||
retval.append ('#undef HAVE_GETENV')
|
||||
return retval
|
||||
core.add_config (config_core)
|
||||
|
||||
#
|
||||
# The Simu module
|
||||
#
|
||||
simu = build.Ns3Module('simulator', 'src/simulator')
|
||||
ns3.add(simu)
|
||||
simu.add_dep('core')
|
||||
simu.add_external_dep('m')
|
||||
simu.add_sources([
|
||||
'high-precision.cc',
|
||||
'time.cc',
|
||||
'event-id.cc',
|
||||
'scheduler.cc',
|
||||
'scheduler-factory.cc',
|
||||
'scheduler-list.cc',
|
||||
'scheduler-heap.cc',
|
||||
'scheduler-map.cc',
|
||||
'event-impl.cc',
|
||||
'simulator.cc',
|
||||
])
|
||||
simu.add_headers([
|
||||
'scheduler-heap.h',
|
||||
'scheduler-map.h',
|
||||
'scheduler-list.h'
|
||||
])
|
||||
simu.add_inst_headers([
|
||||
'high-precision.h',
|
||||
'nstime.h',
|
||||
'event-id.h',
|
||||
'event-impl.h',
|
||||
'simulator.h',
|
||||
'scheduler.h',
|
||||
'scheduler-factory.h',
|
||||
'simulation-singleton.h',
|
||||
])
|
||||
high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n')
|
||||
if high_precision_as_double == 'y':
|
||||
simu.add_inst_header ('high-precision-double.h')
|
||||
simu.add_source ('high-precision-double.cc')
|
||||
else:
|
||||
simu.add_inst_headers ([
|
||||
'high-precision-128.h',
|
||||
'cairo-wideint-private.h'
|
||||
])
|
||||
simu.add_sources ([
|
||||
'high-precision-128.cc',
|
||||
'cairo-wideint.c',
|
||||
])
|
||||
|
||||
def config_simulator (env, config):
|
||||
retval = []
|
||||
high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n')
|
||||
if high_precision_as_double == 'y':
|
||||
retval.append ('#define USE_HIGH_PRECISION_DOUBLE 1')
|
||||
else:
|
||||
retval.append ('#undef USE_HIGH_PRECISION_DOUBLE')
|
||||
if config.CheckCHeader ('stdint.h') == 1:
|
||||
retval.append ('#define HAVE_STDINT_H 1')
|
||||
elif config.CheckCHeader ('inttypes.h') == 1:
|
||||
retval.append ('#define HAVE_INTTYPES_H 1')
|
||||
elif config.CheckCHeader ('sys/inttypes.h') == 1:
|
||||
retval.append ('#define HAVE_SYS_INT_TYPES_H 1')
|
||||
return retval
|
||||
simu.add_config (config_simulator)
|
||||
|
||||
|
||||
#
|
||||
# The Common module
|
||||
#
|
||||
common = build.Ns3Module('common', 'src/common')
|
||||
common.add_deps(['core', 'simulator'])
|
||||
ns3.add(common)
|
||||
common.add_sources([
|
||||
'buffer.cc',
|
||||
'chunk.cc',
|
||||
'header.cc',
|
||||
'trailer.cc',
|
||||
'packet.cc',
|
||||
'tags.cc',
|
||||
'pcap-writer.cc',
|
||||
'variable-tracer-test.cc',
|
||||
'trace-context.cc',
|
||||
'trace-resolver.cc',
|
||||
'callback-trace-source.cc',
|
||||
'empty-trace-resolver.cc',
|
||||
'composite-trace-resolver.cc',
|
||||
'trace-root.cc',
|
||||
'data-rate.cc',
|
||||
])
|
||||
common.add_headers ([
|
||||
])
|
||||
common.add_inst_headers([
|
||||
'buffer.h',
|
||||
'chunk.h',
|
||||
'header.h',
|
||||
'trailer.h',
|
||||
'tags.h',
|
||||
'packet.h',
|
||||
'uv-trace-source.h',
|
||||
'sv-trace-source.h',
|
||||
'fv-trace-source.h',
|
||||
'pcap-writer.h',
|
||||
'callback-trace-source.h',
|
||||
'trace-context.h',
|
||||
'trace-resolver.h',
|
||||
'empty-trace-resolver.h',
|
||||
'composite-trace-resolver.h',
|
||||
'array-trace-resolver.h',
|
||||
'trace-root.h',
|
||||
'terminal-trace-resolver.h',
|
||||
'data-rate.h',
|
||||
])
|
||||
|
||||
node = build.Ns3Module ('node', 'src/node')
|
||||
ns3.add (node)
|
||||
node.add_deps (['core', 'common', 'simulator'])
|
||||
node.add_sources ([
|
||||
'i-node.cc',
|
||||
'ipv4-address.cc',
|
||||
'net-device.cc',
|
||||
'mac-address.cc',
|
||||
'llc-snap-header.cc',
|
||||
'ipv4-route.cc',
|
||||
'queue.cc',
|
||||
'drop-tail.cc',
|
||||
'channel.cc',
|
||||
'node-list.cc',
|
||||
'socket.cc',
|
||||
'i-socket-factory.cc',
|
||||
'i-udp.cc',
|
||||
'i-ipv4.cc',
|
||||
'application.cc',
|
||||
])
|
||||
node.add_inst_headers ([
|
||||
'i-node.h',
|
||||
'ipv4-address.h',
|
||||
'net-device.h',
|
||||
'mac-address.h',
|
||||
'ipv4-route.h',
|
||||
'queue.h',
|
||||
'drop-tail.h',
|
||||
'llc-snap-header.h',
|
||||
'channel.h',
|
||||
'node-list.h',
|
||||
'socket.h',
|
||||
'i-socket-factory.h',
|
||||
'i-udp.h',
|
||||
'i-ipv4.h',
|
||||
'application.h',
|
||||
])
|
||||
|
||||
applications = build.Ns3Module ('applications', 'src/applications')
|
||||
ns3.add (applications)
|
||||
applications.add_deps (['node'])
|
||||
applications.add_sources ([
|
||||
'onoff-application.cc',
|
||||
])
|
||||
applications.add_inst_headers ([
|
||||
'onoff-application.h',
|
||||
])
|
||||
|
||||
inode = build.Ns3Module ('internet-node', 'src/internet-node')
|
||||
ns3.add (inode)
|
||||
inode.add_deps (['node'])
|
||||
inode.add_sources ([
|
||||
'internet-node.cc',
|
||||
'i-node-impl.cc',
|
||||
'l3-demux.cc',
|
||||
'l3-protocol.cc',
|
||||
'ipv4-l4-demux.cc',
|
||||
'ipv4-l4-protocol.cc',
|
||||
'ipv4-header.cc',
|
||||
'udp-header.cc',
|
||||
'ipv4-checksum.cc',
|
||||
'ipv4-interface.cc',
|
||||
'ipv4.cc',
|
||||
'ipv4-end-point.cc',
|
||||
'udp.cc',
|
||||
'arp-header.cc',
|
||||
'arp-cache.cc',
|
||||
'arp-ipv4-interface.cc',
|
||||
'arp.cc',
|
||||
'ipv4-loopback-interface.cc',
|
||||
'header-utils.cc',
|
||||
'udp-socket.cc',
|
||||
'ipv4-end-point-demux.cc',
|
||||
'i-arp-private.cc',
|
||||
'i-ipv4-impl.cc',
|
||||
'i-ipv4-private.cc',
|
||||
'ascii-trace.cc',
|
||||
'pcap-trace.cc',
|
||||
'i-udp-impl.cc',
|
||||
])
|
||||
inode.add_headers ([
|
||||
'ipv4-header.h',
|
||||
'udp-header.h',
|
||||
'ipv4-checksum.h',
|
||||
'arp-header.h',
|
||||
'arp-cache.h',
|
||||
'arp.h',
|
||||
'ipv4-loopback-interface.h',
|
||||
'l3-demux.h',
|
||||
'header-utils.h',
|
||||
'arp-ipv4-interface.h',
|
||||
'udp-socket.h',
|
||||
'udp.h',
|
||||
'i-arp-private.h',
|
||||
'i-ipv4-impl.h',
|
||||
'i-ipv4-private.h',
|
||||
'ipv4.h',
|
||||
'l3-protocol.h',
|
||||
'ipv4-l4-protocol.h',
|
||||
'ipv4-l4-demux.h',
|
||||
'ipv4-end-point-demux.h',
|
||||
'ipv4-end-point.h',
|
||||
'ipv4-header.h',
|
||||
'udp-header.h',
|
||||
'ipv4-interface.h',
|
||||
'sgi-hashmap.h',
|
||||
'i-node-impl.h',
|
||||
'i-udp-impl.h',
|
||||
])
|
||||
inode.add_inst_headers ([
|
||||
'internet-node.h',
|
||||
'ascii-trace.h',
|
||||
'pcap-trace.h',
|
||||
])
|
||||
|
||||
|
||||
|
||||
p2p = build.Ns3Module ('p2p', 'src/devices/p2p')
|
||||
ns3.add (p2p)
|
||||
p2p.add_deps (['node'])
|
||||
p2p.add_sources ([
|
||||
'p2p-net-device.cc',
|
||||
'p2p-channel.cc',
|
||||
'p2p-topology.cc',
|
||||
])
|
||||
p2p.add_inst_headers ([
|
||||
'p2p-net-device.h',
|
||||
'p2p-channel.h',
|
||||
'p2p-topology.h',
|
||||
])
|
||||
|
||||
|
||||
# utils
|
||||
run_tests = build.Ns3Module('run-tests', 'utils')
|
||||
ns3.add(run_tests)
|
||||
run_tests.set_executable()
|
||||
run_tests.add_deps(['core', 'simulator', 'common'])
|
||||
run_tests.add_source('run-tests.cc')
|
||||
|
||||
bench_packets = build.Ns3Module('bench-packets', 'utils')
|
||||
#ns3.add(bench_packets)
|
||||
bench_packets.set_executable()
|
||||
bench_packets.add_dep('core')
|
||||
bench_packets.add_source('bench-packets.cc')
|
||||
|
||||
bench_simu = build.Ns3Module('bench-simulator', 'utils')
|
||||
ns3.add(bench_simu)
|
||||
bench_simu.set_executable()
|
||||
bench_simu.add_dep('simulator')
|
||||
bench_simu.add_source('bench-simulator.cc')
|
||||
|
||||
replay_simu = build.Ns3Module('replay-simulation', 'utils')
|
||||
ns3.add(replay_simu)
|
||||
replay_simu.set_executable()
|
||||
replay_simu.add_dep('simulator')
|
||||
replay_simu.add_source('replay-simulation.cc')
|
||||
|
||||
|
||||
# samples
|
||||
sample_debug = build.Ns3Module('sample-debug', 'samples')
|
||||
sample_debug.set_executable()
|
||||
ns3.add(sample_debug)
|
||||
sample_debug.add_dep('core')
|
||||
sample_debug.add_source('main-debug.cc')
|
||||
sample_debug.add_source('main-debug-other.cc')
|
||||
|
||||
sample_callback = build.Ns3Module('sample-callback', 'samples')
|
||||
sample_callback.set_executable()
|
||||
ns3.add(sample_callback)
|
||||
sample_callback.add_dep('core')
|
||||
sample_callback.add_source('main-callback.cc')
|
||||
|
||||
sample_ptr = build.Ns3Module('sample-ptr', 'samples')
|
||||
sample_ptr.set_executable()
|
||||
ns3.add(sample_ptr)
|
||||
sample_ptr.add_dep('core')
|
||||
sample_ptr.add_source('main-ptr.cc')
|
||||
|
||||
sample_trace = build.Ns3Module('sample-trace', 'samples')
|
||||
#ns3.add(sample_trace)
|
||||
sample_trace.add_dep('common')
|
||||
sample_trace.set_executable()
|
||||
sample_trace.add_source('main-trace.cc')
|
||||
|
||||
sample_simu = build.Ns3Module('sample-simulator', 'samples')
|
||||
ns3.add(sample_simu)
|
||||
sample_simu.set_executable()
|
||||
sample_simu.add_dep('simulator')
|
||||
sample_simu.add_source('main-simulator.cc')
|
||||
|
||||
sample_packet = build.Ns3Module('sample-packet', 'samples')
|
||||
ns3.add(sample_packet)
|
||||
sample_packet.set_executable()
|
||||
sample_packet.add_dep('common')
|
||||
sample_packet.add_source('main-packet.cc')
|
||||
|
||||
sample_test = build.Ns3Module('sample-test', 'samples')
|
||||
sample_test.set_executable()
|
||||
ns3.add(sample_test)
|
||||
sample_test.add_dep('core')
|
||||
sample_test.add_source('main-test.cc')
|
||||
|
||||
sample_simple = build.Ns3Module('sample-simple', 'samples')
|
||||
sample_simple.set_executable()
|
||||
ns3.add(sample_simple)
|
||||
sample_simple.add_deps(['core', 'simulator', 'node', 'internet-node'])
|
||||
sample_simple.add_source('main-simple.cc')
|
||||
|
||||
sample_sp2p = build.Ns3Module('sample-simple-p2p', 'samples')
|
||||
sample_sp2p.set_executable()
|
||||
#n3.add(sample_sp2p)
|
||||
sample_sp2p.add_deps(['core', 'simulator', 'node', 'internet-node', 'p2p'])
|
||||
sample_sp2p.add_source('main-simple-p2p.cc')
|
||||
|
||||
sample_default_value = build.Ns3Module('sample-default-value', 'samples')
|
||||
sample_default_value.set_executable()
|
||||
ns3.add(sample_default_value)
|
||||
sample_default_value.add_deps(['core', 'simulator', 'node', 'p2p'])
|
||||
sample_default_value.add_source('main-default-value.cc')
|
||||
|
||||
# examples
|
||||
example_simple_p2p = build.Ns3Module('simple-p2p', 'examples')
|
||||
example_simple_p2p.set_executable()
|
||||
ns3.add(example_simple_p2p)
|
||||
example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications'])
|
||||
example_simple_p2p.add_source('simple-p2p.cc')
|
||||
|
||||
ns3.generate_dependencies()
|
||||
@@ -0,0 +1,13 @@
|
||||
callback_classes = [
|
||||
['void', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
|
||||
['void', 'ns3::Ptr<ns3::Socket>', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
|
||||
['void', 'ns3::Ptr<ns3::Socket>', 'unsigned int', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
|
||||
['void', 'ns3::Ptr<ns3::Socket>', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
|
||||
['bool', 'ns3::Ptr<ns3::Socket>', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
|
||||
['void', 'ns3::Ptr<ns3::Packet>', 'ns3::Mac48Address', 'ns3::Mac48Address', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
|
||||
['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'],
|
||||
['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty'],
|
||||
['void', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'],
|
||||
['void', 'ns3::Ptr<ns3::Packet>', 'double', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
|
||||
['void', 'ns3::Ptr<ns3::Packet>', 'double', 'ns3::WifiMode', 'ns3::WifiPreamble', 'ns3::empty', 'ns3::empty'],
|
||||
]
|
||||
@@ -0,0 +1,13 @@
|
||||
from pybindgen import Module, FileCodeSink, write_preamble, param, retval
|
||||
|
||||
def register_types(module):
|
||||
module.add_class('MyClass')
|
||||
|
||||
def register_methods(root_module):
|
||||
MyClass = root_module['MyClass']
|
||||
MyClass.add_constructor([], visibility='public')
|
||||
MyClass.add_constructor([param('double', 's'), param('double', 'l'), param('double', 'mean')], visibility='public')
|
||||
|
||||
def register_functions(module):
|
||||
module.add_function('SomeFunction', 'int', [param('int', 'xpto')])
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
from _ns3 import *
|
||||
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## bridge-net-device.h: ns3::BridgeNetDevice [class]
|
||||
module.add_class('BridgeNetDevice', parent=root_module['ns3::NetDevice'])
|
||||
## bridge-channel.h: ns3::BridgeChannel [class]
|
||||
module.add_class('BridgeChannel', parent=root_module['ns3::Channel'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3BridgeNetDevice_methods(root_module, root_module['ns3::BridgeNetDevice'])
|
||||
register_Ns3BridgeChannel_methods(root_module, root_module['ns3::BridgeChannel'])
|
||||
return
|
||||
|
||||
def register_Ns3BridgeNetDevice_methods(root_module, cls):
|
||||
## bridge-net-device.h: ns3::BridgeNetDevice::BridgeNetDevice(ns3::BridgeNetDevice const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::BridgeNetDevice const &', 'arg0')])
|
||||
## bridge-net-device.h: static ns3::TypeId ns3::BridgeNetDevice::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## bridge-net-device.h: ns3::BridgeNetDevice::BridgeNetDevice() [constructor]
|
||||
cls.add_constructor([])
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::AddBridgePort(ns3::Ptr<ns3::NetDevice> bridgePort) [member function]
|
||||
cls.add_method('AddBridgePort',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::NetDevice >', 'bridgePort')])
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::SetName(std::string const name) [member function]
|
||||
cls.add_method('SetName',
|
||||
'void',
|
||||
[param('std::string const', 'name')],
|
||||
is_virtual=True)
|
||||
## bridge-net-device.h: std::string ns3::BridgeNetDevice::GetName() const [member function]
|
||||
cls.add_method('GetName',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::SetIfIndex(uint32_t const index) [member function]
|
||||
cls.add_method('SetIfIndex',
|
||||
'void',
|
||||
[param('uint32_t const', 'index')],
|
||||
is_virtual=True)
|
||||
## bridge-net-device.h: uint32_t ns3::BridgeNetDevice::GetIfIndex() const [member function]
|
||||
cls.add_method('GetIfIndex',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: ns3::Ptr<ns3::Channel> ns3::BridgeNetDevice::GetChannel() const [member function]
|
||||
cls.add_method('GetChannel',
|
||||
'ns3::Ptr< ns3::Channel >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::GetAddress() const [member function]
|
||||
cls.add_method('GetAddress',
|
||||
'ns3::Address',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: bool ns3::BridgeNetDevice::SetMtu(uint16_t const mtu) [member function]
|
||||
cls.add_method('SetMtu',
|
||||
'bool',
|
||||
[param('uint16_t const', 'mtu')],
|
||||
is_virtual=True)
|
||||
## bridge-net-device.h: uint16_t ns3::BridgeNetDevice::GetMtu() const [member function]
|
||||
cls.add_method('GetMtu',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: bool ns3::BridgeNetDevice::IsLinkUp() const [member function]
|
||||
cls.add_method('IsLinkUp',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::SetLinkChangeCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
|
||||
cls.add_method('SetLinkChangeCallback',
|
||||
'void',
|
||||
[param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')],
|
||||
is_virtual=True)
|
||||
## bridge-net-device.h: bool ns3::BridgeNetDevice::IsBroadcast() const [member function]
|
||||
cls.add_method('IsBroadcast',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::GetBroadcast() const [member function]
|
||||
cls.add_method('GetBroadcast',
|
||||
'ns3::Address',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: bool ns3::BridgeNetDevice::IsMulticast() const [member function]
|
||||
cls.add_method('IsMulticast',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::GetMulticast() const [member function]
|
||||
cls.add_method('GetMulticast',
|
||||
'ns3::Address',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: ns3::Address ns3::BridgeNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function]
|
||||
cls.add_method('MakeMulticastAddress',
|
||||
'ns3::Address',
|
||||
[param('ns3::Ipv4Address', 'multicastGroup')],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: bool ns3::BridgeNetDevice::IsPointToPoint() const [member function]
|
||||
cls.add_method('IsPointToPoint',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: bool ns3::BridgeNetDevice::Send(ns3::Ptr<ns3::Packet> packet, ns3::Address const & dest, uint16_t protocolNumber) [member function]
|
||||
cls.add_method('Send',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address const &', 'dest'), param('uint16_t', 'protocolNumber')],
|
||||
is_virtual=True)
|
||||
## bridge-net-device.h: bool ns3::BridgeNetDevice::SendFrom(ns3::Ptr<ns3::Packet> packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function]
|
||||
cls.add_method('SendFrom',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address const &', 'source'), param('ns3::Address const &', 'dest'), param('uint16_t', 'protocolNumber')],
|
||||
is_virtual=True)
|
||||
## bridge-net-device.h: ns3::Ptr<ns3::Node> ns3::BridgeNetDevice::GetNode() const [member function]
|
||||
cls.add_method('GetNode',
|
||||
'ns3::Ptr< ns3::Node >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::SetNode(ns3::Ptr<ns3::Node> node) [member function]
|
||||
cls.add_method('SetNode',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node')],
|
||||
is_virtual=True)
|
||||
## bridge-net-device.h: bool ns3::BridgeNetDevice::NeedsArp() const [member function]
|
||||
cls.add_method('NeedsArp',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet const>, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function]
|
||||
cls.add_method('SetReceiveCallback',
|
||||
'void',
|
||||
[param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet const >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')],
|
||||
is_virtual=True)
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::SetPromiscReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet const>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
|
||||
cls.add_method('SetPromiscReceiveCallback',
|
||||
'void',
|
||||
[param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet const >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')],
|
||||
is_virtual=True)
|
||||
## bridge-net-device.h: bool ns3::BridgeNetDevice::SupportsSendFrom() const [member function]
|
||||
cls.add_method('SupportsSendFrom',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::ReceiveFromDevice(ns3::Ptr<ns3::NetDevice> device, ns3::Ptr<const ns3::Packet> packet, uint16_t protocol, ns3::Address const & source, ns3::Address const & destination, ns3::NetDevice::PacketType packetType) [member function]
|
||||
cls.add_method('ReceiveFromDevice',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Address const &', 'source'), param('ns3::Address const &', 'destination'), param('ns3::NetDevice::PacketType', 'packetType')],
|
||||
visibility='protected')
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardUnicast(ns3::Ptr<ns3::NetDevice> incomingPort, ns3::Ptr<const ns3::Packet> packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function]
|
||||
cls.add_method('ForwardUnicast',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')],
|
||||
visibility='protected')
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::ForwardBroadcast(ns3::Ptr<ns3::NetDevice> incomingPort, ns3::Ptr<const ns3::Packet> packet, uint16_t protocol, ns3::Mac48Address src, ns3::Mac48Address dst) [member function]
|
||||
cls.add_method('ForwardBroadcast',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::NetDevice >', 'incomingPort'), param('ns3::Ptr< const ns3::Packet >', 'packet'), param('uint16_t', 'protocol'), param('ns3::Mac48Address', 'src'), param('ns3::Mac48Address', 'dst')],
|
||||
visibility='protected')
|
||||
## bridge-net-device.h: void ns3::BridgeNetDevice::Learn(ns3::Mac48Address source, ns3::Ptr<ns3::NetDevice> port) [member function]
|
||||
cls.add_method('Learn',
|
||||
'void',
|
||||
[param('ns3::Mac48Address', 'source'), param('ns3::Ptr< ns3::NetDevice >', 'port')],
|
||||
visibility='protected')
|
||||
## bridge-net-device.h: ns3::Ptr<ns3::NetDevice> ns3::BridgeNetDevice::GetLearnedState(ns3::Mac48Address source) [member function]
|
||||
cls.add_method('GetLearnedState',
|
||||
'ns3::Ptr< ns3::NetDevice >',
|
||||
[param('ns3::Mac48Address', 'source')],
|
||||
visibility='protected')
|
||||
return
|
||||
|
||||
def register_Ns3BridgeChannel_methods(root_module, cls):
|
||||
## bridge-channel.h: ns3::BridgeChannel::BridgeChannel(ns3::BridgeChannel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::BridgeChannel const &', 'arg0')])
|
||||
## bridge-channel.h: static ns3::TypeId ns3::BridgeChannel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## bridge-channel.h: ns3::BridgeChannel::BridgeChannel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## bridge-channel.h: void ns3::BridgeChannel::AddChannel(ns3::Ptr<ns3::Channel> bridgedChannel) [member function]
|
||||
cls.add_method('AddChannel',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Channel >', 'bridgedChannel')])
|
||||
## bridge-channel.h: uint32_t ns3::BridgeChannel::GetNDevices() const [member function]
|
||||
cls.add_method('GetNDevices',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## bridge-channel.h: ns3::Ptr<ns3::NetDevice> ns3::BridgeChannel::GetDevice(uint32_t i) const [member function]
|
||||
cls.add_method('GetDevice',
|
||||
'ns3::Ptr< ns3::NetDevice >',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True, is_virtual=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,204 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## gnuplot.h: ns3::Gnuplot [class]
|
||||
module.add_class('Gnuplot')
|
||||
## event-garbage-collector.h: ns3::EventGarbageCollector [class]
|
||||
module.add_class('EventGarbageCollector')
|
||||
## gtk-config-store.h: ns3::GtkConfigStore [class]
|
||||
module.add_class('GtkConfigStore')
|
||||
## gnuplot.h: ns3::GnuplotDataset [class]
|
||||
module.add_class('GnuplotDataset')
|
||||
## gnuplot.h: ns3::GnuplotDataset::Style [enumeration]
|
||||
module.add_enum('Style', ['LINES', 'POINTS', 'LINES_POINTS', 'DOTS', 'IMPULSES', 'STEPS', 'FSTEPS', 'HISTEPS'], outer_class=root_module['ns3::GnuplotDataset'])
|
||||
## gnuplot.h: ns3::GnuplotDataset::ErrorBars [enumeration]
|
||||
module.add_enum('ErrorBars', ['NONE', 'X', 'Y', 'XY'], outer_class=root_module['ns3::GnuplotDataset'])
|
||||
## config-store.h: ns3::ConfigStore [class]
|
||||
module.add_class('ConfigStore', parent=root_module['ns3::ObjectBase'])
|
||||
## delay-jitter-estimation.h: ns3::DelayJitterEstimation [class]
|
||||
module.add_class('DelayJitterEstimation')
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3Gnuplot_methods(root_module, root_module['ns3::Gnuplot'])
|
||||
register_Ns3EventGarbageCollector_methods(root_module, root_module['ns3::EventGarbageCollector'])
|
||||
register_Ns3GtkConfigStore_methods(root_module, root_module['ns3::GtkConfigStore'])
|
||||
register_Ns3GnuplotDataset_methods(root_module, root_module['ns3::GnuplotDataset'])
|
||||
register_Ns3ConfigStore_methods(root_module, root_module['ns3::ConfigStore'])
|
||||
register_Ns3DelayJitterEstimation_methods(root_module, root_module['ns3::DelayJitterEstimation'])
|
||||
return
|
||||
|
||||
def register_Ns3Gnuplot_methods(root_module, cls):
|
||||
## gnuplot.h: ns3::Gnuplot::Gnuplot(ns3::Gnuplot const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::Gnuplot const &', 'arg0')])
|
||||
## gnuplot.h: ns3::Gnuplot::Gnuplot(std::string pngFilename) [constructor]
|
||||
cls.add_constructor([param('std::string', 'pngFilename')])
|
||||
## gnuplot.h: void ns3::Gnuplot::SetLegend(std::string xLegend, std::string yLegend) [member function]
|
||||
cls.add_method('SetLegend',
|
||||
'void',
|
||||
[param('std::string', 'xLegend'), param('std::string', 'yLegend')])
|
||||
## gnuplot.h: void ns3::Gnuplot::AddDataset(ns3::GnuplotDataset const & dataset) [member function]
|
||||
cls.add_method('AddDataset',
|
||||
'void',
|
||||
[param('ns3::GnuplotDataset const &', 'dataset')])
|
||||
## gnuplot.h: void ns3::Gnuplot::GenerateOutput(std::ostream & os) [member function]
|
||||
cls.add_method('GenerateOutput',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')])
|
||||
return
|
||||
|
||||
def register_Ns3EventGarbageCollector_methods(root_module, cls):
|
||||
## event-garbage-collector.h: ns3::EventGarbageCollector::EventGarbageCollector(ns3::EventGarbageCollector const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::EventGarbageCollector const &', 'arg0')])
|
||||
## event-garbage-collector.h: ns3::EventGarbageCollector::EventGarbageCollector() [constructor]
|
||||
cls.add_constructor([])
|
||||
## event-garbage-collector.h: void ns3::EventGarbageCollector::Track(ns3::EventId event) [member function]
|
||||
cls.add_method('Track',
|
||||
'void',
|
||||
[param('ns3::EventId', 'event')])
|
||||
return
|
||||
|
||||
def register_Ns3GtkConfigStore_methods(root_module, cls):
|
||||
## gtk-config-store.h: ns3::GtkConfigStore::GtkConfigStore(ns3::GtkConfigStore const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::GtkConfigStore const &', 'arg0')])
|
||||
## gtk-config-store.h: ns3::GtkConfigStore::GtkConfigStore() [constructor]
|
||||
cls.add_constructor([])
|
||||
## gtk-config-store.h: void ns3::GtkConfigStore::Configure() [member function]
|
||||
cls.add_method('Configure',
|
||||
'void',
|
||||
[])
|
||||
return
|
||||
|
||||
def register_Ns3GnuplotDataset_methods(root_module, cls):
|
||||
## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset(ns3::GnuplotDataset const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::GnuplotDataset const &', 'arg0')])
|
||||
## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset() [constructor]
|
||||
cls.add_constructor([])
|
||||
## gnuplot.h: ns3::GnuplotDataset::GnuplotDataset(std::string title) [constructor]
|
||||
cls.add_constructor([param('std::string', 'title')])
|
||||
## gnuplot.h: void ns3::GnuplotDataset::SetStyle(ns3::GnuplotDataset::Style style) [member function]
|
||||
cls.add_method('SetStyle',
|
||||
'void',
|
||||
[param('ns3::GnuplotDataset::Style', 'style')])
|
||||
## gnuplot.h: void ns3::GnuplotDataset::SetErrorBars(ns3::GnuplotDataset::ErrorBars errorBars) [member function]
|
||||
cls.add_method('SetErrorBars',
|
||||
'void',
|
||||
[param('ns3::GnuplotDataset::ErrorBars', 'errorBars')])
|
||||
## gnuplot.h: void ns3::GnuplotDataset::Add(double x, double y) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('double', 'x'), param('double', 'y')])
|
||||
## gnuplot.h: void ns3::GnuplotDataset::Add(double x, double y, double errorDelta) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('double', 'x'), param('double', 'y'), param('double', 'errorDelta')])
|
||||
return
|
||||
|
||||
def register_Ns3ConfigStore_methods(root_module, cls):
|
||||
## config-store.h: ns3::ConfigStore::ConfigStore(ns3::ConfigStore const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::ConfigStore const &', 'arg0')])
|
||||
## config-store.h: static ns3::TypeId ns3::ConfigStore::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## config-store.h: ns3::TypeId ns3::ConfigStore::GetInstanceTypeId() const [member function]
|
||||
cls.add_method('GetInstanceTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## config-store.h: ns3::ConfigStore::ConfigStore() [constructor]
|
||||
cls.add_constructor([])
|
||||
## config-store.h: void ns3::ConfigStore::Configure() [member function]
|
||||
cls.add_method('Configure',
|
||||
'void',
|
||||
[])
|
||||
return
|
||||
|
||||
def register_Ns3DelayJitterEstimation_methods(root_module, cls):
|
||||
## delay-jitter-estimation.h: ns3::DelayJitterEstimation::DelayJitterEstimation(ns3::DelayJitterEstimation const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::DelayJitterEstimation const &', 'arg0')])
|
||||
## delay-jitter-estimation.h: ns3::DelayJitterEstimation::DelayJitterEstimation() [constructor]
|
||||
cls.add_constructor([])
|
||||
## delay-jitter-estimation.h: static void ns3::DelayJitterEstimation::PrepareTx(ns3::Ptr<const ns3::Packet> packet) [member function]
|
||||
cls.add_method('PrepareTx',
|
||||
'void',
|
||||
[param('ns3::Ptr< const ns3::Packet >', 'packet')],
|
||||
is_static=True)
|
||||
## delay-jitter-estimation.h: void ns3::DelayJitterEstimation::RecordRx(ns3::Ptr<const ns3::Packet> packet) [member function]
|
||||
cls.add_method('RecordRx',
|
||||
'void',
|
||||
[param('ns3::Ptr< const ns3::Packet >', 'packet')])
|
||||
## delay-jitter-estimation.h: ns3::Time ns3::DelayJitterEstimation::GetLastDelay() const [member function]
|
||||
cls.add_method('GetLastDelay',
|
||||
'ns3::Time',
|
||||
[],
|
||||
is_const=True)
|
||||
## delay-jitter-estimation.h: ns3::Time ns3::DelayJitterEstimation::GetLastJitter() const [member function]
|
||||
cls.add_method('GetLastJitter',
|
||||
'ns3::Time',
|
||||
[],
|
||||
is_const=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,437 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## csma-channel.h: ns3::WireState [enumeration]
|
||||
module.add_enum('WireState', ['IDLE', 'TRANSMITTING', 'PROPAGATING'])
|
||||
## csma-channel.h: ns3::CsmaDeviceRec [class]
|
||||
module.add_class('CsmaDeviceRec')
|
||||
## backoff.h: ns3::Backoff [class]
|
||||
module.add_class('Backoff')
|
||||
## csma-channel.h: ns3::CsmaChannel [class]
|
||||
module.add_class('CsmaChannel', parent=root_module['ns3::Channel'])
|
||||
## csma-net-device.h: ns3::CsmaNetDevice [class]
|
||||
module.add_class('CsmaNetDevice', parent=root_module['ns3::NetDevice'])
|
||||
## csma-net-device.h: ns3::CsmaNetDevice::EncapsulationMode [enumeration]
|
||||
module.add_enum('EncapsulationMode', ['ILLEGAL', 'DIX', 'LLC'], outer_class=root_module['ns3::CsmaNetDevice'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3CsmaDeviceRec_methods(root_module, root_module['ns3::CsmaDeviceRec'])
|
||||
register_Ns3Backoff_methods(root_module, root_module['ns3::Backoff'])
|
||||
register_Ns3CsmaChannel_methods(root_module, root_module['ns3::CsmaChannel'])
|
||||
register_Ns3CsmaNetDevice_methods(root_module, root_module['ns3::CsmaNetDevice'])
|
||||
return
|
||||
|
||||
def register_Ns3CsmaDeviceRec_methods(root_module, cls):
|
||||
## csma-channel.h: ns3::CsmaDeviceRec::devicePtr [variable]
|
||||
cls.add_instance_attribute('devicePtr', 'ns3::Ptr< ns3::CsmaNetDevice >', is_const=False)
|
||||
## csma-channel.h: ns3::CsmaDeviceRec::active [variable]
|
||||
cls.add_instance_attribute('active', 'bool', is_const=False)
|
||||
## csma-channel.h: ns3::CsmaDeviceRec::CsmaDeviceRec(ns3::CsmaDeviceRec const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::CsmaDeviceRec const &', 'arg0')])
|
||||
## csma-channel.h: ns3::CsmaDeviceRec::CsmaDeviceRec() [constructor]
|
||||
cls.add_constructor([])
|
||||
## csma-channel.h: ns3::CsmaDeviceRec::CsmaDeviceRec(ns3::Ptr<ns3::CsmaNetDevice> device) [constructor]
|
||||
cls.add_constructor([param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')])
|
||||
## csma-channel.h: bool ns3::CsmaDeviceRec::IsActive() [member function]
|
||||
cls.add_method('IsActive',
|
||||
'bool',
|
||||
[])
|
||||
return
|
||||
|
||||
def register_Ns3Backoff_methods(root_module, cls):
|
||||
## backoff.h: ns3::Backoff::m_minSlots [variable]
|
||||
cls.add_instance_attribute('m_minSlots', 'uint32_t', is_const=False)
|
||||
## backoff.h: ns3::Backoff::m_maxSlots [variable]
|
||||
cls.add_instance_attribute('m_maxSlots', 'uint32_t', is_const=False)
|
||||
## backoff.h: ns3::Backoff::m_ceiling [variable]
|
||||
cls.add_instance_attribute('m_ceiling', 'uint32_t', is_const=False)
|
||||
## backoff.h: ns3::Backoff::m_maxRetries [variable]
|
||||
cls.add_instance_attribute('m_maxRetries', 'uint32_t', is_const=False)
|
||||
## backoff.h: ns3::Backoff::m_slotTime [variable]
|
||||
cls.add_instance_attribute('m_slotTime', 'ns3::Time', is_const=False)
|
||||
## backoff.h: ns3::Backoff::Backoff(ns3::Backoff const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::Backoff const &', 'arg0')])
|
||||
## backoff.h: ns3::Backoff::Backoff() [constructor]
|
||||
cls.add_constructor([])
|
||||
## backoff.h: ns3::Backoff::Backoff(ns3::Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries) [constructor]
|
||||
cls.add_constructor([param('ns3::Time', 'slotTime'), param('uint32_t', 'minSlots'), param('uint32_t', 'maxSlots'), param('uint32_t', 'ceiling'), param('uint32_t', 'maxRetries')])
|
||||
## backoff.h: ns3::Time ns3::Backoff::GetBackoffTime() [member function]
|
||||
cls.add_method('GetBackoffTime',
|
||||
'ns3::Time',
|
||||
[])
|
||||
## backoff.h: void ns3::Backoff::ResetBackoffTime() [member function]
|
||||
cls.add_method('ResetBackoffTime',
|
||||
'void',
|
||||
[])
|
||||
## backoff.h: bool ns3::Backoff::MaxRetriesReached() [member function]
|
||||
cls.add_method('MaxRetriesReached',
|
||||
'bool',
|
||||
[])
|
||||
## backoff.h: void ns3::Backoff::IncrNumRetries() [member function]
|
||||
cls.add_method('IncrNumRetries',
|
||||
'void',
|
||||
[])
|
||||
return
|
||||
|
||||
def register_Ns3CsmaChannel_methods(root_module, cls):
|
||||
## csma-channel.h: ns3::CsmaChannel::CsmaChannel(ns3::CsmaChannel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::CsmaChannel const &', 'arg0')])
|
||||
## csma-channel.h: static ns3::TypeId ns3::CsmaChannel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## csma-channel.h: ns3::CsmaChannel::CsmaChannel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## csma-channel.h: int32_t ns3::CsmaChannel::Attach(ns3::Ptr<ns3::CsmaNetDevice> device) [member function]
|
||||
cls.add_method('Attach',
|
||||
'int32_t',
|
||||
[param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')])
|
||||
## csma-channel.h: bool ns3::CsmaChannel::Detach(ns3::Ptr<ns3::CsmaNetDevice> device) [member function]
|
||||
cls.add_method('Detach',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')])
|
||||
## csma-channel.h: bool ns3::CsmaChannel::Detach(uint32_t deviceId) [member function]
|
||||
cls.add_method('Detach',
|
||||
'bool',
|
||||
[param('uint32_t', 'deviceId')])
|
||||
## csma-channel.h: bool ns3::CsmaChannel::Reattach(uint32_t deviceId) [member function]
|
||||
cls.add_method('Reattach',
|
||||
'bool',
|
||||
[param('uint32_t', 'deviceId')])
|
||||
## csma-channel.h: bool ns3::CsmaChannel::Reattach(ns3::Ptr<ns3::CsmaNetDevice> device) [member function]
|
||||
cls.add_method('Reattach',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')])
|
||||
## csma-channel.h: bool ns3::CsmaChannel::TransmitStart(ns3::Ptr<ns3::Packet> p, uint32_t srcId) [member function]
|
||||
cls.add_method('TransmitStart',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'p'), param('uint32_t', 'srcId')])
|
||||
## csma-channel.h: bool ns3::CsmaChannel::TransmitEnd() [member function]
|
||||
cls.add_method('TransmitEnd',
|
||||
'bool',
|
||||
[])
|
||||
## csma-channel.h: void ns3::CsmaChannel::PropagationCompleteEvent() [member function]
|
||||
cls.add_method('PropagationCompleteEvent',
|
||||
'void',
|
||||
[])
|
||||
## csma-channel.h: int32_t ns3::CsmaChannel::GetDeviceNum(ns3::Ptr<ns3::CsmaNetDevice> device) [member function]
|
||||
cls.add_method('GetDeviceNum',
|
||||
'int32_t',
|
||||
[param('ns3::Ptr< ns3::CsmaNetDevice >', 'device')])
|
||||
## csma-channel.h: ns3::WireState ns3::CsmaChannel::GetState() [member function]
|
||||
cls.add_method('GetState',
|
||||
'ns3::WireState',
|
||||
[])
|
||||
## csma-channel.h: bool ns3::CsmaChannel::IsBusy() [member function]
|
||||
cls.add_method('IsBusy',
|
||||
'bool',
|
||||
[])
|
||||
## csma-channel.h: bool ns3::CsmaChannel::IsActive(uint32_t deviceId) [member function]
|
||||
cls.add_method('IsActive',
|
||||
'bool',
|
||||
[param('uint32_t', 'deviceId')])
|
||||
## csma-channel.h: uint32_t ns3::CsmaChannel::GetNumActDevices() [member function]
|
||||
cls.add_method('GetNumActDevices',
|
||||
'uint32_t',
|
||||
[])
|
||||
## csma-channel.h: uint32_t ns3::CsmaChannel::GetNDevices() const [member function]
|
||||
cls.add_method('GetNDevices',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-channel.h: ns3::Ptr<ns3::NetDevice> ns3::CsmaChannel::GetDevice(uint32_t i) const [member function]
|
||||
cls.add_method('GetDevice',
|
||||
'ns3::Ptr< ns3::NetDevice >',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-channel.h: ns3::Ptr<ns3::CsmaNetDevice> ns3::CsmaChannel::GetCsmaDevice(uint32_t i) const [member function]
|
||||
cls.add_method('GetCsmaDevice',
|
||||
'ns3::Ptr< ns3::CsmaNetDevice >',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## csma-channel.h: ns3::DataRate ns3::CsmaChannel::GetDataRate() [member function]
|
||||
cls.add_method('GetDataRate',
|
||||
'ns3::DataRate',
|
||||
[],
|
||||
is_virtual=True)
|
||||
## csma-channel.h: ns3::Time ns3::CsmaChannel::GetDelay() [member function]
|
||||
cls.add_method('GetDelay',
|
||||
'ns3::Time',
|
||||
[],
|
||||
is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3CsmaNetDevice_methods(root_module, cls):
|
||||
## csma-net-device.h: static ns3::TypeId ns3::CsmaNetDevice::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## csma-net-device.h: ns3::CsmaNetDevice::CsmaNetDevice() [constructor]
|
||||
cls.add_constructor([])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetInterframeGap(ns3::Time t) [member function]
|
||||
cls.add_method('SetInterframeGap',
|
||||
'void',
|
||||
[param('ns3::Time', 't')])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetBackoffParams(ns3::Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t maxRetries, uint32_t ceiling) [member function]
|
||||
cls.add_method('SetBackoffParams',
|
||||
'void',
|
||||
[param('ns3::Time', 'slotTime'), param('uint32_t', 'minSlots'), param('uint32_t', 'maxSlots'), param('uint32_t', 'maxRetries'), param('uint32_t', 'ceiling')])
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::Attach(ns3::Ptr<ns3::CsmaChannel> ch) [member function]
|
||||
cls.add_method('Attach',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::CsmaChannel >', 'ch')])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetQueue(ns3::Ptr<ns3::Queue> queue) [member function]
|
||||
cls.add_method('SetQueue',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Queue >', 'queue')])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveErrorModel(ns3::Ptr<ns3::ErrorModel> em) [member function]
|
||||
cls.add_method('SetReceiveErrorModel',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::ErrorModel >', 'em')])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::Receive(ns3::Ptr<ns3::Packet> p, ns3::Ptr<ns3::CsmaNetDevice> sender) [member function]
|
||||
cls.add_method('Receive',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ptr< ns3::CsmaNetDevice >', 'sender')])
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::IsSendEnabled() [member function]
|
||||
cls.add_method('IsSendEnabled',
|
||||
'bool',
|
||||
[])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetSendEnable(bool enable) [member function]
|
||||
cls.add_method('SetSendEnable',
|
||||
'void',
|
||||
[param('bool', 'enable')])
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::IsReceiveEnabled() [member function]
|
||||
cls.add_method('IsReceiveEnabled',
|
||||
'bool',
|
||||
[])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveEnable(bool enable) [member function]
|
||||
cls.add_method('SetReceiveEnable',
|
||||
'void',
|
||||
[param('bool', 'enable')])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetAddress(ns3::Mac48Address addr) [member function]
|
||||
cls.add_method('SetAddress',
|
||||
'void',
|
||||
[param('ns3::Mac48Address', 'addr')])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetFrameSize(uint16_t frameSize) [member function]
|
||||
cls.add_method('SetFrameSize',
|
||||
'void',
|
||||
[param('uint16_t', 'frameSize')])
|
||||
## csma-net-device.h: uint16_t ns3::CsmaNetDevice::GetFrameSize() const [member function]
|
||||
cls.add_method('GetFrameSize',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetEncapsulationMode(ns3::CsmaNetDevice::EncapsulationMode mode) [member function]
|
||||
cls.add_method('SetEncapsulationMode',
|
||||
'void',
|
||||
[param('ns3::CsmaNetDevice::EncapsulationMode', 'mode')])
|
||||
## csma-net-device.h: ns3::CsmaNetDevice::EncapsulationMode ns3::CsmaNetDevice::GetEncapsulationMode() [member function]
|
||||
cls.add_method('GetEncapsulationMode',
|
||||
'ns3::CsmaNetDevice::EncapsulationMode',
|
||||
[])
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetName(std::string const name) [member function]
|
||||
cls.add_method('SetName',
|
||||
'void',
|
||||
[param('std::string const', 'name')],
|
||||
is_virtual=True)
|
||||
## csma-net-device.h: std::string ns3::CsmaNetDevice::GetName() const [member function]
|
||||
cls.add_method('GetName',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetIfIndex(uint32_t const index) [member function]
|
||||
cls.add_method('SetIfIndex',
|
||||
'void',
|
||||
[param('uint32_t const', 'index')],
|
||||
is_virtual=True)
|
||||
## csma-net-device.h: uint32_t ns3::CsmaNetDevice::GetIfIndex() const [member function]
|
||||
cls.add_method('GetIfIndex',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: ns3::Ptr<ns3::Channel> ns3::CsmaNetDevice::GetChannel() const [member function]
|
||||
cls.add_method('GetChannel',
|
||||
'ns3::Ptr< ns3::Channel >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::SetMtu(uint16_t const mtu) [member function]
|
||||
cls.add_method('SetMtu',
|
||||
'bool',
|
||||
[param('uint16_t const', 'mtu')],
|
||||
is_virtual=True)
|
||||
## csma-net-device.h: uint16_t ns3::CsmaNetDevice::GetMtu() const [member function]
|
||||
cls.add_method('GetMtu',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::GetAddress() const [member function]
|
||||
cls.add_method('GetAddress',
|
||||
'ns3::Address',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::IsLinkUp() const [member function]
|
||||
cls.add_method('IsLinkUp',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetLinkChangeCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
|
||||
cls.add_method('SetLinkChangeCallback',
|
||||
'void',
|
||||
[param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')],
|
||||
is_virtual=True)
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::IsBroadcast() const [member function]
|
||||
cls.add_method('IsBroadcast',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::GetBroadcast() const [member function]
|
||||
cls.add_method('GetBroadcast',
|
||||
'ns3::Address',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::IsMulticast() const [member function]
|
||||
cls.add_method('IsMulticast',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::GetMulticast() const [member function]
|
||||
cls.add_method('GetMulticast',
|
||||
'ns3::Address',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: ns3::Address ns3::CsmaNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function]
|
||||
cls.add_method('MakeMulticastAddress',
|
||||
'ns3::Address',
|
||||
[param('ns3::Ipv4Address', 'multicastGroup')],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::IsPointToPoint() const [member function]
|
||||
cls.add_method('IsPointToPoint',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::Send(ns3::Ptr<ns3::Packet> packet, ns3::Address const & dest, uint16_t protocolNumber) [member function]
|
||||
cls.add_method('Send',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address const &', 'dest'), param('uint16_t', 'protocolNumber')],
|
||||
is_virtual=True)
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::SendFrom(ns3::Ptr<ns3::Packet> packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function]
|
||||
cls.add_method('SendFrom',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address const &', 'source'), param('ns3::Address const &', 'dest'), param('uint16_t', 'protocolNumber')],
|
||||
is_virtual=True)
|
||||
## csma-net-device.h: ns3::Ptr<ns3::Node> ns3::CsmaNetDevice::GetNode() const [member function]
|
||||
cls.add_method('GetNode',
|
||||
'ns3::Ptr< ns3::Node >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetNode(ns3::Ptr<ns3::Node> node) [member function]
|
||||
cls.add_method('SetNode',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node')],
|
||||
is_virtual=True)
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::NeedsArp() const [member function]
|
||||
cls.add_method('NeedsArp',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet const>, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function]
|
||||
cls.add_method('SetReceiveCallback',
|
||||
'void',
|
||||
[param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet const >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')],
|
||||
is_virtual=True)
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::SetPromiscReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet const>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
|
||||
cls.add_method('SetPromiscReceiveCallback',
|
||||
'void',
|
||||
[param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet const >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')],
|
||||
is_virtual=True)
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::SupportsSendFrom() const [member function]
|
||||
cls.add_method('SupportsSendFrom',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
## csma-net-device.h: ns3::Ptr<ns3::Queue> ns3::CsmaNetDevice::GetQueue() const [member function]
|
||||
cls.add_method('GetQueue',
|
||||
'ns3::Ptr< ns3::Queue >',
|
||||
[],
|
||||
is_const=True, visibility='protected')
|
||||
## csma-net-device.h: void ns3::CsmaNetDevice::AddHeader(ns3::Ptr<ns3::Packet> p, ns3::Mac48Address source, ns3::Mac48Address dest, uint16_t protocolNumber) [member function]
|
||||
cls.add_method('AddHeader',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Mac48Address', 'source'), param('ns3::Mac48Address', 'dest'), param('uint16_t', 'protocolNumber')],
|
||||
visibility='protected')
|
||||
## csma-net-device.h: bool ns3::CsmaNetDevice::ProcessHeader(ns3::Ptr<ns3::Packet> p, uint16_t & param) [member function]
|
||||
cls.add_method('ProcessHeader',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t &', 'param')],
|
||||
visibility='protected')
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## global-route-manager.h: ns3::GlobalRouteManager [class]
|
||||
module.add_class('GlobalRouteManager')
|
||||
## global-router-interface.h: ns3::GlobalRoutingLSA [class]
|
||||
module.add_class('GlobalRoutingLSA')
|
||||
## global-router-interface.h: ns3::GlobalRoutingLSA::LSType [enumeration]
|
||||
module.add_enum('LSType', ['Unknown', 'RouterLSA', 'NetworkLSA', 'SummaryLSA', 'SummaryLSA_ASBR', 'ASExternalLSAs'], outer_class=root_module['ns3::GlobalRoutingLSA'])
|
||||
## global-router-interface.h: ns3::GlobalRoutingLSA::SPFStatus [enumeration]
|
||||
module.add_enum('SPFStatus', ['LSA_SPF_NOT_EXPLORED', 'LSA_SPF_CANDIDATE', 'LSA_SPF_IN_SPFTREE'], outer_class=root_module['ns3::GlobalRoutingLSA'])
|
||||
## global-router-interface.h: ns3::GlobalRoutingLinkRecord [class]
|
||||
module.add_class('GlobalRoutingLinkRecord')
|
||||
## global-router-interface.h: ns3::GlobalRoutingLinkRecord::LinkType [enumeration]
|
||||
module.add_enum('LinkType', ['Unknown', 'PointToPoint', 'TransitNetwork', 'StubNetwork', 'VirtualLink'], outer_class=root_module['ns3::GlobalRoutingLinkRecord'])
|
||||
## global-router-interface.h: ns3::GlobalRouter [class]
|
||||
module.add_class('GlobalRouter', is_singleton=True, parent=root_module['ns3::Object'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3GlobalRouteManager_methods(root_module, root_module['ns3::GlobalRouteManager'])
|
||||
register_Ns3GlobalRoutingLSA_methods(root_module, root_module['ns3::GlobalRoutingLSA'])
|
||||
register_Ns3GlobalRoutingLinkRecord_methods(root_module, root_module['ns3::GlobalRoutingLinkRecord'])
|
||||
register_Ns3GlobalRouter_methods(root_module, root_module['ns3::GlobalRouter'])
|
||||
return
|
||||
|
||||
def register_Ns3GlobalRouteManager_methods(root_module, cls):
|
||||
## global-route-manager.h: static void ns3::GlobalRouteManager::PopulateRoutingTables() [member function]
|
||||
cls.add_method('PopulateRoutingTables',
|
||||
'void',
|
||||
[],
|
||||
is_static=True)
|
||||
## global-route-manager.h: static uint32_t ns3::GlobalRouteManager::AllocateRouterId() [member function]
|
||||
cls.add_method('AllocateRouterId',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_static=True)
|
||||
return
|
||||
|
||||
def register_Ns3GlobalRoutingLSA_methods(root_module, cls):
|
||||
## global-router-interface.h: ns3::GlobalRoutingLSA::GlobalRoutingLSA() [constructor]
|
||||
cls.add_constructor([])
|
||||
## global-router-interface.h: ns3::GlobalRoutingLSA::GlobalRoutingLSA(ns3::GlobalRoutingLSA::SPFStatus status, ns3::Ipv4Address linkStateId, ns3::Ipv4Address advertisingRtr) [constructor]
|
||||
cls.add_constructor([param('ns3::GlobalRoutingLSA::SPFStatus', 'status'), param('ns3::Ipv4Address', 'linkStateId'), param('ns3::Ipv4Address', 'advertisingRtr')])
|
||||
## global-router-interface.h: ns3::GlobalRoutingLSA::GlobalRoutingLSA(ns3::GlobalRoutingLSA & lsa) [constructor]
|
||||
cls.add_constructor([param('ns3::GlobalRoutingLSA &', 'lsa')])
|
||||
## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::AddAttachedRouter(ns3::Ipv4Address addr) [member function]
|
||||
cls.add_method('AddAttachedRouter',
|
||||
'uint32_t',
|
||||
[param('ns3::Ipv4Address', 'addr')])
|
||||
## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::AddLinkRecord(ns3::GlobalRoutingLinkRecord * lr) [member function]
|
||||
cls.add_method('AddLinkRecord',
|
||||
'uint32_t',
|
||||
[param('ns3::GlobalRoutingLinkRecord *', 'lr')])
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLSA::ClearLinkRecords() [member function]
|
||||
cls.add_method('ClearLinkRecords',
|
||||
'void',
|
||||
[])
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLSA::CopyLinkRecords(ns3::GlobalRoutingLSA const & lsa) [member function]
|
||||
cls.add_method('CopyLinkRecords',
|
||||
'void',
|
||||
[param('ns3::GlobalRoutingLSA const &', 'lsa')])
|
||||
## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLSA::GetAdvertisingRouter() const [member function]
|
||||
cls.add_method('GetAdvertisingRouter',
|
||||
'ns3::Ipv4Address',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLSA::GetAttachedRouter(uint32_t n) const [member function]
|
||||
cls.add_method('GetAttachedRouter',
|
||||
'ns3::Ipv4Address',
|
||||
[param('uint32_t', 'n')],
|
||||
is_const=True)
|
||||
## global-router-interface.h: ns3::GlobalRoutingLSA::LSType ns3::GlobalRoutingLSA::GetLSType() const [member function]
|
||||
cls.add_method('GetLSType',
|
||||
'ns3::GlobalRoutingLSA::LSType',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: ns3::GlobalRoutingLinkRecord * ns3::GlobalRoutingLSA::GetLinkRecord(uint32_t n) const [member function]
|
||||
cls.add_method('GetLinkRecord',
|
||||
'ns3::GlobalRoutingLinkRecord *',
|
||||
[param('uint32_t', 'n')],
|
||||
is_const=True)
|
||||
## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLSA::GetLinkStateId() const [member function]
|
||||
cls.add_method('GetLinkStateId',
|
||||
'ns3::Ipv4Address',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::GetNAttachedRouters() const [member function]
|
||||
cls.add_method('GetNAttachedRouters',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: uint32_t ns3::GlobalRoutingLSA::GetNLinkRecords() const [member function]
|
||||
cls.add_method('GetNLinkRecords',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: ns3::Ipv4Mask ns3::GlobalRoutingLSA::GetNetworkLSANetworkMask() const [member function]
|
||||
cls.add_method('GetNetworkLSANetworkMask',
|
||||
'ns3::Ipv4Mask',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: ns3::GlobalRoutingLSA::SPFStatus ns3::GlobalRoutingLSA::GetStatus() const [member function]
|
||||
cls.add_method('GetStatus',
|
||||
'ns3::GlobalRoutingLSA::SPFStatus',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: bool ns3::GlobalRoutingLSA::IsEmpty() const [member function]
|
||||
cls.add_method('IsEmpty',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLSA::Print(std::ostream & os) const [member function]
|
||||
cls.add_method('Print',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_const=True)
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLSA::SetAdvertisingRouter(ns3::Ipv4Address rtr) [member function]
|
||||
cls.add_method('SetAdvertisingRouter',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'rtr')])
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLSA::SetLSType(ns3::GlobalRoutingLSA::LSType typ) [member function]
|
||||
cls.add_method('SetLSType',
|
||||
'void',
|
||||
[param('ns3::GlobalRoutingLSA::LSType', 'typ')])
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLSA::SetLinkStateId(ns3::Ipv4Address addr) [member function]
|
||||
cls.add_method('SetLinkStateId',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'addr')])
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLSA::SetNetworkLSANetworkMask(ns3::Ipv4Mask mask) [member function]
|
||||
cls.add_method('SetNetworkLSANetworkMask',
|
||||
'void',
|
||||
[param('ns3::Ipv4Mask', 'mask')])
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLSA::SetStatus(ns3::GlobalRoutingLSA::SPFStatus status) [member function]
|
||||
cls.add_method('SetStatus',
|
||||
'void',
|
||||
[param('ns3::GlobalRoutingLSA::SPFStatus', 'status')])
|
||||
cls.add_output_stream_operator()
|
||||
return
|
||||
|
||||
def register_Ns3GlobalRoutingLinkRecord_methods(root_module, cls):
|
||||
## global-router-interface.h: ns3::GlobalRoutingLinkRecord::GlobalRoutingLinkRecord(ns3::GlobalRoutingLinkRecord const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::GlobalRoutingLinkRecord const &', 'arg0')])
|
||||
## global-router-interface.h: ns3::GlobalRoutingLinkRecord::GlobalRoutingLinkRecord() [constructor]
|
||||
cls.add_constructor([])
|
||||
## global-router-interface.h: ns3::GlobalRoutingLinkRecord::GlobalRoutingLinkRecord(ns3::GlobalRoutingLinkRecord::LinkType linkType, ns3::Ipv4Address linkId, ns3::Ipv4Address linkData, uint16_t metric) [constructor]
|
||||
cls.add_constructor([param('ns3::GlobalRoutingLinkRecord::LinkType', 'linkType'), param('ns3::Ipv4Address', 'linkId'), param('ns3::Ipv4Address', 'linkData'), param('uint16_t', 'metric')])
|
||||
## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLinkRecord::GetLinkId() const [member function]
|
||||
cls.add_method('GetLinkId',
|
||||
'ns3::Ipv4Address',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetLinkId(ns3::Ipv4Address addr) [member function]
|
||||
cls.add_method('SetLinkId',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'addr')])
|
||||
## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRoutingLinkRecord::GetLinkData() const [member function]
|
||||
cls.add_method('GetLinkData',
|
||||
'ns3::Ipv4Address',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetLinkData(ns3::Ipv4Address addr) [member function]
|
||||
cls.add_method('SetLinkData',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'addr')])
|
||||
## global-router-interface.h: ns3::GlobalRoutingLinkRecord::LinkType ns3::GlobalRoutingLinkRecord::GetLinkType() const [member function]
|
||||
cls.add_method('GetLinkType',
|
||||
'ns3::GlobalRoutingLinkRecord::LinkType',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetLinkType(ns3::GlobalRoutingLinkRecord::LinkType linkType) [member function]
|
||||
cls.add_method('SetLinkType',
|
||||
'void',
|
||||
[param('ns3::GlobalRoutingLinkRecord::LinkType', 'linkType')])
|
||||
## global-router-interface.h: uint16_t ns3::GlobalRoutingLinkRecord::GetMetric() const [member function]
|
||||
cls.add_method('GetMetric',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: void ns3::GlobalRoutingLinkRecord::SetMetric(uint16_t metric) [member function]
|
||||
cls.add_method('SetMetric',
|
||||
'void',
|
||||
[param('uint16_t', 'metric')])
|
||||
return
|
||||
|
||||
def register_Ns3GlobalRouter_methods(root_module, cls):
|
||||
## global-router-interface.h: static ns3::TypeId ns3::GlobalRouter::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## global-router-interface.h: ns3::GlobalRouter::GlobalRouter() [constructor]
|
||||
cls.add_constructor([])
|
||||
## global-router-interface.h: ns3::Ipv4Address ns3::GlobalRouter::GetRouterId() const [member function]
|
||||
cls.add_method('GetRouterId',
|
||||
'ns3::Ipv4Address',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: uint32_t ns3::GlobalRouter::DiscoverLSAs() [member function]
|
||||
cls.add_method('DiscoverLSAs',
|
||||
'uint32_t',
|
||||
[])
|
||||
## global-router-interface.h: uint32_t ns3::GlobalRouter::GetNumLSAs() const [member function]
|
||||
cls.add_method('GetNumLSAs',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## global-router-interface.h: bool ns3::GlobalRouter::GetLSA(uint32_t n, ns3::GlobalRoutingLSA & lsa) const [member function]
|
||||
cls.add_method('GetLSA',
|
||||
'bool',
|
||||
[param('uint32_t', 'n'), param('ns3::GlobalRoutingLSA &', 'lsa')],
|
||||
is_const=True)
|
||||
## global-router-interface.h: void ns3::GlobalRouter::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
@@ -0,0 +1,746 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## mobility-helper.h: ns3::MobilityHelper [class]
|
||||
module.add_class('MobilityHelper', allow_subclassing=False)
|
||||
## internet-stack-helper.h: ns3::InternetStackHelper [class]
|
||||
module.add_class('InternetStackHelper', allow_subclassing=False)
|
||||
## node-container.h: ns3::NodeContainer [class]
|
||||
module.add_class('NodeContainer')
|
||||
## point-to-point-helper.h: ns3::PointToPointHelper [class]
|
||||
module.add_class('PointToPointHelper', allow_subclassing=False)
|
||||
## net-device-container.h: ns3::NetDeviceContainer [class]
|
||||
module.add_class('NetDeviceContainer')
|
||||
## csma-helper.h: ns3::CsmaHelper [class]
|
||||
module.add_class('CsmaHelper', allow_subclassing=False)
|
||||
## udp-echo-helper.h: ns3::UdpEchoServerHelper [class]
|
||||
module.add_class('UdpEchoServerHelper', allow_subclassing=False)
|
||||
## olsr-helper.h: ns3::OlsrHelper [class]
|
||||
module.add_class('OlsrHelper', allow_subclassing=False)
|
||||
## packet-socket-helper.h: ns3::PacketSocketHelper [class]
|
||||
module.add_class('PacketSocketHelper', allow_subclassing=False)
|
||||
## on-off-helper.h: ns3::OnOffHelper [class]
|
||||
module.add_class('OnOffHelper', allow_subclassing=False)
|
||||
## udp-echo-helper.h: ns3::UdpEchoClientHelper [class]
|
||||
module.add_class('UdpEchoClientHelper', allow_subclassing=False)
|
||||
## static-multicast-route-helper.h: ns3::StaticMulticastRouteHelper [class]
|
||||
module.add_class('StaticMulticastRouteHelper', allow_subclassing=False)
|
||||
## ipv4-interface-container.h: ns3::Ipv4InterfaceContainer [class]
|
||||
module.add_class('Ipv4InterfaceContainer')
|
||||
## application-container.h: ns3::ApplicationContainer [class]
|
||||
module.add_class('ApplicationContainer')
|
||||
## wifi-helper.h: ns3::WifiHelper [class]
|
||||
module.add_class('WifiHelper', allow_subclassing=False)
|
||||
## ipv4-address-helper.h: ns3::Ipv4AddressHelper [class]
|
||||
module.add_class('Ipv4AddressHelper', allow_subclassing=False)
|
||||
## bridge-helper.h: ns3::BridgeHelper [class]
|
||||
module.add_class('BridgeHelper', allow_subclassing=False)
|
||||
## packet-sink-helper.h: ns3::PacketSinkHelper [class]
|
||||
module.add_class('PacketSinkHelper', allow_subclassing=False)
|
||||
## ns2-mobility-helper.h: ns3::Ns2MobilityHelper [class]
|
||||
module.add_class('Ns2MobilityHelper', allow_subclassing=False)
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3MobilityHelper_methods(root_module, root_module['ns3::MobilityHelper'])
|
||||
register_Ns3InternetStackHelper_methods(root_module, root_module['ns3::InternetStackHelper'])
|
||||
register_Ns3NodeContainer_methods(root_module, root_module['ns3::NodeContainer'])
|
||||
register_Ns3PointToPointHelper_methods(root_module, root_module['ns3::PointToPointHelper'])
|
||||
register_Ns3NetDeviceContainer_methods(root_module, root_module['ns3::NetDeviceContainer'])
|
||||
register_Ns3CsmaHelper_methods(root_module, root_module['ns3::CsmaHelper'])
|
||||
register_Ns3UdpEchoServerHelper_methods(root_module, root_module['ns3::UdpEchoServerHelper'])
|
||||
register_Ns3OlsrHelper_methods(root_module, root_module['ns3::OlsrHelper'])
|
||||
register_Ns3PacketSocketHelper_methods(root_module, root_module['ns3::PacketSocketHelper'])
|
||||
register_Ns3OnOffHelper_methods(root_module, root_module['ns3::OnOffHelper'])
|
||||
register_Ns3UdpEchoClientHelper_methods(root_module, root_module['ns3::UdpEchoClientHelper'])
|
||||
register_Ns3StaticMulticastRouteHelper_methods(root_module, root_module['ns3::StaticMulticastRouteHelper'])
|
||||
register_Ns3Ipv4InterfaceContainer_methods(root_module, root_module['ns3::Ipv4InterfaceContainer'])
|
||||
register_Ns3ApplicationContainer_methods(root_module, root_module['ns3::ApplicationContainer'])
|
||||
register_Ns3WifiHelper_methods(root_module, root_module['ns3::WifiHelper'])
|
||||
register_Ns3Ipv4AddressHelper_methods(root_module, root_module['ns3::Ipv4AddressHelper'])
|
||||
register_Ns3BridgeHelper_methods(root_module, root_module['ns3::BridgeHelper'])
|
||||
register_Ns3PacketSinkHelper_methods(root_module, root_module['ns3::PacketSinkHelper'])
|
||||
register_Ns3Ns2MobilityHelper_methods(root_module, root_module['ns3::Ns2MobilityHelper'])
|
||||
return
|
||||
|
||||
def register_Ns3MobilityHelper_methods(root_module, cls):
|
||||
## mobility-helper.h: ns3::MobilityHelper::MobilityHelper(ns3::MobilityHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::MobilityHelper const &', 'arg0')])
|
||||
## mobility-helper.h: ns3::MobilityHelper::MobilityHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## mobility-helper.h: void ns3::MobilityHelper::SetPositionAllocator(ns3::Ptr<ns3::PositionAllocator> allocator) [member function]
|
||||
cls.add_method('SetPositionAllocator',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::PositionAllocator >', 'allocator')])
|
||||
## mobility-helper.h: void ns3::MobilityHelper::SetPositionAllocator(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue(), std::string n8="", ns3::AttributeValue const & v8=ns3::EmptyAttributeValue(), std::string n9="", ns3::AttributeValue const & v9=ns3::EmptyAttributeValue()) [member function]
|
||||
cls.add_method('SetPositionAllocator',
|
||||
'void',
|
||||
[param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n8', default_value='""'), param('ns3::AttributeValue const &', 'v8', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n9', default_value='""'), param('ns3::AttributeValue const &', 'v9', default_value='ns3::EmptyAttributeValue()')])
|
||||
## mobility-helper.h: void ns3::MobilityHelper::SetMobilityModel(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue(), std::string n8="", ns3::AttributeValue const & v8=ns3::EmptyAttributeValue(), std::string n9="", ns3::AttributeValue const & v9=ns3::EmptyAttributeValue()) [member function]
|
||||
cls.add_method('SetMobilityModel',
|
||||
'void',
|
||||
[param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n8', default_value='""'), param('ns3::AttributeValue const &', 'v8', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n9', default_value='""'), param('ns3::AttributeValue const &', 'v9', default_value='ns3::EmptyAttributeValue()')])
|
||||
## mobility-helper.h: void ns3::MobilityHelper::PushReferenceMobilityModel(ns3::Ptr<ns3::Object> reference) [member function]
|
||||
cls.add_method('PushReferenceMobilityModel',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Object >', 'reference')])
|
||||
## mobility-helper.h: void ns3::MobilityHelper::PopReferenceMobilityModel() [member function]
|
||||
cls.add_method('PopReferenceMobilityModel',
|
||||
'void',
|
||||
[])
|
||||
## mobility-helper.h: std::string ns3::MobilityHelper::GetMobilityModelType() const [member function]
|
||||
cls.add_method('GetMobilityModelType',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True)
|
||||
## mobility-helper.h: void ns3::MobilityHelper::Install(ns3::NodeContainer container) [member function]
|
||||
cls.add_method('Install',
|
||||
'void',
|
||||
[param('ns3::NodeContainer', 'container')])
|
||||
## mobility-helper.h: void ns3::MobilityHelper::InstallAll() [member function]
|
||||
cls.add_method('InstallAll',
|
||||
'void',
|
||||
[])
|
||||
## mobility-helper.h: static void ns3::MobilityHelper::EnableAscii(std::ostream & os, uint32_t nodeid) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('uint32_t', 'nodeid')],
|
||||
is_static=True)
|
||||
## mobility-helper.h: static void ns3::MobilityHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')],
|
||||
is_static=True)
|
||||
## mobility-helper.h: static void ns3::MobilityHelper::EnableAsciiAll(std::ostream & os) [member function]
|
||||
cls.add_method('EnableAsciiAll',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_static=True)
|
||||
return
|
||||
|
||||
def register_Ns3InternetStackHelper_methods(root_module, cls):
|
||||
## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper(ns3::InternetStackHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::InternetStackHelper const &', 'arg0')])
|
||||
## internet-stack-helper.h: ns3::InternetStackHelper::InternetStackHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## internet-stack-helper.h: void ns3::InternetStackHelper::Install(ns3::NodeContainer c) [member function]
|
||||
cls.add_method('Install',
|
||||
'void',
|
||||
[param('ns3::NodeContainer', 'c')])
|
||||
## internet-stack-helper.h: void ns3::InternetStackHelper::SetNscStack(std::string soname) [member function]
|
||||
cls.add_method('SetNscStack',
|
||||
'void',
|
||||
[param('std::string', 'soname')])
|
||||
## internet-stack-helper.h: static void ns3::InternetStackHelper::EnablePcapAll(std::string filename) [member function]
|
||||
cls.add_method('EnablePcapAll',
|
||||
'void',
|
||||
[param('std::string', 'filename')],
|
||||
is_static=True)
|
||||
return
|
||||
|
||||
def register_Ns3NodeContainer_methods(root_module, cls):
|
||||
## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::NodeContainer const &', 'arg0')])
|
||||
## node-container.h: ns3::NodeContainer::NodeContainer() [constructor]
|
||||
cls.add_constructor([])
|
||||
## node-container.h: ns3::NodeContainer::NodeContainer(ns3::Ptr<ns3::Node> node) [constructor]
|
||||
cls.add_constructor([param('ns3::Ptr< ns3::Node >', 'node')])
|
||||
## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & a, ns3::NodeContainer const & b) [constructor]
|
||||
cls.add_constructor([param('ns3::NodeContainer const &', 'a'), param('ns3::NodeContainer const &', 'b')])
|
||||
## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & a, ns3::NodeContainer const & b, ns3::NodeContainer const & c) [constructor]
|
||||
cls.add_constructor([param('ns3::NodeContainer const &', 'a'), param('ns3::NodeContainer const &', 'b'), param('ns3::NodeContainer const &', 'c')])
|
||||
## node-container.h: ns3::NodeContainer::NodeContainer(ns3::NodeContainer const & a, ns3::NodeContainer const & b, ns3::NodeContainer const & c, ns3::NodeContainer const & d) [constructor]
|
||||
cls.add_constructor([param('ns3::NodeContainer const &', 'a'), param('ns3::NodeContainer const &', 'b'), param('ns3::NodeContainer const &', 'c'), param('ns3::NodeContainer const &', 'd')])
|
||||
## node-container.h: __gnu_cxx::__normal_iterator<const ns3::Ptr<ns3::Node>*,std::vector<ns3::Ptr<ns3::Node>, std::allocator<ns3::Ptr<ns3::Node> > > > ns3::NodeContainer::Begin() const [member function]
|
||||
cls.add_method('Begin',
|
||||
'__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node > > >',
|
||||
[],
|
||||
is_const=True)
|
||||
## node-container.h: __gnu_cxx::__normal_iterator<const ns3::Ptr<ns3::Node>*,std::vector<ns3::Ptr<ns3::Node>, std::allocator<ns3::Ptr<ns3::Node> > > > ns3::NodeContainer::End() const [member function]
|
||||
cls.add_method('End',
|
||||
'__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Node >, std::vector< ns3::Ptr< ns3::Node > > >',
|
||||
[],
|
||||
is_const=True)
|
||||
## node-container.h: uint32_t ns3::NodeContainer::GetN() const [member function]
|
||||
cls.add_method('GetN',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## node-container.h: ns3::Ptr<ns3::Node> ns3::NodeContainer::Get(uint32_t i) const [member function]
|
||||
cls.add_method('Get',
|
||||
'ns3::Ptr< ns3::Node >',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## node-container.h: void ns3::NodeContainer::Create(uint32_t n) [member function]
|
||||
cls.add_method('Create',
|
||||
'void',
|
||||
[param('uint32_t', 'n')])
|
||||
## node-container.h: void ns3::NodeContainer::Add(ns3::NodeContainer other) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('ns3::NodeContainer', 'other')])
|
||||
## node-container.h: void ns3::NodeContainer::Add(ns3::Ptr<ns3::Node> node) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node')])
|
||||
## node-container.h: static ns3::NodeContainer ns3::NodeContainer::GetGlobal() [member function]
|
||||
cls.add_method('GetGlobal',
|
||||
'ns3::NodeContainer',
|
||||
[],
|
||||
is_static=True)
|
||||
return
|
||||
|
||||
def register_Ns3PointToPointHelper_methods(root_module, cls):
|
||||
## point-to-point-helper.h: ns3::PointToPointHelper::PointToPointHelper(ns3::PointToPointHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::PointToPointHelper const &', 'arg0')])
|
||||
## point-to-point-helper.h: ns3::PointToPointHelper::PointToPointHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## point-to-point-helper.h: void ns3::PointToPointHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
|
||||
cls.add_method('SetQueue',
|
||||
'void',
|
||||
[param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
|
||||
## point-to-point-helper.h: void ns3::PointToPointHelper::SetDeviceAttribute(std::string name, ns3::AttributeValue const & value) [member function]
|
||||
cls.add_method('SetDeviceAttribute',
|
||||
'void',
|
||||
[param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
|
||||
## point-to-point-helper.h: void ns3::PointToPointHelper::SetChannelAttribute(std::string name, ns3::AttributeValue const & value) [member function]
|
||||
cls.add_method('SetChannelAttribute',
|
||||
'void',
|
||||
[param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
|
||||
## point-to-point-helper.h: void ns3::PointToPointHelper::SetDeviceParameter(std::string name, ns3::AttributeValue const & value) [member function]
|
||||
cls.add_method('SetDeviceParameter',
|
||||
'void',
|
||||
[param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')],
|
||||
deprecated=True)
|
||||
## point-to-point-helper.h: void ns3::PointToPointHelper::SetChannelParameter(std::string name, ns3::AttributeValue const & value) [member function]
|
||||
cls.add_method('SetChannelParameter',
|
||||
'void',
|
||||
[param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')],
|
||||
deprecated=True)
|
||||
## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
|
||||
cls.add_method('EnablePcap',
|
||||
'void',
|
||||
[param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')],
|
||||
is_static=True)
|
||||
## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
|
||||
cls.add_method('EnablePcap',
|
||||
'void',
|
||||
[param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')],
|
||||
is_static=True)
|
||||
## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
|
||||
cls.add_method('EnablePcap',
|
||||
'void',
|
||||
[param('std::string', 'filename'), param('ns3::NodeContainer', 'n')],
|
||||
is_static=True)
|
||||
## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcapAll(std::string filename) [member function]
|
||||
cls.add_method('EnablePcapAll',
|
||||
'void',
|
||||
[param('std::string', 'filename')],
|
||||
is_static=True)
|
||||
## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')],
|
||||
is_static=True)
|
||||
## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')],
|
||||
is_static=True)
|
||||
## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')],
|
||||
is_static=True)
|
||||
## point-to-point-helper.h: static void ns3::PointToPointHelper::EnableAsciiAll(std::ostream & os) [member function]
|
||||
cls.add_method('EnableAsciiAll',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_static=True)
|
||||
## point-to-point-helper.h: ns3::NetDeviceContainer ns3::PointToPointHelper::Install(ns3::NodeContainer c) [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::NetDeviceContainer',
|
||||
[param('ns3::NodeContainer', 'c')])
|
||||
## point-to-point-helper.h: ns3::NetDeviceContainer ns3::PointToPointHelper::Install(ns3::Ptr<ns3::Node> a, ns3::Ptr<ns3::Node> b) [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::NetDeviceContainer',
|
||||
[param('ns3::Ptr< ns3::Node >', 'a'), param('ns3::Ptr< ns3::Node >', 'b')])
|
||||
return
|
||||
|
||||
def register_Ns3NetDeviceContainer_methods(root_module, cls):
|
||||
## net-device-container.h: ns3::NetDeviceContainer::NetDeviceContainer(ns3::NetDeviceContainer const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::NetDeviceContainer const &', 'arg0')])
|
||||
## net-device-container.h: ns3::NetDeviceContainer::NetDeviceContainer() [constructor]
|
||||
cls.add_constructor([])
|
||||
## net-device-container.h: ns3::NetDeviceContainer::NetDeviceContainer(ns3::Ptr<ns3::NetDevice> dev) [constructor]
|
||||
cls.add_constructor([param('ns3::Ptr< ns3::NetDevice >', 'dev')])
|
||||
## net-device-container.h: ns3::NetDeviceContainer::NetDeviceContainer(ns3::NetDeviceContainer const & a, ns3::NetDeviceContainer const & b) [constructor]
|
||||
cls.add_constructor([param('ns3::NetDeviceContainer const &', 'a'), param('ns3::NetDeviceContainer const &', 'b')])
|
||||
## net-device-container.h: __gnu_cxx::__normal_iterator<const ns3::Ptr<ns3::NetDevice>*,std::vector<ns3::Ptr<ns3::NetDevice>, std::allocator<ns3::Ptr<ns3::NetDevice> > > > ns3::NetDeviceContainer::Begin() const [member function]
|
||||
cls.add_method('Begin',
|
||||
'__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::NetDevice >, std::vector< ns3::Ptr< ns3::NetDevice > > >',
|
||||
[],
|
||||
is_const=True)
|
||||
## net-device-container.h: __gnu_cxx::__normal_iterator<const ns3::Ptr<ns3::NetDevice>*,std::vector<ns3::Ptr<ns3::NetDevice>, std::allocator<ns3::Ptr<ns3::NetDevice> > > > ns3::NetDeviceContainer::End() const [member function]
|
||||
cls.add_method('End',
|
||||
'__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::NetDevice >, std::vector< ns3::Ptr< ns3::NetDevice > > >',
|
||||
[],
|
||||
is_const=True)
|
||||
## net-device-container.h: uint32_t ns3::NetDeviceContainer::GetN() const [member function]
|
||||
cls.add_method('GetN',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## net-device-container.h: ns3::Ptr<ns3::NetDevice> ns3::NetDeviceContainer::Get(uint32_t i) const [member function]
|
||||
cls.add_method('Get',
|
||||
'ns3::Ptr< ns3::NetDevice >',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## net-device-container.h: void ns3::NetDeviceContainer::Add(ns3::NetDeviceContainer other) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('ns3::NetDeviceContainer', 'other')])
|
||||
## net-device-container.h: void ns3::NetDeviceContainer::Add(ns3::Ptr<ns3::NetDevice> device) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::NetDevice >', 'device')])
|
||||
return
|
||||
|
||||
def register_Ns3CsmaHelper_methods(root_module, cls):
|
||||
## csma-helper.h: ns3::CsmaHelper::CsmaHelper(ns3::CsmaHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::CsmaHelper const &', 'arg0')])
|
||||
## csma-helper.h: ns3::CsmaHelper::CsmaHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## csma-helper.h: void ns3::CsmaHelper::SetQueue(std::string type, std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue()) [member function]
|
||||
cls.add_method('SetQueue',
|
||||
'void',
|
||||
[param('std::string', 'type'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()')])
|
||||
## csma-helper.h: void ns3::CsmaHelper::SetDeviceAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
|
||||
cls.add_method('SetDeviceAttribute',
|
||||
'void',
|
||||
[param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
|
||||
## csma-helper.h: void ns3::CsmaHelper::SetChannelAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
|
||||
cls.add_method('SetChannelAttribute',
|
||||
'void',
|
||||
[param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
|
||||
## csma-helper.h: void ns3::CsmaHelper::SetDeviceParameter(std::string n1, ns3::AttributeValue const & v1) [member function]
|
||||
cls.add_method('SetDeviceParameter',
|
||||
'void',
|
||||
[param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')],
|
||||
deprecated=True)
|
||||
## csma-helper.h: void ns3::CsmaHelper::SetChannelParameter(std::string n1, ns3::AttributeValue const & v1) [member function]
|
||||
cls.add_method('SetChannelParameter',
|
||||
'void',
|
||||
[param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')],
|
||||
deprecated=True)
|
||||
## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
|
||||
cls.add_method('EnablePcap',
|
||||
'void',
|
||||
[param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')],
|
||||
is_static=True)
|
||||
## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
|
||||
cls.add_method('EnablePcap',
|
||||
'void',
|
||||
[param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')],
|
||||
is_static=True)
|
||||
## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
|
||||
cls.add_method('EnablePcap',
|
||||
'void',
|
||||
[param('std::string', 'filename'), param('ns3::NodeContainer', 'n')],
|
||||
is_static=True)
|
||||
## csma-helper.h: static void ns3::CsmaHelper::EnablePcapAll(std::string filename) [member function]
|
||||
cls.add_method('EnablePcapAll',
|
||||
'void',
|
||||
[param('std::string', 'filename')],
|
||||
is_static=True)
|
||||
## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')],
|
||||
is_static=True)
|
||||
## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')],
|
||||
is_static=True)
|
||||
## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')],
|
||||
is_static=True)
|
||||
## csma-helper.h: static void ns3::CsmaHelper::EnableAsciiAll(std::ostream & os) [member function]
|
||||
cls.add_method('EnableAsciiAll',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_static=True)
|
||||
## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c) [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::NetDeviceContainer',
|
||||
[param('ns3::NodeContainer const &', 'c')])
|
||||
## csma-helper.h: ns3::NetDeviceContainer ns3::CsmaHelper::Install(ns3::NodeContainer const & c, ns3::Ptr<ns3::CsmaChannel> channel) [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::NetDeviceContainer',
|
||||
[param('ns3::NodeContainer const &', 'c'), param('ns3::Ptr< ns3::CsmaChannel >', 'channel')])
|
||||
return
|
||||
|
||||
def register_Ns3UdpEchoServerHelper_methods(root_module, cls):
|
||||
## udp-echo-helper.h: ns3::UdpEchoServerHelper::UdpEchoServerHelper(ns3::UdpEchoServerHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::UdpEchoServerHelper const &', 'arg0')])
|
||||
## udp-echo-helper.h: ns3::UdpEchoServerHelper::UdpEchoServerHelper(uint16_t port) [constructor]
|
||||
cls.add_constructor([param('uint16_t', 'port')])
|
||||
## udp-echo-helper.h: void ns3::UdpEchoServerHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function]
|
||||
cls.add_method('SetAttribute',
|
||||
'void',
|
||||
[param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
|
||||
## udp-echo-helper.h: ns3::ApplicationContainer ns3::UdpEchoServerHelper::Install(ns3::NodeContainer c) [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::ApplicationContainer',
|
||||
[param('ns3::NodeContainer', 'c')])
|
||||
return
|
||||
|
||||
def register_Ns3OlsrHelper_methods(root_module, cls):
|
||||
## olsr-helper.h: ns3::OlsrHelper::OlsrHelper(ns3::OlsrHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::OlsrHelper const &', 'arg0')])
|
||||
## olsr-helper.h: ns3::OlsrHelper::OlsrHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## olsr-helper.h: void ns3::OlsrHelper::SetAgent(std::string tid, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
|
||||
cls.add_method('SetAgent',
|
||||
'void',
|
||||
[param('std::string', 'tid'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
|
||||
## olsr-helper.h: void ns3::OlsrHelper::Install(ns3::NodeContainer container) [member function]
|
||||
cls.add_method('Install',
|
||||
'void',
|
||||
[param('ns3::NodeContainer', 'container')])
|
||||
## olsr-helper.h: void ns3::OlsrHelper::Install(ns3::Ptr<ns3::Node> node) [member function]
|
||||
cls.add_method('Install',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node')])
|
||||
## olsr-helper.h: void ns3::OlsrHelper::InstallAll() [member function]
|
||||
cls.add_method('InstallAll',
|
||||
'void',
|
||||
[])
|
||||
return
|
||||
|
||||
def register_Ns3PacketSocketHelper_methods(root_module, cls):
|
||||
## packet-socket-helper.h: ns3::PacketSocketHelper::PacketSocketHelper(ns3::PacketSocketHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::PacketSocketHelper const &', 'arg0')])
|
||||
## packet-socket-helper.h: ns3::PacketSocketHelper::PacketSocketHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## packet-socket-helper.h: void ns3::PacketSocketHelper::Install(ns3::NodeContainer c) [member function]
|
||||
cls.add_method('Install',
|
||||
'void',
|
||||
[param('ns3::NodeContainer', 'c')])
|
||||
return
|
||||
|
||||
def register_Ns3OnOffHelper_methods(root_module, cls):
|
||||
## on-off-helper.h: ns3::OnOffHelper::OnOffHelper(ns3::OnOffHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::OnOffHelper const &', 'arg0')])
|
||||
## on-off-helper.h: ns3::OnOffHelper::OnOffHelper(std::string protocol, ns3::Address address) [constructor]
|
||||
cls.add_constructor([param('std::string', 'protocol'), param('ns3::Address', 'address')])
|
||||
## on-off-helper.h: void ns3::OnOffHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function]
|
||||
cls.add_method('SetAttribute',
|
||||
'void',
|
||||
[param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
|
||||
## on-off-helper.h: ns3::ApplicationContainer ns3::OnOffHelper::Install(ns3::NodeContainer c) [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::ApplicationContainer',
|
||||
[param('ns3::NodeContainer', 'c')])
|
||||
return
|
||||
|
||||
def register_Ns3UdpEchoClientHelper_methods(root_module, cls):
|
||||
## udp-echo-helper.h: ns3::UdpEchoClientHelper::UdpEchoClientHelper(ns3::UdpEchoClientHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::UdpEchoClientHelper const &', 'arg0')])
|
||||
## udp-echo-helper.h: ns3::UdpEchoClientHelper::UdpEchoClientHelper(ns3::Ipv4Address ip, uint16_t port) [constructor]
|
||||
cls.add_constructor([param('ns3::Ipv4Address', 'ip'), param('uint16_t', 'port')])
|
||||
## udp-echo-helper.h: void ns3::UdpEchoClientHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function]
|
||||
cls.add_method('SetAttribute',
|
||||
'void',
|
||||
[param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
|
||||
## udp-echo-helper.h: ns3::ApplicationContainer ns3::UdpEchoClientHelper::Install(ns3::NodeContainer c) [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::ApplicationContainer',
|
||||
[param('ns3::NodeContainer', 'c')])
|
||||
return
|
||||
|
||||
def register_Ns3StaticMulticastRouteHelper_methods(root_module, cls):
|
||||
## static-multicast-route-helper.h: ns3::StaticMulticastRouteHelper::StaticMulticastRouteHelper(ns3::StaticMulticastRouteHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::StaticMulticastRouteHelper const &', 'arg0')])
|
||||
## static-multicast-route-helper.h: ns3::StaticMulticastRouteHelper::StaticMulticastRouteHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## static-multicast-route-helper.h: void ns3::StaticMulticastRouteHelper::AddMulticastRoute(ns3::Ptr<ns3::Node> arg0, ns3::Ipv4Address source, ns3::Ipv4Address group, ns3::Ptr<ns3::NetDevice> input, ns3::NetDeviceContainer output) [member function]
|
||||
cls.add_method('AddMulticastRoute',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'arg0'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'group'), param('ns3::Ptr< ns3::NetDevice >', 'input'), param('ns3::NetDeviceContainer', 'output')])
|
||||
## static-multicast-route-helper.h: void ns3::StaticMulticastRouteHelper::SetDefaultMulticastRoute(ns3::Ptr<ns3::Node> n, ns3::Ptr<ns3::NetDevice> nd) [member function]
|
||||
cls.add_method('SetDefaultMulticastRoute',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'n'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
|
||||
## static-multicast-route-helper.h: void ns3::StaticMulticastRouteHelper::JoinMulticastGroup(ns3::Ptr<ns3::Node> n, ns3::Ipv4Address source, ns3::Ipv4Address group) [member function]
|
||||
cls.add_method('JoinMulticastGroup',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'n'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'group')])
|
||||
return
|
||||
|
||||
def register_Ns3Ipv4InterfaceContainer_methods(root_module, cls):
|
||||
## ipv4-interface-container.h: ns3::Ipv4InterfaceContainer::Ipv4InterfaceContainer(ns3::Ipv4InterfaceContainer const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::Ipv4InterfaceContainer const &', 'arg0')])
|
||||
## ipv4-interface-container.h: ns3::Ipv4InterfaceContainer::Ipv4InterfaceContainer() [constructor]
|
||||
cls.add_constructor([])
|
||||
## ipv4-interface-container.h: uint32_t ns3::Ipv4InterfaceContainer::GetN() const [member function]
|
||||
cls.add_method('GetN',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-interface-container.h: ns3::Ipv4Address ns3::Ipv4InterfaceContainer::GetAddress(uint32_t i) const [member function]
|
||||
cls.add_method('GetAddress',
|
||||
'ns3::Ipv4Address',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## ipv4-interface-container.h: void ns3::Ipv4InterfaceContainer::SetMetric(uint32_t i, uint16_t metric) [member function]
|
||||
cls.add_method('SetMetric',
|
||||
'void',
|
||||
[param('uint32_t', 'i'), param('uint16_t', 'metric')])
|
||||
## ipv4-interface-container.h: void ns3::Ipv4InterfaceContainer::Add(ns3::Ptr<ns3::Ipv4> ipv4, uint32_t interface) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Ipv4 >', 'ipv4'), param('uint32_t', 'interface')])
|
||||
return
|
||||
|
||||
def register_Ns3ApplicationContainer_methods(root_module, cls):
|
||||
## application-container.h: ns3::ApplicationContainer::ApplicationContainer(ns3::ApplicationContainer const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::ApplicationContainer const &', 'arg0')])
|
||||
## application-container.h: ns3::ApplicationContainer::ApplicationContainer() [constructor]
|
||||
cls.add_constructor([])
|
||||
## application-container.h: __gnu_cxx::__normal_iterator<const ns3::Ptr<ns3::Application>*,std::vector<ns3::Ptr<ns3::Application>, std::allocator<ns3::Ptr<ns3::Application> > > > ns3::ApplicationContainer::Begin() const [member function]
|
||||
cls.add_method('Begin',
|
||||
'__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Application >, std::vector< ns3::Ptr< ns3::Application > > >',
|
||||
[],
|
||||
is_const=True)
|
||||
## application-container.h: __gnu_cxx::__normal_iterator<const ns3::Ptr<ns3::Application>*,std::vector<ns3::Ptr<ns3::Application>, std::allocator<ns3::Ptr<ns3::Application> > > > ns3::ApplicationContainer::End() const [member function]
|
||||
cls.add_method('End',
|
||||
'__gnu_cxx::__normal_iterator< const ns3::Ptr< ns3::Application >, std::vector< ns3::Ptr< ns3::Application > > >',
|
||||
[],
|
||||
is_const=True)
|
||||
## application-container.h: uint32_t ns3::ApplicationContainer::GetN() const [member function]
|
||||
cls.add_method('GetN',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## application-container.h: ns3::Ptr<ns3::Application> ns3::ApplicationContainer::Get(uint32_t i) const [member function]
|
||||
cls.add_method('Get',
|
||||
'ns3::Ptr< ns3::Application >',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## application-container.h: void ns3::ApplicationContainer::Add(ns3::ApplicationContainer other) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('ns3::ApplicationContainer', 'other')])
|
||||
## application-container.h: void ns3::ApplicationContainer::Add(ns3::Ptr<ns3::Application> application) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Application >', 'application')])
|
||||
## application-container.h: void ns3::ApplicationContainer::Start(ns3::Time start) [member function]
|
||||
cls.add_method('Start',
|
||||
'void',
|
||||
[param('ns3::Time', 'start')])
|
||||
## application-container.h: void ns3::ApplicationContainer::Stop(ns3::Time stop) [member function]
|
||||
cls.add_method('Stop',
|
||||
'void',
|
||||
[param('ns3::Time', 'stop')])
|
||||
return
|
||||
|
||||
def register_Ns3WifiHelper_methods(root_module, cls):
|
||||
## wifi-helper.h: ns3::WifiHelper::WifiHelper(ns3::WifiHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::WifiHelper const &', 'arg0')])
|
||||
## wifi-helper.h: ns3::WifiHelper::WifiHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## wifi-helper.h: void ns3::WifiHelper::SetRemoteStationManager(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
|
||||
cls.add_method('SetRemoteStationManager',
|
||||
'void',
|
||||
[param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
|
||||
## wifi-helper.h: void ns3::WifiHelper::SetMac(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
|
||||
cls.add_method('SetMac',
|
||||
'void',
|
||||
[param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
|
||||
## wifi-helper.h: void ns3::WifiHelper::SetPhy(std::string phyType, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
|
||||
cls.add_method('SetPhy',
|
||||
'void',
|
||||
[param('std::string', 'phyType'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
|
||||
## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
|
||||
cls.add_method('EnablePcap',
|
||||
'void',
|
||||
[param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')],
|
||||
is_static=True)
|
||||
## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
|
||||
cls.add_method('EnablePcap',
|
||||
'void',
|
||||
[param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')],
|
||||
is_static=True)
|
||||
## wifi-helper.h: static void ns3::WifiHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
|
||||
cls.add_method('EnablePcap',
|
||||
'void',
|
||||
[param('std::string', 'filename'), param('ns3::NodeContainer', 'n')],
|
||||
is_static=True)
|
||||
## wifi-helper.h: static void ns3::WifiHelper::EnablePcapAll(std::string filename) [member function]
|
||||
cls.add_method('EnablePcapAll',
|
||||
'void',
|
||||
[param('std::string', 'filename')],
|
||||
is_static=True)
|
||||
## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')],
|
||||
is_static=True)
|
||||
## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')],
|
||||
is_static=True)
|
||||
## wifi-helper.h: static void ns3::WifiHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
|
||||
cls.add_method('EnableAscii',
|
||||
'void',
|
||||
[param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')],
|
||||
is_static=True)
|
||||
## wifi-helper.h: static void ns3::WifiHelper::EnableAsciiAll(std::ostream & os) [member function]
|
||||
cls.add_method('EnableAsciiAll',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_static=True)
|
||||
## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::NodeContainer c) const [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::NetDeviceContainer',
|
||||
[param('ns3::NodeContainer', 'c')],
|
||||
is_const=True)
|
||||
## wifi-helper.h: ns3::NetDeviceContainer ns3::WifiHelper::Install(ns3::NodeContainer c, ns3::Ptr<ns3::WifiChannel> channel) const [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::NetDeviceContainer',
|
||||
[param('ns3::NodeContainer', 'c'), param('ns3::Ptr< ns3::WifiChannel >', 'channel')],
|
||||
is_const=True)
|
||||
return
|
||||
|
||||
def register_Ns3Ipv4AddressHelper_methods(root_module, cls):
|
||||
## ipv4-address-helper.h: ns3::Ipv4AddressHelper::Ipv4AddressHelper(ns3::Ipv4AddressHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::Ipv4AddressHelper const &', 'arg0')])
|
||||
## ipv4-address-helper.h: ns3::Ipv4AddressHelper::Ipv4AddressHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## ipv4-address-helper.h: void ns3::Ipv4AddressHelper::SetBase(ns3::Ipv4Address network, ns3::Ipv4Mask mask, ns3::Ipv4Address base="0.0.0.1") [member function]
|
||||
cls.add_method('SetBase',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'mask'), param('ns3::Ipv4Address', 'base', default_value='"0.0.0.1"')])
|
||||
## ipv4-address-helper.h: ns3::Ipv4Address ns3::Ipv4AddressHelper::NewNetwork() [member function]
|
||||
cls.add_method('NewNetwork',
|
||||
'ns3::Ipv4Address',
|
||||
[])
|
||||
## ipv4-address-helper.h: ns3::Ipv4Address ns3::Ipv4AddressHelper::NewAddress() [member function]
|
||||
cls.add_method('NewAddress',
|
||||
'ns3::Ipv4Address',
|
||||
[])
|
||||
## ipv4-address-helper.h: ns3::Ipv4InterfaceContainer ns3::Ipv4AddressHelper::Assign(ns3::NetDeviceContainer const & c) [member function]
|
||||
cls.add_method('Assign',
|
||||
'ns3::Ipv4InterfaceContainer',
|
||||
[param('ns3::NetDeviceContainer const &', 'c')])
|
||||
return
|
||||
|
||||
def register_Ns3BridgeHelper_methods(root_module, cls):
|
||||
## bridge-helper.h: ns3::BridgeHelper::BridgeHelper(ns3::BridgeHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::BridgeHelper const &', 'arg0')])
|
||||
## bridge-helper.h: ns3::BridgeHelper::BridgeHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## bridge-helper.h: void ns3::BridgeHelper::SetDeviceAttribute(std::string n1, ns3::AttributeValue const & v1) [member function]
|
||||
cls.add_method('SetDeviceAttribute',
|
||||
'void',
|
||||
[param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
|
||||
## bridge-helper.h: ns3::NetDeviceContainer ns3::BridgeHelper::Install(ns3::Ptr<ns3::Node> node, ns3::NetDeviceContainer c) [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::NetDeviceContainer',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::NetDeviceContainer', 'c')])
|
||||
return
|
||||
|
||||
def register_Ns3PacketSinkHelper_methods(root_module, cls):
|
||||
## packet-sink-helper.h: ns3::PacketSinkHelper::PacketSinkHelper(ns3::PacketSinkHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::PacketSinkHelper const &', 'arg0')])
|
||||
## packet-sink-helper.h: ns3::PacketSinkHelper::PacketSinkHelper(std::string protocol, ns3::Address address) [constructor]
|
||||
cls.add_constructor([param('std::string', 'protocol'), param('ns3::Address', 'address')])
|
||||
## packet-sink-helper.h: void ns3::PacketSinkHelper::SetAttribute(std::string name, ns3::AttributeValue const & value) [member function]
|
||||
cls.add_method('SetAttribute',
|
||||
'void',
|
||||
[param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
|
||||
## packet-sink-helper.h: ns3::ApplicationContainer ns3::PacketSinkHelper::Install(ns3::NodeContainer c) [member function]
|
||||
cls.add_method('Install',
|
||||
'ns3::ApplicationContainer',
|
||||
[param('ns3::NodeContainer', 'c')])
|
||||
return
|
||||
|
||||
def register_Ns3Ns2MobilityHelper_methods(root_module, cls):
|
||||
## ns2-mobility-helper.h: ns3::Ns2MobilityHelper::Ns2MobilityHelper(ns3::Ns2MobilityHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::Ns2MobilityHelper const &', 'arg0')])
|
||||
## ns2-mobility-helper.h: ns3::Ns2MobilityHelper::Ns2MobilityHelper(std::string filename) [constructor]
|
||||
cls.add_constructor([param('std::string', 'filename')])
|
||||
## ns2-mobility-helper.h: void ns3::Ns2MobilityHelper::Install() const [member function]
|
||||
cls.add_method('Install',
|
||||
'void',
|
||||
[],
|
||||
is_const=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
@@ -0,0 +1,661 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## ipv4-interface.h: ns3::Ipv4Interface [class]
|
||||
module.add_class('Ipv4Interface', parent=root_module['ns3::Object'])
|
||||
## udp-header.h: ns3::UdpHeader [class]
|
||||
module.add_class('UdpHeader', parent=root_module['ns3::Header'])
|
||||
## tcp-header.h: ns3::TcpHeader [class]
|
||||
module.add_class('TcpHeader', parent=root_module['ns3::Header'])
|
||||
## tcp-header.h: ns3::TcpHeader::Flags_t [enumeration]
|
||||
module.add_enum('Flags_t', ['NONE', 'FIN', 'SYN', 'RST', 'PSH', 'ACK', 'URG'], outer_class=root_module['ns3::TcpHeader'])
|
||||
## ipv4-l3-protocol.h: ns3::Ipv4L3Protocol [class]
|
||||
module.add_class('Ipv4L3Protocol', parent=root_module['ns3::Object'])
|
||||
## ipv4-static-routing.h: ns3::Ipv4StaticRouting [class]
|
||||
module.add_class('Ipv4StaticRouting', parent=root_module['ns3::Ipv4RoutingProtocol'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3Ipv4Interface_methods(root_module, root_module['ns3::Ipv4Interface'])
|
||||
register_Ns3UdpHeader_methods(root_module, root_module['ns3::UdpHeader'])
|
||||
register_Ns3TcpHeader_methods(root_module, root_module['ns3::TcpHeader'])
|
||||
register_Ns3Ipv4L3Protocol_methods(root_module, root_module['ns3::Ipv4L3Protocol'])
|
||||
register_Ns3Ipv4StaticRouting_methods(root_module, root_module['ns3::Ipv4StaticRouting'])
|
||||
return
|
||||
|
||||
def register_Ns3Ipv4Interface_methods(root_module, cls):
|
||||
## ipv4-interface.h: ns3::Ipv4Interface::Ipv4Interface(ns3::Ipv4Interface const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::Ipv4Interface const &', 'arg0')])
|
||||
## ipv4-interface.h: static ns3::TypeId ns3::Ipv4Interface::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## ipv4-interface.h: ns3::Ipv4Interface::Ipv4Interface() [constructor]
|
||||
cls.add_constructor([])
|
||||
## ipv4-interface.h: ns3::Ptr<ns3::NetDevice> ns3::Ipv4Interface::GetDevice() const [member function]
|
||||
cls.add_method('GetDevice',
|
||||
'ns3::Ptr< ns3::NetDevice >',
|
||||
[],
|
||||
is_pure_virtual=True, is_const=True, is_virtual=True)
|
||||
## ipv4-interface.h: void ns3::Ipv4Interface::SetAddress(ns3::Ipv4Address a) [member function]
|
||||
cls.add_method('SetAddress',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'a')])
|
||||
## ipv4-interface.h: void ns3::Ipv4Interface::SetNetworkMask(ns3::Ipv4Mask mask) [member function]
|
||||
cls.add_method('SetNetworkMask',
|
||||
'void',
|
||||
[param('ns3::Ipv4Mask', 'mask')])
|
||||
## ipv4-interface.h: ns3::Ipv4Address ns3::Ipv4Interface::GetBroadcast() const [member function]
|
||||
cls.add_method('GetBroadcast',
|
||||
'ns3::Ipv4Address',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-interface.h: ns3::Ipv4Mask ns3::Ipv4Interface::GetNetworkMask() const [member function]
|
||||
cls.add_method('GetNetworkMask',
|
||||
'ns3::Ipv4Mask',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-interface.h: void ns3::Ipv4Interface::SetMetric(uint16_t metric) [member function]
|
||||
cls.add_method('SetMetric',
|
||||
'void',
|
||||
[param('uint16_t', 'metric')])
|
||||
## ipv4-interface.h: uint16_t ns3::Ipv4Interface::GetMetric() const [member function]
|
||||
cls.add_method('GetMetric',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-interface.h: ns3::Ipv4Address ns3::Ipv4Interface::GetAddress() const [member function]
|
||||
cls.add_method('GetAddress',
|
||||
'ns3::Ipv4Address',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-interface.h: uint16_t ns3::Ipv4Interface::GetMtu() const [member function]
|
||||
cls.add_method('GetMtu',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-interface.h: bool ns3::Ipv4Interface::IsUp() const [member function]
|
||||
cls.add_method('IsUp',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-interface.h: bool ns3::Ipv4Interface::IsDown() const [member function]
|
||||
cls.add_method('IsDown',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-interface.h: void ns3::Ipv4Interface::SetUp() [member function]
|
||||
cls.add_method('SetUp',
|
||||
'void',
|
||||
[])
|
||||
## ipv4-interface.h: void ns3::Ipv4Interface::SetDown() [member function]
|
||||
cls.add_method('SetDown',
|
||||
'void',
|
||||
[])
|
||||
## ipv4-interface.h: void ns3::Ipv4Interface::Send(ns3::Ptr<ns3::Packet> p, ns3::Ipv4Address dest) [member function]
|
||||
cls.add_method('Send',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ipv4Address', 'dest')])
|
||||
## ipv4-interface.h: void ns3::Ipv4Interface::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
## ipv4-interface.h: void ns3::Ipv4Interface::SendTo(ns3::Ptr<ns3::Packet> p, ns3::Ipv4Address dest) [member function]
|
||||
cls.add_method('SendTo',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ipv4Address', 'dest')],
|
||||
is_pure_virtual=True, visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3UdpHeader_methods(root_module, cls):
|
||||
## udp-header.h: ns3::UdpHeader::UdpHeader(ns3::UdpHeader const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::UdpHeader const &', 'arg0')])
|
||||
## udp-header.h: ns3::UdpHeader::UdpHeader() [constructor]
|
||||
cls.add_constructor([])
|
||||
## udp-header.h: void ns3::UdpHeader::EnableChecksums() [member function]
|
||||
cls.add_method('EnableChecksums',
|
||||
'void',
|
||||
[])
|
||||
## udp-header.h: void ns3::UdpHeader::SetDestinationPort(uint16_t port) [member function]
|
||||
cls.add_method('SetDestinationPort',
|
||||
'void',
|
||||
[param('uint16_t', 'port')])
|
||||
## udp-header.h: void ns3::UdpHeader::SetSourcePort(uint16_t port) [member function]
|
||||
cls.add_method('SetSourcePort',
|
||||
'void',
|
||||
[param('uint16_t', 'port')])
|
||||
## udp-header.h: uint16_t ns3::UdpHeader::GetSourcePort() const [member function]
|
||||
cls.add_method('GetSourcePort',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## udp-header.h: uint16_t ns3::UdpHeader::GetDestinationPort() const [member function]
|
||||
cls.add_method('GetDestinationPort',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## udp-header.h: void ns3::UdpHeader::InitializeChecksum(ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function]
|
||||
cls.add_method('InitializeChecksum',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')])
|
||||
## udp-header.h: static ns3::TypeId ns3::UdpHeader::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## udp-header.h: ns3::TypeId ns3::UdpHeader::GetInstanceTypeId() const [member function]
|
||||
cls.add_method('GetInstanceTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## udp-header.h: void ns3::UdpHeader::Print(std::ostream & os) const [member function]
|
||||
cls.add_method('Print',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_const=True, is_virtual=True)
|
||||
## udp-header.h: uint32_t ns3::UdpHeader::GetSerializedSize() const [member function]
|
||||
cls.add_method('GetSerializedSize',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## udp-header.h: void ns3::UdpHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
|
||||
cls.add_method('Serialize',
|
||||
'void',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_const=True, is_virtual=True)
|
||||
## udp-header.h: uint32_t ns3::UdpHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
|
||||
cls.add_method('Deserialize',
|
||||
'uint32_t',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_virtual=True)
|
||||
## udp-header.h: bool ns3::UdpHeader::IsChecksumOk() const [member function]
|
||||
cls.add_method('IsChecksumOk',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True)
|
||||
return
|
||||
|
||||
def register_Ns3TcpHeader_methods(root_module, cls):
|
||||
## tcp-header.h: ns3::TcpHeader::TcpHeader(ns3::TcpHeader const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::TcpHeader const &', 'arg0')])
|
||||
## tcp-header.h: ns3::TcpHeader::TcpHeader() [constructor]
|
||||
cls.add_constructor([])
|
||||
## tcp-header.h: void ns3::TcpHeader::EnableChecksums() [member function]
|
||||
cls.add_method('EnableChecksums',
|
||||
'void',
|
||||
[])
|
||||
## tcp-header.h: void ns3::TcpHeader::SetSourcePort(uint16_t port) [member function]
|
||||
cls.add_method('SetSourcePort',
|
||||
'void',
|
||||
[param('uint16_t', 'port')])
|
||||
## tcp-header.h: void ns3::TcpHeader::SetDestinationPort(uint16_t port) [member function]
|
||||
cls.add_method('SetDestinationPort',
|
||||
'void',
|
||||
[param('uint16_t', 'port')])
|
||||
## tcp-header.h: void ns3::TcpHeader::SetSequenceNumber(SequenceNumber sequenceNumber) [member function]
|
||||
cls.add_method('SetSequenceNumber',
|
||||
'void',
|
||||
[param('SequenceNumber', 'sequenceNumber')])
|
||||
## tcp-header.h: void ns3::TcpHeader::SetAckNumber(SequenceNumber ackNumber) [member function]
|
||||
cls.add_method('SetAckNumber',
|
||||
'void',
|
||||
[param('SequenceNumber', 'ackNumber')])
|
||||
## tcp-header.h: void ns3::TcpHeader::SetLength(uint8_t length) [member function]
|
||||
cls.add_method('SetLength',
|
||||
'void',
|
||||
[param('uint8_t', 'length')])
|
||||
## tcp-header.h: void ns3::TcpHeader::SetFlags(uint8_t flags) [member function]
|
||||
cls.add_method('SetFlags',
|
||||
'void',
|
||||
[param('uint8_t', 'flags')])
|
||||
## tcp-header.h: void ns3::TcpHeader::SetWindowSize(uint16_t windowSize) [member function]
|
||||
cls.add_method('SetWindowSize',
|
||||
'void',
|
||||
[param('uint16_t', 'windowSize')])
|
||||
## tcp-header.h: void ns3::TcpHeader::SetUrgentPointer(uint16_t urgentPointer) [member function]
|
||||
cls.add_method('SetUrgentPointer',
|
||||
'void',
|
||||
[param('uint16_t', 'urgentPointer')])
|
||||
## tcp-header.h: uint16_t ns3::TcpHeader::GetSourcePort() const [member function]
|
||||
cls.add_method('GetSourcePort',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## tcp-header.h: uint16_t ns3::TcpHeader::GetDestinationPort() const [member function]
|
||||
cls.add_method('GetDestinationPort',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## tcp-header.h: SequenceNumber ns3::TcpHeader::GetSequenceNumber() const [member function]
|
||||
cls.add_method('GetSequenceNumber',
|
||||
'SequenceNumber',
|
||||
[],
|
||||
is_const=True)
|
||||
## tcp-header.h: SequenceNumber ns3::TcpHeader::GetAckNumber() const [member function]
|
||||
cls.add_method('GetAckNumber',
|
||||
'SequenceNumber',
|
||||
[],
|
||||
is_const=True)
|
||||
## tcp-header.h: uint8_t ns3::TcpHeader::GetLength() const [member function]
|
||||
cls.add_method('GetLength',
|
||||
'uint8_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## tcp-header.h: uint8_t ns3::TcpHeader::GetFlags() const [member function]
|
||||
cls.add_method('GetFlags',
|
||||
'uint8_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## tcp-header.h: uint16_t ns3::TcpHeader::GetWindowSize() const [member function]
|
||||
cls.add_method('GetWindowSize',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## tcp-header.h: uint16_t ns3::TcpHeader::GetUrgentPointer() const [member function]
|
||||
cls.add_method('GetUrgentPointer',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## tcp-header.h: void ns3::TcpHeader::InitializeChecksum(ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function]
|
||||
cls.add_method('InitializeChecksum',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')])
|
||||
## tcp-header.h: static ns3::TypeId ns3::TcpHeader::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## tcp-header.h: ns3::TypeId ns3::TcpHeader::GetInstanceTypeId() const [member function]
|
||||
cls.add_method('GetInstanceTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## tcp-header.h: void ns3::TcpHeader::Print(std::ostream & os) const [member function]
|
||||
cls.add_method('Print',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_const=True, is_virtual=True)
|
||||
## tcp-header.h: uint32_t ns3::TcpHeader::GetSerializedSize() const [member function]
|
||||
cls.add_method('GetSerializedSize',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## tcp-header.h: void ns3::TcpHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
|
||||
cls.add_method('Serialize',
|
||||
'void',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_const=True, is_virtual=True)
|
||||
## tcp-header.h: uint32_t ns3::TcpHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
|
||||
cls.add_method('Deserialize',
|
||||
'uint32_t',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_virtual=True)
|
||||
## tcp-header.h: bool ns3::TcpHeader::IsChecksumOk() const [member function]
|
||||
cls.add_method('IsChecksumOk',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True)
|
||||
return
|
||||
|
||||
def register_Ns3Ipv4L3Protocol_methods(root_module, cls):
|
||||
## ipv4-l3-protocol.h: ns3::Ipv4L3Protocol::PROT_NUMBER [variable]
|
||||
cls.add_static_attribute('PROT_NUMBER', 'uint16_t const', is_const=True)
|
||||
## ipv4-l3-protocol.h: static ns3::TypeId ns3::Ipv4L3Protocol::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## ipv4-l3-protocol.h: ns3::Ipv4L3Protocol::Ipv4L3Protocol() [constructor]
|
||||
cls.add_constructor([])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetNode(ns3::Ptr<ns3::Node> node) [member function]
|
||||
cls.add_method('SetNode',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Insert(ns3::Ptr<ns3::Ipv4L4Protocol> protocol) [member function]
|
||||
cls.add_method('Insert',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Ipv4L4Protocol >', 'protocol')])
|
||||
## ipv4-l3-protocol.h: ns3::Ptr<ns3::Ipv4L4Protocol> ns3::Ipv4L3Protocol::GetProtocol(int protocolNumber) [member function]
|
||||
cls.add_method('GetProtocol',
|
||||
'ns3::Ptr< ns3::Ipv4L4Protocol >',
|
||||
[param('int', 'protocolNumber')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Remove(ns3::Ptr<ns3::Ipv4L4Protocol> protocol) [member function]
|
||||
cls.add_method('Remove',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Ipv4L4Protocol >', 'protocol')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDefaultTtl(uint8_t ttl) [member function]
|
||||
cls.add_method('SetDefaultTtl',
|
||||
'void',
|
||||
[param('uint8_t', 'ttl')])
|
||||
## ipv4-l3-protocol.h: ns3::Ptr<ns3::Ipv4Interface> ns3::Ipv4L3Protocol::FindInterfaceForDevice(ns3::Ptr<const ns3::NetDevice> device) [member function]
|
||||
cls.add_method('FindInterfaceForDevice',
|
||||
'ns3::Ptr< ns3::Ipv4Interface >',
|
||||
[param('ns3::Ptr< const ns3::NetDevice >', 'device')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Receive(ns3::Ptr<ns3::NetDevice> device, ns3::Ptr<const ns3::Packet> p, uint16_t protocol, ns3::Address const & from, ns3::Address const & to, ns3::NetDevice::PacketType packetType) [member function]
|
||||
cls.add_method('Receive',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::NetDevice >', 'device'), param('ns3::Ptr< const ns3::Packet >', 'p'), param('uint16_t', 'protocol'), param('ns3::Address const &', 'from'), param('ns3::Address const &', 'to'), param('ns3::NetDevice::PacketType', 'packetType')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Send(ns3::Ptr<ns3::Packet> packet, ns3::Ipv4Address source, ns3::Ipv4Address destination, uint8_t protocol) [member function]
|
||||
cls.add_method('Send',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Ipv4Address', 'source'), param('ns3::Ipv4Address', 'destination'), param('uint8_t', 'protocol')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function]
|
||||
cls.add_method('AddHostRouteTo',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function]
|
||||
cls.add_method('AddHostRouteTo',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function]
|
||||
cls.add_method('AddNetworkRouteTo',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function]
|
||||
cls.add_method('AddNetworkRouteTo',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function]
|
||||
cls.add_method('SetDefaultRoute',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Lookup(ns3::Ipv4Header const & ipHeader, ns3::Ptr<ns3::Packet> packet, ns3::Callback<void,bool,const ns3::Ipv4Route&,ns3::Ptr<ns3::Packet>,const ns3::Ipv4Header&,ns3::empty,ns3::empty> routeReply) [member function]
|
||||
cls.add_method('Lookup',
|
||||
'void',
|
||||
[param('ns3::Ipv4Header const &', 'ipHeader'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')])
|
||||
## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::GetNRoutes() [member function]
|
||||
cls.add_method('GetNRoutes',
|
||||
'uint32_t',
|
||||
[])
|
||||
## ipv4-l3-protocol.h: ns3::Ipv4Route * ns3::Ipv4L3Protocol::GetRoute(uint32_t i) [member function]
|
||||
cls.add_method('GetRoute',
|
||||
'ns3::Ipv4Route *',
|
||||
[param('uint32_t', 'i')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::RemoveRoute(uint32_t i) [member function]
|
||||
cls.add_method('RemoveRoute',
|
||||
'void',
|
||||
[param('uint32_t', 'i')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector<unsigned int, std::allocator<unsigned int> > outputInterfaces) [member function]
|
||||
cls.add_method('AddMulticastRoute',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int >', 'outputInterfaces')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDefaultMulticastRoute(uint32_t onputInterface) [member function]
|
||||
cls.add_method('SetDefaultMulticastRoute',
|
||||
'void',
|
||||
[param('uint32_t', 'onputInterface')])
|
||||
## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::GetNMulticastRoutes() const [member function]
|
||||
cls.add_method('GetNMulticastRoutes',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: ns3::Ipv4MulticastRoute * ns3::Ipv4L3Protocol::GetMulticastRoute(uint32_t i) const [member function]
|
||||
cls.add_method('GetMulticastRoute',
|
||||
'ns3::Ipv4MulticastRoute *',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::RemoveMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface) [member function]
|
||||
cls.add_method('RemoveMulticastRoute',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::RemoveMulticastRoute(uint32_t i) [member function]
|
||||
cls.add_method('RemoveMulticastRoute',
|
||||
'void',
|
||||
[param('uint32_t', 'i')])
|
||||
## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::AddInterface(ns3::Ptr<ns3::NetDevice> device) [member function]
|
||||
cls.add_method('AddInterface',
|
||||
'uint32_t',
|
||||
[param('ns3::Ptr< ns3::NetDevice >', 'device')])
|
||||
## ipv4-l3-protocol.h: ns3::Ptr<ns3::Ipv4Interface> ns3::Ipv4L3Protocol::GetInterface(uint32_t i) const [member function]
|
||||
cls.add_method('GetInterface',
|
||||
'ns3::Ptr< ns3::Ipv4Interface >',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::GetNInterfaces() const [member function]
|
||||
cls.add_method('GetNInterfaces',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::FindInterfaceForAddr(ns3::Ipv4Address addr) const [member function]
|
||||
cls.add_method('FindInterfaceForAddr',
|
||||
'uint32_t',
|
||||
[param('ns3::Ipv4Address', 'addr')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: uint32_t ns3::Ipv4L3Protocol::FindInterfaceForAddr(ns3::Ipv4Address addr, ns3::Ipv4Mask mask) const [member function]
|
||||
cls.add_method('FindInterfaceForAddr',
|
||||
'uint32_t',
|
||||
[param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: int32_t ns3::Ipv4L3Protocol::FindInterfaceIndexForDevice(ns3::Ptr<ns3::NetDevice> device) const [member function]
|
||||
cls.add_method('FindInterfaceIndexForDevice',
|
||||
'int32_t',
|
||||
[param('ns3::Ptr< ns3::NetDevice >', 'device')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::JoinMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function]
|
||||
cls.add_method('JoinMulticastGroup',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::LeaveMulticastGroup(ns3::Ipv4Address origin, ns3::Ipv4Address group) [member function]
|
||||
cls.add_method('LeaveMulticastGroup',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetAddress(uint32_t i, ns3::Ipv4Address address) [member function]
|
||||
cls.add_method('SetAddress',
|
||||
'void',
|
||||
[param('uint32_t', 'i'), param('ns3::Ipv4Address', 'address')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetNetworkMask(uint32_t i, ns3::Ipv4Mask mask) [member function]
|
||||
cls.add_method('SetNetworkMask',
|
||||
'void',
|
||||
[param('uint32_t', 'i'), param('ns3::Ipv4Mask', 'mask')])
|
||||
## ipv4-l3-protocol.h: ns3::Ipv4Mask ns3::Ipv4L3Protocol::GetNetworkMask(uint32_t t) const [member function]
|
||||
cls.add_method('GetNetworkMask',
|
||||
'ns3::Ipv4Mask',
|
||||
[param('uint32_t', 't')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: ns3::Ipv4Address ns3::Ipv4L3Protocol::GetAddress(uint32_t i) const [member function]
|
||||
cls.add_method('GetAddress',
|
||||
'ns3::Ipv4Address',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetMetric(uint32_t i, uint16_t metric) [member function]
|
||||
cls.add_method('SetMetric',
|
||||
'void',
|
||||
[param('uint32_t', 'i'), param('uint16_t', 'metric')])
|
||||
## ipv4-l3-protocol.h: uint16_t ns3::Ipv4L3Protocol::GetMetric(uint32_t i) const [member function]
|
||||
cls.add_method('GetMetric',
|
||||
'uint16_t',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: bool ns3::Ipv4L3Protocol::GetIfIndexForDestination(ns3::Ipv4Address destination, uint32_t & ifIndex) const [member function]
|
||||
cls.add_method('GetIfIndexForDestination',
|
||||
'bool',
|
||||
[param('ns3::Ipv4Address', 'destination'), param('uint32_t &', 'ifIndex')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: uint16_t ns3::Ipv4L3Protocol::GetMtu(uint32_t i) const [member function]
|
||||
cls.add_method('GetMtu',
|
||||
'uint16_t',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: bool ns3::Ipv4L3Protocol::IsUp(uint32_t i) const [member function]
|
||||
cls.add_method('IsUp',
|
||||
'bool',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetUp(uint32_t i) [member function]
|
||||
cls.add_method('SetUp',
|
||||
'void',
|
||||
[param('uint32_t', 'i')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::SetDown(uint32_t i) [member function]
|
||||
cls.add_method('SetDown',
|
||||
'void',
|
||||
[param('uint32_t', 'i')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::AddRoutingProtocol(ns3::Ptr<ns3::Ipv4RoutingProtocol> routingProtocol, int priority) [member function]
|
||||
cls.add_method('AddRoutingProtocol',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Ipv4RoutingProtocol >', 'routingProtocol'), param('int', 'priority')])
|
||||
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3Ipv4StaticRouting_methods(root_module, cls):
|
||||
## ipv4-static-routing.h: ns3::Ipv4StaticRouting::Ipv4StaticRouting(ns3::Ipv4StaticRouting const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::Ipv4StaticRouting const &', 'arg0')])
|
||||
## ipv4-static-routing.h: ns3::Ipv4StaticRouting::Ipv4StaticRouting() [constructor]
|
||||
cls.add_constructor([])
|
||||
## ipv4-static-routing.h: bool ns3::Ipv4StaticRouting::RequestRoute(uint32_t ifIndex, ns3::Ipv4Header const & ipHeader, ns3::Ptr<ns3::Packet> packet, ns3::Callback<void,bool,const ns3::Ipv4Route&,ns3::Ptr<ns3::Packet>,const ns3::Ipv4Header&,ns3::empty,ns3::empty> routeReply) [member function]
|
||||
cls.add_method('RequestRoute',
|
||||
'bool',
|
||||
[param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header const &', 'ipHeader'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, const ns3::Ipv4Route&, ns3::Ptr< ns3::Packet >, const ns3::Ipv4Header&, ns3::empty, ns3::empty >', 'routeReply')],
|
||||
is_virtual=True)
|
||||
## ipv4-static-routing.h: bool ns3::Ipv4StaticRouting::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function]
|
||||
cls.add_method('RequestIfIndex',
|
||||
'bool',
|
||||
[param('ns3::Ipv4Address', 'destination'), param('uint32_t &', 'ifIndex')],
|
||||
is_virtual=True)
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function]
|
||||
cls.add_method('AddHostRouteTo',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'dest'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')])
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddHostRouteTo(ns3::Ipv4Address dest, uint32_t interface) [member function]
|
||||
cls.add_method('AddHostRouteTo',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'dest'), param('uint32_t', 'interface')])
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, ns3::Ipv4Address nextHop, uint32_t interface) [member function]
|
||||
cls.add_method('AddNetworkRouteTo',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')])
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddNetworkRouteTo(ns3::Ipv4Address network, ns3::Ipv4Mask networkMask, uint32_t interface) [member function]
|
||||
cls.add_method('AddNetworkRouteTo',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'network'), param('ns3::Ipv4Mask', 'networkMask'), param('uint32_t', 'interface')])
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::SetDefaultRoute(ns3::Ipv4Address nextHop, uint32_t interface) [member function]
|
||||
cls.add_method('SetDefaultRoute',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'nextHop'), param('uint32_t', 'interface')])
|
||||
## ipv4-static-routing.h: uint32_t ns3::Ipv4StaticRouting::GetNRoutes() [member function]
|
||||
cls.add_method('GetNRoutes',
|
||||
'uint32_t',
|
||||
[])
|
||||
## ipv4-static-routing.h: ns3::Ipv4Route * ns3::Ipv4StaticRouting::GetDefaultRoute() [member function]
|
||||
cls.add_method('GetDefaultRoute',
|
||||
'ns3::Ipv4Route *',
|
||||
[])
|
||||
## ipv4-static-routing.h: ns3::Ipv4Route * ns3::Ipv4StaticRouting::GetRoute(uint32_t i) [member function]
|
||||
cls.add_method('GetRoute',
|
||||
'ns3::Ipv4Route *',
|
||||
[param('uint32_t', 'i')])
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::RemoveRoute(uint32_t i) [member function]
|
||||
cls.add_method('RemoveRoute',
|
||||
'void',
|
||||
[param('uint32_t', 'i')])
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::AddMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface, std::vector<unsigned int, std::allocator<unsigned int> > outputInterfaces) [member function]
|
||||
cls.add_method('AddMulticastRoute',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface'), param('std::vector< unsigned int >', 'outputInterfaces')])
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface) [member function]
|
||||
cls.add_method('SetDefaultMulticastRoute',
|
||||
'void',
|
||||
[param('uint32_t', 'outputInterface')])
|
||||
## ipv4-static-routing.h: uint32_t ns3::Ipv4StaticRouting::GetNMulticastRoutes() const [member function]
|
||||
cls.add_method('GetNMulticastRoutes',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-static-routing.h: ns3::Ipv4MulticastRoute * ns3::Ipv4StaticRouting::GetMulticastRoute(uint32_t i) const [member function]
|
||||
cls.add_method('GetMulticastRoute',
|
||||
'ns3::Ipv4MulticastRoute *',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## ipv4-static-routing.h: ns3::Ipv4MulticastRoute * ns3::Ipv4StaticRouting::GetDefaultMulticastRoute() const [member function]
|
||||
cls.add_method('GetDefaultMulticastRoute',
|
||||
'ns3::Ipv4MulticastRoute *',
|
||||
[],
|
||||
is_const=True)
|
||||
## ipv4-static-routing.h: bool ns3::Ipv4StaticRouting::RemoveMulticastRoute(ns3::Ipv4Address origin, ns3::Ipv4Address group, uint32_t inputInterface) [member function]
|
||||
cls.add_method('RemoveMulticastRoute',
|
||||
'bool',
|
||||
[param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group'), param('uint32_t', 'inputInterface')])
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index) [member function]
|
||||
cls.add_method('RemoveMulticastRoute',
|
||||
'void',
|
||||
[param('uint32_t', 'index')])
|
||||
## ipv4-static-routing.h: void ns3::Ipv4StaticRouting::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
## internet-stack.h: extern void ns3::AddInternetStack(ns3::Ptr<ns3::Node> node) [free function]
|
||||
module.add_function('AddInternetStack',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node')])
|
||||
## internet-stack.h: extern void ns3::AddNscInternetStack(ns3::Ptr<ns3::Node> node, std::string const & soname) [free function]
|
||||
module.add_function('AddNscInternetStack',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node'), param('std::string const &', 'soname')])
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
@@ -0,0 +1,723 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## static-speed-helper.h: ns3::StaticSpeedHelper [class]
|
||||
module.add_class('StaticSpeedHelper', allow_subclassing=False)
|
||||
## vector.h: ns3::Vector [class]
|
||||
module.add_class('Vector')
|
||||
## vector.h: ns3::VectorChecker [class]
|
||||
module.add_class('VectorChecker', parent=root_module['ns3::AttributeChecker'])
|
||||
## rectangle.h: ns3::RectangleChecker [class]
|
||||
module.add_class('RectangleChecker', parent=root_module['ns3::AttributeChecker'])
|
||||
## rectangle.h: ns3::Rectangle [class]
|
||||
module.add_class('Rectangle')
|
||||
## rectangle.h: ns3::Rectangle::Side [enumeration]
|
||||
module.add_enum('Side', ['RIGHT', 'LEFT', 'TOP', 'BOTTOM'], outer_class=root_module['ns3::Rectangle'])
|
||||
## position-allocator.h: ns3::PositionAllocator [class]
|
||||
module.add_class('PositionAllocator', parent=root_module['ns3::Object'])
|
||||
## position-allocator.h: ns3::ListPositionAllocator [class]
|
||||
module.add_class('ListPositionAllocator', parent=root_module['ns3::PositionAllocator'])
|
||||
## rectangle.h: ns3::RectangleValue [class]
|
||||
module.add_class('RectangleValue', parent=root_module['ns3::AttributeValue'])
|
||||
## position-allocator.h: ns3::RandomRectanglePositionAllocator [class]
|
||||
module.add_class('RandomRectanglePositionAllocator', parent=root_module['ns3::PositionAllocator'])
|
||||
## vector.h: ns3::VectorValue [class]
|
||||
module.add_class('VectorValue', parent=root_module['ns3::AttributeValue'])
|
||||
## position-allocator.h: ns3::RandomDiscPositionAllocator [class]
|
||||
module.add_class('RandomDiscPositionAllocator', parent=root_module['ns3::PositionAllocator'])
|
||||
## mobility-model.h: ns3::MobilityModel [class]
|
||||
module.add_class('MobilityModel', parent=root_module['ns3::Object'])
|
||||
## random-direction-2d-mobility-model.h: ns3::RandomDirection2dMobilityModel [class]
|
||||
module.add_class('RandomDirection2dMobilityModel', parent=root_module['ns3::MobilityModel'])
|
||||
## position-allocator.h: ns3::GridPositionAllocator [class]
|
||||
module.add_class('GridPositionAllocator', parent=root_module['ns3::PositionAllocator'])
|
||||
## position-allocator.h: ns3::GridPositionAllocator::LayoutType [enumeration]
|
||||
module.add_enum('LayoutType', ['ROW_FIRST', 'COLUMN_FIRST'], outer_class=root_module['ns3::GridPositionAllocator'])
|
||||
## random-waypoint-mobility-model.h: ns3::RandomWaypointMobilityModel [class]
|
||||
module.add_class('RandomWaypointMobilityModel', parent=root_module['ns3::MobilityModel'])
|
||||
## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel [class]
|
||||
module.add_class('RandomWalk2dMobilityModel', parent=root_module['ns3::MobilityModel'])
|
||||
## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel::Mode [enumeration]
|
||||
module.add_enum('Mode', ['MODE_DISTANCE', 'MODE_TIME'], outer_class=root_module['ns3::RandomWalk2dMobilityModel'])
|
||||
## static-speed-mobility-model.h: ns3::StaticSpeedMobilityModel [class]
|
||||
module.add_class('StaticSpeedMobilityModel', parent=root_module['ns3::MobilityModel'])
|
||||
## hierarchical-mobility-model.h: ns3::HierarchicalMobilityModel [class]
|
||||
module.add_class('HierarchicalMobilityModel', parent=root_module['ns3::MobilityModel'])
|
||||
## static-mobility-model.h: ns3::StaticMobilityModel [class]
|
||||
module.add_class('StaticMobilityModel', parent=root_module['ns3::MobilityModel'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3StaticSpeedHelper_methods(root_module, root_module['ns3::StaticSpeedHelper'])
|
||||
register_Ns3Vector_methods(root_module, root_module['ns3::Vector'])
|
||||
register_Ns3VectorChecker_methods(root_module, root_module['ns3::VectorChecker'])
|
||||
register_Ns3RectangleChecker_methods(root_module, root_module['ns3::RectangleChecker'])
|
||||
register_Ns3Rectangle_methods(root_module, root_module['ns3::Rectangle'])
|
||||
register_Ns3PositionAllocator_methods(root_module, root_module['ns3::PositionAllocator'])
|
||||
register_Ns3ListPositionAllocator_methods(root_module, root_module['ns3::ListPositionAllocator'])
|
||||
register_Ns3RectangleValue_methods(root_module, root_module['ns3::RectangleValue'])
|
||||
register_Ns3RandomRectanglePositionAllocator_methods(root_module, root_module['ns3::RandomRectanglePositionAllocator'])
|
||||
register_Ns3VectorValue_methods(root_module, root_module['ns3::VectorValue'])
|
||||
register_Ns3RandomDiscPositionAllocator_methods(root_module, root_module['ns3::RandomDiscPositionAllocator'])
|
||||
register_Ns3MobilityModel_methods(root_module, root_module['ns3::MobilityModel'])
|
||||
register_Ns3RandomDirection2dMobilityModel_methods(root_module, root_module['ns3::RandomDirection2dMobilityModel'])
|
||||
register_Ns3GridPositionAllocator_methods(root_module, root_module['ns3::GridPositionAllocator'])
|
||||
register_Ns3RandomWaypointMobilityModel_methods(root_module, root_module['ns3::RandomWaypointMobilityModel'])
|
||||
register_Ns3RandomWalk2dMobilityModel_methods(root_module, root_module['ns3::RandomWalk2dMobilityModel'])
|
||||
register_Ns3StaticSpeedMobilityModel_methods(root_module, root_module['ns3::StaticSpeedMobilityModel'])
|
||||
register_Ns3HierarchicalMobilityModel_methods(root_module, root_module['ns3::HierarchicalMobilityModel'])
|
||||
register_Ns3StaticMobilityModel_methods(root_module, root_module['ns3::StaticMobilityModel'])
|
||||
return
|
||||
|
||||
def register_Ns3StaticSpeedHelper_methods(root_module, cls):
|
||||
## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::StaticSpeedHelper const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::StaticSpeedHelper const &', 'arg0')])
|
||||
## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper() [constructor]
|
||||
cls.add_constructor([])
|
||||
## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position) [constructor]
|
||||
cls.add_constructor([param('ns3::Vector const &', 'position')])
|
||||
## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position, ns3::Vector const & speed) [constructor]
|
||||
cls.add_constructor([param('ns3::Vector const &', 'position'), param('ns3::Vector const &', 'speed')])
|
||||
## static-speed-helper.h: void ns3::StaticSpeedHelper::InitializePosition(ns3::Vector const & position) [member function]
|
||||
cls.add_method('InitializePosition',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'position')])
|
||||
## static-speed-helper.h: void ns3::StaticSpeedHelper::Reset(ns3::Vector const & speed) [member function]
|
||||
cls.add_method('Reset',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'speed')])
|
||||
## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition(ns3::Rectangle const & bounds) const [member function]
|
||||
cls.add_method('GetCurrentPosition',
|
||||
'ns3::Vector',
|
||||
[param('ns3::Rectangle const &', 'bounds')],
|
||||
is_const=True)
|
||||
## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition() const [member function]
|
||||
cls.add_method('GetCurrentPosition',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True)
|
||||
## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetVelocity() const [member function]
|
||||
cls.add_method('GetVelocity',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True)
|
||||
## static-speed-helper.h: void ns3::StaticSpeedHelper::SetSpeed(ns3::Vector const & speed) [member function]
|
||||
cls.add_method('SetSpeed',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'speed')])
|
||||
## static-speed-helper.h: void ns3::StaticSpeedHelper::Pause() [member function]
|
||||
cls.add_method('Pause',
|
||||
'void',
|
||||
[])
|
||||
## static-speed-helper.h: void ns3::StaticSpeedHelper::Unpause() [member function]
|
||||
cls.add_method('Unpause',
|
||||
'void',
|
||||
[])
|
||||
return
|
||||
|
||||
def register_Ns3Vector_methods(root_module, cls):
|
||||
## vector.h: ns3::Vector::Vector(ns3::Vector const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::Vector const &', 'arg0')])
|
||||
## vector.h: ns3::Vector::Vector(double _x, double _y, double _z) [constructor]
|
||||
cls.add_constructor([param('double', '_x'), param('double', '_y'), param('double', '_z')])
|
||||
## vector.h: ns3::Vector::Vector() [constructor]
|
||||
cls.add_constructor([])
|
||||
## vector.h: ns3::Vector::x [variable]
|
||||
cls.add_instance_attribute('x', 'double', is_const=False)
|
||||
## vector.h: ns3::Vector::y [variable]
|
||||
cls.add_instance_attribute('y', 'double', is_const=False)
|
||||
## vector.h: ns3::Vector::z [variable]
|
||||
cls.add_instance_attribute('z', 'double', is_const=False)
|
||||
cls.add_output_stream_operator()
|
||||
return
|
||||
|
||||
def register_Ns3VectorChecker_methods(root_module, cls):
|
||||
## vector.h: ns3::VectorChecker::VectorChecker(ns3::VectorChecker const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::VectorChecker const &', 'arg0')])
|
||||
## vector.h: ns3::VectorChecker::VectorChecker() [constructor]
|
||||
cls.add_constructor([])
|
||||
return
|
||||
|
||||
def register_Ns3RectangleChecker_methods(root_module, cls):
|
||||
## rectangle.h: ns3::RectangleChecker::RectangleChecker(ns3::RectangleChecker const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::RectangleChecker const &', 'arg0')])
|
||||
## rectangle.h: ns3::RectangleChecker::RectangleChecker() [constructor]
|
||||
cls.add_constructor([])
|
||||
return
|
||||
|
||||
def register_Ns3Rectangle_methods(root_module, cls):
|
||||
## rectangle.h: ns3::Rectangle::Rectangle(ns3::Rectangle const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::Rectangle const &', 'arg0')])
|
||||
## rectangle.h: ns3::Rectangle::Rectangle(double _xMin, double _xMax, double _yMin, double _yMax) [constructor]
|
||||
cls.add_constructor([param('double', '_xMin'), param('double', '_xMax'), param('double', '_yMin'), param('double', '_yMax')])
|
||||
## rectangle.h: ns3::Rectangle::Rectangle() [constructor]
|
||||
cls.add_constructor([])
|
||||
## rectangle.h: ns3::Vector ns3::Rectangle::CalculateIntersection(ns3::Vector const & current, ns3::Vector const & speed) const [member function]
|
||||
cls.add_method('CalculateIntersection',
|
||||
'ns3::Vector',
|
||||
[param('ns3::Vector const &', 'current'), param('ns3::Vector const &', 'speed')],
|
||||
is_const=True)
|
||||
## rectangle.h: ns3::Rectangle::Side ns3::Rectangle::GetClosestSide(ns3::Vector const & position) const [member function]
|
||||
cls.add_method('GetClosestSide',
|
||||
'ns3::Rectangle::Side',
|
||||
[param('ns3::Vector const &', 'position')],
|
||||
is_const=True)
|
||||
## rectangle.h: bool ns3::Rectangle::IsInside(ns3::Vector const & position) const [member function]
|
||||
cls.add_method('IsInside',
|
||||
'bool',
|
||||
[param('ns3::Vector const &', 'position')],
|
||||
is_const=True)
|
||||
## rectangle.h: ns3::Rectangle::xMax [variable]
|
||||
cls.add_instance_attribute('xMax', 'double', is_const=False)
|
||||
## rectangle.h: ns3::Rectangle::xMin [variable]
|
||||
cls.add_instance_attribute('xMin', 'double', is_const=False)
|
||||
## rectangle.h: ns3::Rectangle::yMax [variable]
|
||||
cls.add_instance_attribute('yMax', 'double', is_const=False)
|
||||
## rectangle.h: ns3::Rectangle::yMin [variable]
|
||||
cls.add_instance_attribute('yMin', 'double', is_const=False)
|
||||
cls.add_output_stream_operator()
|
||||
return
|
||||
|
||||
def register_Ns3PositionAllocator_methods(root_module, cls):
|
||||
## position-allocator.h: ns3::PositionAllocator::PositionAllocator(ns3::PositionAllocator const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::PositionAllocator const &', 'arg0')])
|
||||
## position-allocator.h: static ns3::TypeId ns3::PositionAllocator::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## position-allocator.h: ns3::PositionAllocator::PositionAllocator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## position-allocator.h: ns3::Vector ns3::PositionAllocator::GetNext() const [member function]
|
||||
cls.add_method('GetNext',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_pure_virtual=True, is_const=True, is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3ListPositionAllocator_methods(root_module, cls):
|
||||
## position-allocator.h: ns3::ListPositionAllocator::ListPositionAllocator(ns3::ListPositionAllocator const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::ListPositionAllocator const &', 'arg0')])
|
||||
## position-allocator.h: static ns3::TypeId ns3::ListPositionAllocator::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## position-allocator.h: ns3::ListPositionAllocator::ListPositionAllocator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## position-allocator.h: void ns3::ListPositionAllocator::Add(ns3::Vector v) [member function]
|
||||
cls.add_method('Add',
|
||||
'void',
|
||||
[param('ns3::Vector', 'v')])
|
||||
## position-allocator.h: ns3::Vector ns3::ListPositionAllocator::GetNext() const [member function]
|
||||
cls.add_method('GetNext',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3RectangleValue_methods(root_module, cls):
|
||||
## rectangle.h: ns3::RectangleValue::RectangleValue(ns3::RectangleValue const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::RectangleValue const &', 'arg0')])
|
||||
## rectangle.h: ns3::RectangleValue::RectangleValue() [constructor]
|
||||
cls.add_constructor([])
|
||||
## rectangle.h: ns3::RectangleValue::RectangleValue(ns3::Rectangle const & value) [constructor]
|
||||
cls.add_constructor([param('ns3::Rectangle const &', 'value')])
|
||||
## rectangle.h: void ns3::RectangleValue::Set(ns3::Rectangle const & value) [member function]
|
||||
cls.add_method('Set',
|
||||
'void',
|
||||
[param('ns3::Rectangle const &', 'value')])
|
||||
## rectangle.h: ns3::Rectangle ns3::RectangleValue::Get() const [member function]
|
||||
cls.add_method('Get',
|
||||
'ns3::Rectangle',
|
||||
[],
|
||||
is_const=True)
|
||||
## rectangle.h: ns3::Ptr<ns3::AttributeValue> ns3::RectangleValue::Copy() const [member function]
|
||||
cls.add_method('Copy',
|
||||
'ns3::Ptr< ns3::AttributeValue >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## rectangle.h: std::string ns3::RectangleValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
|
||||
cls.add_method('SerializeToString',
|
||||
'std::string',
|
||||
[param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
|
||||
is_const=True, is_virtual=True)
|
||||
## rectangle.h: bool ns3::RectangleValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
|
||||
cls.add_method('DeserializeFromString',
|
||||
'bool',
|
||||
[param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
|
||||
is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3RandomRectanglePositionAllocator_methods(root_module, cls):
|
||||
## position-allocator.h: ns3::RandomRectanglePositionAllocator::RandomRectanglePositionAllocator(ns3::RandomRectanglePositionAllocator const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::RandomRectanglePositionAllocator const &', 'arg0')])
|
||||
## position-allocator.h: static ns3::TypeId ns3::RandomRectanglePositionAllocator::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## position-allocator.h: ns3::RandomRectanglePositionAllocator::RandomRectanglePositionAllocator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## position-allocator.h: void ns3::RandomRectanglePositionAllocator::SetX(ns3::RandomVariable x) [member function]
|
||||
cls.add_method('SetX',
|
||||
'void',
|
||||
[param('ns3::RandomVariable', 'x')])
|
||||
## position-allocator.h: void ns3::RandomRectanglePositionAllocator::SetY(ns3::RandomVariable y) [member function]
|
||||
cls.add_method('SetY',
|
||||
'void',
|
||||
[param('ns3::RandomVariable', 'y')])
|
||||
## position-allocator.h: ns3::Vector ns3::RandomRectanglePositionAllocator::GetNext() const [member function]
|
||||
cls.add_method('GetNext',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3VectorValue_methods(root_module, cls):
|
||||
## vector.h: ns3::VectorValue::VectorValue(ns3::VectorValue const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::VectorValue const &', 'arg0')])
|
||||
## vector.h: ns3::VectorValue::VectorValue() [constructor]
|
||||
cls.add_constructor([])
|
||||
## vector.h: ns3::VectorValue::VectorValue(ns3::Vector const & value) [constructor]
|
||||
cls.add_constructor([param('ns3::Vector const &', 'value')])
|
||||
## vector.h: void ns3::VectorValue::Set(ns3::Vector const & value) [member function]
|
||||
cls.add_method('Set',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'value')])
|
||||
## vector.h: ns3::Vector ns3::VectorValue::Get() const [member function]
|
||||
cls.add_method('Get',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True)
|
||||
## vector.h: ns3::Ptr<ns3::AttributeValue> ns3::VectorValue::Copy() const [member function]
|
||||
cls.add_method('Copy',
|
||||
'ns3::Ptr< ns3::AttributeValue >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## vector.h: std::string ns3::VectorValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
|
||||
cls.add_method('SerializeToString',
|
||||
'std::string',
|
||||
[param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
|
||||
is_const=True, is_virtual=True)
|
||||
## vector.h: bool ns3::VectorValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
|
||||
cls.add_method('DeserializeFromString',
|
||||
'bool',
|
||||
[param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
|
||||
is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3RandomDiscPositionAllocator_methods(root_module, cls):
|
||||
## position-allocator.h: ns3::RandomDiscPositionAllocator::RandomDiscPositionAllocator(ns3::RandomDiscPositionAllocator const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::RandomDiscPositionAllocator const &', 'arg0')])
|
||||
## position-allocator.h: static ns3::TypeId ns3::RandomDiscPositionAllocator::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## position-allocator.h: ns3::RandomDiscPositionAllocator::RandomDiscPositionAllocator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetTheta(ns3::RandomVariable theta) [member function]
|
||||
cls.add_method('SetTheta',
|
||||
'void',
|
||||
[param('ns3::RandomVariable', 'theta')])
|
||||
## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetRho(ns3::RandomVariable rho) [member function]
|
||||
cls.add_method('SetRho',
|
||||
'void',
|
||||
[param('ns3::RandomVariable', 'rho')])
|
||||
## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetX(double x) [member function]
|
||||
cls.add_method('SetX',
|
||||
'void',
|
||||
[param('double', 'x')])
|
||||
## position-allocator.h: void ns3::RandomDiscPositionAllocator::SetY(double y) [member function]
|
||||
cls.add_method('SetY',
|
||||
'void',
|
||||
[param('double', 'y')])
|
||||
## position-allocator.h: ns3::Vector ns3::RandomDiscPositionAllocator::GetNext() const [member function]
|
||||
cls.add_method('GetNext',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3MobilityModel_methods(root_module, cls):
|
||||
## mobility-model.h: ns3::MobilityModel::MobilityModel(ns3::MobilityModel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::MobilityModel const &', 'arg0')])
|
||||
## mobility-model.h: static ns3::TypeId ns3::MobilityModel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## mobility-model.h: ns3::MobilityModel::MobilityModel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## mobility-model.h: ns3::Vector ns3::MobilityModel::GetPosition() const [member function]
|
||||
cls.add_method('GetPosition',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True)
|
||||
## mobility-model.h: void ns3::MobilityModel::SetPosition(ns3::Vector const & position) [member function]
|
||||
cls.add_method('SetPosition',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'position')])
|
||||
## mobility-model.h: ns3::Vector ns3::MobilityModel::GetVelocity() const [member function]
|
||||
cls.add_method('GetVelocity',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True)
|
||||
## mobility-model.h: double ns3::MobilityModel::GetDistanceFrom(ns3::Ptr<const ns3::MobilityModel> position) const [member function]
|
||||
cls.add_method('GetDistanceFrom',
|
||||
'double',
|
||||
[param('ns3::Ptr< const ns3::MobilityModel >', 'position')],
|
||||
is_const=True)
|
||||
## mobility-model.h: void ns3::MobilityModel::NotifyCourseChange() const [member function]
|
||||
cls.add_method('NotifyCourseChange',
|
||||
'void',
|
||||
[],
|
||||
is_const=True, visibility='protected')
|
||||
## mobility-model.h: ns3::Vector ns3::MobilityModel::DoGetPosition() const [member function]
|
||||
cls.add_method('DoGetPosition',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
|
||||
## mobility-model.h: void ns3::MobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
|
||||
cls.add_method('DoSetPosition',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'position')],
|
||||
is_pure_virtual=True, visibility='private', is_virtual=True)
|
||||
## mobility-model.h: ns3::Vector ns3::MobilityModel::DoGetVelocity() const [member function]
|
||||
cls.add_method('DoGetVelocity',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3RandomDirection2dMobilityModel_methods(root_module, cls):
|
||||
## random-direction-2d-mobility-model.h: ns3::RandomDirection2dMobilityModel::RandomDirection2dMobilityModel(ns3::RandomDirection2dMobilityModel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::RandomDirection2dMobilityModel const &', 'arg0')])
|
||||
## random-direction-2d-mobility-model.h: static ns3::TypeId ns3::RandomDirection2dMobilityModel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## random-direction-2d-mobility-model.h: ns3::RandomDirection2dMobilityModel::RandomDirection2dMobilityModel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## random-direction-2d-mobility-model.h: void ns3::RandomDirection2dMobilityModel::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
## random-direction-2d-mobility-model.h: ns3::Vector ns3::RandomDirection2dMobilityModel::DoGetPosition() const [member function]
|
||||
cls.add_method('DoGetPosition',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
## random-direction-2d-mobility-model.h: void ns3::RandomDirection2dMobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
|
||||
cls.add_method('DoSetPosition',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'position')],
|
||||
visibility='private', is_virtual=True)
|
||||
## random-direction-2d-mobility-model.h: ns3::Vector ns3::RandomDirection2dMobilityModel::DoGetVelocity() const [member function]
|
||||
cls.add_method('DoGetVelocity',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3GridPositionAllocator_methods(root_module, cls):
|
||||
## position-allocator.h: ns3::GridPositionAllocator::GridPositionAllocator(ns3::GridPositionAllocator const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::GridPositionAllocator const &', 'arg0')])
|
||||
## position-allocator.h: static ns3::TypeId ns3::GridPositionAllocator::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## position-allocator.h: ns3::GridPositionAllocator::GridPositionAllocator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## position-allocator.h: void ns3::GridPositionAllocator::SetMinX(double xMin) [member function]
|
||||
cls.add_method('SetMinX',
|
||||
'void',
|
||||
[param('double', 'xMin')])
|
||||
## position-allocator.h: void ns3::GridPositionAllocator::SetMinY(double yMin) [member function]
|
||||
cls.add_method('SetMinY',
|
||||
'void',
|
||||
[param('double', 'yMin')])
|
||||
## position-allocator.h: void ns3::GridPositionAllocator::SetDeltaX(double deltaX) [member function]
|
||||
cls.add_method('SetDeltaX',
|
||||
'void',
|
||||
[param('double', 'deltaX')])
|
||||
## position-allocator.h: void ns3::GridPositionAllocator::SetDeltaY(double deltaY) [member function]
|
||||
cls.add_method('SetDeltaY',
|
||||
'void',
|
||||
[param('double', 'deltaY')])
|
||||
## position-allocator.h: void ns3::GridPositionAllocator::SetN(uint32_t n) [member function]
|
||||
cls.add_method('SetN',
|
||||
'void',
|
||||
[param('uint32_t', 'n')])
|
||||
## position-allocator.h: void ns3::GridPositionAllocator::SetLayoutType(ns3::GridPositionAllocator::LayoutType layoutType) [member function]
|
||||
cls.add_method('SetLayoutType',
|
||||
'void',
|
||||
[param('ns3::GridPositionAllocator::LayoutType', 'layoutType')])
|
||||
## position-allocator.h: double ns3::GridPositionAllocator::GetMinX() const [member function]
|
||||
cls.add_method('GetMinX',
|
||||
'double',
|
||||
[],
|
||||
is_const=True)
|
||||
## position-allocator.h: double ns3::GridPositionAllocator::GetMinY() const [member function]
|
||||
cls.add_method('GetMinY',
|
||||
'double',
|
||||
[],
|
||||
is_const=True)
|
||||
## position-allocator.h: double ns3::GridPositionAllocator::GetDeltaX() const [member function]
|
||||
cls.add_method('GetDeltaX',
|
||||
'double',
|
||||
[],
|
||||
is_const=True)
|
||||
## position-allocator.h: double ns3::GridPositionAllocator::GetDeltaY() const [member function]
|
||||
cls.add_method('GetDeltaY',
|
||||
'double',
|
||||
[],
|
||||
is_const=True)
|
||||
## position-allocator.h: uint32_t ns3::GridPositionAllocator::GetN() const [member function]
|
||||
cls.add_method('GetN',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## position-allocator.h: ns3::GridPositionAllocator::LayoutType ns3::GridPositionAllocator::GetLayoutType() const [member function]
|
||||
cls.add_method('GetLayoutType',
|
||||
'ns3::GridPositionAllocator::LayoutType',
|
||||
[],
|
||||
is_const=True)
|
||||
## position-allocator.h: ns3::Vector ns3::GridPositionAllocator::GetNext() const [member function]
|
||||
cls.add_method('GetNext',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3RandomWaypointMobilityModel_methods(root_module, cls):
|
||||
## random-waypoint-mobility-model.h: ns3::RandomWaypointMobilityModel::RandomWaypointMobilityModel(ns3::RandomWaypointMobilityModel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::RandomWaypointMobilityModel const &', 'arg0')])
|
||||
## random-waypoint-mobility-model.h: static ns3::TypeId ns3::RandomWaypointMobilityModel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## random-waypoint-mobility-model.h: ns3::RandomWaypointMobilityModel::RandomWaypointMobilityModel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## random-waypoint-mobility-model.h: ns3::Vector ns3::RandomWaypointMobilityModel::DoGetPosition() const [member function]
|
||||
cls.add_method('DoGetPosition',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
## random-waypoint-mobility-model.h: void ns3::RandomWaypointMobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
|
||||
cls.add_method('DoSetPosition',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'position')],
|
||||
visibility='private', is_virtual=True)
|
||||
## random-waypoint-mobility-model.h: ns3::Vector ns3::RandomWaypointMobilityModel::DoGetVelocity() const [member function]
|
||||
cls.add_method('DoGetVelocity',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3RandomWalk2dMobilityModel_methods(root_module, cls):
|
||||
## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel::RandomWalk2dMobilityModel(ns3::RandomWalk2dMobilityModel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::RandomWalk2dMobilityModel const &', 'arg0')])
|
||||
## random-walk-2d-mobility-model.h: static ns3::TypeId ns3::RandomWalk2dMobilityModel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## random-walk-2d-mobility-model.h: ns3::RandomWalk2dMobilityModel::RandomWalk2dMobilityModel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## random-walk-2d-mobility-model.h: void ns3::RandomWalk2dMobilityModel::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
## random-walk-2d-mobility-model.h: ns3::Vector ns3::RandomWalk2dMobilityModel::DoGetPosition() const [member function]
|
||||
cls.add_method('DoGetPosition',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
## random-walk-2d-mobility-model.h: void ns3::RandomWalk2dMobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
|
||||
cls.add_method('DoSetPosition',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'position')],
|
||||
visibility='private', is_virtual=True)
|
||||
## random-walk-2d-mobility-model.h: ns3::Vector ns3::RandomWalk2dMobilityModel::DoGetVelocity() const [member function]
|
||||
cls.add_method('DoGetVelocity',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3StaticSpeedMobilityModel_methods(root_module, cls):
|
||||
## static-speed-mobility-model.h: ns3::StaticSpeedMobilityModel::StaticSpeedMobilityModel(ns3::StaticSpeedMobilityModel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::StaticSpeedMobilityModel const &', 'arg0')])
|
||||
## static-speed-mobility-model.h: static ns3::TypeId ns3::StaticSpeedMobilityModel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## static-speed-mobility-model.h: ns3::StaticSpeedMobilityModel::StaticSpeedMobilityModel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::SetSpeed(ns3::Vector const & speed) [member function]
|
||||
cls.add_method('SetSpeed',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'speed')])
|
||||
## static-speed-mobility-model.h: ns3::Vector ns3::StaticSpeedMobilityModel::DoGetPosition() const [member function]
|
||||
cls.add_method('DoGetPosition',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
|
||||
cls.add_method('DoSetPosition',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'position')],
|
||||
visibility='private', is_virtual=True)
|
||||
## static-speed-mobility-model.h: ns3::Vector ns3::StaticSpeedMobilityModel::DoGetVelocity() const [member function]
|
||||
cls.add_method('DoGetVelocity',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3HierarchicalMobilityModel_methods(root_module, cls):
|
||||
## hierarchical-mobility-model.h: ns3::HierarchicalMobilityModel::HierarchicalMobilityModel(ns3::HierarchicalMobilityModel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::HierarchicalMobilityModel const &', 'arg0')])
|
||||
## hierarchical-mobility-model.h: static ns3::TypeId ns3::HierarchicalMobilityModel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## hierarchical-mobility-model.h: ns3::HierarchicalMobilityModel::HierarchicalMobilityModel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## hierarchical-mobility-model.h: ns3::Ptr<ns3::MobilityModel> ns3::HierarchicalMobilityModel::GetChild() const [member function]
|
||||
cls.add_method('GetChild',
|
||||
'ns3::Ptr< ns3::MobilityModel >',
|
||||
[],
|
||||
is_const=True)
|
||||
## hierarchical-mobility-model.h: ns3::Ptr<ns3::MobilityModel> ns3::HierarchicalMobilityModel::GetParent() const [member function]
|
||||
cls.add_method('GetParent',
|
||||
'ns3::Ptr< ns3::MobilityModel >',
|
||||
[],
|
||||
is_const=True)
|
||||
## hierarchical-mobility-model.h: ns3::Vector ns3::HierarchicalMobilityModel::DoGetPosition() const [member function]
|
||||
cls.add_method('DoGetPosition',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
## hierarchical-mobility-model.h: void ns3::HierarchicalMobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
|
||||
cls.add_method('DoSetPosition',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'position')],
|
||||
visibility='private', is_virtual=True)
|
||||
## hierarchical-mobility-model.h: ns3::Vector ns3::HierarchicalMobilityModel::DoGetVelocity() const [member function]
|
||||
cls.add_method('DoGetVelocity',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3StaticMobilityModel_methods(root_module, cls):
|
||||
## static-mobility-model.h: ns3::StaticMobilityModel::StaticMobilityModel(ns3::StaticMobilityModel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::StaticMobilityModel const &', 'arg0')])
|
||||
## static-mobility-model.h: static ns3::TypeId ns3::StaticMobilityModel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## static-mobility-model.h: ns3::StaticMobilityModel::StaticMobilityModel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## static-mobility-model.h: ns3::Vector ns3::StaticMobilityModel::DoGetPosition() const [member function]
|
||||
cls.add_method('DoGetPosition',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
## static-mobility-model.h: void ns3::StaticMobilityModel::DoSetPosition(ns3::Vector const & position) [member function]
|
||||
cls.add_method('DoSetPosition',
|
||||
'void',
|
||||
[param('ns3::Vector const &', 'position')],
|
||||
visibility='private', is_virtual=True)
|
||||
## static-mobility-model.h: ns3::Vector ns3::StaticMobilityModel::DoGetVelocity() const [member function]
|
||||
cls.add_method('DoGetVelocity',
|
||||
'ns3::Vector',
|
||||
[],
|
||||
is_const=True, visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
## rectangle.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeRectangleChecker() [free function]
|
||||
module.add_function('MakeRectangleChecker',
|
||||
'ns3::Ptr< ns3::AttributeChecker const >',
|
||||
[])
|
||||
## vector.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeVectorChecker() [free function]
|
||||
module.add_function('MakeVectorChecker',
|
||||
'ns3::Ptr< ns3::AttributeChecker const >',
|
||||
[])
|
||||
## vector.h: extern double ns3::CalculateDistance(ns3::Vector const & a, ns3::Vector const & b) [free function]
|
||||
module.add_function('CalculateDistance',
|
||||
'double',
|
||||
[param('ns3::Vector const &', 'a'), param('ns3::Vector const &', 'b')])
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,466 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## olsr-header.h: ns3::olsr::MessageHeader [class]
|
||||
module.add_class('MessageHeader', parent=root_module['ns3::Header'])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::MessageType [enumeration]
|
||||
module.add_enum('MessageType', ['HELLO_MESSAGE', 'TC_MESSAGE', 'MID_MESSAGE', 'HNA_MESSAGE'], outer_class=root_module['ns3::olsr::MessageHeader'])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Mid [struct]
|
||||
module.add_class('Mid', outer_class=root_module['ns3::olsr::MessageHeader'])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello [struct]
|
||||
module.add_class('Hello', outer_class=root_module['ns3::olsr::MessageHeader'])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::LinkMessage [struct]
|
||||
module.add_class('LinkMessage', outer_class=root_module['ns3::olsr::MessageHeader::Hello'])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Tc [struct]
|
||||
module.add_class('Tc', outer_class=root_module['ns3::olsr::MessageHeader'])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna [struct]
|
||||
module.add_class('Hna', outer_class=root_module['ns3::olsr::MessageHeader'])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna::Association [struct]
|
||||
module.add_class('Association', outer_class=root_module['ns3::olsr::MessageHeader::Hna'])
|
||||
## olsr-agent.h: ns3::olsr::Agent [class]
|
||||
module.add_class('Agent', parent=root_module['ns3::Object'])
|
||||
## olsr-header.h: ns3::olsr::PacketHeader [class]
|
||||
module.add_class('PacketHeader', parent=root_module['ns3::Header'])
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3OlsrMessageHeader_methods(root_module, root_module['ns3::olsr::MessageHeader'])
|
||||
register_Ns3OlsrMessageHeaderMid_methods(root_module, root_module['ns3::olsr::MessageHeader::Mid'])
|
||||
register_Ns3OlsrMessageHeaderHello_methods(root_module, root_module['ns3::olsr::MessageHeader::Hello'])
|
||||
register_Ns3OlsrMessageHeaderHelloLinkMessage_methods(root_module, root_module['ns3::olsr::MessageHeader::Hello::LinkMessage'])
|
||||
register_Ns3OlsrMessageHeaderTc_methods(root_module, root_module['ns3::olsr::MessageHeader::Tc'])
|
||||
register_Ns3OlsrMessageHeaderHna_methods(root_module, root_module['ns3::olsr::MessageHeader::Hna'])
|
||||
register_Ns3OlsrMessageHeaderHnaAssociation_methods(root_module, root_module['ns3::olsr::MessageHeader::Hna::Association'])
|
||||
register_Ns3OlsrAgent_methods(root_module, root_module['ns3::olsr::Agent'])
|
||||
register_Ns3OlsrPacketHeader_methods(root_module, root_module['ns3::olsr::PacketHeader'])
|
||||
return
|
||||
|
||||
def register_Ns3OlsrMessageHeader_methods(root_module, cls):
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::MessageHeader(ns3::olsr::MessageHeader const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::olsr::MessageHeader const &', 'arg0')])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::MessageHeader() [constructor]
|
||||
cls.add_constructor([])
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
|
||||
cls.add_method('Deserialize',
|
||||
'uint32_t',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_virtual=True)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello & ns3::olsr::MessageHeader::GetHello() [member function]
|
||||
cls.add_method('GetHello',
|
||||
'ns3::olsr::MessageHeader::Hello &',
|
||||
[])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello const & ns3::olsr::MessageHeader::GetHello() const [member function]
|
||||
cls.add_method('GetHello',
|
||||
'ns3::olsr::MessageHeader::Hello const &',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna & ns3::olsr::MessageHeader::GetHna() [member function]
|
||||
cls.add_method('GetHna',
|
||||
'ns3::olsr::MessageHeader::Hna &',
|
||||
[])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna const & ns3::olsr::MessageHeader::GetHna() const [member function]
|
||||
cls.add_method('GetHna',
|
||||
'ns3::olsr::MessageHeader::Hna const &',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: uint8_t ns3::olsr::MessageHeader::GetHopCount() const [member function]
|
||||
cls.add_method('GetHopCount',
|
||||
'uint8_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: ns3::TypeId ns3::olsr::MessageHeader::GetInstanceTypeId() const [member function]
|
||||
cls.add_method('GetInstanceTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## olsr-header.h: uint16_t ns3::olsr::MessageHeader::GetMessageSequenceNumber() const [member function]
|
||||
cls.add_method('GetMessageSequenceNumber',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::MessageType ns3::olsr::MessageHeader::GetMessageType() const [member function]
|
||||
cls.add_method('GetMessageType',
|
||||
'ns3::olsr::MessageHeader::MessageType',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Mid & ns3::olsr::MessageHeader::GetMid() [member function]
|
||||
cls.add_method('GetMid',
|
||||
'ns3::olsr::MessageHeader::Mid &',
|
||||
[])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Mid const & ns3::olsr::MessageHeader::GetMid() const [member function]
|
||||
cls.add_method('GetMid',
|
||||
'ns3::olsr::MessageHeader::Mid const &',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: ns3::Ipv4Address ns3::olsr::MessageHeader::GetOriginatorAddress() const [member function]
|
||||
cls.add_method('GetOriginatorAddress',
|
||||
'ns3::Ipv4Address',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::GetSerializedSize() const [member function]
|
||||
cls.add_method('GetSerializedSize',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Tc & ns3::olsr::MessageHeader::GetTc() [member function]
|
||||
cls.add_method('GetTc',
|
||||
'ns3::olsr::MessageHeader::Tc &',
|
||||
[])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Tc const & ns3::olsr::MessageHeader::GetTc() const [member function]
|
||||
cls.add_method('GetTc',
|
||||
'ns3::olsr::MessageHeader::Tc const &',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: uint8_t ns3::olsr::MessageHeader::GetTimeToLive() const [member function]
|
||||
cls.add_method('GetTimeToLive',
|
||||
'uint8_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: static ns3::TypeId ns3::olsr::MessageHeader::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## olsr-header.h: ns3::Time ns3::olsr::MessageHeader::GetVTime() const [member function]
|
||||
cls.add_method('GetVTime',
|
||||
'ns3::Time',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Print(std::ostream & os) const [member function]
|
||||
cls.add_method('Print',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_const=True, is_virtual=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
|
||||
cls.add_method('Serialize',
|
||||
'void',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_const=True, is_virtual=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::SetHopCount(uint8_t hopCount) [member function]
|
||||
cls.add_method('SetHopCount',
|
||||
'void',
|
||||
[param('uint8_t', 'hopCount')])
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::SetMessageSequenceNumber(uint16_t messageSequenceNumber) [member function]
|
||||
cls.add_method('SetMessageSequenceNumber',
|
||||
'void',
|
||||
[param('uint16_t', 'messageSequenceNumber')])
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::SetMessageType(ns3::olsr::MessageHeader::MessageType messageType) [member function]
|
||||
cls.add_method('SetMessageType',
|
||||
'void',
|
||||
[param('ns3::olsr::MessageHeader::MessageType', 'messageType')])
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::SetOriginatorAddress(ns3::Ipv4Address originatorAddress) [member function]
|
||||
cls.add_method('SetOriginatorAddress',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'originatorAddress')])
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::SetTimeToLive(uint8_t timeToLive) [member function]
|
||||
cls.add_method('SetTimeToLive',
|
||||
'void',
|
||||
[param('uint8_t', 'timeToLive')])
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::SetVTime(ns3::Time time) [member function]
|
||||
cls.add_method('SetVTime',
|
||||
'void',
|
||||
[param('ns3::Time', 'time')])
|
||||
cls.add_output_stream_operator()
|
||||
return
|
||||
|
||||
def register_Ns3OlsrMessageHeaderMid_methods(root_module, cls):
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Mid::Mid() [constructor]
|
||||
cls.add_constructor([])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Mid::Mid(ns3::olsr::MessageHeader::Mid const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::olsr::MessageHeader::Mid const &', 'arg0')])
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Mid::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function]
|
||||
cls.add_method('Deserialize',
|
||||
'uint32_t',
|
||||
[param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')])
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Mid::GetSerializedSize() const [member function]
|
||||
cls.add_method('GetSerializedSize',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Mid::Print(std::ostream & os) const [member function]
|
||||
cls.add_method('Print',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Mid::Serialize(ns3::Buffer::Iterator start) const [member function]
|
||||
cls.add_method('Serialize',
|
||||
'void',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_const=True)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Mid::interfaceAddresses [variable]
|
||||
cls.add_instance_attribute('interfaceAddresses', 'std::vector< ns3::Ipv4Address >', is_const=False)
|
||||
return
|
||||
|
||||
def register_Ns3OlsrMessageHeaderHello_methods(root_module, cls):
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::Hello() [constructor]
|
||||
cls.add_constructor([])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::Hello(ns3::olsr::MessageHeader::Hello const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::olsr::MessageHeader::Hello const &', 'arg0')])
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hello::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function]
|
||||
cls.add_method('Deserialize',
|
||||
'uint32_t',
|
||||
[param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')])
|
||||
## olsr-header.h: ns3::Time ns3::olsr::MessageHeader::Hello::GetHTime() const [member function]
|
||||
cls.add_method('GetHTime',
|
||||
'ns3::Time',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hello::GetSerializedSize() const [member function]
|
||||
cls.add_method('GetSerializedSize',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Hello::Print(std::ostream & os) const [member function]
|
||||
cls.add_method('Print',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Hello::Serialize(ns3::Buffer::Iterator start) const [member function]
|
||||
cls.add_method('Serialize',
|
||||
'void',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Hello::SetHTime(ns3::Time time) [member function]
|
||||
cls.add_method('SetHTime',
|
||||
'void',
|
||||
[param('ns3::Time', 'time')])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::hTime [variable]
|
||||
cls.add_instance_attribute('hTime', 'uint8_t', is_const=False)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::linkMessages [variable]
|
||||
cls.add_instance_attribute('linkMessages', 'std::vector< ns3::olsr::MessageHeader::Hello::LinkMessage >', is_const=False)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::willingness [variable]
|
||||
cls.add_instance_attribute('willingness', 'uint8_t', is_const=False)
|
||||
return
|
||||
|
||||
def register_Ns3OlsrMessageHeaderHelloLinkMessage_methods(root_module, cls):
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::LinkMessage::linkCode [variable]
|
||||
cls.add_instance_attribute('linkCode', 'uint8_t', is_const=False)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::LinkMessage::neighborInterfaceAddresses [variable]
|
||||
cls.add_instance_attribute('neighborInterfaceAddresses', 'std::vector< ns3::Ipv4Address >', is_const=False)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::LinkMessage::LinkMessage(ns3::olsr::MessageHeader::Hello::LinkMessage const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::olsr::MessageHeader::Hello::LinkMessage const &', 'arg0')])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hello::LinkMessage::LinkMessage() [constructor]
|
||||
cls.add_constructor([])
|
||||
return
|
||||
|
||||
def register_Ns3OlsrMessageHeaderTc_methods(root_module, cls):
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Tc::Tc() [constructor]
|
||||
cls.add_constructor([])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Tc::Tc(ns3::olsr::MessageHeader::Tc const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::olsr::MessageHeader::Tc const &', 'arg0')])
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Tc::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function]
|
||||
cls.add_method('Deserialize',
|
||||
'uint32_t',
|
||||
[param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')])
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Tc::GetSerializedSize() const [member function]
|
||||
cls.add_method('GetSerializedSize',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Tc::Print(std::ostream & os) const [member function]
|
||||
cls.add_method('Print',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Tc::Serialize(ns3::Buffer::Iterator start) const [member function]
|
||||
cls.add_method('Serialize',
|
||||
'void',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_const=True)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Tc::ansn [variable]
|
||||
cls.add_instance_attribute('ansn', 'uint16_t', is_const=False)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Tc::neighborAddresses [variable]
|
||||
cls.add_instance_attribute('neighborAddresses', 'std::vector< ns3::Ipv4Address >', is_const=False)
|
||||
return
|
||||
|
||||
def register_Ns3OlsrMessageHeaderHna_methods(root_module, cls):
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna::Hna() [constructor]
|
||||
cls.add_constructor([])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna::Hna(ns3::olsr::MessageHeader::Hna const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::olsr::MessageHeader::Hna const &', 'arg0')])
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hna::Deserialize(ns3::Buffer::Iterator start, uint32_t messageSize) [member function]
|
||||
cls.add_method('Deserialize',
|
||||
'uint32_t',
|
||||
[param('ns3::Buffer::Iterator', 'start'), param('uint32_t', 'messageSize')])
|
||||
## olsr-header.h: uint32_t ns3::olsr::MessageHeader::Hna::GetSerializedSize() const [member function]
|
||||
cls.add_method('GetSerializedSize',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Hna::Print(std::ostream & os) const [member function]
|
||||
cls.add_method('Print',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_const=True)
|
||||
## olsr-header.h: void ns3::olsr::MessageHeader::Hna::Serialize(ns3::Buffer::Iterator start) const [member function]
|
||||
cls.add_method('Serialize',
|
||||
'void',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_const=True)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna::associations [variable]
|
||||
cls.add_instance_attribute('associations', 'std::vector< ns3::olsr::MessageHeader::Hna::Association >', is_const=False)
|
||||
return
|
||||
|
||||
def register_Ns3OlsrMessageHeaderHnaAssociation_methods(root_module, cls):
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna::Association::address [variable]
|
||||
cls.add_instance_attribute('address', 'ns3::Ipv4Address', is_const=False)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna::Association::mask [variable]
|
||||
cls.add_instance_attribute('mask', 'ns3::Ipv4Mask', is_const=False)
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna::Association::Association(ns3::olsr::MessageHeader::Hna::Association const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::olsr::MessageHeader::Hna::Association const &', 'arg0')])
|
||||
## olsr-header.h: ns3::olsr::MessageHeader::Hna::Association::Association() [constructor]
|
||||
cls.add_constructor([])
|
||||
return
|
||||
|
||||
def register_Ns3OlsrAgent_methods(root_module, cls):
|
||||
## olsr-agent.h: ns3::olsr::Agent::Agent(ns3::olsr::Agent const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::olsr::Agent const &', 'arg0')])
|
||||
## olsr-agent.h: ns3::olsr::Agent::Agent() [constructor]
|
||||
cls.add_constructor([])
|
||||
## olsr-agent.h: static ns3::TypeId ns3::olsr::Agent::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## olsr-agent.h: void ns3::olsr::Agent::SetNode(ns3::Ptr<ns3::Node> node) [member function]
|
||||
cls.add_method('SetNode',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node')],
|
||||
is_pure_virtual=True, is_virtual=True)
|
||||
## olsr-agent.h: void ns3::olsr::Agent::SetMainInterface(uint32_t interface) [member function]
|
||||
cls.add_method('SetMainInterface',
|
||||
'void',
|
||||
[param('uint32_t', 'interface')],
|
||||
is_pure_virtual=True, is_virtual=True)
|
||||
## olsr-agent.h: void ns3::olsr::Agent::Start() [member function]
|
||||
cls.add_method('Start',
|
||||
'void',
|
||||
[],
|
||||
is_pure_virtual=True, is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3OlsrPacketHeader_methods(root_module, cls):
|
||||
## olsr-header.h: ns3::olsr::PacketHeader::PacketHeader(ns3::olsr::PacketHeader const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::olsr::PacketHeader const &', 'arg0')])
|
||||
## olsr-header.h: ns3::olsr::PacketHeader::PacketHeader() [constructor]
|
||||
cls.add_constructor([])
|
||||
## olsr-header.h: uint32_t ns3::olsr::PacketHeader::Deserialize(ns3::Buffer::Iterator start) [member function]
|
||||
cls.add_method('Deserialize',
|
||||
'uint32_t',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_virtual=True)
|
||||
## olsr-header.h: ns3::TypeId ns3::olsr::PacketHeader::GetInstanceTypeId() const [member function]
|
||||
cls.add_method('GetInstanceTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## olsr-header.h: uint16_t ns3::olsr::PacketHeader::GetPacketLength() const [member function]
|
||||
cls.add_method('GetPacketLength',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: uint16_t ns3::olsr::PacketHeader::GetPacketSequenceNumber() const [member function]
|
||||
cls.add_method('GetPacketSequenceNumber',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True)
|
||||
## olsr-header.h: uint32_t ns3::olsr::PacketHeader::GetSerializedSize() const [member function]
|
||||
cls.add_method('GetSerializedSize',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## olsr-header.h: static ns3::TypeId ns3::olsr::PacketHeader::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## olsr-header.h: void ns3::olsr::PacketHeader::Print(std::ostream & os) const [member function]
|
||||
cls.add_method('Print',
|
||||
'void',
|
||||
[param('std::ostream &', 'os')],
|
||||
is_const=True, is_virtual=True)
|
||||
## olsr-header.h: void ns3::olsr::PacketHeader::Serialize(ns3::Buffer::Iterator start) const [member function]
|
||||
cls.add_method('Serialize',
|
||||
'void',
|
||||
[param('ns3::Buffer::Iterator', 'start')],
|
||||
is_const=True, is_virtual=True)
|
||||
## olsr-header.h: void ns3::olsr::PacketHeader::SetPacketLength(uint16_t length) [member function]
|
||||
cls.add_method('SetPacketLength',
|
||||
'void',
|
||||
[param('uint16_t', 'length')])
|
||||
## olsr-header.h: void ns3::olsr::PacketHeader::SetPacketSequenceNumber(uint16_t seqnum) [member function]
|
||||
cls.add_method('SetPacketSequenceNumber',
|
||||
'void',
|
||||
[param('uint16_t', 'seqnum')])
|
||||
cls.add_output_stream_operator()
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
## olsr-header.h: extern double ns3::olsr::EmfToSeconds(uint8_t emf) [free function]
|
||||
module.add_function('EmfToSeconds',
|
||||
'double',
|
||||
[param('uint8_t', 'emf')])
|
||||
## olsr-header.h: extern uint8_t ns3::olsr::SecondsToEmf(double seconds) [free function]
|
||||
module.add_function('SecondsToEmf',
|
||||
'uint8_t',
|
||||
[param('double', 'seconds')])
|
||||
return
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## onoff-application.h: ns3::OnOffApplication [class]
|
||||
module.add_class('OnOffApplication', parent=root_module['ns3::Application'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3OnOffApplication_methods(root_module, root_module['ns3::OnOffApplication'])
|
||||
return
|
||||
|
||||
def register_Ns3OnOffApplication_methods(root_module, cls):
|
||||
## onoff-application.h: ns3::OnOffApplication::OnOffApplication(ns3::OnOffApplication const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::OnOffApplication const &', 'arg0')])
|
||||
## onoff-application.h: static ns3::TypeId ns3::OnOffApplication::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## onoff-application.h: ns3::OnOffApplication::OnOffApplication() [constructor]
|
||||
cls.add_constructor([])
|
||||
## onoff-application.h: void ns3::OnOffApplication::SetMaxBytes(uint32_t maxBytes) [member function]
|
||||
cls.add_method('SetMaxBytes',
|
||||
'void',
|
||||
[param('uint32_t', 'maxBytes')])
|
||||
## onoff-application.h: void ns3::OnOffApplication::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
## onoff-application.h: void ns3::OnOffApplication::StartApplication() [member function]
|
||||
cls.add_method('StartApplication',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
## onoff-application.h: void ns3::OnOffApplication::StopApplication() [member function]
|
||||
cls.add_method('StopApplication',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## packet-sink.h: ns3::PacketSink [class]
|
||||
module.add_class('PacketSink', parent=root_module['ns3::Application'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3PacketSink_methods(root_module, root_module['ns3::PacketSink'])
|
||||
return
|
||||
|
||||
def register_Ns3PacketSink_methods(root_module, cls):
|
||||
## packet-sink.h: ns3::PacketSink::PacketSink(ns3::PacketSink const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::PacketSink const &', 'arg0')])
|
||||
## packet-sink.h: static ns3::TypeId ns3::PacketSink::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## packet-sink.h: ns3::PacketSink::PacketSink() [constructor]
|
||||
cls.add_constructor([])
|
||||
## packet-sink.h: void ns3::PacketSink::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
## packet-sink.h: void ns3::PacketSink::StartApplication() [member function]
|
||||
cls.add_method('StartApplication',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
## packet-sink.h: void ns3::PacketSink::StopApplication() [member function]
|
||||
cls.add_method('StopApplication',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## point-to-point-channel.h: ns3::PointToPointChannel [class]
|
||||
module.add_class('PointToPointChannel', parent=root_module['ns3::Channel'])
|
||||
## point-to-point-net-device.h: ns3::PointToPointNetDevice [class]
|
||||
module.add_class('PointToPointNetDevice', parent=root_module['ns3::NetDevice'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3PointToPointChannel_methods(root_module, root_module['ns3::PointToPointChannel'])
|
||||
register_Ns3PointToPointNetDevice_methods(root_module, root_module['ns3::PointToPointNetDevice'])
|
||||
return
|
||||
|
||||
def register_Ns3PointToPointChannel_methods(root_module, cls):
|
||||
## point-to-point-channel.h: ns3::PointToPointChannel::PointToPointChannel(ns3::PointToPointChannel const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::PointToPointChannel const &', 'arg0')])
|
||||
## point-to-point-channel.h: static ns3::TypeId ns3::PointToPointChannel::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## point-to-point-channel.h: ns3::PointToPointChannel::PointToPointChannel() [constructor]
|
||||
cls.add_constructor([])
|
||||
## point-to-point-channel.h: void ns3::PointToPointChannel::Attach(ns3::Ptr<ns3::PointToPointNetDevice> device) [member function]
|
||||
cls.add_method('Attach',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::PointToPointNetDevice >', 'device')])
|
||||
## point-to-point-channel.h: bool ns3::PointToPointChannel::TransmitStart(ns3::Ptr<ns3::Packet> p, ns3::Ptr<ns3::PointToPointNetDevice> src, ns3::Time txTime) [member function]
|
||||
cls.add_method('TransmitStart',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Ptr< ns3::PointToPointNetDevice >', 'src'), param('ns3::Time', 'txTime')])
|
||||
## point-to-point-channel.h: uint32_t ns3::PointToPointChannel::GetNDevices() const [member function]
|
||||
cls.add_method('GetNDevices',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-channel.h: ns3::Ptr<ns3::PointToPointNetDevice> ns3::PointToPointChannel::GetPointToPointDevice(uint32_t i) const [member function]
|
||||
cls.add_method('GetPointToPointDevice',
|
||||
'ns3::Ptr< ns3::PointToPointNetDevice >',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True)
|
||||
## point-to-point-channel.h: ns3::Ptr<ns3::NetDevice> ns3::PointToPointChannel::GetDevice(uint32_t i) const [member function]
|
||||
cls.add_method('GetDevice',
|
||||
'ns3::Ptr< ns3::NetDevice >',
|
||||
[param('uint32_t', 'i')],
|
||||
is_const=True, is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3PointToPointNetDevice_methods(root_module, cls):
|
||||
## point-to-point-net-device.h: ns3::PointToPointNetDevice::PointToPointNetDevice(ns3::PointToPointNetDevice const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::PointToPointNetDevice const &', 'arg0')])
|
||||
## point-to-point-net-device.h: static ns3::TypeId ns3::PointToPointNetDevice::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## point-to-point-net-device.h: ns3::PointToPointNetDevice::PointToPointNetDevice() [constructor]
|
||||
cls.add_constructor([])
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetDataRate(ns3::DataRate bps) [member function]
|
||||
cls.add_method('SetDataRate',
|
||||
'void',
|
||||
[param('ns3::DataRate', 'bps')])
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetInterframeGap(ns3::Time t) [member function]
|
||||
cls.add_method('SetInterframeGap',
|
||||
'void',
|
||||
[param('ns3::Time', 't')])
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::Attach(ns3::Ptr<ns3::PointToPointChannel> ch) [member function]
|
||||
cls.add_method('Attach',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::PointToPointChannel >', 'ch')])
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetQueue(ns3::Ptr<ns3::Queue> queue) [member function]
|
||||
cls.add_method('SetQueue',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Queue >', 'queue')])
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveErrorModel(ns3::Ptr<ns3::ErrorModel> em) [member function]
|
||||
cls.add_method('SetReceiveErrorModel',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::ErrorModel >', 'em')])
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::Receive(ns3::Ptr<ns3::Packet> p) [member function]
|
||||
cls.add_method('Receive',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'p')])
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetAddress(ns3::Mac48Address addr) [member function]
|
||||
cls.add_method('SetAddress',
|
||||
'void',
|
||||
[param('ns3::Mac48Address', 'addr')])
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetName(std::string const name) [member function]
|
||||
cls.add_method('SetName',
|
||||
'void',
|
||||
[param('std::string const', 'name')],
|
||||
is_virtual=True)
|
||||
## point-to-point-net-device.h: std::string ns3::PointToPointNetDevice::GetName() const [member function]
|
||||
cls.add_method('GetName',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetIfIndex(uint32_t const index) [member function]
|
||||
cls.add_method('SetIfIndex',
|
||||
'void',
|
||||
[param('uint32_t const', 'index')],
|
||||
is_virtual=True)
|
||||
## point-to-point-net-device.h: uint32_t ns3::PointToPointNetDevice::GetIfIndex() const [member function]
|
||||
cls.add_method('GetIfIndex',
|
||||
'uint32_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: ns3::Ptr<ns3::Channel> ns3::PointToPointNetDevice::GetChannel() const [member function]
|
||||
cls.add_method('GetChannel',
|
||||
'ns3::Ptr< ns3::Channel >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::GetAddress() const [member function]
|
||||
cls.add_method('GetAddress',
|
||||
'ns3::Address',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::SetMtu(uint16_t const mtu) [member function]
|
||||
cls.add_method('SetMtu',
|
||||
'bool',
|
||||
[param('uint16_t const', 'mtu')],
|
||||
is_virtual=True)
|
||||
## point-to-point-net-device.h: uint16_t ns3::PointToPointNetDevice::GetMtu() const [member function]
|
||||
cls.add_method('GetMtu',
|
||||
'uint16_t',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsLinkUp() const [member function]
|
||||
cls.add_method('IsLinkUp',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetLinkChangeCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
|
||||
cls.add_method('SetLinkChangeCallback',
|
||||
'void',
|
||||
[param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')],
|
||||
is_virtual=True)
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsBroadcast() const [member function]
|
||||
cls.add_method('IsBroadcast',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::GetBroadcast() const [member function]
|
||||
cls.add_method('GetBroadcast',
|
||||
'ns3::Address',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsMulticast() const [member function]
|
||||
cls.add_method('IsMulticast',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::GetMulticast() const [member function]
|
||||
cls.add_method('GetMulticast',
|
||||
'ns3::Address',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: ns3::Address ns3::PointToPointNetDevice::MakeMulticastAddress(ns3::Ipv4Address multicastGroup) const [member function]
|
||||
cls.add_method('MakeMulticastAddress',
|
||||
'ns3::Address',
|
||||
[param('ns3::Ipv4Address', 'multicastGroup')],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::IsPointToPoint() const [member function]
|
||||
cls.add_method('IsPointToPoint',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::Send(ns3::Ptr<ns3::Packet> packet, ns3::Address const & dest, uint16_t protocolNumber) [member function]
|
||||
cls.add_method('Send',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address const &', 'dest'), param('uint16_t', 'protocolNumber')],
|
||||
is_virtual=True)
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::SendFrom(ns3::Ptr<ns3::Packet> packet, ns3::Address const & source, ns3::Address const & dest, uint16_t protocolNumber) [member function]
|
||||
cls.add_method('SendFrom',
|
||||
'bool',
|
||||
[param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Address const &', 'source'), param('ns3::Address const &', 'dest'), param('uint16_t', 'protocolNumber')],
|
||||
is_virtual=True)
|
||||
## point-to-point-net-device.h: ns3::Ptr<ns3::Node> ns3::PointToPointNetDevice::GetNode() const [member function]
|
||||
cls.add_method('GetNode',
|
||||
'ns3::Ptr< ns3::Node >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetNode(ns3::Ptr<ns3::Node> node) [member function]
|
||||
cls.add_method('SetNode',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::Node >', 'node')],
|
||||
is_virtual=True)
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::NeedsArp() const [member function]
|
||||
cls.add_method('NeedsArp',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet const>, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function]
|
||||
cls.add_method('SetReceiveCallback',
|
||||
'void',
|
||||
[param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet const >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')],
|
||||
is_virtual=True)
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetPromiscReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet const>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
|
||||
cls.add_method('SetPromiscReceiveCallback',
|
||||
'void',
|
||||
[param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet const >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')],
|
||||
is_virtual=True)
|
||||
## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::SupportsSendFrom() const [member function]
|
||||
cls.add_method('SupportsSendFrom',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## point-to-point-net-device.h: void ns3::PointToPointNetDevice::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,410 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## data-output-interface.h: ns3::DataOutputCallback [class]
|
||||
module.add_class('DataOutputCallback', allow_subclassing=True)
|
||||
## data-calculator.h: ns3::DataCalculator [class]
|
||||
module.add_class('DataCalculator', parent=root_module['ns3::Object'])
|
||||
## basic-data-calculators.h: ns3::CounterCalculator<unsigned int> [class]
|
||||
module.add_class('CounterCalculator', template_parameters=['unsigned int'], parent=root_module['ns3::DataCalculator'])
|
||||
## data-collector.h: ns3::DataCollector [class]
|
||||
module.add_class('DataCollector', parent=root_module['ns3::Object'])
|
||||
## time-data-calculators.h: ns3::TimeMinMaxAvgTotalCalculator [class]
|
||||
module.add_class('TimeMinMaxAvgTotalCalculator', parent=root_module['ns3::DataCalculator'])
|
||||
## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator<unsigned int> [class]
|
||||
module.add_class('MinMaxAvgTotalCalculator', template_parameters=['unsigned int'], parent=root_module['ns3::DataCalculator'])
|
||||
## data-output-interface.h: ns3::DataOutputInterface [class]
|
||||
module.add_class('DataOutputInterface', parent=root_module['ns3::Object'])
|
||||
## packet-data-calculators.h: ns3::PacketCounterCalculator [class]
|
||||
module.add_class('PacketCounterCalculator', parent=root_module['ns3::CounterCalculator< unsigned int >'])
|
||||
## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator [class]
|
||||
module.add_class('PacketSizeMinMaxAvgTotalCalculator', parent=root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >'])
|
||||
## omnet-data-output.h: ns3::OmnetDataOutput [class]
|
||||
module.add_class('OmnetDataOutput', parent=root_module['ns3::DataOutputInterface'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3DataOutputCallback_methods(root_module, root_module['ns3::DataOutputCallback'])
|
||||
register_Ns3DataCalculator_methods(root_module, root_module['ns3::DataCalculator'])
|
||||
register_Ns3CounterCalculator__Unsigned_int_methods(root_module, root_module['ns3::CounterCalculator< unsigned int >'])
|
||||
register_Ns3DataCollector_methods(root_module, root_module['ns3::DataCollector'])
|
||||
register_Ns3TimeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::TimeMinMaxAvgTotalCalculator'])
|
||||
register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >'])
|
||||
register_Ns3DataOutputInterface_methods(root_module, root_module['ns3::DataOutputInterface'])
|
||||
register_Ns3PacketCounterCalculator_methods(root_module, root_module['ns3::PacketCounterCalculator'])
|
||||
register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::PacketSizeMinMaxAvgTotalCalculator'])
|
||||
register_Ns3OmnetDataOutput_methods(root_module, root_module['ns3::OmnetDataOutput'])
|
||||
return
|
||||
|
||||
def register_Ns3DataOutputCallback_methods(root_module, cls):
|
||||
## data-output-interface.h: ns3::DataOutputCallback::DataOutputCallback(ns3::DataOutputCallback const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::DataOutputCallback const &', 'arg0')])
|
||||
## data-output-interface.h: ns3::DataOutputCallback::DataOutputCallback() [constructor]
|
||||
cls.add_constructor([])
|
||||
## data-output-interface.h: void ns3::DataOutputCallback::OutputSingleton(std::string key, std::string variable, int val) [member function]
|
||||
cls.add_method('OutputSingleton',
|
||||
'void',
|
||||
[param('std::string', 'key'), param('std::string', 'variable'), param('int', 'val')],
|
||||
is_pure_virtual=True, is_virtual=True)
|
||||
## data-output-interface.h: void ns3::DataOutputCallback::OutputSingleton(std::string key, std::string variable, uint32_t val) [member function]
|
||||
cls.add_method('OutputSingleton',
|
||||
'void',
|
||||
[param('std::string', 'key'), param('std::string', 'variable'), param('uint32_t', 'val')],
|
||||
is_pure_virtual=True, is_virtual=True)
|
||||
## data-output-interface.h: void ns3::DataOutputCallback::OutputSingleton(std::string key, std::string variable, double val) [member function]
|
||||
cls.add_method('OutputSingleton',
|
||||
'void',
|
||||
[param('std::string', 'key'), param('std::string', 'variable'), param('double', 'val')],
|
||||
is_pure_virtual=True, is_virtual=True)
|
||||
## data-output-interface.h: void ns3::DataOutputCallback::OutputSingleton(std::string key, std::string variable, std::string val) [member function]
|
||||
cls.add_method('OutputSingleton',
|
||||
'void',
|
||||
[param('std::string', 'key'), param('std::string', 'variable'), param('std::string', 'val')],
|
||||
is_pure_virtual=True, is_virtual=True)
|
||||
## data-output-interface.h: void ns3::DataOutputCallback::OutputSingleton(std::string key, std::string variable, ns3::Time val) [member function]
|
||||
cls.add_method('OutputSingleton',
|
||||
'void',
|
||||
[param('std::string', 'key'), param('std::string', 'variable'), param('ns3::Time', 'val')],
|
||||
is_pure_virtual=True, is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3DataCalculator_methods(root_module, cls):
|
||||
## data-calculator.h: ns3::DataCalculator::DataCalculator(ns3::DataCalculator const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::DataCalculator const &', 'arg0')])
|
||||
## data-calculator.h: ns3::DataCalculator::DataCalculator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## data-calculator.h: bool ns3::DataCalculator::GetEnabled() const [member function]
|
||||
cls.add_method('GetEnabled',
|
||||
'bool',
|
||||
[],
|
||||
is_const=True)
|
||||
## data-calculator.h: void ns3::DataCalculator::Enable() [member function]
|
||||
cls.add_method('Enable',
|
||||
'void',
|
||||
[])
|
||||
## data-calculator.h: void ns3::DataCalculator::Disable() [member function]
|
||||
cls.add_method('Disable',
|
||||
'void',
|
||||
[])
|
||||
## data-calculator.h: void ns3::DataCalculator::SetKey(std::string const key) [member function]
|
||||
cls.add_method('SetKey',
|
||||
'void',
|
||||
[param('std::string const', 'key')])
|
||||
## data-calculator.h: std::string ns3::DataCalculator::GetKey() const [member function]
|
||||
cls.add_method('GetKey',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True)
|
||||
## data-calculator.h: void ns3::DataCalculator::Start(ns3::Time const & startTime) [member function]
|
||||
cls.add_method('Start',
|
||||
'void',
|
||||
[param('ns3::Time const &', 'startTime')],
|
||||
is_virtual=True)
|
||||
## data-calculator.h: void ns3::DataCalculator::Stop(ns3::Time const & stopTime) [member function]
|
||||
cls.add_method('Stop',
|
||||
'void',
|
||||
[param('ns3::Time const &', 'stopTime')],
|
||||
is_virtual=True)
|
||||
## data-calculator.h: void ns3::DataCalculator::Output(ns3::DataOutputCallback & callback) const [member function]
|
||||
cls.add_method('Output',
|
||||
'void',
|
||||
[param('ns3::DataOutputCallback &', 'callback')],
|
||||
is_pure_virtual=True, is_const=True, is_virtual=True)
|
||||
## data-calculator.h: void ns3::DataCalculator::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3CounterCalculator__Unsigned_int_methods(root_module, cls):
|
||||
## basic-data-calculators.h: ns3::CounterCalculator<unsigned int>::CounterCalculator(ns3::CounterCalculator<unsigned int> const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::CounterCalculator< unsigned int >', 'arg0')])
|
||||
## basic-data-calculators.h: ns3::CounterCalculator<unsigned int>::CounterCalculator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## basic-data-calculators.h: void ns3::CounterCalculator<unsigned int>::Update() [member function]
|
||||
cls.add_method('Update',
|
||||
'void',
|
||||
[])
|
||||
## basic-data-calculators.h: void ns3::CounterCalculator<unsigned int>::Update(unsigned int const i) [member function]
|
||||
cls.add_method('Update',
|
||||
'void',
|
||||
[param('unsigned int const', 'i')])
|
||||
## basic-data-calculators.h: unsigned int ns3::CounterCalculator<unsigned int>::GetCount() const [member function]
|
||||
cls.add_method('GetCount',
|
||||
'unsigned int',
|
||||
[],
|
||||
is_const=True)
|
||||
## basic-data-calculators.h: void ns3::CounterCalculator<unsigned int>::Output(ns3::DataOutputCallback & callback) const [member function]
|
||||
cls.add_method('Output',
|
||||
'void',
|
||||
[param('ns3::DataOutputCallback &', 'callback')],
|
||||
is_const=True, is_virtual=True)
|
||||
## basic-data-calculators.h: void ns3::CounterCalculator<unsigned int>::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
cls.add_copy_constructor()
|
||||
return
|
||||
|
||||
def register_Ns3DataCollector_methods(root_module, cls):
|
||||
## data-collector.h: ns3::DataCollector::DataCollector(ns3::DataCollector const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::DataCollector const &', 'arg0')])
|
||||
## data-collector.h: ns3::DataCollector::DataCollector() [constructor]
|
||||
cls.add_constructor([])
|
||||
## data-collector.h: void ns3::DataCollector::DescribeRun(std::string experiment, std::string strategy, std::string input, std::string runID, std::string description="") [member function]
|
||||
cls.add_method('DescribeRun',
|
||||
'void',
|
||||
[param('std::string', 'experiment'), param('std::string', 'strategy'), param('std::string', 'input'), param('std::string', 'runID'), param('std::string', 'description', default_value='""')])
|
||||
## data-collector.h: std::string ns3::DataCollector::GetExperimentLabel() const [member function]
|
||||
cls.add_method('GetExperimentLabel',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True)
|
||||
## data-collector.h: std::string ns3::DataCollector::GetStrategyLabel() const [member function]
|
||||
cls.add_method('GetStrategyLabel',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True)
|
||||
## data-collector.h: std::string ns3::DataCollector::GetInputLabel() const [member function]
|
||||
cls.add_method('GetInputLabel',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True)
|
||||
## data-collector.h: std::string ns3::DataCollector::GetRunLabel() const [member function]
|
||||
cls.add_method('GetRunLabel',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True)
|
||||
## data-collector.h: std::string ns3::DataCollector::GetDescription() const [member function]
|
||||
cls.add_method('GetDescription',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True)
|
||||
## data-collector.h: void ns3::DataCollector::AddMetadata(std::string key, std::string value) [member function]
|
||||
cls.add_method('AddMetadata',
|
||||
'void',
|
||||
[param('std::string', 'key'), param('std::string', 'value')])
|
||||
## data-collector.h: void ns3::DataCollector::AddMetadata(std::string key, double value) [member function]
|
||||
cls.add_method('AddMetadata',
|
||||
'void',
|
||||
[param('std::string', 'key'), param('double', 'value')])
|
||||
## data-collector.h: void ns3::DataCollector::AddMetadata(std::string key, uint32_t value) [member function]
|
||||
cls.add_method('AddMetadata',
|
||||
'void',
|
||||
[param('std::string', 'key'), param('uint32_t', 'value')])
|
||||
## data-collector.h: std::_List_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > ns3::DataCollector::MetadataBegin() [member function]
|
||||
cls.add_method('MetadataBegin',
|
||||
'std::_List_iterator< std::pair< std::basic_string< char, std::char_traits< char >, std::allocator< char > >, std::basic_string< char, std::char_traits< char >, std::allocator< char > > > >',
|
||||
[])
|
||||
## data-collector.h: std::_List_iterator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > ns3::DataCollector::MetadataEnd() [member function]
|
||||
cls.add_method('MetadataEnd',
|
||||
'std::_List_iterator< std::pair< std::basic_string< char, std::char_traits< char >, std::allocator< char > >, std::basic_string< char, std::char_traits< char >, std::allocator< char > > > >',
|
||||
[])
|
||||
## data-collector.h: void ns3::DataCollector::AddDataCalculator(ns3::Ptr<ns3::DataCalculator> datac) [member function]
|
||||
cls.add_method('AddDataCalculator',
|
||||
'void',
|
||||
[param('ns3::Ptr< ns3::DataCalculator >', 'datac')])
|
||||
## data-collector.h: std::_List_iterator<ns3::Ptr<ns3::DataCalculator> > ns3::DataCollector::DataCalculatorBegin() [member function]
|
||||
cls.add_method('DataCalculatorBegin',
|
||||
'std::_List_iterator< ns3::Ptr< ns3::DataCalculator > >',
|
||||
[])
|
||||
## data-collector.h: std::_List_iterator<ns3::Ptr<ns3::DataCalculator> > ns3::DataCollector::DataCalculatorEnd() [member function]
|
||||
cls.add_method('DataCalculatorEnd',
|
||||
'std::_List_iterator< ns3::Ptr< ns3::DataCalculator > >',
|
||||
[])
|
||||
## data-collector.h: void ns3::DataCollector::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3TimeMinMaxAvgTotalCalculator_methods(root_module, cls):
|
||||
## time-data-calculators.h: ns3::TimeMinMaxAvgTotalCalculator::TimeMinMaxAvgTotalCalculator(ns3::TimeMinMaxAvgTotalCalculator const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::TimeMinMaxAvgTotalCalculator const &', 'arg0')])
|
||||
## time-data-calculators.h: ns3::TimeMinMaxAvgTotalCalculator::TimeMinMaxAvgTotalCalculator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## time-data-calculators.h: void ns3::TimeMinMaxAvgTotalCalculator::Update(ns3::Time const i) [member function]
|
||||
cls.add_method('Update',
|
||||
'void',
|
||||
[param('ns3::Time const', 'i')])
|
||||
## time-data-calculators.h: void ns3::TimeMinMaxAvgTotalCalculator::Output(ns3::DataOutputCallback & callback) const [member function]
|
||||
cls.add_method('Output',
|
||||
'void',
|
||||
[param('ns3::DataOutputCallback &', 'callback')],
|
||||
is_const=True, is_virtual=True)
|
||||
## time-data-calculators.h: void ns3::TimeMinMaxAvgTotalCalculator::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, cls):
|
||||
## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator<unsigned int>::MinMaxAvgTotalCalculator(ns3::MinMaxAvgTotalCalculator<unsigned int> const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::MinMaxAvgTotalCalculator< unsigned int >', 'arg0')])
|
||||
## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator<unsigned int>::MinMaxAvgTotalCalculator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator<unsigned int>::Update(unsigned int const i) [member function]
|
||||
cls.add_method('Update',
|
||||
'void',
|
||||
[param('unsigned int const', 'i')])
|
||||
## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator<unsigned int>::Output(ns3::DataOutputCallback & callback) const [member function]
|
||||
cls.add_method('Output',
|
||||
'void',
|
||||
[param('ns3::DataOutputCallback &', 'callback')],
|
||||
is_const=True, is_virtual=True)
|
||||
## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator<unsigned int>::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
cls.add_copy_constructor()
|
||||
return
|
||||
|
||||
def register_Ns3DataOutputInterface_methods(root_module, cls):
|
||||
## data-output-interface.h: ns3::DataOutputInterface::DataOutputInterface(ns3::DataOutputInterface const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::DataOutputInterface const &', 'arg0')])
|
||||
## data-output-interface.h: ns3::DataOutputInterface::DataOutputInterface() [constructor]
|
||||
cls.add_constructor([])
|
||||
## data-output-interface.h: void ns3::DataOutputInterface::Output(ns3::DataCollector & dc) [member function]
|
||||
cls.add_method('Output',
|
||||
'void',
|
||||
[param('ns3::DataCollector &', 'dc')],
|
||||
is_pure_virtual=True, is_virtual=True)
|
||||
## data-output-interface.h: void ns3::DataOutputInterface::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3PacketCounterCalculator_methods(root_module, cls):
|
||||
## packet-data-calculators.h: ns3::PacketCounterCalculator::PacketCounterCalculator(ns3::PacketCounterCalculator const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::PacketCounterCalculator const &', 'arg0')])
|
||||
## packet-data-calculators.h: ns3::PacketCounterCalculator::PacketCounterCalculator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## packet-data-calculators.h: void ns3::PacketCounterCalculator::PacketUpdate(std::string path, ns3::Ptr<const ns3::Packet> packet) [member function]
|
||||
cls.add_method('PacketUpdate',
|
||||
'void',
|
||||
[param('std::string', 'path'), param('ns3::Ptr< const ns3::Packet >', 'packet')])
|
||||
## packet-data-calculators.h: void ns3::PacketCounterCalculator::FrameUpdate(std::string path, ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address realto) [member function]
|
||||
cls.add_method('FrameUpdate',
|
||||
'void',
|
||||
[param('std::string', 'path'), param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'realto')])
|
||||
## packet-data-calculators.h: void ns3::PacketCounterCalculator::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, cls):
|
||||
## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator(ns3::PacketSizeMinMaxAvgTotalCalculator const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::PacketSizeMinMaxAvgTotalCalculator const &', 'arg0')])
|
||||
## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator() [constructor]
|
||||
cls.add_constructor([])
|
||||
## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::PacketUpdate(std::string path, ns3::Ptr<const ns3::Packet> packet) [member function]
|
||||
cls.add_method('PacketUpdate',
|
||||
'void',
|
||||
[param('std::string', 'path'), param('ns3::Ptr< const ns3::Packet >', 'packet')])
|
||||
## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::FrameUpdate(std::string path, ns3::Ptr<const ns3::Packet> packet, ns3::Mac48Address realto) [member function]
|
||||
cls.add_method('FrameUpdate',
|
||||
'void',
|
||||
[param('std::string', 'path'), param('ns3::Ptr< const ns3::Packet >', 'packet'), param('ns3::Mac48Address', 'realto')])
|
||||
## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3OmnetDataOutput_methods(root_module, cls):
|
||||
## omnet-data-output.h: ns3::OmnetDataOutput::OmnetDataOutput(ns3::OmnetDataOutput const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::OmnetDataOutput const &', 'arg0')])
|
||||
## omnet-data-output.h: ns3::OmnetDataOutput::OmnetDataOutput() [constructor]
|
||||
cls.add_constructor([])
|
||||
## omnet-data-output.h: void ns3::OmnetDataOutput::Output(ns3::DataCollector & dc) [member function]
|
||||
cls.add_method('Output',
|
||||
'void',
|
||||
[param('ns3::DataCollector &', 'dc')],
|
||||
is_virtual=True)
|
||||
## omnet-data-output.h: void ns3::OmnetDataOutput::SetFilePrefix(std::string const prefix) [member function]
|
||||
cls.add_method('SetFilePrefix',
|
||||
'void',
|
||||
[param('std::string const', 'prefix')])
|
||||
## omnet-data-output.h: std::string ns3::OmnetDataOutput::GetFilePrefix() const [member function]
|
||||
cls.add_method('GetFilePrefix',
|
||||
'std::string',
|
||||
[],
|
||||
is_const=True)
|
||||
## omnet-data-output.h: void ns3::OmnetDataOutput::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
## udp-echo-client.h: ns3::UdpEchoClient [class]
|
||||
module.add_class('UdpEchoClient', parent=root_module['ns3::Application'])
|
||||
## udp-echo-server.h: ns3::UdpEchoServer [class]
|
||||
module.add_class('UdpEchoServer', parent=root_module['ns3::Application'])
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
register_Ns3UdpEchoClient_methods(root_module, root_module['ns3::UdpEchoClient'])
|
||||
register_Ns3UdpEchoServer_methods(root_module, root_module['ns3::UdpEchoServer'])
|
||||
return
|
||||
|
||||
def register_Ns3UdpEchoClient_methods(root_module, cls):
|
||||
## udp-echo-client.h: ns3::UdpEchoClient::UdpEchoClient(ns3::UdpEchoClient const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::UdpEchoClient const &', 'arg0')])
|
||||
## udp-echo-client.h: static ns3::TypeId ns3::UdpEchoClient::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## udp-echo-client.h: ns3::UdpEchoClient::UdpEchoClient() [constructor]
|
||||
cls.add_constructor([])
|
||||
## udp-echo-client.h: void ns3::UdpEchoClient::SetRemote(ns3::Ipv4Address ip, uint16_t port) [member function]
|
||||
cls.add_method('SetRemote',
|
||||
'void',
|
||||
[param('ns3::Ipv4Address', 'ip'), param('uint16_t', 'port')])
|
||||
## udp-echo-client.h: void ns3::UdpEchoClient::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
## udp-echo-client.h: void ns3::UdpEchoClient::StartApplication() [member function]
|
||||
cls.add_method('StartApplication',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
## udp-echo-client.h: void ns3::UdpEchoClient::StopApplication() [member function]
|
||||
cls.add_method('StopApplication',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_Ns3UdpEchoServer_methods(root_module, cls):
|
||||
## udp-echo-server.h: ns3::UdpEchoServer::UdpEchoServer(ns3::UdpEchoServer const & arg0) [copy constructor]
|
||||
cls.add_constructor([param('ns3::UdpEchoServer const &', 'arg0')])
|
||||
## udp-echo-server.h: static ns3::TypeId ns3::UdpEchoServer::GetTypeId() [member function]
|
||||
cls.add_method('GetTypeId',
|
||||
'ns3::TypeId',
|
||||
[],
|
||||
is_static=True)
|
||||
## udp-echo-server.h: ns3::UdpEchoServer::UdpEchoServer() [constructor]
|
||||
cls.add_constructor([])
|
||||
## udp-echo-server.h: void ns3::UdpEchoServer::DoDispose() [member function]
|
||||
cls.add_method('DoDispose',
|
||||
'void',
|
||||
[],
|
||||
visibility='protected', is_virtual=True)
|
||||
## udp-echo-server.h: void ns3::UdpEchoServer::StartApplication() [member function]
|
||||
cls.add_method('StartApplication',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
## udp-echo-server.h: void ns3::UdpEchoServer::StopApplication() [member function]
|
||||
cls.add_method('StopApplication',
|
||||
'void',
|
||||
[],
|
||||
visibility='private', is_virtual=True)
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,178 @@
|
||||
#include "ns3module.h"
|
||||
|
||||
|
||||
namespace ns3{
|
||||
|
||||
void PythonCompleteConstruct (Ptr<Object> object, TypeId typeId, const AttributeList &attributes)
|
||||
{
|
||||
object->SetTypeId (typeId);
|
||||
object->Object::Construct (attributes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class PythonEventImpl : public ns3::EventImpl
|
||||
{
|
||||
private:
|
||||
PyObject *m_callback;
|
||||
PyObject *m_args;
|
||||
public:
|
||||
PythonEventImpl (PyObject *callback, PyObject *args)
|
||||
{
|
||||
m_callback = callback;
|
||||
Py_INCREF(m_callback);
|
||||
m_args = args;
|
||||
Py_INCREF(m_args);
|
||||
}
|
||||
virtual ~PythonEventImpl ()
|
||||
{
|
||||
Py_DECREF(m_callback);
|
||||
Py_DECREF(m_args);
|
||||
}
|
||||
virtual void Notify ()
|
||||
{
|
||||
PyObject *retval = PyObject_CallObject(m_callback, m_args);
|
||||
if (retval) {
|
||||
if (retval != Py_None) {
|
||||
PyErr_SetString(PyExc_TypeError, "event callback should return None");
|
||||
PyErr_Print();
|
||||
}
|
||||
Py_DECREF(retval);
|
||||
} else {
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
PyObject *
|
||||
_wrap_Simulator_Schedule(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs,
|
||||
PyObject **return_exception)
|
||||
{
|
||||
PyObject *exc_type, *traceback;
|
||||
PyObject *py_time;
|
||||
PyObject *py_callback;
|
||||
PyObject *user_args;
|
||||
ns3::Ptr<PythonEventImpl> py_event_impl;
|
||||
PyNs3EventId *py_EventId;
|
||||
|
||||
if (kwargs && PyObject_Length(kwargs) > 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "keyword arguments not supported");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (PyTuple_GET_SIZE(args) < 2) {
|
||||
PyErr_SetString(PyExc_TypeError, "ns3.Simulator.Schedule needs at least 2 arguments");
|
||||
goto error;
|
||||
}
|
||||
py_time = PyTuple_GET_ITEM(args, 0);
|
||||
py_callback = PyTuple_GET_ITEM(args, 1);
|
||||
|
||||
if (!PyObject_IsInstance(py_time, (PyObject*) &PyNs3Time_Type)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Parameter 1 should be a ns3.Time instance");
|
||||
goto error;
|
||||
}
|
||||
if (!PyCallable_Check(py_callback)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Parameter 2 should be callable");
|
||||
goto error;
|
||||
}
|
||||
user_args = PyTuple_GetSlice(args, 2, PyTuple_GET_SIZE(args));
|
||||
py_event_impl = ns3::Create<PythonEventImpl>(py_callback, user_args);
|
||||
Py_DECREF(user_args);
|
||||
|
||||
py_EventId = PyObject_New(PyNs3EventId, &PyNs3EventId_Type);
|
||||
py_EventId->obj = new ns3::EventId(
|
||||
ns3::Simulator::Schedule(*((PyNs3Time *) py_time)->obj, py_event_impl));
|
||||
return (PyObject *) py_EventId;
|
||||
|
||||
error:
|
||||
PyErr_Fetch(&exc_type, return_exception, &traceback);
|
||||
Py_XDECREF(exc_type);
|
||||
Py_XDECREF(traceback);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PyObject *
|
||||
_wrap_Simulator_ScheduleNow(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs,
|
||||
PyObject **return_exception)
|
||||
{
|
||||
PyObject *exc_type, *traceback;
|
||||
PyObject *py_callback;
|
||||
PyObject *user_args;
|
||||
ns3::Ptr<PythonEventImpl> py_event_impl;
|
||||
PyNs3EventId *py_EventId;
|
||||
|
||||
if (kwargs && PyObject_Length(kwargs) > 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "keyword arguments not supported");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (PyTuple_GET_SIZE(args) < 1) {
|
||||
PyErr_SetString(PyExc_TypeError, "ns3.Simulator.Schedule needs at least 1 argument");
|
||||
goto error;
|
||||
}
|
||||
py_callback = PyTuple_GET_ITEM(args, 0);
|
||||
|
||||
if (!PyCallable_Check(py_callback)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Parameter 2 should be callable");
|
||||
goto error;
|
||||
}
|
||||
user_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
|
||||
py_event_impl = ns3::Create<PythonEventImpl>(py_callback, user_args);
|
||||
Py_DECREF(user_args);
|
||||
|
||||
py_EventId = PyObject_New(PyNs3EventId, &PyNs3EventId_Type);
|
||||
py_EventId->obj = new ns3::EventId(ns3::Simulator::ScheduleNow(py_event_impl));
|
||||
return (PyObject *) py_EventId;
|
||||
|
||||
error:
|
||||
PyErr_Fetch(&exc_type, return_exception, &traceback);
|
||||
Py_XDECREF(exc_type);
|
||||
Py_XDECREF(traceback);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PyObject *
|
||||
_wrap_Simulator_ScheduleDestroy(PyNs3Simulator *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs,
|
||||
PyObject **return_exception)
|
||||
{
|
||||
PyObject *exc_type, *traceback;
|
||||
PyObject *py_callback;
|
||||
PyObject *user_args;
|
||||
ns3::Ptr<PythonEventImpl> py_event_impl;
|
||||
PyNs3EventId *py_EventId;
|
||||
|
||||
if (kwargs && PyObject_Length(kwargs) > 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "keyword arguments not supported");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (PyTuple_GET_SIZE(args) < 1) {
|
||||
PyErr_SetString(PyExc_TypeError, "ns3.Simulator.Schedule needs at least 1 argument");
|
||||
goto error;
|
||||
}
|
||||
py_callback = PyTuple_GET_ITEM(args, 0);
|
||||
|
||||
if (!PyCallable_Check(py_callback)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Parameter 2 should be callable");
|
||||
goto error;
|
||||
}
|
||||
user_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
|
||||
py_event_impl = ns3::Create<PythonEventImpl>(py_callback, user_args);
|
||||
Py_DECREF(user_args);
|
||||
|
||||
py_EventId = PyObject_New(PyNs3EventId, &PyNs3EventId_Type);
|
||||
py_EventId->obj = new ns3::EventId(ns3::Simulator::ScheduleDestroy(py_event_impl));
|
||||
return (PyObject *) py_EventId;
|
||||
|
||||
error:
|
||||
PyErr_Fetch(&exc_type, return_exception, &traceback);
|
||||
Py_XDECREF(exc_type);
|
||||
Py_XDECREF(traceback);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Executable
+144
@@ -0,0 +1,144 @@
|
||||
|
||||
LOCAL_MODULES = [
|
||||
#'my_extra_api_definitions',
|
||||
]
|
||||
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
from pybindgen import FileCodeSink, write_preamble
|
||||
from pybindgen.module import MultiSectionFactory
|
||||
import pybindgen.settings
|
||||
|
||||
from ns3modulegen_generated import module_init, register_types, register_methods, register_functions
|
||||
import ns3modulegen_core_customizations
|
||||
import callbacks_list
|
||||
|
||||
this_script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
|
||||
class ErrorHandler(pybindgen.settings.ErrorHandler):
|
||||
def handle_error(self, wrapper, exception, traceback_):
|
||||
try:
|
||||
stack = wrapper.stack_where_defined
|
||||
except AttributeError:
|
||||
print >> sys.stderr, "??:??: %s / %r" % (wrapper, exception)
|
||||
else:
|
||||
stack = list(stack)
|
||||
stack.reverse()
|
||||
for (filename, line_number, function_name, text) in stack:
|
||||
file_dir = os.path.dirname(os.path.abspath(filename))
|
||||
if file_dir == this_script_dir:
|
||||
print >> sys.stderr, "%s:%i: %r" % (os.path.join("..", "bindings", "python", os.path.basename(filename)),
|
||||
line_number, exception)
|
||||
break
|
||||
return True
|
||||
pybindgen.settings.error_handler = ErrorHandler()
|
||||
|
||||
pybindgen.settings.wrapper_registry = pybindgen.settings.StdMapWrapperRegistry
|
||||
|
||||
|
||||
class MyMultiSectionFactory(MultiSectionFactory):
|
||||
|
||||
def __init__(self, main_file_name, modules):
|
||||
super(MyMultiSectionFactory, self).__init__()
|
||||
self.main_file_name = main_file_name
|
||||
self.main_sink = FileCodeSink(open(main_file_name, "wt"))
|
||||
self.header_name = "ns3module.h"
|
||||
header_file_name = os.path.join(os.path.dirname(self.main_file_name), self.header_name)
|
||||
self.header_sink = FileCodeSink(open(header_file_name, "wt"))
|
||||
self.section_sinks = {'__main__': self.main_sink}
|
||||
|
||||
for module in modules:
|
||||
section_name = 'ns3_module_%s' % module.replace('-', '_')
|
||||
file_name = os.path.join(os.path.dirname(self.main_file_name), "%s.cc" % section_name)
|
||||
sink = FileCodeSink(open(file_name, "wt"))
|
||||
self.section_sinks[section_name] = sink
|
||||
|
||||
def get_section_code_sink(self, section_name):
|
||||
return self.section_sinks[section_name]
|
||||
|
||||
def get_main_code_sink(self):
|
||||
return self.main_sink
|
||||
|
||||
def get_common_header_code_sink(self):
|
||||
return self.header_sink
|
||||
|
||||
def get_common_header_include(self):
|
||||
return '"%s"' % self.header_name
|
||||
|
||||
def close(self):
|
||||
self.header_sink.file.close()
|
||||
self.main_sink.file.close()
|
||||
for sink in self.section_sinks.itervalues():
|
||||
sink.file.close()
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
out = MyMultiSectionFactory(sys.argv[1], sys.argv[2:])
|
||||
root_module = module_init()
|
||||
root_module.add_include('"everything.h"')
|
||||
|
||||
register_types(root_module)
|
||||
|
||||
ns3modulegen_core_customizations.Simulator_customizations(root_module)
|
||||
ns3modulegen_core_customizations.CommandLine_customizations(root_module)
|
||||
|
||||
|
||||
for local_module in LOCAL_MODULES:
|
||||
mod = __import__(local_module)
|
||||
mod.register_types(root_module)
|
||||
|
||||
ns3modulegen_core_customizations.generate_callback_classes(root_module.after_forward_declarations,
|
||||
callbacks_list.callback_classes)
|
||||
|
||||
|
||||
register_methods(root_module)
|
||||
|
||||
for local_module in LOCAL_MODULES:
|
||||
mod = __import__(local_module)
|
||||
mod.register_methods(root_module)
|
||||
|
||||
ns3modulegen_core_customizations.Object_customizations(root_module)
|
||||
ns3modulegen_core_customizations.Attribute_customizations(root_module)
|
||||
|
||||
register_functions(root_module)
|
||||
|
||||
for local_module in LOCAL_MODULES:
|
||||
mod = __import__(local_module)
|
||||
mod.register_functions(root_module)
|
||||
|
||||
enabled_features = os.environ['NS3_ENABLED_FEATURES'].split(',')
|
||||
|
||||
# if GtkConfigStore support is disabled, disable the class wrapper
|
||||
if 'GtkConfigStore' not in enabled_features:
|
||||
try:
|
||||
root_module.classes.remove(root_module['ns3::GtkConfigStore'])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# if no sqlite, the class SqliteDataOutput is disabled
|
||||
if 'SqliteDataOutput' not in enabled_features:
|
||||
try:
|
||||
root_module.classes.remove(root_module['ns3::SqliteDataOutput'])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if 'Threading' not in enabled_features:
|
||||
for clsname in ['SystemThread', 'SystemMutex', 'SystemCondition', 'CriticalSection']:
|
||||
root_module.classes.remove(root_module['ns3::%s' % clsname])
|
||||
|
||||
if 'RealTime' not in enabled_features:
|
||||
for clsname in ['WallClockSynchronizer', 'RealtimeSimulatorImpl', 'RealtimeEventLock']:
|
||||
root_module.classes.remove(root_module['ns3::%s' % clsname])
|
||||
root_module.enums.remove(root_module['ns3::RealtimeSimulatorImpl::SynchronizationMode'])
|
||||
|
||||
root_module.generate(out, '_ns3')
|
||||
|
||||
out.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -0,0 +1,519 @@
|
||||
import re
|
||||
|
||||
from pybindgen.typehandlers import base as typehandlers
|
||||
from pybindgen import ReturnValue, Parameter
|
||||
from pybindgen.cppmethod import CustomCppMethodWrapper, CustomCppConstructorWrapper
|
||||
from pybindgen.typehandlers.codesink import MemoryCodeSink
|
||||
from pybindgen.typehandlers import ctypeparser
|
||||
from pybindgen import cppclass
|
||||
import warnings
|
||||
|
||||
from pybindgen.typehandlers.base import CodeGenerationError
|
||||
|
||||
import sys
|
||||
|
||||
class SmartPointerTransformation(typehandlers.TypeTransformation):
|
||||
"""
|
||||
This class provides a "type transformation" that tends to support
|
||||
NS-3 smart pointers. Parameters such as "Ptr<Foo> foo" are
|
||||
transformed into something like Parameter.new("Foo*", "foo",
|
||||
transfer_ownership=False). Return values such as Ptr<Foo> are
|
||||
transformed into ReturnValue.new("Foo*",
|
||||
caller_owns_return=False). Since the underlying objects have
|
||||
reference counting, PyBindGen does the right thing.
|
||||
"""
|
||||
def __init__(self):
|
||||
super(SmartPointerTransformation, self).__init__()
|
||||
self.rx = re.compile(r'(ns3::|::ns3::|)Ptr<([^>]+)>')
|
||||
|
||||
def _get_untransformed_type_traits(self, name):
|
||||
m = self.rx.match(name)
|
||||
is_const = False
|
||||
if m is None:
|
||||
return None, False
|
||||
else:
|
||||
name1 = m.group(2).strip()
|
||||
if name1.startswith('const '):
|
||||
name1 = name1[len('const '):]
|
||||
is_const = True
|
||||
if name1.endswith(' const'):
|
||||
name1 = name1[:-len(' const')]
|
||||
is_const = True
|
||||
new_name = name1+' *'
|
||||
|
||||
if new_name.startswith('::'):
|
||||
new_name = new_name[2:]
|
||||
return new_name, is_const
|
||||
|
||||
def get_untransformed_name(self, name):
|
||||
new_name, dummy_is_const = self._get_untransformed_type_traits(name)
|
||||
return new_name
|
||||
|
||||
def create_type_handler(self, type_handler, *args, **kwargs):
|
||||
if issubclass(type_handler, Parameter):
|
||||
kwargs['transfer_ownership'] = False
|
||||
elif issubclass(type_handler, ReturnValue):
|
||||
kwargs['caller_owns_return'] = False
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
## fix the ctype, add ns3:: namespace
|
||||
orig_ctype, is_const = self._get_untransformed_type_traits(args[0])
|
||||
if is_const:
|
||||
correct_ctype = 'ns3::Ptr< %s const >' % orig_ctype[:-2]
|
||||
else:
|
||||
correct_ctype = 'ns3::Ptr< %s >' % orig_ctype[:-2]
|
||||
args = tuple([correct_ctype] + list(args[1:]))
|
||||
|
||||
handler = type_handler(*args, **kwargs)
|
||||
handler.set_tranformation(self, orig_ctype)
|
||||
return handler
|
||||
|
||||
def untransform(self, type_handler, declarations, code_block, expression):
|
||||
return 'const_cast<%s> (ns3::PeekPointer (%s))' % (type_handler.untransformed_ctype, expression)
|
||||
|
||||
def transform(self, type_handler, declarations, code_block, expression):
|
||||
assert type_handler.untransformed_ctype[-1] == '*'
|
||||
return 'ns3::Ptr< %s > (%s)' % (type_handler.untransformed_ctype[:-1], expression)
|
||||
|
||||
## register the type transformation
|
||||
transf = SmartPointerTransformation()
|
||||
typehandlers.return_type_matcher.register_transformation(transf)
|
||||
typehandlers.param_type_matcher.register_transformation(transf)
|
||||
del transf
|
||||
|
||||
|
||||
class ArgvParam(Parameter):
|
||||
"""
|
||||
Converts a python list-of-strings argument to a pair of 'int argc,
|
||||
char *argv[]' arguments to pass into C.
|
||||
|
||||
One Python argument becomes two C function arguments -> it's a miracle!
|
||||
|
||||
Note: this parameter type handler is not registered by any name;
|
||||
must be used explicitly.
|
||||
"""
|
||||
|
||||
DIRECTIONS = [Parameter.DIRECTION_IN]
|
||||
CTYPES = []
|
||||
|
||||
def convert_c_to_python(self, wrapper):
|
||||
raise NotImplementedError
|
||||
|
||||
def convert_python_to_c(self, wrapper):
|
||||
py_name = wrapper.declarations.declare_variable('PyObject*', 'py_' + self.name)
|
||||
argc_var = wrapper.declarations.declare_variable('int', 'argc')
|
||||
name = wrapper.declarations.declare_variable('char**', self.name)
|
||||
idx = wrapper.declarations.declare_variable('Py_ssize_t', 'idx')
|
||||
wrapper.parse_params.add_parameter('O!', ['&PyList_Type', '&'+py_name], self.name)
|
||||
|
||||
#wrapper.before_call.write_error_check('!PyList_Check(%s)' % py_name) # XXX
|
||||
|
||||
wrapper.before_call.write_code("%s = (char **) malloc(sizeof(char*)*PyList_Size(%s));"
|
||||
% (name, py_name))
|
||||
wrapper.before_call.add_cleanup_code('free(%s);' % name)
|
||||
wrapper.before_call.write_code('''
|
||||
for (%(idx)s = 0; %(idx)s < PyList_Size(%(py_name)s); %(idx)s++)
|
||||
{
|
||||
''' % vars())
|
||||
wrapper.before_call.sink.indent()
|
||||
wrapper.before_call.write_code('''
|
||||
PyObject *item = PyList_GET_ITEM(%(py_name)s, %(idx)s);
|
||||
''' % vars())
|
||||
#wrapper.before_call.write_error_check('item == NULL')
|
||||
wrapper.before_call.write_error_check(
|
||||
'!PyString_Check(item)',
|
||||
failure_cleanup=('PyErr_SetString(PyExc_TypeError, '
|
||||
'"argument %s must be a list of strings");') % self.name)
|
||||
wrapper.before_call.write_code(
|
||||
'%s[%s] = PyString_AsString(item);' % (name, idx))
|
||||
wrapper.before_call.sink.unindent()
|
||||
wrapper.before_call.write_code('}')
|
||||
wrapper.before_call.write_code('%s = PyList_Size(%s);' % (argc_var, py_name))
|
||||
|
||||
wrapper.call_params.append(argc_var)
|
||||
wrapper.call_params.append(name)
|
||||
|
||||
|
||||
class CallbackImplProxyMethod(typehandlers.ReverseWrapperBase):
|
||||
"""
|
||||
Class that generates a proxy virtual method that calls a similarly named python method.
|
||||
"""
|
||||
|
||||
def __init__(self, return_value, parameters):
|
||||
super(CallbackImplProxyMethod, self).__init__(return_value, parameters)
|
||||
|
||||
def generate_python_call(self):
|
||||
"""code to call the python method"""
|
||||
build_params = self.build_params.get_parameters(force_tuple_creation=True)
|
||||
if build_params[0][0] == '"':
|
||||
build_params[0] = '(char *) ' + build_params[0]
|
||||
args = self.before_call.declare_variable('PyObject*', 'args')
|
||||
self.before_call.write_code('%s = Py_BuildValue(%s);'
|
||||
% (args, ', '.join(build_params)))
|
||||
self.before_call.add_cleanup_code('Py_DECREF(%s);' % args)
|
||||
self.before_call.write_code('py_retval = PyObject_CallObject(m_callback, %s);' % args)
|
||||
self.before_call.write_error_check('py_retval == NULL')
|
||||
self.before_call.add_cleanup_code('Py_DECREF(py_retval);')
|
||||
|
||||
|
||||
|
||||
|
||||
def generate_callback_classes(out, callbacks):
|
||||
for callback_impl_num, template_parameters in enumerate(callbacks):
|
||||
sink = MemoryCodeSink()
|
||||
cls_name = "ns3::Callback< %s >" % ', '.join(template_parameters)
|
||||
#print >> sys.stderr, "***** trying to register callback: %r" % cls_name
|
||||
class_name = "PythonCallbackImpl%i" % callback_impl_num
|
||||
sink.writeln('''
|
||||
class %s : public ns3::CallbackImpl<%s>
|
||||
{
|
||||
public:
|
||||
PyObject *m_callback;
|
||||
%s(PyObject *callback)
|
||||
{
|
||||
Py_INCREF(callback);
|
||||
m_callback = callback;
|
||||
}
|
||||
virtual ~%s()
|
||||
{
|
||||
Py_DECREF(m_callback);
|
||||
m_callback = NULL;
|
||||
}
|
||||
|
||||
virtual bool IsEqual(ns3::Ptr<const ns3::CallbackImplBase> other_base) const
|
||||
{
|
||||
const %s *other = dynamic_cast<const %s*> (ns3::PeekPointer (other_base));
|
||||
if (other != NULL)
|
||||
return (other->m_callback == m_callback);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
''' % (class_name, ', '.join(template_parameters), class_name, class_name, class_name, class_name))
|
||||
sink.indent()
|
||||
callback_return = template_parameters[0]
|
||||
return_ctype = ctypeparser.parse_type(callback_return)
|
||||
if ('const' in return_ctype.remove_modifiers()):
|
||||
kwargs = {'is_const': True}
|
||||
else:
|
||||
kwargs = {}
|
||||
try:
|
||||
return_type = ReturnValue.new(str(return_ctype), **kwargs)
|
||||
except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex:
|
||||
warnings.warn("***** Unable to register callback; Return value '%s' error (used in %s): %r"
|
||||
% (callback_return, cls_name, ex),
|
||||
Warning)
|
||||
continue
|
||||
|
||||
arguments = []
|
||||
ok = True
|
||||
callback_parameters = [arg for arg in template_parameters[1:] if arg != 'ns3::empty']
|
||||
for arg_num, arg_type in enumerate(callback_parameters):
|
||||
arg_name = 'arg%i' % (arg_num+1)
|
||||
|
||||
param_ctype = ctypeparser.parse_type(arg_type)
|
||||
if ('const' in param_ctype.remove_modifiers()):
|
||||
kwargs = {'is_const': True}
|
||||
else:
|
||||
kwargs = {}
|
||||
try:
|
||||
arguments.append(Parameter.new(str(param_ctype), arg_name, **kwargs))
|
||||
except (typehandlers.TypeLookupError, typehandlers.TypeConfigurationError), ex:
|
||||
warnings.warn("***** Unable to register callback; parameter '%s %s' error (used in %s): %r"
|
||||
% (arg_type, arg_name, cls_name, ex),
|
||||
Warning)
|
||||
ok = False
|
||||
if not ok:
|
||||
continue
|
||||
|
||||
wrapper = CallbackImplProxyMethod(return_type, arguments)
|
||||
wrapper.generate(sink, 'operator()', decl_modifiers=[])
|
||||
|
||||
sink.unindent()
|
||||
sink.writeln('};\n')
|
||||
sink.flush_to(out)
|
||||
|
||||
class PythonCallbackParameter(Parameter):
|
||||
"Class handlers"
|
||||
CTYPES = [cls_name]
|
||||
#print >> sys.stderr, "***** registering callback handler: %r" % ctypeparser.normalize_type_string(cls_name)
|
||||
DIRECTIONS = [Parameter.DIRECTION_IN]
|
||||
PYTHON_CALLBACK_IMPL_NAME = class_name
|
||||
TEMPLATE_ARGS = template_parameters
|
||||
|
||||
def convert_python_to_c(self, wrapper):
|
||||
"parses python args to get C++ value"
|
||||
assert isinstance(wrapper, typehandlers.ForwardWrapperBase)
|
||||
|
||||
py_callback = wrapper.declarations.declare_variable('PyObject*', self.name)
|
||||
wrapper.parse_params.add_parameter('O', ['&'+py_callback], self.name)
|
||||
wrapper.before_call.write_error_check(
|
||||
'!PyCallable_Check(%s)' % py_callback,
|
||||
'PyErr_SetString(PyExc_TypeError, "parameter \'%s\' must be callbale");' % self.name)
|
||||
callback_impl = wrapper.declarations.declare_variable(
|
||||
'ns3::Ptr<%s>' % self.PYTHON_CALLBACK_IMPL_NAME,
|
||||
'%s_cb_impl' % self.name)
|
||||
wrapper.before_call.write_code("%s = ns3::Create<%s> (%s);"
|
||||
% (callback_impl, self.PYTHON_CALLBACK_IMPL_NAME, py_callback))
|
||||
wrapper.call_params.append(
|
||||
'ns3::Callback<%s> (%s)' % (', '.join(self.TEMPLATE_ARGS), callback_impl))
|
||||
|
||||
def convert_c_to_python(self, wrapper):
|
||||
raise typehandlers.NotSupportedError("Reverse wrappers for ns3::Callback<...> types "
|
||||
"(python using callbacks defined in C++) not implemented.")
|
||||
|
||||
|
||||
# def write_preamble(out):
|
||||
# pybindgen.write_preamble(out)
|
||||
# out.writeln("#include \"ns3/everything.h\"")
|
||||
|
||||
|
||||
|
||||
def Simulator_customizations(module):
|
||||
Simulator = module['ns3::Simulator']
|
||||
|
||||
## Simulator::Schedule(delay, callback, ...user..args...)
|
||||
Simulator.add_custom_method_wrapper("Schedule", "_wrap_Simulator_Schedule",
|
||||
flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"])
|
||||
|
||||
|
||||
## Simulator::ScheduleNow(callback, ...user..args...)
|
||||
Simulator.add_custom_method_wrapper("ScheduleNow", "_wrap_Simulator_ScheduleNow",
|
||||
flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"])
|
||||
|
||||
|
||||
## Simulator::ScheduleDestroy(callback, ...user..args...)
|
||||
Simulator.add_custom_method_wrapper("ScheduleDestroy", "_wrap_Simulator_ScheduleDestroy",
|
||||
flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"])
|
||||
|
||||
|
||||
def CommandLine_customizations(module):
|
||||
CommandLine = module['ns3::CommandLine']
|
||||
CommandLine.add_method('Parse', None, [ArgvParam(None, 'argv')],
|
||||
is_static=False)
|
||||
|
||||
|
||||
def Object_customizations(module):
|
||||
## ---------------------------------------------------------------------
|
||||
## Here we generate custom constructor code for all classes that
|
||||
## derive from ns3::Object. The custom constructors are needed in
|
||||
## order to support kwargs only and to translate kwargs into ns3
|
||||
## attributes, etc.
|
||||
## ---------------------------------------------------------------------
|
||||
Object = module['ns3::Object']
|
||||
|
||||
|
||||
## add a GetTypeId method to all generatd helper classes
|
||||
def helper_class_hook(helper_class):
|
||||
decl = """
|
||||
static ns3::TypeId GetTypeId (void)
|
||||
{
|
||||
static ns3::TypeId tid = ns3::TypeId ("%s")
|
||||
.SetParent< %s > ()
|
||||
;
|
||||
return tid;
|
||||
}""" % (helper_class.name, helper_class.class_.full_name)
|
||||
|
||||
helper_class.add_custom_method(decl)
|
||||
helper_class.add_post_generation_code(
|
||||
"NS_OBJECT_ENSURE_REGISTERED (%s);" % helper_class.name)
|
||||
Object.add_helper_class_hook(helper_class_hook)
|
||||
|
||||
## Replace all class constructors with a generic constructor based on CreateObject<T> (AttributeList)
|
||||
module.header.writeln('''
|
||||
namespace ns3 {
|
||||
|
||||
void PythonCompleteConstruct (Ptr<Object> object, TypeId typeId, const AttributeList &attributes);
|
||||
|
||||
template <typename T>
|
||||
Ptr<T> CreateObjectPython (PyObject *pyobj, const AttributeList &attributes)
|
||||
{
|
||||
Ptr<T> p = Ptr<T> (new T (), false);
|
||||
p->set_pyobj (pyobj);
|
||||
PythonCompleteConstruct (p, T::GetTypeId (), attributes);
|
||||
return p;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
''')
|
||||
|
||||
for cls in module.classes:
|
||||
if not cls.is_subclass(Object):
|
||||
continue
|
||||
cls.constructors = [] # clear the list of constructors
|
||||
|
||||
## add our own custom constructor, if possible
|
||||
try:
|
||||
construct_name = cls.get_construct_name()
|
||||
except CodeGenerationError:
|
||||
construct_name = None
|
||||
|
||||
if construct_name and not cls.helper_class:
|
||||
construct_code = '''
|
||||
ns3::Ptr< %(CONSTRUCT_NAME)s > obj = ns3::CreateObject< %(CONSTRUCT_NAME)s > (attrList);
|
||||
obj->Ref ();
|
||||
self->obj = ns3::PeekPointer (obj);
|
||||
''' % dict (CONSTRUCT_NAME=construct_name)
|
||||
|
||||
elif not construct_name and not cls.helper_class:
|
||||
continue
|
||||
|
||||
elif not construct_name and cls.helper_class:
|
||||
construct_code = '''
|
||||
if (self->ob_type != &%(PYTYPESTRUCT)s)
|
||||
{
|
||||
ns3::Ptr< %(HELPER_CLASS_NAME)s > obj = ns3::CreateObjectPython< %(HELPER_CLASS_NAME)s > ((PyObject *)self, attrList);
|
||||
obj->Ref ();
|
||||
self->obj = ns3::PeekPointer (obj);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "Class cannot be constructed (unless subclassed)");
|
||||
{
|
||||
PyObject *exc_type, *traceback;
|
||||
PyErr_Fetch(&exc_type, return_exception, &traceback);
|
||||
Py_XDECREF(exc_type);
|
||||
Py_XDECREF(traceback);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
''' % dict (CONSTRUCT_NAME=construct_name, HELPER_CLASS_NAME=cls.helper_class.name,
|
||||
PYTYPESTRUCT=cls.pytypestruct)
|
||||
|
||||
elif construct_name and cls.helper_class:
|
||||
construct_code = '''
|
||||
if (self->ob_type != &%(PYTYPESTRUCT)s)
|
||||
{
|
||||
ns3::Ptr< %(HELPER_CLASS_NAME)s > obj = ns3::CreateObjectPython< %(HELPER_CLASS_NAME)s > ((PyObject *)self, attrList);
|
||||
obj->Ref ();
|
||||
self->obj = ns3::PeekPointer (obj);
|
||||
} else {
|
||||
ns3::Ptr< %(CONSTRUCT_NAME)s > obj = ns3::CreateObject< %(CONSTRUCT_NAME)s > (attrList);
|
||||
obj->Ref ();
|
||||
self->obj = ns3::PeekPointer (obj);
|
||||
}
|
||||
''' % dict (CONSTRUCT_NAME=construct_name, HELPER_CLASS_NAME=cls.helper_class.name,
|
||||
PYTYPESTRUCT=cls.pytypestruct)
|
||||
else:
|
||||
raise AssertionError
|
||||
|
||||
wrapper_name = "_wrap_create_object_%s" % (cls.mangled_full_name,)
|
||||
constructor = '''
|
||||
static int %(WRAPPER_NAME)s (%(PYSTRUCT)s *self, PyObject *args, PyObject *kwargs, PyObject **return_exception)
|
||||
{
|
||||
if (PyTuple_Size(args)) {
|
||||
PyErr_SetString(PyExc_TypeError, "positional arguments not supported "
|
||||
"for ns3.Object constructors, only keyword arguments"
|
||||
" should be used (AttributeName=Value)");
|
||||
{
|
||||
PyObject *exc_type, *traceback;
|
||||
PyErr_Fetch(&exc_type, return_exception, &traceback);
|
||||
Py_XDECREF(exc_type);
|
||||
Py_XDECREF(traceback);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
ns3::AttributeList attrList;
|
||||
if (kwargs && KwargsToAttributeList(kwargs, %(CLASS_NAME)s::GetTypeId(), attrList)) {
|
||||
{
|
||||
PyObject *exc_type, *traceback;
|
||||
PyErr_Fetch(&exc_type, return_exception, &traceback);
|
||||
Py_XDECREF(exc_type);
|
||||
Py_XDECREF(traceback);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
%(CONSTRUCT_CODE)s
|
||||
return 0;
|
||||
}
|
||||
''' % dict(WRAPPER_NAME=wrapper_name, PYSTRUCT=cls.pystruct, CLASS_NAME=cls.full_name,
|
||||
CONSTRUCT_CODE=construct_code, PURE_VIRTUALS=cls.have_pure_virtual_methods)
|
||||
cls.add_constructor(CustomCppConstructorWrapper(wrapper_name, constructor))
|
||||
|
||||
|
||||
# Generate conversion function from PyObject* to AttributeValue
|
||||
# sink = module.body
|
||||
# sink.writeln('''
|
||||
# Ptr<AttributeValue> AttributeValueFromPyObject (PyObject *obj)
|
||||
# {
|
||||
# // note: needs to check for bool first, because bool is a subclass of int
|
||||
# if (PyBool_Check(obj)) {
|
||||
# return Create<BooleanValue>(PyObject_IsTrue(obj));
|
||||
# } else if (PyInt_Check(obj)) {
|
||||
# return Create<IntegerValue>(PyInt_AsLong(obj));
|
||||
# } else if (PyLong_Check(obj)) {
|
||||
# return Create<IntegerValue>(PyLong_AsLongLong(obj));
|
||||
# } else if (PyFloat_Check(obj)) {
|
||||
# return Create<DoubleValue>(PyFloat_AsDouble(obj));
|
||||
# }
|
||||
|
||||
# ''')
|
||||
|
||||
|
||||
|
||||
## ---------------------------------------------------------------------
|
||||
## -------------- write the KwargsToAttributeList function -------------
|
||||
## ---------------------------------------------------------------------
|
||||
Attribute = module['ns3::AttributeValue']
|
||||
module.after_forward_declarations.writeln(
|
||||
'int KwargsToAttributeList(PyObject *kwargs, ns3::TypeId tid, ns3::AttributeList &oAttrList);')
|
||||
|
||||
module.body.writeln(
|
||||
'''
|
||||
int KwargsToAttributeList(PyObject *kwargs, ns3::TypeId tid, ns3::AttributeList &oAttrList)
|
||||
{
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
|
||||
while (PyDict_Next(kwargs, &pos, &key, &value)) {
|
||||
if (!PyString_Check(key)) {
|
||||
PyErr_SetString(PyExc_TypeError, "kwargs keys must be strings");
|
||||
return -1;
|
||||
}
|
||||
if (PyObject_IsInstance(value, (PyObject*) &%s)) {
|
||||
oAttrList.SetWithTid(tid, PyString_AsString(key), *((%s *) value)->obj);''' \
|
||||
% (Attribute.pytypestruct, Attribute.pystruct))
|
||||
|
||||
for conversion_source in Attribute.get_all_implicit_conversions():
|
||||
module.body.writeln('''
|
||||
} else if (PyObject_IsInstance(value, (PyObject*) &%s)) {
|
||||
oAttrList.SetWithTid(tid, PyString_AsString(key), *((%s *) value)->obj);''' \
|
||||
% (conversion_source.pytypestruct, conversion_source.pystruct))
|
||||
|
||||
possible_type_names = ", ".join([cls.name for cls in [Attribute] + Attribute.get_all_implicit_conversions()])
|
||||
module.body.writeln('''
|
||||
} else {
|
||||
PyErr_Format(PyExc_TypeError, \"parameter must an instance of one of the types (%s), not %%s\", value->ob_type->tp_name);
|
||||
return -1;
|
||||
}''' % (possible_type_names))
|
||||
|
||||
module.body.writeln(
|
||||
'''
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
''')
|
||||
|
||||
|
||||
def Attribute_customizations(module):
|
||||
# Fix up for the "const AttributeValue &v = EmptyAttribute()"
|
||||
# case, as used extensively by helper classes.
|
||||
|
||||
# Here's why we need to do this: pybindgen.gccxmlscanner, when
|
||||
# scanning parameter default values, is only provided with the
|
||||
# value as a simple C expression string. (py)gccxml does not
|
||||
# report the type of the default value.
|
||||
|
||||
# As a workaround, here we iterate over all parameters of all
|
||||
# methods of all classes and tell pybindgen what is the type of
|
||||
# the default value for attributes.
|
||||
|
||||
for cls in module.classes:
|
||||
for meth in cls.get_all_methods():
|
||||
for param in meth.parameters:
|
||||
if isinstance(param, cppclass.CppClassRefParameter):
|
||||
if param.cpp_class.name == 'AttributeValue' \
|
||||
and param.default_value is not None \
|
||||
and param.default_value_type is None:
|
||||
param.default_value_type = 'ns3::EmptyAttributeValue'
|
||||
|
||||
@@ -0,0 +1,709 @@
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass
|
||||
|
||||
|
||||
import pybindgen.settings
|
||||
import warnings
|
||||
|
||||
class ErrorHandler(pybindgen.settings.ErrorHandler):
|
||||
def handle_error(self, wrapper, exception, traceback_):
|
||||
warnings.warn("exception %r in wrapper %s" % (exception, wrapper))
|
||||
return True
|
||||
pybindgen.settings.error_handler = ErrorHandler()
|
||||
|
||||
|
||||
import sys
|
||||
import ns3_module_core
|
||||
import ns3_module_simulator
|
||||
import ns3_module_mobility
|
||||
import ns3_module_common
|
||||
import ns3_module_contrib
|
||||
import ns3_module_node
|
||||
import ns3_module_point_to_point
|
||||
import ns3_module_stats
|
||||
import ns3_module_internet_stack
|
||||
import ns3_module_wifi
|
||||
import ns3_module_csma
|
||||
import ns3_module_bridge
|
||||
import ns3_module_packet_sink
|
||||
import ns3_module_global_routing
|
||||
import ns3_module_onoff
|
||||
import ns3_module_olsr
|
||||
import ns3_module_udp_echo
|
||||
import ns3_module_helper
|
||||
|
||||
def module_init():
|
||||
root_module = Module('ns3', cpp_namespace='::ns3')
|
||||
return root_module
|
||||
|
||||
def register_types(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
root_module.begin_section('ns3_module_core')
|
||||
ns3_module_core.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_core__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_core__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_core')
|
||||
root_module.begin_section('ns3_module_simulator')
|
||||
ns3_module_simulator.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_simulator__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_simulator__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_simulator')
|
||||
root_module.begin_section('ns3_module_mobility')
|
||||
ns3_module_mobility.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_mobility__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_mobility__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_mobility')
|
||||
root_module.begin_section('ns3_module_common')
|
||||
ns3_module_common.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_common__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_common__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_common')
|
||||
root_module.begin_section('ns3_module_contrib')
|
||||
ns3_module_contrib.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_contrib__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_contrib__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_contrib')
|
||||
root_module.begin_section('ns3_module_node')
|
||||
ns3_module_node.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_node__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_node__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_node')
|
||||
root_module.begin_section('ns3_module_point_to_point')
|
||||
ns3_module_point_to_point.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_point_to_point__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_point_to_point__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_point_to_point')
|
||||
root_module.begin_section('ns3_module_stats')
|
||||
ns3_module_stats.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_stats__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_stats__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_stats')
|
||||
root_module.begin_section('ns3_module_internet_stack')
|
||||
ns3_module_internet_stack.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_internet_stack__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_internet_stack__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_internet_stack')
|
||||
root_module.begin_section('ns3_module_wifi')
|
||||
ns3_module_wifi.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_wifi__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_wifi__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_wifi')
|
||||
root_module.begin_section('ns3_module_csma')
|
||||
ns3_module_csma.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_csma__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_csma__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_csma')
|
||||
root_module.begin_section('ns3_module_bridge')
|
||||
ns3_module_bridge.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_bridge__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_bridge__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_bridge')
|
||||
root_module.begin_section('ns3_module_packet_sink')
|
||||
ns3_module_packet_sink.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_packet_sink__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_packet_sink__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_packet_sink')
|
||||
root_module.begin_section('ns3_module_global_routing')
|
||||
ns3_module_global_routing.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_global_routing__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_global_routing__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_global_routing')
|
||||
root_module.begin_section('ns3_module_onoff')
|
||||
ns3_module_onoff.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_onoff__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_onoff__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_onoff')
|
||||
root_module.begin_section('ns3_module_olsr')
|
||||
ns3_module_olsr.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_olsr__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_olsr__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_olsr')
|
||||
root_module.begin_section('ns3_module_udp_echo')
|
||||
ns3_module_udp_echo.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_udp_echo__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_udp_echo__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_udp_echo')
|
||||
root_module.begin_section('ns3_module_helper')
|
||||
ns3_module_helper.register_types(module)
|
||||
|
||||
try:
|
||||
import ns3_module_helper__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_helper__local.register_types(module)
|
||||
|
||||
root_module.end_section('ns3_module_helper')
|
||||
|
||||
## Register a nested module for the namespace internal
|
||||
|
||||
nested_module = module.add_cpp_namespace('internal')
|
||||
register_types_ns3_internal(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace TimeStepPrecision
|
||||
|
||||
nested_module = module.add_cpp_namespace('TimeStepPrecision')
|
||||
register_types_ns3_TimeStepPrecision(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
nested_module = module.add_cpp_namespace('Config')
|
||||
register_types_ns3_Config(nested_module)
|
||||
|
||||
|
||||
## Register a nested module for the namespace olsr
|
||||
|
||||
nested_module = module.add_cpp_namespace('olsr')
|
||||
register_types_ns3_olsr(nested_module)
|
||||
|
||||
|
||||
def register_types_ns3_internal(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_TimeStepPrecision(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_Config(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_types_ns3_olsr(module):
|
||||
root_module = module.get_root()
|
||||
|
||||
|
||||
def register_methods(root_module):
|
||||
root_module.begin_section('ns3_module_core')
|
||||
ns3_module_core.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_core__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_core__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_core')
|
||||
root_module.begin_section('ns3_module_simulator')
|
||||
ns3_module_simulator.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_simulator__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_simulator__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_simulator')
|
||||
root_module.begin_section('ns3_module_mobility')
|
||||
ns3_module_mobility.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_mobility__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_mobility__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_mobility')
|
||||
root_module.begin_section('ns3_module_common')
|
||||
ns3_module_common.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_common__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_common__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_common')
|
||||
root_module.begin_section('ns3_module_contrib')
|
||||
ns3_module_contrib.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_contrib__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_contrib__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_contrib')
|
||||
root_module.begin_section('ns3_module_node')
|
||||
ns3_module_node.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_node__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_node__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_node')
|
||||
root_module.begin_section('ns3_module_point_to_point')
|
||||
ns3_module_point_to_point.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_point_to_point__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_point_to_point__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_point_to_point')
|
||||
root_module.begin_section('ns3_module_stats')
|
||||
ns3_module_stats.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_stats__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_stats__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_stats')
|
||||
root_module.begin_section('ns3_module_internet_stack')
|
||||
ns3_module_internet_stack.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_internet_stack__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_internet_stack__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_internet_stack')
|
||||
root_module.begin_section('ns3_module_wifi')
|
||||
ns3_module_wifi.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_wifi__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_wifi__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_wifi')
|
||||
root_module.begin_section('ns3_module_csma')
|
||||
ns3_module_csma.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_csma__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_csma__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_csma')
|
||||
root_module.begin_section('ns3_module_bridge')
|
||||
ns3_module_bridge.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_bridge__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_bridge__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_bridge')
|
||||
root_module.begin_section('ns3_module_packet_sink')
|
||||
ns3_module_packet_sink.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_packet_sink__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_packet_sink__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_packet_sink')
|
||||
root_module.begin_section('ns3_module_global_routing')
|
||||
ns3_module_global_routing.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_global_routing__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_global_routing__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_global_routing')
|
||||
root_module.begin_section('ns3_module_onoff')
|
||||
ns3_module_onoff.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_onoff__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_onoff__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_onoff')
|
||||
root_module.begin_section('ns3_module_olsr')
|
||||
ns3_module_olsr.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_olsr__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_olsr__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_olsr')
|
||||
root_module.begin_section('ns3_module_udp_echo')
|
||||
ns3_module_udp_echo.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_udp_echo__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_udp_echo__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_udp_echo')
|
||||
root_module.begin_section('ns3_module_helper')
|
||||
ns3_module_helper.register_methods(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_helper__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_helper__local.register_methods(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_helper')
|
||||
return
|
||||
|
||||
def register_functions(root_module):
|
||||
module = root_module
|
||||
root_module.begin_section('ns3_module_core')
|
||||
ns3_module_core.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_core__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_core__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_core')
|
||||
root_module.begin_section('ns3_module_simulator')
|
||||
ns3_module_simulator.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_simulator__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_simulator__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_simulator')
|
||||
root_module.begin_section('ns3_module_mobility')
|
||||
ns3_module_mobility.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_mobility__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_mobility__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_mobility')
|
||||
root_module.begin_section('ns3_module_common')
|
||||
ns3_module_common.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_common__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_common__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_common')
|
||||
root_module.begin_section('ns3_module_contrib')
|
||||
ns3_module_contrib.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_contrib__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_contrib__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_contrib')
|
||||
root_module.begin_section('ns3_module_node')
|
||||
ns3_module_node.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_node__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_node__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_node')
|
||||
root_module.begin_section('ns3_module_point_to_point')
|
||||
ns3_module_point_to_point.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_point_to_point__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_point_to_point__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_point_to_point')
|
||||
root_module.begin_section('ns3_module_stats')
|
||||
ns3_module_stats.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_stats__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_stats__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_stats')
|
||||
root_module.begin_section('ns3_module_internet_stack')
|
||||
ns3_module_internet_stack.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_internet_stack__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_internet_stack__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_internet_stack')
|
||||
root_module.begin_section('ns3_module_wifi')
|
||||
ns3_module_wifi.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_wifi__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_wifi__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_wifi')
|
||||
root_module.begin_section('ns3_module_csma')
|
||||
ns3_module_csma.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_csma__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_csma__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_csma')
|
||||
root_module.begin_section('ns3_module_bridge')
|
||||
ns3_module_bridge.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_bridge__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_bridge__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_bridge')
|
||||
root_module.begin_section('ns3_module_packet_sink')
|
||||
ns3_module_packet_sink.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_packet_sink__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_packet_sink__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_packet_sink')
|
||||
root_module.begin_section('ns3_module_global_routing')
|
||||
ns3_module_global_routing.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_global_routing__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_global_routing__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_global_routing')
|
||||
root_module.begin_section('ns3_module_onoff')
|
||||
ns3_module_onoff.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_onoff__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_onoff__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_onoff')
|
||||
root_module.begin_section('ns3_module_olsr')
|
||||
ns3_module_olsr.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_olsr__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_olsr__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_olsr')
|
||||
root_module.begin_section('ns3_module_udp_echo')
|
||||
ns3_module_udp_echo.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_udp_echo__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_udp_echo__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_udp_echo')
|
||||
root_module.begin_section('ns3_module_helper')
|
||||
ns3_module_helper.register_functions(root_module)
|
||||
|
||||
try:
|
||||
import ns3_module_helper__local
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
ns3_module_helper__local.register_functions(root_module)
|
||||
|
||||
root_module.end_section('ns3_module_helper')
|
||||
register_functions_ns3_internal(module.get_submodule('internal'), root_module)
|
||||
register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module)
|
||||
register_functions_ns3_Config(module.get_submodule('Config'), root_module)
|
||||
register_functions_ns3_olsr(module.get_submodule('olsr'), root_module)
|
||||
return
|
||||
|
||||
def register_functions_ns3_internal(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_TimeStepPrecision(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_Config(module, root_module):
|
||||
return
|
||||
|
||||
def register_functions_ns3_olsr(module, root_module):
|
||||
return
|
||||
|
||||
def main():
|
||||
out = FileCodeSink(sys.stdout)
|
||||
root_module = module_init()
|
||||
register_types(root_module)
|
||||
register_methods(root_module)
|
||||
register_functions(root_module)
|
||||
root_module.generate(out)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
import pybindgen.settings
|
||||
from pybindgen.gccxmlparser import ModuleParser, PygenClassifier, PygenSection, WrapperWarning
|
||||
from pybindgen.typehandlers.codesink import FileCodeSink
|
||||
from pygccxml.declarations import templates
|
||||
from pygccxml.declarations.class_declaration import class_t
|
||||
from pygccxml.declarations.calldef import free_function_t, member_function_t, constructor_t
|
||||
|
||||
|
||||
## we need the smart pointer type transformation to be active even
|
||||
## during gccxml scanning.
|
||||
import ns3modulegen_core_customizations
|
||||
|
||||
|
||||
## silence gccxmlparser errors; we only want error handling in the
|
||||
## generated python script, not while scanning.
|
||||
class ErrorHandler(pybindgen.settings.ErrorHandler):
|
||||
def handle_error(self, dummy_wrapper, dummy_exception, dummy_traceback_):
|
||||
return True
|
||||
pybindgen.settings.error_handler = ErrorHandler()
|
||||
import warnings
|
||||
warnings.filterwarnings(category=WrapperWarning, action='ignore')
|
||||
|
||||
type_annotations = {
|
||||
'::ns3::RefCountBase': {
|
||||
'incref_method': 'Ref',
|
||||
'decref_method': 'Unref',
|
||||
'peekref_method': 'GetReferenceCount',
|
||||
'automatic_type_narrowing': 'true',
|
||||
},
|
||||
'::ns3::Object': {
|
||||
'incref_method': 'Ref',
|
||||
'decref_method': 'Unref',
|
||||
'peekref_method': 'GetReferenceCount',
|
||||
'automatic_type_narrowing': 'true',
|
||||
},
|
||||
'::ns3::Packet': {
|
||||
'incref_method': 'Ref',
|
||||
'decref_method': 'Unref',
|
||||
'peekref_method': 'GetReferenceCount',
|
||||
},
|
||||
'::ns3::CallbackImplBase': {
|
||||
'incref_method': 'Ref',
|
||||
'decref_method': 'Unref',
|
||||
'peekref_method': 'GetReferenceCount',
|
||||
},
|
||||
'::ns3::PacketMetadata': {
|
||||
'ignore': None,
|
||||
},
|
||||
'::ns3::AttributeChecker': {
|
||||
'automatic_type_narrowing': 'true',
|
||||
'allow_subclassing': 'false',
|
||||
},
|
||||
'::ns3::AttributeValue': {
|
||||
'automatic_type_narrowing': 'true',
|
||||
'allow_subclassing': 'false',
|
||||
},
|
||||
'ns3::RandomVariable::RandomVariable(ns3::RandomVariableBase const & variable) [constructor]': {
|
||||
'ignore': None,
|
||||
},
|
||||
'ns3::RandomVariableBase * ns3::RandomVariable::Peek() const [member function]': {
|
||||
'ignore': None,
|
||||
},
|
||||
'void ns3::RandomVariable::GetSeed(uint32_t * seed) const [member function]': {
|
||||
'params': {'seed':{'direction':'out',
|
||||
'array_length':'6'}}
|
||||
},
|
||||
'bool ns3::TypeId::LookupAttributeByName(std::string name, ns3::TypeId::AttributeInfo * info) const [member function]': {
|
||||
'params': {'info':{'transfer_ownership': 'false'}}
|
||||
},
|
||||
'static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function]': {
|
||||
'params': {'tid': {'transfer_ownership': 'false'}}
|
||||
},
|
||||
'bool ns3::TraceSourceAccessor::ConnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': {
|
||||
'params': {'obj': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'bool ns3::TraceSourceAccessor::Connect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': {
|
||||
'params': {'obj': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'bool ns3::TraceSourceAccessor::DisconnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': {
|
||||
'params': {'obj': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'bool ns3::TraceSourceAccessor::Disconnect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': {
|
||||
'params': {'obj': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'bool ns3::AttributeAccessor::Set(ns3::ObjectBase * object, ns3::AttributeValue const & value) const [member function]': {
|
||||
'params': {'object': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'ns3::EmpiricalVariable::EmpiricalVariable(ns3::RandomVariableBase const & variable) [constructor]': {
|
||||
'ignore': None
|
||||
},
|
||||
'static ns3::AttributeList * ns3::AttributeList::GetGlobal() [member function]': {
|
||||
'caller_owns_return': 'false'
|
||||
},
|
||||
'void ns3::CommandLine::Parse(int argc, char * * argv) const [member function]': {
|
||||
'ignore': None # manually wrapped
|
||||
},
|
||||
'extern void ns3::PythonCompleteConstruct(ns3::Ptr<ns3::Object> object, ns3::TypeId typeId, ns3::AttributeList const & attributes) [free function]': {
|
||||
'ignore': None # used transparently by, should not be wrapped
|
||||
},
|
||||
}
|
||||
|
||||
def get_ns3_relative_path(path):
|
||||
l = []
|
||||
head = path
|
||||
while head:
|
||||
head, tail = os.path.split(head)
|
||||
if tail == 'ns3':
|
||||
return os.path.join(*l)
|
||||
l.insert(0, tail)
|
||||
raise AssertionError("is the path %r inside ns3?!" % path)
|
||||
|
||||
|
||||
def pre_scan_hook(dummy_module_parser,
|
||||
pygccxml_definition,
|
||||
global_annotations,
|
||||
parameter_annotations):
|
||||
ns3_header = get_ns3_relative_path(pygccxml_definition.location.file_name)
|
||||
|
||||
## Note: we don't include line numbers in the comments because
|
||||
## those numbers are very likely to change frequently, which would
|
||||
## cause needless changes, since the generated python files are
|
||||
## kept under version control.
|
||||
|
||||
#global_annotations['pygen_comment'] = "%s:%i: %s" % \
|
||||
# (ns3_header, pygccxml_definition.location.line, pygccxml_definition)
|
||||
global_annotations['pygen_comment'] = "%s: %s" % \
|
||||
(ns3_header, pygccxml_definition)
|
||||
|
||||
|
||||
## handle ns3::Object::GetObject (left to its own devices,
|
||||
## pybindgen will generate a mangled name containing the template
|
||||
## argument type name).
|
||||
if isinstance(pygccxml_definition, member_function_t) \
|
||||
and pygccxml_definition.parent.name == 'Object' \
|
||||
and pygccxml_definition.name == 'GetObject':
|
||||
template_args = templates.args(pygccxml_definition.demangled_name)
|
||||
if template_args == ['ns3::Object']:
|
||||
global_annotations['template_instance_names'] = 'ns3::Object=>GetObject'
|
||||
|
||||
## Don't wrap Simulator::Schedule* (manually wrapped)
|
||||
if isinstance(pygccxml_definition, member_function_t) \
|
||||
and pygccxml_definition.parent.name == 'Simulator' \
|
||||
and pygccxml_definition.name.startswith('Schedule'):
|
||||
global_annotations['ignore'] = None
|
||||
|
||||
# unblock python threads for Simulator::Run
|
||||
if isinstance(pygccxml_definition, member_function_t) \
|
||||
and pygccxml_definition.parent.name == 'Simulator' \
|
||||
and pygccxml_definition.name == 'Run':
|
||||
global_annotations['unblock_threads'] = True
|
||||
|
||||
|
||||
## classes
|
||||
if isinstance(pygccxml_definition, class_t):
|
||||
# no need for helper classes to allow subclassing in Python, I think...
|
||||
if pygccxml_definition.name.endswith('Helper'):
|
||||
global_annotations['allow_subclassing'] = 'false'
|
||||
|
||||
if pygccxml_definition.decl_string.startswith('::ns3::Callback<'):
|
||||
# manually handled in ns3modulegen_core_customizations.py
|
||||
global_annotations['ignore'] = None
|
||||
return
|
||||
|
||||
if pygccxml_definition.decl_string.startswith('::ns3::TracedCallback<'):
|
||||
global_annotations['ignore'] = None
|
||||
return
|
||||
|
||||
if pygccxml_definition.decl_string.startswith('::ns3::Ptr<'):
|
||||
# handled by pybindgen "type transformation"
|
||||
global_annotations['ignore'] = None
|
||||
return
|
||||
|
||||
# table driven class customization
|
||||
try:
|
||||
annotations = type_annotations[pygccxml_definition.decl_string]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
global_annotations.update(annotations)
|
||||
|
||||
## free functions
|
||||
if isinstance(pygccxml_definition, free_function_t):
|
||||
if pygccxml_definition.name == 'PeekPointer':
|
||||
global_annotations['ignore'] = None
|
||||
return
|
||||
|
||||
## table driven methods/constructors/functions customization
|
||||
if isinstance(pygccxml_definition, (free_function_t, member_function_t, constructor_t)):
|
||||
try:
|
||||
annotations = type_annotations[str(pygccxml_definition)]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
for key,value in annotations.items():
|
||||
if key == 'params':
|
||||
parameter_annotations.update (value)
|
||||
del annotations['params']
|
||||
global_annotations.update(annotations)
|
||||
|
||||
|
||||
# def post_scan_hook(dummy_module_parser, dummy_pygccxml_definition, pybindgen_wrapper):
|
||||
# ## classes
|
||||
# if isinstance(pybindgen_wrapper, CppClass):
|
||||
# if pybindgen_wrapper.name.endswith('Checker'):
|
||||
# print >> sys.stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", pybindgen_wrapper
|
||||
# #pybindgen_wrapper.set_instance_creation_function(AttributeChecker_instance_creation_function)
|
||||
|
||||
|
||||
def scan_callback_classes(module_parser, callback_classes_file):
|
||||
callback_classes_file.write("callback_classes = [\n")
|
||||
for cls in module_parser.module_namespace.classes(function=module_parser.location_filter,
|
||||
recursive=False):
|
||||
if not cls.name.startswith("Callback<"):
|
||||
continue
|
||||
assert templates.is_instantiation(cls.decl_string), "%s is not a template instantiation" % cls
|
||||
dummy_cls_name, template_parameters = templates.split(cls.decl_string)
|
||||
callback_classes_file.write(" %r,\n" % template_parameters)
|
||||
callback_classes_file.write("]\n")
|
||||
|
||||
|
||||
class MyPygenClassifier(PygenClassifier):
|
||||
def __init__(self, headers_map):
|
||||
self.headers_map = headers_map
|
||||
|
||||
def classify(self, pygccxml_definition):
|
||||
name = os.path.basename(pygccxml_definition.location.file_name)
|
||||
try:
|
||||
return self.headers_map[name]
|
||||
except KeyError:
|
||||
return '__main__'
|
||||
|
||||
|
||||
def ns3_module_scan(top_builddir, pygen_file_name, everything_h):
|
||||
|
||||
ns3_modules = eval(sys.stdin.read())
|
||||
|
||||
## do a topological sort on the modules graph
|
||||
from topsort import topsort
|
||||
graph = []
|
||||
for ns3_module_name, (ns3_module_deps, dummy) in ns3_modules.iteritems():
|
||||
for dep in ns3_module_deps:
|
||||
graph.append((dep, ns3_module_name))
|
||||
sorted_ns3_modules = topsort(graph)
|
||||
#print >> sys.stderr, "******* topological sort: ", sorted_ns3_modules
|
||||
|
||||
sections = [PygenSection('__main__', FileCodeSink(open(pygen_file_name, "wt")))]
|
||||
headers_map = {} # header_name -> section_name
|
||||
for ns3_module in sorted_ns3_modules:
|
||||
section_name = "ns3_module_%s" % ns3_module.replace('-', '_')
|
||||
file_name = os.path.join(os.path.dirname(pygen_file_name), "%s.py" % section_name)
|
||||
sections.append(PygenSection(section_name, FileCodeSink(open(file_name, "wt")),
|
||||
section_name + "__local"))
|
||||
for header in ns3_modules[ns3_module][1]:
|
||||
headers_map[header] = section_name
|
||||
|
||||
module_parser = ModuleParser('ns3', 'ns3')
|
||||
|
||||
module_parser.add_pre_scan_hook(pre_scan_hook)
|
||||
#module_parser.add_post_scan_hook(post_scan_hook)
|
||||
|
||||
gccxml_options = dict(
|
||||
include_paths=[top_builddir],
|
||||
define_symbols={
|
||||
#'NS3_ASSERT_ENABLE': None,
|
||||
#'NS3_LOG_ENABLE': None,
|
||||
}
|
||||
)
|
||||
|
||||
module_parser.parse_init([everything_h],
|
||||
None, whitelist_paths=[top_builddir, os.path.dirname(everything_h)],
|
||||
#includes=['"ns3/everything.h"'],
|
||||
pygen_sink=sections,
|
||||
pygen_classifier=MyPygenClassifier(headers_map),
|
||||
gccxml_options=gccxml_options)
|
||||
module_parser.scan_types()
|
||||
|
||||
callback_classes_file = open(os.path.join(os.path.dirname(pygen_file_name), "callbacks_list.py"), "wt")
|
||||
scan_callback_classes(module_parser, callback_classes_file)
|
||||
callback_classes_file.close()
|
||||
|
||||
|
||||
module_parser.scan_methods()
|
||||
module_parser.scan_functions()
|
||||
module_parser.parse_finalize()
|
||||
|
||||
for section in sections:
|
||||
section.code_sink.file.close()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ns3_module_scan(sys.argv[1], sys.argv[3], sys.argv[2])
|
||||
|
||||
@@ -0,0 +1,909 @@
|
||||
# Copyright (c) 2007 RADLogic
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""Provide various handy Python functions.
|
||||
|
||||
Running this script directly will execute the doctests.
|
||||
|
||||
Functions:
|
||||
int2bin(i, n) -- Convert integer to binary string.
|
||||
bin2int(bin_string) -- Convert binary string to integer.
|
||||
reverse(input_string) -- Reverse a string.
|
||||
transpose(matrix) -- Transpose a list of lists.
|
||||
polygon_area(points_list) -- Calculate the area of an arbitrary polygon.
|
||||
timestamp() -- Return string containing current time stamp.
|
||||
pt2str(point) -- Return prettier string version of point tuple.
|
||||
gcf(a, b) -- Return the greatest common factor of two numbers.
|
||||
lcm(a, b) -- Return the least common multiple of two numbers.
|
||||
permutations(input_list) -- Generate all permutations of a list of items.
|
||||
reduce_fraction(fraction) -- Reduce fraction (num, denom) to simplest form.
|
||||
quantile(l, p) -- Return p quantile of list l. E.g. p=0.25 for q1.
|
||||
trim(l) -- Discard values in list more than 1.5*IQR outside IQR.
|
||||
nice_units(value) -- Return value converted to human readable units.
|
||||
uniquify(seq) -- Return sequence with duplicate items in sequence seq removed.
|
||||
reverse_dict(d) -- Return the dictionary with the items as keys and vice-versa.
|
||||
lsb(x, n) -- Return the n least significant bits of x.
|
||||
gray_encode(i) -- Gray encode the given integer.
|
||||
random_vec(bits, max_value=None) -- Return a random binary vector.
|
||||
binary_range(bits) -- Return list of all possible binary numbers width=bits.
|
||||
float_range([start], stop, [step]) -- Return range of floats.
|
||||
find_common_fixes(s1, s2) -- Find common (prefix, suffix) of two strings.
|
||||
is_rotated(seq1, seq2) -- Return true if the list is a rotation of other list.
|
||||
getmodule(obj) -- Return the module that contains the object definition of obj.
|
||||
(use inspect.getmodule instead, though)
|
||||
get_args(argv) -- Store command-line args in a dictionary.
|
||||
|
||||
This module requires Python >= 2.2
|
||||
|
||||
"""
|
||||
__author__ = 'Tim Wegener <twegener@radlogic.com.au>'
|
||||
__date__ = '$Date: 2007/03/27 03:15:06 $'
|
||||
__version__ = '$Revision: 0.45 $'
|
||||
__credits__ = """
|
||||
David Chandler, for polygon area algorithm.
|
||||
(http://www.davidchandler.com/AreaOfAGeneralPolygon.pdf)
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import random
|
||||
|
||||
try:
|
||||
True, False
|
||||
except NameError:
|
||||
True, False = (1==1, 0==1)
|
||||
|
||||
|
||||
def int2bin(i, n):
|
||||
"""Convert decimal integer i to n-bit binary number (string).
|
||||
|
||||
>>> int2bin(0, 8)
|
||||
'00000000'
|
||||
|
||||
>>> int2bin(123, 8)
|
||||
'01111011'
|
||||
|
||||
>>> int2bin(123L, 8)
|
||||
'01111011'
|
||||
|
||||
>>> int2bin(15, 2)
|
||||
Traceback (most recent call last):
|
||||
ValueError: Value too large for given number of bits.
|
||||
|
||||
"""
|
||||
hex2bin = {'0': '0000', '1': '0001', '2': '0010', '3': '0011',
|
||||
'4': '0100', '5': '0101', '6': '0110', '7': '0111',
|
||||
'8': '1000', '9': '1001', 'a': '1010', 'b': '1011',
|
||||
'c': '1100', 'd': '1101', 'e': '1110', 'f': '1111'}
|
||||
# Convert to hex then map each hex digit to binary equivalent.
|
||||
result = ''.join([hex2bin[x] for x in hex(i).lower().replace('l','')[2:]])
|
||||
|
||||
# Shrink result to appropriate length.
|
||||
# Raise an error if the value is changed by the truncation.
|
||||
if '1' in result[:-n]:
|
||||
raise ValueError("Value too large for given number of bits.")
|
||||
result = result[-n:]
|
||||
# Zero-pad if length longer than mapped result.
|
||||
result = '0'*(n-len(result)) + result
|
||||
return result
|
||||
|
||||
|
||||
def bin2int(bin_string):
|
||||
"""Convert binary number string to decimal integer.
|
||||
|
||||
Note: Python > v2 has int(bin_string, 2)
|
||||
|
||||
>>> bin2int('1111')
|
||||
15
|
||||
|
||||
>>> bin2int('0101')
|
||||
5
|
||||
|
||||
"""
|
||||
## result = 0
|
||||
## bin_list = list(bin_string)
|
||||
## if len(filter(lambda x: x in ('1','0'), bin_list)) < len(bin_list):
|
||||
## raise Exception ("bin2int: Error - not a binary number: %s"
|
||||
## % bin_string)
|
||||
## bit_list = map(int, bin_list)
|
||||
## bit_list.reverse() # Make most significant bit have highest index.
|
||||
## for bit_place in range(len(bit_list)):
|
||||
## result = result + ((2**bit_place) * bit_list[bit_place])
|
||||
## return result
|
||||
return int(bin_string, 2)
|
||||
|
||||
|
||||
def reverse(input_string):
|
||||
"""Reverse a string. Useful for strings of binary numbers.
|
||||
|
||||
>>> reverse('abc')
|
||||
'cba'
|
||||
|
||||
"""
|
||||
str_list = list(input_string)
|
||||
str_list.reverse()
|
||||
return ''.join(str_list)
|
||||
|
||||
|
||||
def transpose(matrix):
|
||||
"""Transpose a list of lists.
|
||||
|
||||
>>> transpose([['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']])
|
||||
[['a', 'd', 'g'], ['b', 'e', 'h'], ['c', 'f', 'i']]
|
||||
|
||||
>>> transpose([['a', 'b', 'c'], ['d', 'e', 'f']])
|
||||
[['a', 'd'], ['b', 'e'], ['c', 'f']]
|
||||
|
||||
>>> transpose([['a', 'b'], ['d', 'e'], ['g', 'h']])
|
||||
[['a', 'd', 'g'], ['b', 'e', 'h']]
|
||||
|
||||
"""
|
||||
result = zip(*matrix)
|
||||
# Convert list of tuples to list of lists.
|
||||
# map is faster than a list comprehension since it is being used with
|
||||
# a built-in function as an argument.
|
||||
result = map(list, result)
|
||||
return result
|
||||
|
||||
|
||||
def polygon_area(points_list, precision=100):
|
||||
"""Calculate area of an arbitrary polygon using an algorithm from the web.
|
||||
|
||||
Return the area of the polygon as a positive float.
|
||||
|
||||
Arguments:
|
||||
points_list -- list of point tuples [(x0, y0), (x1, y1), (x2, y2), ...]
|
||||
(Unclosed polygons will be closed automatically.
|
||||
precision -- Internal arithmetic precision (integer arithmetic).
|
||||
|
||||
>>> polygon_area([(0, 0), (0, 1), (1, 1), (1, 2), (2, 2), (2, 0), (0, 0)])
|
||||
3.0
|
||||
|
||||
Credits:
|
||||
Area of a General Polygon by David Chandler
|
||||
http://www.davidchandler.com/AreaOfAGeneralPolygon.pdf
|
||||
|
||||
"""
|
||||
# Scale up co-ordinates and convert them to integers.
|
||||
for i in range(len(points_list)):
|
||||
points_list[i] = (int(points_list[i][0] * precision),
|
||||
int(points_list[i][1] * precision))
|
||||
# Close polygon if not closed.
|
||||
if points_list[-1] != points_list[0]:
|
||||
points_list.append(points_list[0])
|
||||
# Calculate area.
|
||||
area = 0
|
||||
for i in range(len(points_list)-1):
|
||||
(x_i, y_i) = points_list[i]
|
||||
(x_i_plus_1, y_i_plus_1) = points_list[i+1]
|
||||
area = area + (x_i_plus_1 * y_i) - (y_i_plus_1 * x_i)
|
||||
area = abs(area / 2)
|
||||
# Unscale area.
|
||||
area = float(area)/(precision**2)
|
||||
return area
|
||||
|
||||
|
||||
def timestamp():
|
||||
"""Return string containing current time stamp.
|
||||
|
||||
Note: In Python 2 onwards can use time.asctime() with no arguments.
|
||||
|
||||
"""
|
||||
|
||||
return time.asctime()
|
||||
|
||||
|
||||
def pt2str(point):
|
||||
"""Return prettier string version of point tuple.
|
||||
|
||||
>>> pt2str((1.8, 1.9))
|
||||
'(1.8, 1.9)'
|
||||
|
||||
"""
|
||||
return "(%s, %s)" % (str(point[0]), str(point[1]))
|
||||
|
||||
|
||||
def gcf(a, b, epsilon=1e-16):
|
||||
"""Return the greatest common factor of a and b, using Euclidean algorithm.
|
||||
|
||||
Arguments:
|
||||
a, b -- two numbers
|
||||
If both numbers are integers return an integer result,
|
||||
otherwise return a float result.
|
||||
epsilon -- floats less than this magnitude are considered to be zero
|
||||
(default: 1e-16)
|
||||
|
||||
Examples:
|
||||
|
||||
>>> gcf(12, 34)
|
||||
2
|
||||
|
||||
>>> gcf(13.5, 4)
|
||||
0.5
|
||||
|
||||
>>> gcf(-2, 4)
|
||||
2
|
||||
|
||||
>>> gcf(5, 0)
|
||||
5
|
||||
|
||||
By (a convenient) definition:
|
||||
>>> gcf(0, 0)
|
||||
0
|
||||
|
||||
"""
|
||||
result = max(a, b)
|
||||
remainder = min(a, b)
|
||||
while remainder and abs(remainder) > epsilon:
|
||||
new_remainder = result % remainder
|
||||
result = remainder
|
||||
remainder = new_remainder
|
||||
return abs(result)
|
||||
|
||||
def lcm(a, b, precision=None):
|
||||
"""Return the least common multiple of a and b, using the gcf function.
|
||||
|
||||
Arguments:
|
||||
a, b -- two numbers. If both are integers return an integer result,
|
||||
otherwise a return a float result.
|
||||
precision -- scaling factor if a and/or b are floats.
|
||||
|
||||
>>> lcm(21, 6)
|
||||
42
|
||||
|
||||
>>> lcm(2.5, 3.5)
|
||||
17.5
|
||||
|
||||
>>> str(lcm(1.5e-8, 2.5e-8, precision=1e9))
|
||||
'7.5e-08'
|
||||
|
||||
By (an arbitary) definition:
|
||||
>>> lcm(0, 0)
|
||||
0
|
||||
|
||||
"""
|
||||
# Note: Dummy precision argument is for backwards compatibility.
|
||||
# Do the division first.
|
||||
# (See http://en.wikipedia.org/wiki/Least_common_multiple )
|
||||
denom = gcf(a, b)
|
||||
if denom == 0:
|
||||
result = 0
|
||||
else:
|
||||
result = a * (b / denom)
|
||||
return result
|
||||
|
||||
|
||||
def permutations(input_list):
|
||||
"""Return a list containing all permutations of the input list.
|
||||
|
||||
Note: This is a recursive function.
|
||||
|
||||
>>> perms = permutations(['a', 'b', 'c'])
|
||||
>>> perms.sort()
|
||||
>>> for perm in perms:
|
||||
... print perm
|
||||
['a', 'b', 'c']
|
||||
['a', 'c', 'b']
|
||||
['b', 'a', 'c']
|
||||
['b', 'c', 'a']
|
||||
['c', 'a', 'b']
|
||||
['c', 'b', 'a']
|
||||
|
||||
"""
|
||||
out_lists = []
|
||||
if len(input_list) > 1:
|
||||
# Extract first item in list.
|
||||
item = input_list[0]
|
||||
# Find all permutations of remainder of list. (Recursive call.)
|
||||
sub_lists = permutations(input_list[1:])
|
||||
# For every permutation of the sub list...
|
||||
for sub_list in sub_lists:
|
||||
# Insert the extracted first item at every position of the list.
|
||||
for i in range(len(input_list)):
|
||||
new_list = sub_list[:]
|
||||
new_list.insert(i, item)
|
||||
out_lists.append(new_list)
|
||||
else:
|
||||
# Termination condition: only one item in input list.
|
||||
out_lists = [input_list]
|
||||
return out_lists
|
||||
|
||||
|
||||
def reduce_fraction(fraction):
|
||||
"""Reduce fraction tuple to simplest form. fraction=(num, denom)
|
||||
|
||||
>>> reduce_fraction((14, 7))
|
||||
(2, 1)
|
||||
|
||||
>>> reduce_fraction((-2, 4))
|
||||
(-1, 2)
|
||||
|
||||
>>> reduce_fraction((0, 4))
|
||||
(0, 1)
|
||||
|
||||
>>> reduce_fraction((4, 0))
|
||||
(1, 0)
|
||||
|
||||
"""
|
||||
(numerator, denominator) = fraction
|
||||
common_factor = abs(gcf(numerator, denominator))
|
||||
result = (numerator/common_factor, denominator/common_factor)
|
||||
return result
|
||||
|
||||
|
||||
def quantile(l, p):
|
||||
"""Return p quantile of list l. E.g. p=0.25 for q1.
|
||||
|
||||
See:
|
||||
http://rweb.stat.umn.edu/R/library/base/html/quantile.html
|
||||
|
||||
"""
|
||||
l_sort = l[:]
|
||||
l_sort.sort()
|
||||
n = len(l)
|
||||
r = 1 + ((n - 1) * p)
|
||||
i = int(r)
|
||||
f = r - i
|
||||
if i < n:
|
||||
result = (1-f)*l_sort[i-1] + f*l_sort[i]
|
||||
else:
|
||||
result = l_sort[i-1]
|
||||
return result
|
||||
|
||||
|
||||
def trim(l):
|
||||
"""Discard values in list more than 1.5*IQR outside IQR.
|
||||
|
||||
(IQR is inter-quartile-range)
|
||||
|
||||
This function uses rad_util.quantile
|
||||
|
||||
1.5*IQR -- mild outlier
|
||||
3*IQR -- extreme outlier
|
||||
|
||||
See:
|
||||
http://wind.cc.whecn.edu/~pwildman/statnew/section_7_-_exploratory_data_analysis.htm
|
||||
|
||||
"""
|
||||
l_sort = l[:]
|
||||
l_sort.sort()
|
||||
# Calculate medianscore (based on stats.py lmedianscore by Gary Strangman)
|
||||
if len(l_sort) % 2 == 0:
|
||||
# If even number of scores, average middle 2.
|
||||
index = int(len(l_sort) / 2) # Integer division correct
|
||||
median = float(l_sort[index] + l_sort[index-1]) / 2
|
||||
else:
|
||||
# int divsion gives mid value when count from 0
|
||||
index = int(len(l_sort) / 2)
|
||||
median = l_sort[index]
|
||||
# Calculate IQR.
|
||||
q1 = quantile(l_sort, 0.25)
|
||||
q3 = quantile(l_sort, 0.75)
|
||||
iqr = q3 - q1
|
||||
iqr_extra = iqr * 1.5
|
||||
def in_interval(x, i=iqr_extra, q1=q1, q3=q3):
|
||||
return (x >= q1-i and x <= q3+i)
|
||||
l_trimmed = [x for x in l_sort if in_interval(x)]
|
||||
return l_trimmed
|
||||
|
||||
|
||||
def nice_units(value, dp=0, sigfigs=None, suffix='', space=' ',
|
||||
use_extra_prefixes=False, use_full_name=False, mode='si'):
|
||||
"""Return value converted to human readable units eg milli, micro, etc.
|
||||
|
||||
Arguments:
|
||||
value -- number in base units
|
||||
dp -- number of decimal places to display (rounded)
|
||||
sigfigs -- number of significant figures to display (rounded)
|
||||
This overrides dp if set.
|
||||
suffix -- optional unit suffix to append to unit multiplier
|
||||
space -- seperator between value and unit multiplier (default: ' ')
|
||||
use_extra_prefixes -- use hecto, deka, deci and centi as well if set.
|
||||
(default: False)
|
||||
use_full_name -- use full name for multiplier symbol,
|
||||
e.g. milli instead of m
|
||||
(default: False)
|
||||
mode -- 'si' for SI prefixes, 'bin' for binary multipliers (1024, etc.)
|
||||
(Default: 'si')
|
||||
|
||||
SI prefixes from:
|
||||
http://physics.nist.gov/cuu/Units/prefixes.html
|
||||
(Greek mu changed to u.)
|
||||
Binary prefixes based on:
|
||||
http://physics.nist.gov/cuu/Units/binary.html
|
||||
|
||||
>>> nice_units(2e-11)
|
||||
'20 p'
|
||||
|
||||
>>> nice_units(2e-11, space='')
|
||||
'20p'
|
||||
|
||||
"""
|
||||
si_prefixes = {1e24: ('Y', 'yotta'),
|
||||
1e21: ('Z', 'zetta'),
|
||||
1e18: ('E', 'exa'),
|
||||
1e15: ('P', 'peta'),
|
||||
1e12: ('T', 'tera'),
|
||||
1e9: ('G', 'giga'),
|
||||
1e6: ('M', 'mega'),
|
||||
1e3: ('k', 'kilo'),
|
||||
1e-3: ('m', 'milli'),
|
||||
1e-6: ('u', 'micro'),
|
||||
1e-9: ('n', 'nano'),
|
||||
1e-12: ('p', 'pico'),
|
||||
1e-15: ('f', 'femto'),
|
||||
1e-18: ('a', 'atto'),
|
||||
1e-21: ('z', 'zepto'),
|
||||
1e-24: ('y', 'yocto')
|
||||
}
|
||||
if use_extra_prefixes:
|
||||
si_prefixes.update({1e2: ('h', 'hecto'),
|
||||
1e1: ('da', 'deka'),
|
||||
1e-1: ('d', 'deci'),
|
||||
1e-2: ('c', 'centi')
|
||||
})
|
||||
bin_prefixes = {2**10: ('K', 'kilo'),
|
||||
2**20: ('M', 'mega'),
|
||||
2**30: ('G', 'mega'),
|
||||
2**40: ('T', 'tera'),
|
||||
2**50: ('P', 'peta'),
|
||||
2**60: ('E', 'exa')
|
||||
}
|
||||
if mode == 'bin':
|
||||
prefixes = bin_prefixes
|
||||
else:
|
||||
prefixes = si_prefixes
|
||||
prefixes[1] = ('', '') # Unity.
|
||||
# Determine appropriate multiplier.
|
||||
multipliers = prefixes.keys()
|
||||
multipliers.sort()
|
||||
mult = None
|
||||
for i in range(len(multipliers) - 1):
|
||||
lower_mult = multipliers[i]
|
||||
upper_mult = multipliers[i+1]
|
||||
if lower_mult <= value < upper_mult:
|
||||
mult_i = i
|
||||
break
|
||||
if mult is None:
|
||||
if value < multipliers[0]:
|
||||
mult_i = 0
|
||||
elif value >= multipliers[-1]:
|
||||
mult_i = len(multipliers) - 1
|
||||
mult = multipliers[mult_i]
|
||||
# Convert value for this multiplier.
|
||||
new_value = value / mult
|
||||
# Deal with special case due to rounding.
|
||||
if sigfigs is None:
|
||||
if mult_i < (len(multipliers) - 1) and \
|
||||
round(new_value, dp) == \
|
||||
round((multipliers[mult_i+1] / mult), dp):
|
||||
mult = multipliers[mult_i + 1]
|
||||
new_value = value / mult
|
||||
# Concatenate multiplier symbol.
|
||||
if use_full_name:
|
||||
label_type = 1
|
||||
else:
|
||||
label_type = 0
|
||||
# Round and truncate to appropriate precision.
|
||||
if sigfigs is None:
|
||||
str_value = eval('"%.'+str(dp)+'f" % new_value', locals(), {})
|
||||
else:
|
||||
str_value = eval('"%.'+str(sigfigs)+'g" % new_value', locals(), {})
|
||||
return str_value + space + prefixes[mult][label_type] + suffix
|
||||
|
||||
|
||||
def uniquify(seq, preserve_order=False):
|
||||
"""Return sequence with duplicate items in sequence seq removed.
|
||||
|
||||
The code is based on usenet post by Tim Peters.
|
||||
|
||||
This code is O(N) if the sequence items are hashable, O(N**2) if not.
|
||||
|
||||
Peter Bengtsson has a blog post with an empirical comparison of other
|
||||
approaches:
|
||||
http://www.peterbe.com/plog/uniqifiers-benchmark
|
||||
|
||||
If order is not important and the sequence items are hashable then
|
||||
list(set(seq)) is readable and efficient.
|
||||
|
||||
If order is important and the sequence items are hashable generator
|
||||
expressions can be used (in py >= 2.4) (useful for large sequences):
|
||||
seen = set()
|
||||
do_something(x for x in seq if x not in seen or seen.add(x))
|
||||
|
||||
Arguments:
|
||||
seq -- sequence
|
||||
preserve_order -- if not set the order will be arbitrary
|
||||
Using this option will incur a speed penalty.
|
||||
(default: False)
|
||||
|
||||
Example showing order preservation:
|
||||
|
||||
>>> uniquify(['a', 'aa', 'b', 'b', 'ccc', 'ccc', 'd'], preserve_order=True)
|
||||
['a', 'aa', 'b', 'ccc', 'd']
|
||||
|
||||
Example using a sequence of un-hashable items:
|
||||
|
||||
>>> uniquify([['z'], ['x'], ['y'], ['z']], preserve_order=True)
|
||||
[['z'], ['x'], ['y']]
|
||||
|
||||
The sorted output or the non-order-preserving approach should equal
|
||||
that of the sorted order-preserving approach output:
|
||||
|
||||
>>> unordered = uniquify([3, 3, 1, 2], preserve_order=False)
|
||||
>>> unordered.sort()
|
||||
>>> ordered = uniquify([3, 3, 1, 2], preserve_order=True)
|
||||
>>> ordered.sort()
|
||||
>>> ordered
|
||||
[1, 2, 3]
|
||||
>>> int(ordered == unordered)
|
||||
1
|
||||
|
||||
"""
|
||||
try:
|
||||
# Attempt fast algorithm.
|
||||
d = {}
|
||||
if preserve_order:
|
||||
# This is based on Dave Kirby's method (f8) noted in the post:
|
||||
# http://www.peterbe.com/plog/uniqifiers-benchmark
|
||||
return [x for x in seq if (x not in d) and not d.__setitem__(x, 0)]
|
||||
else:
|
||||
for x in seq:
|
||||
d[x] = 0
|
||||
return d.keys()
|
||||
except TypeError:
|
||||
# Have an unhashable object, so use slow algorithm.
|
||||
result = []
|
||||
app = result.append
|
||||
for x in seq:
|
||||
if x not in result:
|
||||
app(x)
|
||||
return result
|
||||
|
||||
# Alias to noun form for backward compatibility.
|
||||
unique = uniquify
|
||||
|
||||
|
||||
def reverse_dict(d):
|
||||
"""Reverse a dictionary so the items become the keys and vice-versa.
|
||||
|
||||
Note: The results will be arbitrary if the items are not unique.
|
||||
|
||||
>>> d = reverse_dict({'a': 1, 'b': 2})
|
||||
>>> d_items = d.items()
|
||||
>>> d_items.sort()
|
||||
>>> d_items
|
||||
[(1, 'a'), (2, 'b')]
|
||||
|
||||
"""
|
||||
result = {}
|
||||
for key, value in d.items():
|
||||
result[value] = key
|
||||
return result
|
||||
|
||||
|
||||
def lsb(x, n):
|
||||
"""Return the n least significant bits of x.
|
||||
|
||||
>>> lsb(13, 3)
|
||||
5
|
||||
|
||||
"""
|
||||
return x & ((2 ** n) - 1)
|
||||
|
||||
|
||||
def gray_encode(i):
|
||||
"""Gray encode the given integer."""
|
||||
|
||||
return i ^ (i >> 1)
|
||||
|
||||
|
||||
def random_vec(bits, max_value=None):
|
||||
"""Generate a random binary vector of length bits and given max value."""
|
||||
|
||||
vector = ""
|
||||
for _ in range(int(bits / 10) + 1):
|
||||
i = int((2**10) * random.random())
|
||||
vector += int2bin(i, 10)
|
||||
|
||||
if max_value and (max_value < 2 ** bits - 1):
|
||||
vector = int2bin((int(vector, 2) / (2 ** bits - 1)) * max_value, bits)
|
||||
|
||||
return vector[0:bits]
|
||||
|
||||
|
||||
def binary_range(bits):
|
||||
"""Return a list of all possible binary numbers in order with width=bits.
|
||||
|
||||
It would be nice to extend it to match the
|
||||
functionality of python's range() built-in function.
|
||||
|
||||
"""
|
||||
l = []
|
||||
v = ['0'] * bits
|
||||
|
||||
toggle = [1] + [0] * bits
|
||||
|
||||
while toggle[bits] != 1:
|
||||
v_copy = v[:]
|
||||
v_copy.reverse()
|
||||
l.append(''.join(v_copy))
|
||||
|
||||
toggle = [1] + [0]*bits
|
||||
i = 0
|
||||
while i < bits and toggle[i] == 1:
|
||||
if toggle[i]:
|
||||
if v[i] == '0':
|
||||
v[i] = '1'
|
||||
toggle[i+1] = 0
|
||||
else:
|
||||
v[i] = '0'
|
||||
toggle[i+1] = 1
|
||||
i += 1
|
||||
return l
|
||||
|
||||
|
||||
def float_range(start, stop=None, step=None):
|
||||
"""Return a list containing an arithmetic progression of floats.
|
||||
|
||||
Return a list of floats between 0.0 (or start) and stop with an
|
||||
increment of step.
|
||||
|
||||
This is in functionality to python's range() built-in function
|
||||
but can accept float increments.
|
||||
|
||||
As with range(), stop is omitted from the list.
|
||||
|
||||
"""
|
||||
if stop is None:
|
||||
stop = float(start)
|
||||
start = 0.0
|
||||
|
||||
if step is None:
|
||||
step = 1.0
|
||||
|
||||
cur = float(start)
|
||||
l = []
|
||||
while cur < stop:
|
||||
l.append(cur)
|
||||
cur += step
|
||||
|
||||
return l
|
||||
|
||||
|
||||
def find_common_fixes(s1, s2):
|
||||
"""Find common (prefix, suffix) of two strings.
|
||||
|
||||
>>> find_common_fixes('abc', 'def')
|
||||
('', '')
|
||||
|
||||
>>> find_common_fixes('abcelephantdef', 'abccowdef')
|
||||
('abc', 'def')
|
||||
|
||||
>>> find_common_fixes('abcelephantdef', 'abccow')
|
||||
('abc', '')
|
||||
|
||||
>>> find_common_fixes('elephantdef', 'abccowdef')
|
||||
('', 'def')
|
||||
|
||||
"""
|
||||
prefix = []
|
||||
suffix = []
|
||||
|
||||
i = 0
|
||||
common_len = min(len(s1), len(s2))
|
||||
while i < common_len:
|
||||
if s1[i] != s2[i]:
|
||||
break
|
||||
|
||||
prefix.append(s1[i])
|
||||
i += 1
|
||||
|
||||
i = 1
|
||||
while i < (common_len + 1):
|
||||
if s1[-i] != s2[-i]:
|
||||
break
|
||||
|
||||
suffix.append(s1[-i])
|
||||
i += 1
|
||||
|
||||
suffix.reverse()
|
||||
|
||||
prefix = ''.join(prefix)
|
||||
suffix = ''.join(suffix)
|
||||
|
||||
return (prefix, suffix)
|
||||
|
||||
|
||||
def is_rotated(seq1, seq2):
|
||||
"""Return true if the first sequence is a rotation of the second sequence.
|
||||
|
||||
>>> seq1 = ['A', 'B', 'C', 'D']
|
||||
>>> seq2 = ['C', 'D', 'A', 'B']
|
||||
>>> int(is_rotated(seq1, seq2))
|
||||
1
|
||||
|
||||
>>> seq2 = ['C', 'D', 'B', 'A']
|
||||
>>> int(is_rotated(seq1, seq2))
|
||||
0
|
||||
|
||||
>>> seq1 = ['A', 'B', 'C', 'A']
|
||||
>>> seq2 = ['A', 'A', 'B', 'C']
|
||||
>>> int(is_rotated(seq1, seq2))
|
||||
1
|
||||
|
||||
>>> seq2 = ['A', 'B', 'C', 'A']
|
||||
>>> int(is_rotated(seq1, seq2))
|
||||
1
|
||||
|
||||
>>> seq2 = ['A', 'A', 'C', 'B']
|
||||
>>> int(is_rotated(seq1, seq2))
|
||||
0
|
||||
|
||||
"""
|
||||
# Do a sanity check.
|
||||
if len(seq1) != len(seq2):
|
||||
return False
|
||||
# Look for occurrences of second sequence head item in first sequence.
|
||||
start_indexes = []
|
||||
head_item = seq2[0]
|
||||
for index1 in range(len(seq1)):
|
||||
if seq1[index1] == head_item:
|
||||
start_indexes.append(index1)
|
||||
# Check that wrapped sequence matches.
|
||||
double_seq1 = seq1 + seq1
|
||||
for index1 in start_indexes:
|
||||
if double_seq1[index1:index1+len(seq1)] == seq2:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getmodule(obj):
|
||||
"""Return the module that contains the object definition of obj.
|
||||
|
||||
Note: Use inspect.getmodule instead.
|
||||
|
||||
Arguments:
|
||||
obj -- python obj, generally a class or a function
|
||||
|
||||
Examples:
|
||||
|
||||
A function:
|
||||
>>> module = getmodule(random.choice)
|
||||
>>> module.__name__
|
||||
'random'
|
||||
>>> module is random
|
||||
1
|
||||
|
||||
A class:
|
||||
>>> module = getmodule(random.Random)
|
||||
>>> module.__name__
|
||||
'random'
|
||||
>>> module is random
|
||||
1
|
||||
|
||||
A class inheriting from a class in another module:
|
||||
(note: The inheriting class must define at least one function.)
|
||||
>>> class MyRandom(random.Random):
|
||||
... def play(self):
|
||||
... pass
|
||||
>>> module = getmodule(MyRandom)
|
||||
>>> if __name__ == '__main__':
|
||||
... name = 'rad_util'
|
||||
... else:
|
||||
... name = module.__name__
|
||||
>>> name
|
||||
'rad_util'
|
||||
>>> module is sys.modules[__name__]
|
||||
1
|
||||
|
||||
Discussion:
|
||||
This approach is slightly hackish, and won't work in various situations.
|
||||
However, this was the approach recommended by GvR, so it's as good as
|
||||
you'll get.
|
||||
|
||||
See GvR's post in this thread:
|
||||
http://groups.google.com.au/group/comp.lang.python/browse_thread/thread/966a7bdee07e3b34/c3cab3f41ea84236?lnk=st&q=python+determine+class+module&rnum=4&hl=en#c3cab3f41ea84236
|
||||
|
||||
"""
|
||||
if hasattr(obj, 'func_globals'):
|
||||
func = obj
|
||||
else:
|
||||
# Handle classes.
|
||||
func = None
|
||||
for item in obj.__dict__.values():
|
||||
if hasattr(item, 'func_globals'):
|
||||
func = item
|
||||
break
|
||||
if func is None:
|
||||
raise ValueError("No functions attached to object: %r" % obj)
|
||||
module_name = func.func_globals['__name__']
|
||||
# Get module.
|
||||
module = sys.modules[module_name]
|
||||
return module
|
||||
|
||||
|
||||
def round_grid(value, grid, mode=0):
|
||||
"""Round off the given value to the given grid size.
|
||||
|
||||
Arguments:
|
||||
value -- value to be roudne
|
||||
grid -- result must be a multiple of this
|
||||
mode -- 0 nearest, 1 up, -1 down
|
||||
|
||||
Examples:
|
||||
|
||||
>>> round_grid(7.5, 5)
|
||||
10
|
||||
|
||||
>>> round_grid(7.5, 5, mode=-1)
|
||||
5
|
||||
|
||||
>>> round_grid(7.3, 5, mode=1)
|
||||
10
|
||||
|
||||
>>> round_grid(7.3, 5.0, mode=1)
|
||||
10.0
|
||||
|
||||
"""
|
||||
off_grid = value % grid
|
||||
if mode == 0:
|
||||
add_one = int(off_grid >= (grid / 2.0))
|
||||
elif mode == 1 and off_grid:
|
||||
add_one = 1
|
||||
elif mode == -1 and off_grid:
|
||||
add_one = 0
|
||||
result = ((int(value / grid) + add_one) * grid)
|
||||
return result
|
||||
|
||||
|
||||
def get_args(argv):
|
||||
"""Store command-line args in a dictionary.
|
||||
|
||||
-, -- prefixes are removed
|
||||
Items not prefixed with - or -- are stored as a list, indexed by 'args'
|
||||
|
||||
For options that take a value use --option=value
|
||||
|
||||
Consider using optparse or getopt (in Python standard library) instead.
|
||||
|
||||
"""
|
||||
d = {}
|
||||
args = []
|
||||
|
||||
for arg in argv:
|
||||
|
||||
if arg.startswith('-'):
|
||||
parts = re.sub(r'^-+', '', arg).split('=')
|
||||
if len(parts) == 2:
|
||||
d[parts[0]] = parts[1]
|
||||
else:
|
||||
d[parts[0]] = None
|
||||
else:
|
||||
args.append(arg)
|
||||
|
||||
d['args'] = args
|
||||
|
||||
return d
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod(sys.modules['__main__'])
|
||||
|
||||
@@ -0,0 +1,392 @@
|
||||
# topsort - dependency (topological) sorting and cycle finding functions
|
||||
# Copyright (C) 2007 RADLogic
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation;
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# See http://www.fsf.org/licensing/licenses/lgpl.txt for full license text.
|
||||
"""Provide toplogical sorting (i.e. dependency sorting) functions.
|
||||
|
||||
The topsort function is based on code posted on Usenet by Tim Peters.
|
||||
|
||||
Modifications:
|
||||
- added doctests
|
||||
- changed some bits to use current Python idioms
|
||||
(listcomp instead of filter, +=/-=, inherit from Exception)
|
||||
- added a topsort_levels version that ports items in each dependency level
|
||||
into a sub-list
|
||||
- added find_cycles to aid in cycle debugging
|
||||
|
||||
Run this module directly to run the doctests (unittests).
|
||||
Make sure they all pass before checking in any modifications.
|
||||
|
||||
Requires Python >= 2.2
|
||||
(For Python 2.2 also requires separate sets.py module)
|
||||
|
||||
This requires the rad_util.py module.
|
||||
|
||||
"""
|
||||
|
||||
# Provide support for Python 2.2*
|
||||
from __future__ import generators
|
||||
|
||||
__version__ = '$Revision: 0.9 $'
|
||||
__date__ = '$Date: 2007/03/27 04:15:26 $'
|
||||
__credits__ = '''Tim Peters -- original topsort code
|
||||
Tim Wegener -- doctesting, updating to current idioms, topsort_levels,
|
||||
find_cycles
|
||||
'''
|
||||
|
||||
# Make Python 2.3 sets look like Python 2.4 sets.
|
||||
try:
|
||||
set
|
||||
except NameError:
|
||||
from sets import Set as set
|
||||
|
||||
from rad_util import is_rotated
|
||||
|
||||
|
||||
class CycleError(Exception):
|
||||
"""Cycle Error"""
|
||||
pass
|
||||
|
||||
|
||||
def topsort(pairlist):
|
||||
"""Topologically sort a list of (parent, child) pairs.
|
||||
|
||||
Return a list of the elements in dependency order (parent to child order).
|
||||
|
||||
>>> print topsort( [(1,2), (3,4), (5,6), (1,3), (1,5), (1,6), (2,5)] )
|
||||
[1, 2, 3, 5, 4, 6]
|
||||
|
||||
>>> print topsort( [(1,2), (1,3), (2,4), (3,4), (5,6), (4,5)] )
|
||||
[1, 2, 3, 4, 5, 6]
|
||||
|
||||
>>> print topsort( [(1,2), (2,3), (3,2)] )
|
||||
Traceback (most recent call last):
|
||||
CycleError: ([1], {2: 1, 3: 1}, {2: [3], 3: [2]})
|
||||
|
||||
"""
|
||||
num_parents = {} # element -> # of predecessors
|
||||
children = {} # element -> list of successors
|
||||
for parent, child in pairlist:
|
||||
# Make sure every element is a key in num_parents.
|
||||
if not num_parents.has_key( parent ):
|
||||
num_parents[parent] = 0
|
||||
if not num_parents.has_key( child ):
|
||||
num_parents[child] = 0
|
||||
|
||||
# Since child has a parent, increment child's num_parents count.
|
||||
num_parents[child] += 1
|
||||
|
||||
# ... and parent gains a child.
|
||||
children.setdefault(parent, []).append(child)
|
||||
|
||||
# Suck up everything without a parent.
|
||||
answer = [x for x in num_parents.keys() if num_parents[x] == 0]
|
||||
|
||||
# For everything in answer, knock down the parent count on its children.
|
||||
# Note that answer grows *in* the loop.
|
||||
for parent in answer:
|
||||
del num_parents[parent]
|
||||
if children.has_key( parent ):
|
||||
for child in children[parent]:
|
||||
num_parents[child] -= 1
|
||||
if num_parents[child] == 0:
|
||||
answer.append( child )
|
||||
# Following "del" isn't needed; just makes
|
||||
# CycleError details easier to grasp.
|
||||
del children[parent]
|
||||
|
||||
if num_parents:
|
||||
# Everything in num_parents has at least one child ->
|
||||
# there's a cycle.
|
||||
raise CycleError(answer, num_parents, children)
|
||||
return answer
|
||||
|
||||
def topsort_levels(pairlist):
|
||||
"""Topologically sort a list of (parent, child) pairs into depth levels.
|
||||
|
||||
This returns a generator.
|
||||
Turn this into a an iterator using the iter built-in function.
|
||||
(if you iterate over the iterator, each element gets generated when
|
||||
it is asked for, rather than generating the whole list up-front.)
|
||||
|
||||
Each generated element is a list of items at that dependency level.
|
||||
|
||||
>>> dependency_pairs = [(1,2), (3,4), (5,6), (1,3), (1,5), (1,6), (2,5)]
|
||||
>>> for level in iter(topsort_levels( dependency_pairs )):
|
||||
... print level
|
||||
[1]
|
||||
[2, 3]
|
||||
[4, 5]
|
||||
[6]
|
||||
|
||||
>>> dependency_pairs = [(1,2), (1,3), (2,4), (3,4), (5,6), (4,5)]
|
||||
>>> for level in iter(topsort_levels( dependency_pairs )):
|
||||
... print level
|
||||
[1]
|
||||
[2, 3]
|
||||
[4]
|
||||
[5]
|
||||
[6]
|
||||
|
||||
>>> dependency_pairs = [(1,2), (2,3), (3,4), (4, 3)]
|
||||
>>> try:
|
||||
... for level in iter(topsort_levels( dependency_pairs )):
|
||||
... print level
|
||||
... except CycleError, exc:
|
||||
... print 'CycleError:', exc
|
||||
[1]
|
||||
[2]
|
||||
CycleError: ({3: 1, 4: 1}, {3: [4], 4: [3]})
|
||||
|
||||
|
||||
The cycle error should look like.
|
||||
CycleError: ({3: 1, 4: 1}, {3: [4], 4: [3]})
|
||||
# todo: Make the doctest more robust (i.e. handle arbitrary dict order).
|
||||
|
||||
"""
|
||||
num_parents = {} # element -> # of predecessors
|
||||
children = {} # element -> list of successors
|
||||
for parent, child in pairlist:
|
||||
# Make sure every element is a key in num_parents.
|
||||
if not num_parents.has_key( parent ):
|
||||
num_parents[parent] = 0
|
||||
if not num_parents.has_key( child ):
|
||||
num_parents[child] = 0
|
||||
|
||||
# Since child has a parent, increment child's num_parents count.
|
||||
num_parents[child] += 1
|
||||
|
||||
# ... and parent gains a child.
|
||||
children.setdefault(parent, []).append(child)
|
||||
|
||||
return topsort_levels_core(num_parents, children)
|
||||
|
||||
def topsort_levels_core(num_parents, children):
|
||||
"""Topologically sort a bunch of interdependent items based on dependency.
|
||||
|
||||
This returns a generator.
|
||||
Turn this into a an iterator using the iter built-in function.
|
||||
(if you iterate over the iterator, each element gets generated when
|
||||
it is asked for, rather than generating the whole list up-front.)
|
||||
|
||||
Each generated element is a list of items at that dependency level.
|
||||
|
||||
>>> list(topsort_levels_core(
|
||||
... {1: 0, 2: 1, 3: 1, 4: 1, 5: 2, 6: 2},
|
||||
... {1: [2, 3, 5, 6], 2: [5], 3: [4], 4: [], 5: [6]}))
|
||||
[[1], [2, 3], [4, 5], [6]]
|
||||
|
||||
>>> list(topsort_levels_core(
|
||||
... {1: 0, 2: 2, 3: 1},
|
||||
... {1: [2], 2: [3], 3: [2]}))
|
||||
Traceback (most recent call last):
|
||||
CycleError: ({2: 1, 3: 1}, {2: [3], 3: [2]})
|
||||
|
||||
This function has a more complicated interface than topsort_levels,
|
||||
but is useful if the data is easier to generate in this form.
|
||||
|
||||
Arguments:
|
||||
num_parents -- key: item, value: number of parents (predecessors)
|
||||
children -- key: item, value: list of children (successors)
|
||||
|
||||
"""
|
||||
while 1:
|
||||
# Suck up everything without a predecessor.
|
||||
level_parents = [x for x in num_parents.keys() if num_parents[x] == 0]
|
||||
|
||||
if not level_parents:
|
||||
break
|
||||
|
||||
# Offer the next generated item,
|
||||
# which is a list of the items at this dependency level.
|
||||
yield level_parents
|
||||
|
||||
# For everything item in this level,
|
||||
# decrement the parent count,
|
||||
# since we have accounted for its parent.
|
||||
for level_parent in level_parents:
|
||||
|
||||
del num_parents[level_parent]
|
||||
|
||||
if children.has_key(level_parent):
|
||||
for level_parent_child in children[level_parent]:
|
||||
num_parents[level_parent_child] -= 1
|
||||
del children[level_parent]
|
||||
|
||||
if num_parents:
|
||||
# Everything in num_parents has at least one child ->
|
||||
# there's a cycle.
|
||||
raise CycleError(num_parents, children)
|
||||
else:
|
||||
# This is the end of the generator.
|
||||
raise StopIteration
|
||||
|
||||
|
||||
def find_cycles(parent_children):
|
||||
"""Yield cycles. Each result is a list of items comprising a cycle.
|
||||
|
||||
Use a 'stack' based approach to find all the cycles.
|
||||
This is a generator, so yields each cycle as it finds it.
|
||||
|
||||
It is implicit that the last item in each cycle list is a parent of the
|
||||
first item (thereby forming a cycle).
|
||||
|
||||
Arguments:
|
||||
parent_children -- parent -> collection of children
|
||||
|
||||
Simplest cycle:
|
||||
>>> cycles = list(find_cycles({'A': ['B'], 'B': ['A']}))
|
||||
>>> len(cycles)
|
||||
1
|
||||
>>> cycle = cycles[0]
|
||||
>>> cycle.sort()
|
||||
>>> print cycle
|
||||
['A', 'B']
|
||||
|
||||
Simplest cycle with extra baggage at the start and the end:
|
||||
>>> cycles = list(find_cycles(parent_children={'A': ['B'],
|
||||
... 'B': ['C'],
|
||||
... 'C': ['B', 'D'],
|
||||
... 'D': [],
|
||||
... }))
|
||||
>>> len(cycles)
|
||||
1
|
||||
>>> cycle = cycles[0]
|
||||
>>> cycle.sort()
|
||||
>>> print cycle
|
||||
['B', 'C']
|
||||
|
||||
Double cycle:
|
||||
>>> cycles = list(find_cycles(parent_children={'A': ['B'],
|
||||
... 'B': ['C1', 'C2'],
|
||||
... 'C1': ['D1'],
|
||||
... 'D1': ['E1'],
|
||||
... 'E1': ['D1'],
|
||||
... 'C2': ['D2'],
|
||||
... 'D2': ['E2'],
|
||||
... 'E2': ['D2'],
|
||||
... }))
|
||||
>>> len(cycles)
|
||||
2
|
||||
>>> for cycle in cycles:
|
||||
... cycle.sort()
|
||||
>>> cycles.sort()
|
||||
>>> cycle1 = cycles[0]
|
||||
>>> cycle1.sort()
|
||||
>>> print cycle1
|
||||
['D1', 'E1']
|
||||
>>> cycle2 = cycles[1]
|
||||
>>> cycle2.sort()
|
||||
>>> print cycle2
|
||||
['D2', 'E2']
|
||||
|
||||
Simple cycle with children not specified for one item:
|
||||
# todo: Should this barf instead?
|
||||
>>> cycles = list(find_cycles(parent_children={'A': ['B'],
|
||||
... 'B': ['A'],
|
||||
... 'C': ['D']}))
|
||||
>>> len(cycles)
|
||||
1
|
||||
>>> cycle = cycles[0]
|
||||
>>> cycle.sort()
|
||||
>>> print cycle
|
||||
['A', 'B']
|
||||
|
||||
Diamond cycle
|
||||
>>> cycles = list(find_cycles(parent_children={'A': ['B1', 'B2'],
|
||||
... 'B1': ['C'],
|
||||
... 'B2': ['C'],
|
||||
... 'C': ['A', 'B1']}))
|
||||
>>> len(cycles)
|
||||
3
|
||||
>>> sorted_cycles = []
|
||||
>>> for cycle in cycles:
|
||||
... cycle = list(cycle)
|
||||
... cycle.sort()
|
||||
... sorted_cycles.append(cycle)
|
||||
>>> sorted_cycles.sort()
|
||||
>>> for cycle in sorted_cycles:
|
||||
... print cycle
|
||||
['A', 'B1', 'C']
|
||||
['A', 'B2', 'C']
|
||||
['B1', 'C']
|
||||
|
||||
Hairy case (order can matter if something is wrong):
|
||||
(Note order of B and C in the list.)
|
||||
>>> cycles = list(find_cycles(parent_children={
|
||||
... 'TD': ['DD'],
|
||||
... 'TC': ['DC'],
|
||||
... 'DC': ['DQ'],
|
||||
... 'C': ['DQ'],
|
||||
... 'DQ': ['IA', 'TO'],
|
||||
... 'IA': ['A'],
|
||||
... 'A': ['B', 'C'],
|
||||
... }))
|
||||
>>> len(cycles)
|
||||
1
|
||||
>>> cycle = cycles[0]
|
||||
>>> cycle.sort()
|
||||
>>> print cycle
|
||||
['A', 'C', 'DQ', 'IA']
|
||||
|
||||
"""
|
||||
cycles = []
|
||||
visited_nodes = set()
|
||||
|
||||
for parent in parent_children:
|
||||
if parent in visited_nodes:
|
||||
# This node is part of a path that has already been traversed.
|
||||
continue
|
||||
|
||||
paths = [[parent]]
|
||||
while paths:
|
||||
path = paths.pop()
|
||||
|
||||
parent = path[-1]
|
||||
|
||||
try:
|
||||
children = parent_children[parent]
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
for child in children:
|
||||
# Keeping a set of the path nodes, for O(1) lookups at the
|
||||
# expense of more memory and complexity, actually makes speed
|
||||
# worse. (Due to construction of sets.)
|
||||
# This is O(N).
|
||||
if child in path:
|
||||
# This is a cycle.
|
||||
cycle = path[path.index(child):]
|
||||
# Check that this is not a dup cycle.
|
||||
is_dup = False
|
||||
for other_cycle in cycles:
|
||||
if is_rotated(other_cycle, cycle):
|
||||
is_dup = True
|
||||
break
|
||||
if not is_dup:
|
||||
cycles.append(cycle)
|
||||
yield cycle
|
||||
else:
|
||||
# Push this new path onto the 'stack'.
|
||||
# This is probably the most expensive part of the algorithm
|
||||
# (a list copy).
|
||||
paths.append(path + [child])
|
||||
# Mark the node as visited.
|
||||
visited_nodes.add(child)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Run the doctest tests.
|
||||
import sys
|
||||
import doctest
|
||||
doctest.testmod(sys.modules['__main__'])
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
exec "`dirname "$0"`"/../../waf "$@"
|
||||
@@ -0,0 +1,444 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
import re
|
||||
import Params
|
||||
import Configure
|
||||
import Object
|
||||
import Action
|
||||
import os
|
||||
import Task
|
||||
import pproc as subprocess
|
||||
from Params import fatal, warning
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
## Adjust python path to look for our local copy of pybindgen
|
||||
LOCAL_PYBINDGEN_PATH = os.path.join(os.getcwd(), "bindings", "python", "pybindgen")
|
||||
#PYBINDGEN_BRANCH = 'lp:pybindgen'
|
||||
PYBINDGEN_BRANCH = 'https://launchpad.net/pybindgen'
|
||||
if os.environ.get('PYTHONPATH', ''):
|
||||
os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH + os.pathsep + os.environ.get('PYTHONPATH')
|
||||
else:
|
||||
os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH
|
||||
|
||||
## https://launchpad.net/pybindgen/
|
||||
REQUIRED_PYBINDGEN_VERSION = (0, 9, 0, 578)
|
||||
REQUIRED_PYGCCXML_VERSION = (0, 9, 5)
|
||||
|
||||
|
||||
def set_options(opt):
|
||||
opt.tool_options('python')
|
||||
opt.add_option('--disable-python',
|
||||
help=("Don't build Python bindings."),
|
||||
action="store_true", default=False,
|
||||
dest='python_disable')
|
||||
opt.add_option('--python-scan',
|
||||
help=("Rescan Python bindings. Needs working GCCXML / pygccxml environment."),
|
||||
action="store_true", default=False,
|
||||
dest='python_scan')
|
||||
opt.add_option('--pybindgen-checkout',
|
||||
help=("During configure, force checkout of pybingen inside ns-3, "
|
||||
"instead of using the system installed version."),
|
||||
action="store_true", default=False,
|
||||
dest='pybindgen_checkout')
|
||||
|
||||
def fetch_pybindgen(conf):
|
||||
"""
|
||||
Fetches pybindgen from launchpad as bindings/python/pybindgen.
|
||||
Returns True if successful, False it not.
|
||||
"""
|
||||
bzr = conf.find_program("bzr")
|
||||
if not bzr:
|
||||
warning("the program 'bzr' is needed in order to fetch pybindgen")
|
||||
return False
|
||||
if len(REQUIRED_PYBINDGEN_VERSION) == 4:
|
||||
rev = "-rrevno:%i" % REQUIRED_PYBINDGEN_VERSION[3]
|
||||
else:
|
||||
rev = "-rtag:%s" % '.'.join([str(x) for x in REQUIRED_PYBINDGEN_VERSION])
|
||||
if os.path.exists(LOCAL_PYBINDGEN_PATH):
|
||||
print "Trying to update pybindgen; this will fail if no network connection is available."
|
||||
|
||||
cmd = [bzr, "pull", rev, PYBINDGEN_BRANCH]
|
||||
print " => ", ' '.join(cmd)
|
||||
if subprocess.Popen(cmd, cwd=LOCAL_PYBINDGEN_PATH).wait():
|
||||
return False
|
||||
print "Update was successful."
|
||||
else:
|
||||
print "Trying to fetch pybindgen; this will fail if no network connection is available."
|
||||
cmd = [bzr, "checkout", rev, PYBINDGEN_BRANCH, LOCAL_PYBINDGEN_PATH]
|
||||
print " => ", ' '.join(cmd)
|
||||
if subprocess.Popen(cmd).wait():
|
||||
return False
|
||||
print "Fetch was successful."
|
||||
|
||||
## generate a fake version.py file in pybindgen it's safer this
|
||||
## way, since the normal version generation process requires
|
||||
## bazaar python bindings, which may not be available.
|
||||
vfile = open(os.path.join(LOCAL_PYBINDGEN_PATH, "pybindgen", "version.py"), "wt")
|
||||
vfile.write("""
|
||||
# (fake version generated by ns-3)
|
||||
__version__ = %r
|
||||
""" % list(REQUIRED_PYBINDGEN_VERSION))
|
||||
vfile.close()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def configure(conf):
|
||||
conf.env['ENABLE_PYTHON_BINDINGS'] = False
|
||||
if Params.g_options.python_disable:
|
||||
conf.report_optional_feature("python", "Python Bindings", False,
|
||||
"disabled by user request")
|
||||
return
|
||||
|
||||
conf.check_tool('misc')
|
||||
|
||||
if sys.platform == 'cygwin':
|
||||
conf.report_optional_feature("python", "Python Bindings", False,
|
||||
"unsupported platform 'cygwin'")
|
||||
warning("Python is not supported in CygWin environment. Try MingW instead.")
|
||||
return
|
||||
|
||||
## Check for Python
|
||||
try:
|
||||
conf.check_tool('python')
|
||||
conf.check_python_version((2,3))
|
||||
conf.check_python_headers()
|
||||
except Configure.ConfigurationError, ex:
|
||||
conf.report_optional_feature("python", "Python Bindings", False, str(ex))
|
||||
return
|
||||
|
||||
## Check for pybindgen
|
||||
if Params.g_options.pybindgen_checkout:
|
||||
fetch_pybindgen(conf)
|
||||
|
||||
try:
|
||||
conf.check_python_module('pybindgen')
|
||||
except Configure.ConfigurationError:
|
||||
warning("pybindgen missing")
|
||||
if not fetch_pybindgen(conf):
|
||||
conf.report_optional_feature("python", "Python Bindings", False,
|
||||
"PyBindGen missing and could not be retrieved")
|
||||
return
|
||||
else:
|
||||
out = subprocess.Popen([conf.env['PYTHON'], "-c",
|
||||
"import pybindgen.version; "
|
||||
"print '.'.join([str(x) for x in pybindgen.version.__version__])"],
|
||||
stdout=subprocess.PIPE).communicate()[0]
|
||||
pybindgen_version_str = out.strip()
|
||||
pybindgen_version = tuple([int(x) for x in pybindgen_version_str.split('.')])
|
||||
conf.check_message('pybindgen', 'version',
|
||||
(pybindgen_version >= REQUIRED_PYBINDGEN_VERSION),
|
||||
pybindgen_version_str)
|
||||
if not (pybindgen_version >= REQUIRED_PYBINDGEN_VERSION):
|
||||
warning("pybindgen (found %s) is too old (need %s)" %
|
||||
(pybindgen_version_str,
|
||||
'.'.join([str(x) for x in REQUIRED_PYBINDGEN_VERSION])))
|
||||
if not fetch_pybindgen(conf):
|
||||
conf.report_optional_feature("python", "Python Bindings", False,
|
||||
"PyBindGen too old and newer version could not be retrieved")
|
||||
return
|
||||
|
||||
## If all has gone well, we finally enable the Python bindings
|
||||
conf.env['ENABLE_PYTHON_BINDINGS'] = True
|
||||
conf.report_optional_feature("python", "Python Bindings", True, None)
|
||||
|
||||
## Check for pygccxml
|
||||
try:
|
||||
conf.check_python_module('pygccxml')
|
||||
except Configure.ConfigurationError:
|
||||
conf.report_optional_feature("pygccxml", "Python API Scanning Support", False,
|
||||
"Missing 'pygccxml' Python module")
|
||||
return
|
||||
|
||||
out = subprocess.Popen([conf.env['PYTHON'], "-c",
|
||||
"import pygccxml; print pygccxml.__version__"],
|
||||
stdout=subprocess.PIPE).communicate()[0]
|
||||
pygccxml_version_str = out.strip()
|
||||
pygccxml_version = tuple([int(x) for x in pygccxml_version_str.split('.')])
|
||||
conf.check_message('pygccxml', 'version',
|
||||
(pygccxml_version >= REQUIRED_PYGCCXML_VERSION),
|
||||
pygccxml_version_str)
|
||||
if not (pygccxml_version >= REQUIRED_PYGCCXML_VERSION):
|
||||
warning("pygccxml (found %s) is too old (need %s) => "
|
||||
"automatic scanning of API definitions will not be possible" %
|
||||
(pygccxml_version_str,
|
||||
'.'.join([str(x) for x in REQUIRED_PYGCCXML_VERSION])))
|
||||
conf.report_optional_feature("pygccxml", "Python API Scanning Support", False,
|
||||
"pygccxml too old")
|
||||
return
|
||||
|
||||
|
||||
## Check gccxml version
|
||||
gccxml = conf.find_program('gccxml', var='GCCXML')
|
||||
if not gccxml:
|
||||
warning("gccxml missing; automatic scanning of API definitions will not be possible")
|
||||
conf.report_optional_feature("pygccxml", "Python API Scanning Support", False,
|
||||
"gccxml missing")
|
||||
return
|
||||
|
||||
gccxml_version_line = os.popen(gccxml + " --version").readline().strip()
|
||||
m = re.match( "^GCC-XML version (\d\.\d(\.\d)?)$", gccxml_version_line)
|
||||
gccxml_version = m.group(1)
|
||||
gccxml_version_ok = ([int(s) for s in gccxml_version.split('.')] >= [0, 9])
|
||||
conf.check_message('gccxml', 'version', True, gccxml_version)
|
||||
if not gccxml_version_ok:
|
||||
warning("gccxml too old, need version >= 0.9; automatic scanning of API definitions will not be possible")
|
||||
conf.report_optional_feature("pygccxml", "Python API Scanning Support", False,
|
||||
"gccxml too old")
|
||||
return
|
||||
|
||||
## If we reached
|
||||
conf.env['ENABLE_PYTHON_SCANNING'] = True
|
||||
conf.report_optional_feature("pygccxml", "Python API Scanning Support", True, None)
|
||||
|
||||
|
||||
prio_headers = {
|
||||
-2: (
|
||||
"string.h", # work around http://www.gccxml.org/Bug/view.php?id=6682
|
||||
),
|
||||
-1: (
|
||||
"propagation-delay-model.h",
|
||||
"propagation-loss-model.h",
|
||||
"net-device.h",
|
||||
)
|
||||
}
|
||||
|
||||
def get_header_prio(header):
|
||||
for prio, headers in prio_headers.iteritems():
|
||||
if header in headers:
|
||||
return prio
|
||||
return 1
|
||||
|
||||
|
||||
def calc_header_include(path):
|
||||
(head, tail) = os.path.split (path)
|
||||
if tail == 'ns3':
|
||||
return ''
|
||||
else:
|
||||
return os.path.join (calc_header_include (head), tail)
|
||||
|
||||
|
||||
def gen_ns3_metaheader(task):
|
||||
assert len(task.m_outputs) == 1
|
||||
|
||||
header_files = [calc_header_include(node.abspath(task.m_env)) for node in task.m_inputs]
|
||||
outfile = file(task.m_outputs[0].bldpath(task.m_env), "w")
|
||||
|
||||
def sort_func(h1, h2):
|
||||
return cmp((get_header_prio(h1), h1), (get_header_prio(h1), h2))
|
||||
|
||||
header_files.sort(sort_func)
|
||||
|
||||
for header in header_files:
|
||||
print >> outfile, "#include \"ns3/%s\"" % (header,)
|
||||
|
||||
print >> outfile, """
|
||||
namespace ns3 {
|
||||
static inline Ptr<Object>
|
||||
__dummy_function_to_force_template_instantiation (Ptr<Object> obj, TypeId typeId)
|
||||
{
|
||||
return obj->GetObject<Object> (typeId);
|
||||
}
|
||||
|
||||
}
|
||||
"""
|
||||
outfile.close()
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
class all_ns3_headers_taskgen(Object.task_gen):
|
||||
"""Generates a 'everything.h' header file that includes some/all public ns3 headers.
|
||||
This single header file is to be parsed only once by gccxml, for greater efficiency.
|
||||
"""
|
||||
def __init__(self, *features):
|
||||
Object.task_gen.__init__(self, *features)
|
||||
self.inst_var = 0#'INCLUDEDIR'
|
||||
#self.inst_dir = 'ns3'
|
||||
|
||||
def apply(self):
|
||||
## get all of the ns3 headers
|
||||
ns3_dir_node = Params.g_build.m_srcnode.find_dir("ns3")
|
||||
all_headers_inputs = []
|
||||
|
||||
for filename in self.to_list(self.source):
|
||||
src_node = ns3_dir_node.find_build(filename)
|
||||
if src_node is None:
|
||||
Params.fatal("source ns3 header file %s not found" % (filename,))
|
||||
all_headers_inputs.append(src_node)
|
||||
|
||||
## if self.source was empty, include all ns3 headers in enabled modules
|
||||
if not all_headers_inputs:
|
||||
for ns3headers in Object.g_allobjs:
|
||||
if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare
|
||||
## skip headers not part of enabled modules
|
||||
if self.env['NS3_ENABLED_MODULES']:
|
||||
if ("ns3-%s" % ns3headers.module) not in self.env['NS3_ENABLED_MODULES']:
|
||||
continue
|
||||
|
||||
for source in ns3headers.to_list(ns3headers.source):
|
||||
#source = os.path.basename(source)
|
||||
node = ns3_dir_node.find_build(source)
|
||||
if node is None:
|
||||
fatal("missing header file %s" % (source,))
|
||||
all_headers_inputs.append(node)
|
||||
assert all_headers_inputs
|
||||
all_headers_outputs = [self.path.find_build("everything.h")]
|
||||
task = self.create_task('gen-ns3-metaheader', self.env, 4)
|
||||
task.set_inputs(all_headers_inputs)
|
||||
task.set_outputs(all_headers_outputs)
|
||||
|
||||
def install(self):
|
||||
pass
|
||||
|
||||
|
||||
def get_modules_and_headers():
|
||||
"""
|
||||
Gets a dict of
|
||||
module_name => ([module_dep1, module_dep2, ...], [module_header1, module_header2, ...])
|
||||
tuples, one for each module.
|
||||
"""
|
||||
|
||||
retval = {}
|
||||
for module in Object.g_allobjs:
|
||||
if not module.name.startswith('ns3-'):
|
||||
continue
|
||||
module_name = module.name[4:] # strip the ns3- prefix
|
||||
## find the headers object for this module
|
||||
headers = []
|
||||
for ns3headers in Object.g_allobjs:
|
||||
if type(ns3headers).__name__ != 'ns3header_taskgen': # XXX: find less hackish way to compare
|
||||
continue
|
||||
if ns3headers.module != module_name:
|
||||
continue
|
||||
for source in ns3headers.to_list(ns3headers.source):
|
||||
headers.append(source)
|
||||
retval[module_name] = (list(module.module_deps), headers)
|
||||
return retval
|
||||
|
||||
|
||||
|
||||
class PythonScanTask(Task.TaskBase):
|
||||
"""Uses gccxml to scan the file 'everything.h' and extract API definitions.
|
||||
"""
|
||||
def __init__(self, curdirnode, env):
|
||||
self.m_display = 'python-scan'
|
||||
self.prio = 5 # everything.h has prio 4
|
||||
super(PythonScanTask, self).__init__()
|
||||
self.curdirnode = curdirnode
|
||||
self.env = env
|
||||
|
||||
def run(self):
|
||||
#print "Rescanning the python bindings..."
|
||||
argv = [
|
||||
self.env['PYTHON'],
|
||||
os.path.join(self.curdirnode.abspath(), 'ns3modulescan.py'), # scanning script
|
||||
self.curdirnode.find_dir('../..').abspath(self.env), # include path (where the ns3 include dir is)
|
||||
self.curdirnode.find_build('everything.h').abspath(self.env),
|
||||
os.path.join(self.curdirnode.abspath(), 'ns3modulegen_generated.py'), # output file
|
||||
]
|
||||
scan = subprocess.Popen(argv, stdin=subprocess.PIPE)
|
||||
scan.stdin.write(repr(get_modules_and_headers()))
|
||||
scan.stdin.close()
|
||||
if scan.wait():
|
||||
raise SystemExit(1)
|
||||
|
||||
|
||||
def build(bld):
|
||||
if Params.g_options.python_disable:
|
||||
return
|
||||
|
||||
env = bld.env_of_name('default')
|
||||
curdir = bld.m_curdirnode.abspath()
|
||||
|
||||
#Object.register('all-ns3-headers', AllNs3Headers)
|
||||
Action.Action('gen-ns3-metaheader', func=gen_ns3_metaheader, color='BLUE')
|
||||
|
||||
if env['ENABLE_PYTHON_BINDINGS']:
|
||||
obj = bld.create_obj('all_ns3_headers')
|
||||
|
||||
if Params.g_options.python_scan:
|
||||
if not env['ENABLE_PYTHON_SCANNING']:
|
||||
Params.fatal("Cannot re-scan python bindings: (py)gccxml not available")
|
||||
PythonScanTask(bld.m_curdirnode, env)
|
||||
|
||||
## Get a list of scanned modules; the set of scanned modules
|
||||
## may be smaller than the set of all modules, in case a new
|
||||
## ns3 module is being developed which wasn't scanned yet.
|
||||
scanned_modules = []
|
||||
for filename in os.listdir(curdir):
|
||||
m = re.match(r"^ns3_module_(.+)\.py$", filename)
|
||||
if m is None:
|
||||
continue
|
||||
name = m.group(1)
|
||||
if name.endswith("__local"):
|
||||
continue
|
||||
scanned_modules.append(name)
|
||||
|
||||
if env['ENABLE_PYTHON_BINDINGS']:
|
||||
bindgen = bld.create_obj('command-output')
|
||||
bindgen.name = 'pybindgen'
|
||||
bindgen.command = env['PYTHON']
|
||||
bindgen.command_is_external = True
|
||||
bindgen.stderr = 'ns3modulegen.log'
|
||||
bindgen.argv = [
|
||||
bindgen.input_file("ns3modulegen.py"),
|
||||
bindgen.output_file("ns3module.cc"),
|
||||
]
|
||||
bindgen.argv.extend(get_modules_and_headers().iterkeys())
|
||||
bindgen.hidden_inputs = ['ns3modulegen_generated.py',
|
||||
'ns3modulegen_core_customizations.py']
|
||||
|
||||
for module in scanned_modules:
|
||||
bindgen.hidden_inputs.append("ns3_module_%s.py" % module)
|
||||
local = "ns3_module_%s__local.py" % module
|
||||
if os.path.exists(os.path.join(curdir, local)):
|
||||
bindgen.hidden_inputs.append(local)
|
||||
|
||||
bindgen.hidden_outputs = ['ns3module.h']
|
||||
for module in scanned_modules:
|
||||
bindgen.hidden_outputs.append("ns3_module_%s.cc" % module)
|
||||
|
||||
bindgen.prio = 50
|
||||
|
||||
bindgen.os_env = dict(os.environ)
|
||||
features = []
|
||||
for (name, caption, was_enabled, reason_not_enabled) in env['NS3_OPTIONAL_FEATURES']:
|
||||
if was_enabled:
|
||||
features.append(name)
|
||||
bindgen.os_env['NS3_ENABLED_FEATURES'] = ','.join(features)
|
||||
|
||||
|
||||
## we build python bindings if either we have the tools to
|
||||
## generate them or if the pregenerated source file is already
|
||||
## present in the source dir.
|
||||
if env['ENABLE_PYTHON_BINDINGS'] \
|
||||
or os.path.exists(os.path.join(bld.m_curdirnode.abspath(), 'ns3module.cc')):
|
||||
pymod = bld.create_obj('cpp', 'shlib', 'pyext')
|
||||
pymod.source = ['ns3module.cc', 'ns3module_helpers.cc']
|
||||
pymod.includes = '.'
|
||||
for module in scanned_modules:
|
||||
pymod.source.append("ns3_module_%s.cc" % module)
|
||||
pymod.target = 'ns3/_ns3'
|
||||
pymod.name = 'ns3module'
|
||||
pymod.uselib_local = "ns3"
|
||||
pymod.env.append_value('CXXDEFINES', ['NS_DEPRECATED=""', 'NS3_DEPRECATED_H'])
|
||||
|
||||
# copy the __init__.py file to the build dir waf can't handle
|
||||
# this, it's against waf's principles to have build dir files
|
||||
# with the same name as source dir files, apparently.
|
||||
dirnode = bld.m_curdirnode.find_dir('ns3')
|
||||
src = os.path.join(dirnode.abspath(), '__init__.py')
|
||||
dst = os.path.join(dirnode.abspath(env), '__init__.py')
|
||||
try:
|
||||
need_copy = os.stat(src).st_mtime > os.stat(dst).st_mtime
|
||||
except OSError:
|
||||
need_copy = True
|
||||
if need_copy:
|
||||
try:
|
||||
os.mkdir(os.path.dirname(dst))
|
||||
except OSError:
|
||||
pass
|
||||
print "%r -> %r" % (src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
@@ -1,561 +0,0 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
# Copyright (c) 2006 INRIA
|
||||
# All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 as
|
||||
# published by the Free Software Foundation;
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
|
||||
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
from SCons.Environment import Environment
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
import SCons
|
||||
|
||||
# hack stolen from wengo
|
||||
# to get an ARGUMENTS defined correctly
|
||||
try:
|
||||
ARGUMENTS = SCons.Script.ARGUMENTS
|
||||
COMMAND_LINE_TARGETS = SCons.Script.COMMAND_LINE_TARGETS
|
||||
except AttributeError:
|
||||
from SCons.Script.SConscript import Arguments
|
||||
from SCons.Script.SConscript import CommandLineTargets
|
||||
ARGUMENTS = Arguments
|
||||
COMMAND_LINE_TARGETS = CommandLineTargets
|
||||
|
||||
class Ns3Module:
|
||||
def __init__(self, name, dir):
|
||||
self.sources = []
|
||||
self.inst_headers = []
|
||||
self.headers = []
|
||||
self.extra_dist = []
|
||||
self.deps = []
|
||||
self.external_deps = []
|
||||
self.config = []
|
||||
self.name = name
|
||||
self.dir = dir
|
||||
self.executable = False
|
||||
self.library = True
|
||||
self.ldflags = []
|
||||
self.header_inst_dir = ''
|
||||
def set_library(self):
|
||||
self.library = True
|
||||
self.executable = False
|
||||
def set_executable(self):
|
||||
self.library = False
|
||||
self.executable = True
|
||||
def add_config(self, config_fn):
|
||||
self.config.append(config_fn)
|
||||
def add_extra_dist(self, dist):
|
||||
self.extra_dist.append(dist)
|
||||
def add_external_dep(self, dep):
|
||||
self.external_deps.append(dep)
|
||||
def add_dep(self, dep):
|
||||
self.deps.append(dep)
|
||||
def add_deps(self, deps):
|
||||
self.deps.extend(deps)
|
||||
def add_source(self, source):
|
||||
self.sources.append(source)
|
||||
def add_sources(self, sources):
|
||||
self.sources.extend(sources)
|
||||
def add_header(self, header):
|
||||
self.headers.append(header)
|
||||
def add_headers(self, headers):
|
||||
self.headers.extend(headers)
|
||||
def add_inst_header(self, header):
|
||||
self.inst_headers.append(header)
|
||||
def add_inst_headers(self, headers):
|
||||
self.inst_headers.extend(headers)
|
||||
def add_ldflags (self, ldflags):
|
||||
self.ldflags.extend (ldflags)
|
||||
def add_ldflag (self, ldflag):
|
||||
self.add_ldflags ([ldflag])
|
||||
def set_header_inst_dir (self, inst_dir):
|
||||
self.header_inst_dir = inst_dir
|
||||
|
||||
|
||||
def MyCopyAction(target, source, env):
|
||||
try:
|
||||
if len(target) == len(source):
|
||||
for i in range(len(target)):
|
||||
shutil.copy(source[i].path, target[i].path)
|
||||
return 0
|
||||
else:
|
||||
return 'invalid target/source match'
|
||||
except:
|
||||
print
|
||||
return 'exception'
|
||||
def MyCopyActionPrint(target, source, env):
|
||||
if len(target) == len(source):
|
||||
output = ''
|
||||
for i in range(len(target)):
|
||||
output = output + 'copy \'' + source[i].path + '\' to \'' + target[i].path + '\''
|
||||
if i < len(target) - 1:
|
||||
output = output + '\n'
|
||||
return output
|
||||
else:
|
||||
return 'error in copy'
|
||||
def GcxxEmitter(target, source, env):
|
||||
if os.path.exists(source[0].path):
|
||||
return [target, source]
|
||||
else:
|
||||
return [[], []]
|
||||
def MyRmTree(target, source, env):
|
||||
shutil.rmtree(env['RM_DIR'])
|
||||
return 0
|
||||
def MyRmTreePrint(target, source, env):
|
||||
return ''
|
||||
def print_cmd_line(s, target, src, env):
|
||||
print 'Building ' + (' and '.join([str(x) for x in target])) + '...'
|
||||
|
||||
class Ns3BuildVariant:
|
||||
def __init__(self):
|
||||
self.static = False
|
||||
self.gcxx_deps = False
|
||||
self.gcxx_root = ''
|
||||
self.build_root = ''
|
||||
self.env = None
|
||||
|
||||
class Ns3:
|
||||
def __init__(self):
|
||||
self.__modules = []
|
||||
self.extra_dist = []
|
||||
self.build_dir = 'build'
|
||||
self.version = '0.0.1'
|
||||
self.name = 'noname'
|
||||
self.distname = 'noname'
|
||||
self.doxygen_config = ''
|
||||
def add(self, module):
|
||||
self.__modules.append(module)
|
||||
def add_extra_dist(self, dist):
|
||||
self.extra_dist.append(dist)
|
||||
def __get_module(self, name):
|
||||
for module in self.__modules:
|
||||
if module.name == name:
|
||||
return module
|
||||
return None
|
||||
def get_mod_output(self, module, variant):
|
||||
if module.executable:
|
||||
suffix = variant.env.subst(variant.env['PROGSUFFIX'])
|
||||
filename = os.path.join(variant.build_root, 'bin',
|
||||
module.name + suffix)
|
||||
else:
|
||||
if variant.static:
|
||||
prefix = variant.env['LIBPREFIX']
|
||||
suffix = variant.env['LIBSUFFIX']
|
||||
else:
|
||||
prefix = variant.env['SHLIBPREFIX']
|
||||
suffix = variant.env['SHLIBSUFFIX']
|
||||
prefix = variant.env.subst(prefix)
|
||||
suffix = variant.env.subst(suffix)
|
||||
filename = os.path.join(variant.build_root, 'lib',
|
||||
prefix + module.name + suffix)
|
||||
return filename
|
||||
def get_obj_builders(self, variant, module):
|
||||
env = variant.env.Copy ()
|
||||
objects = []
|
||||
hash = {}
|
||||
self.get_internal_deps (module, hash)
|
||||
for dep in hash.values ():
|
||||
if dep.header_inst_dir != '':
|
||||
inc_dir = os.path.join(variant.build_root, 'include',
|
||||
self.name, dep.header_inst_dir)
|
||||
env.Append (CPPPATH = [inc_dir])
|
||||
|
||||
if len(module.config) > 0:
|
||||
src_config_file = os.path.join(self.build_dir, 'config', module.name + '-config.h')
|
||||
tgt_config_file = os.path.join(variant.build_root, 'include',
|
||||
self.name, module.name + '-config.h')
|
||||
|
||||
for source in module.sources:
|
||||
obj_file = os.path.splitext(source)[0] + '.o'
|
||||
tgt = os.path.join(variant.build_root, module.dir, obj_file)
|
||||
src = os.path.join(module.dir, source)
|
||||
if variant.static:
|
||||
obj_builder = env.StaticObject(target = tgt, source = src)
|
||||
else:
|
||||
obj_builder = env.SharedObject(target = tgt, source = src)
|
||||
if len(module.config) > 0:
|
||||
config_file = env.MyCopyBuilder(target = [tgt_config_file],
|
||||
source = [src_config_file])
|
||||
env.Depends(obj_builder, config_file)
|
||||
if variant.gcxx_deps:
|
||||
gcno_tgt = os.path.join(variant.build_root, module.dir,
|
||||
os.path.splitext(source)[0] + '.gcno')
|
||||
gcda_tgt = os.path.join(variant.build_root, module.dir,
|
||||
os.path.splitext(source)[0] + '.gcda')
|
||||
gcda_src = os.path.join(variant.gcxx_root, module.dir,
|
||||
os.path.splitext(source)[0] + '.gcda')
|
||||
gcno_src = os.path.join(variant.gcxx_root, module.dir,
|
||||
os.path.splitext(source)[0] + '.gcno')
|
||||
gcno_builder = env.CopyGcxxBuilder(target = gcno_tgt, source = gcno_src)
|
||||
gcda_builder = env.CopyGcxxBuilder(target = gcda_tgt, source = gcda_src)
|
||||
env.Depends(obj_builder, gcda_builder)
|
||||
env.Depends(obj_builder, gcno_builder)
|
||||
objects.append(obj_builder)
|
||||
return objects
|
||||
def get_internal_deps(self, module, hash):
|
||||
for dep_name in module.deps:
|
||||
dep = self.__get_module(dep_name)
|
||||
hash[dep_name] = dep
|
||||
self.get_internal_deps(dep, hash)
|
||||
def get_external_deps(self, module):
|
||||
hash = {}
|
||||
self.get_internal_deps(module, hash)
|
||||
ext_hash = {}
|
||||
for mod in hash.values():
|
||||
for ext_dep in mod.external_deps:
|
||||
ext_hash[ext_dep] = 1
|
||||
return ext_hash.keys()
|
||||
def get_sorted_deps(self, module):
|
||||
h = {}
|
||||
self.get_internal_deps(module, h)
|
||||
modules = []
|
||||
for dep in h.keys():
|
||||
deps_copy = []
|
||||
mod = h[dep]
|
||||
deps_copy.extend(mod.deps)
|
||||
modules.append([mod, deps_copy])
|
||||
sorted = []
|
||||
while len(modules) > 0:
|
||||
to_remove = []
|
||||
for item in modules:
|
||||
if len(item[1]) == 0:
|
||||
to_remove.append(item[0].name)
|
||||
for item in to_remove:
|
||||
for i in modules:
|
||||
if item in i[1]:
|
||||
i[1].remove(item)
|
||||
new_modules = []
|
||||
for mod in modules:
|
||||
found = False
|
||||
for i in to_remove:
|
||||
if i == mod[0].name:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
new_modules.append(mod)
|
||||
modules = new_modules
|
||||
sorted.extend(to_remove)
|
||||
sorted.reverse()
|
||||
# append external deps
|
||||
ext_deps = self.get_external_deps(module)
|
||||
for dep in ext_deps:
|
||||
sorted.append(dep)
|
||||
return sorted
|
||||
|
||||
def gen_mod_dep(self, variant):
|
||||
build_root = variant.build_root
|
||||
cpp_path = os.path.join(variant.build_root, 'include')
|
||||
env = variant.env
|
||||
env.Append(CPPPATH = [cpp_path])
|
||||
header_dir = os.path.join(build_root, 'include', self.name)
|
||||
lib_path = os.path.join(build_root, 'lib')
|
||||
env.Append (LIBPATH = [lib_path])
|
||||
module_builders = []
|
||||
for module in self.__modules:
|
||||
my_env = env.Copy ();
|
||||
objects = self.get_obj_builders(variant, module)
|
||||
libs = self.get_sorted_deps(module)
|
||||
my_env.Append (LIBS = libs)
|
||||
my_env.Append (LINKFLAGS = module.ldflags)
|
||||
|
||||
filename = self.get_mod_output(module, variant)
|
||||
if module.executable:
|
||||
module_builder = my_env.Program(target=filename, source=objects)
|
||||
else:
|
||||
if variant.static:
|
||||
module_builder = my_env.StaticLibrary(target=filename, source=objects)
|
||||
else:
|
||||
module_builder = my_env.SharedLibrary(target=filename, source=objects)
|
||||
|
||||
for dep_name in module.deps:
|
||||
dep = self.__get_module(dep_name)
|
||||
my_env.Depends(module_builder, self.get_mod_output(dep, variant))
|
||||
|
||||
for header in module.inst_headers:
|
||||
if module.header_inst_dir != '':
|
||||
tgt = os.path.join(header_dir, module.header_inst_dir, header)
|
||||
else:
|
||||
tgt = os.path.join(header_dir, header)
|
||||
src = os.path.join(module.dir, header)
|
||||
#builder = env.Install(target = tgt, source = src)
|
||||
header_builder = my_env.MyCopyBuilder(target=tgt, source=src)
|
||||
my_env.Depends(module_builder, header_builder)
|
||||
|
||||
module_builders.append(module_builder)
|
||||
return module_builders
|
||||
def gen_mod_config(self, env):
|
||||
config_dir = os.path.join(self.build_dir, 'config')
|
||||
for module in self.__modules:
|
||||
if len(module.config) > 0:
|
||||
config_file = os.path.join(config_dir, module.name + '-config.h')
|
||||
config_file_guard = module.name + '_CONFIG_H'
|
||||
config_file_guard.upper()
|
||||
if not os.path.isfile(config_file):
|
||||
if not os.path.isdir(config_dir):
|
||||
os.makedirs(config_dir)
|
||||
outfile = open(config_file, 'w')
|
||||
outfile.write('#ifndef ' + config_file_guard + '\n')
|
||||
outfile.write('#define ' + config_file_guard + '\n')
|
||||
config = env.Configure()
|
||||
for fn in module.config:
|
||||
output = fn(env, config)
|
||||
for o in output:
|
||||
outfile.write(o)
|
||||
outfile.write('\n')
|
||||
outfile.write('#endif /*' + config_file_guard + '*/\n')
|
||||
config.Finish()
|
||||
def generate_dependencies(self):
|
||||
inheritenv = (ARGUMENTS.get('inheritenv', 'n') in 'yY1')
|
||||
if inheritenv:
|
||||
env = Environment(ENV=os.environ)
|
||||
else:
|
||||
env = Environment()
|
||||
self.gen_mod_config(env)
|
||||
cc = env['CC']
|
||||
cxx = env.subst(env['CXX'])
|
||||
if cc == '':
|
||||
print "Missing C compiler."
|
||||
env.Exit (1);
|
||||
if cxx == '':
|
||||
print "Missing C++ compiler."
|
||||
env.Exit (1);
|
||||
common_flags = ARGUMENTS.get('cflags', '').split(' ')
|
||||
cxxflags = ARGUMENTS.get('cxxflags', '').split(' ')
|
||||
ldflags = ARGUMENTS.get('ldflags', '').split(' ')
|
||||
if cc == 'cl' and cxx == 'cl':
|
||||
env = Environment(tools=['mingw'])
|
||||
cc = env['CC']
|
||||
cxx = env.subst(env['CXX'])
|
||||
if cc == 'gcc' and cxx == 'g++':
|
||||
common_flags.extend(['-g3', '-Wall', '-Werror'])
|
||||
debug_flags = []
|
||||
opti_flags = ['-O3']
|
||||
elif cc == 'cl' and cxx == 'cl':
|
||||
env = Environment(ENV=os.environ)
|
||||
debug_flags = ['-W1', '-GX', '-EHsc', '-D_DEBUG', '/MDd']
|
||||
opti_flags = ['-O2', '-EHsc', '-DNDEBUG', '/MD']
|
||||
cc = ARGUMENTS.get ('cc', '')
|
||||
cxx = ARGUMENTS.get ('cxx', '')
|
||||
if cc != '':
|
||||
env.Replace (CC = cc)
|
||||
if cxx != '':
|
||||
env.Replace (CXX = cxx)
|
||||
env.Append(CCFLAGS = common_flags,
|
||||
CPPDEFINES = ['RUN_SELF_TESTS'],
|
||||
TARFLAGS = '-c -z',
|
||||
CPPFLAGS = cxxflags,
|
||||
LINKFLAGS = ldflags)
|
||||
if env['PLATFORM'] == 'posix':
|
||||
env.Append(LINKFLAGS = ' -z origin')
|
||||
env.Append(RPATH=env.Literal(os.path.join('\\$$ORIGIN', os.pardir, 'lib')))
|
||||
verbose = ARGUMENTS.get('verbose', 'n')
|
||||
if verbose == 'n':
|
||||
env['PRINT_CMD_LINE_FUNC'] = print_cmd_line
|
||||
header_builder = Builder(action = Action(MyCopyAction, strfunction=MyCopyActionPrint))
|
||||
env.Append(BUILDERS = {'MyCopyBuilder':header_builder})
|
||||
gcxx_builder = Builder(action = Action(MyCopyAction, strfunction=MyCopyActionPrint),
|
||||
emitter = GcxxEmitter)
|
||||
env.Append(BUILDERS = {'CopyGcxxBuilder':gcxx_builder})
|
||||
variant = Ns3BuildVariant()
|
||||
builders = []
|
||||
|
||||
|
||||
gcov_env = env.Copy()
|
||||
gcov_env.Append(CFLAGS = ['-fprofile-arcs', '-ftest-coverage'],
|
||||
CXXFLAGS = ['-fprofile-arcs', '-ftest-coverage'],
|
||||
LINKFLAGS = ['-fprofile-arcs'])
|
||||
# code coverage analysis
|
||||
variant.static = False
|
||||
variant.env = gcov_env
|
||||
variant.build_root = os.path.join(self.build_dir, 'gcov')
|
||||
builders = self.gen_mod_dep(variant)
|
||||
for builder in builders:
|
||||
gcov_env.Alias('gcov', builder)
|
||||
gcov_env.Alias('lcov-report')
|
||||
if 'lcov-report' in COMMAND_LINE_TARGETS:
|
||||
lcov_report_dir = os.path.join(self.build_dir, 'lcov-report')
|
||||
create_dir_command = "rm -rf " + lcov_report_dir
|
||||
create_dir_command += " && mkdir " + lcov_report_dir + ";"
|
||||
gcov_env.Execute(create_dir_command)
|
||||
info_file = os.path.join(lcov_report_dir, self.name + '.info')
|
||||
lcov_command = "utils/lcov/lcov -c -d . -o " + info_file
|
||||
lcov_command += " --source-dirs=" + os.getcwd()
|
||||
lcov_command += ":" + os.path.join(os.getcwd(),
|
||||
variant.build_root,
|
||||
'include')
|
||||
gcov_env.Execute(lcov_command)
|
||||
genhtml_command = "utils/lcov/genhtml -o " + lcov_report_dir
|
||||
genhtml_command += " " + info_file
|
||||
gcov_env.Execute(genhtml_command)
|
||||
|
||||
|
||||
|
||||
opt_env = env.Copy()
|
||||
opt_env.Append(CFLAGS=opti_flags,
|
||||
CXXFLAGS=opti_flags,
|
||||
CPPDEFINES=['NDEBUG'])
|
||||
# optimized static support
|
||||
variant.static = True
|
||||
variant.env = opt_env
|
||||
variant.build_root = os.path.join(self.build_dir, 'opt-static')
|
||||
builders = self.gen_mod_dep(variant)
|
||||
for builder in builders:
|
||||
opt_env.Alias('opt-static', builder)
|
||||
|
||||
|
||||
opt_env = env.Copy()
|
||||
opt_env.Append(CFLAGS = opti_flags,
|
||||
CXXFLAGS = opti_flags,
|
||||
CPPDEFINES = ['NDEBUG'])
|
||||
# optimized shared support
|
||||
variant.static = False
|
||||
variant.env = opt_env
|
||||
variant.build_root = os.path.join(self.build_dir, 'opt-shared')
|
||||
builders = self.gen_mod_dep(variant)
|
||||
for builder in builders:
|
||||
opt_env.Alias('opt-shared', builder)
|
||||
|
||||
|
||||
arc_env = env.Copy()
|
||||
arc_env.Append(CFLAGS=opti_flags,
|
||||
CXXFLAGS=opti_flags,
|
||||
CPPDEFINES=['NDEBUG'])
|
||||
arc_env.Append(CFLAGS=['-frandom-seed=0', '-fprofile-generate'],
|
||||
CXXFLAGS=['-frandom-seed=0', '-fprofile-generate'],
|
||||
LINKFLAGS=['-frandom-seed=0', '-fprofile-generate'])
|
||||
# arc profiling
|
||||
variant.static = False
|
||||
variant.env = arc_env
|
||||
variant.build_root = os.path.join(self.build_dir, 'opt-arc')
|
||||
builders = self.gen_mod_dep(variant)
|
||||
for builder in builders:
|
||||
arc_env.Alias('opt-arc', builder)
|
||||
|
||||
|
||||
arcrebuild_env = env.Copy()
|
||||
arcrebuild_env.Append(CFLAGS=opti_flags,
|
||||
CXXFLAGS=opti_flags,
|
||||
CPPDEFINES=['NDEBUG'])
|
||||
arcrebuild_env.Append(CFLAGS=['-frandom-seed=0', '-fprofile-use'],
|
||||
CXXFLAGS=['-frandom-seed=0', '-fprofile-use'],
|
||||
LINKFLAGS=['-frandom-seed=0', '-fprofile-use'])
|
||||
# arc rebuild
|
||||
variant.static = False
|
||||
variant.env = arcrebuild_env
|
||||
variant.gcxx_deps = True
|
||||
variant.gcxx_root = os.path.join(self.build_dir, 'opt-arc')
|
||||
variant.build_root = os.path.join(self.build_dir, 'opt-arc-rebuild')
|
||||
builders = self.gen_mod_dep(variant)
|
||||
for builder in builders:
|
||||
arcrebuild_env.Alias('opt-arc-rebuild', builder)
|
||||
variant.gcxx_deps = False
|
||||
|
||||
|
||||
|
||||
|
||||
dbg_env = env.Copy()
|
||||
dbg_env.Append(CFLAGS = debug_flags,
|
||||
CXXFLAGS = debug_flags,
|
||||
CPPDEFINES = ['NS3_DEBUG_ENABLE',
|
||||
'NS3_ASSERT_ENABLE'])
|
||||
# debug static support
|
||||
variant.static = True
|
||||
variant.env = dbg_env
|
||||
variant.build_root = os.path.join(self.build_dir, 'dbg-static')
|
||||
builders = self.gen_mod_dep(variant)
|
||||
for builder in builders:
|
||||
dbg_env.Alias('dbg-static', builder)
|
||||
|
||||
dbg_env = env.Copy()
|
||||
dbg_env.Append(CFLAGS=debug_flags,
|
||||
CXXFLAGS=debug_flags,
|
||||
CPPDEFINES = ['NS3_DEBUG_ENABLE',
|
||||
'NS3_ASSERT_ENABLE'])
|
||||
# debug shared support
|
||||
variant.static = False
|
||||
variant.env = dbg_env
|
||||
variant.build_root = os.path.join(self.build_dir, 'dbg-shared')
|
||||
builders = self.gen_mod_dep(variant)
|
||||
for builder in builders:
|
||||
dbg_env.Alias('dbg-shared', builder)
|
||||
|
||||
env.Alias('dbg', 'dbg-shared')
|
||||
env.Alias('opt', 'opt-shared')
|
||||
env.Default('dbg')
|
||||
env.Alias('all', ['dbg-shared', 'dbg-static', 'opt-shared', 'opt-static'])
|
||||
|
||||
|
||||
# dist support
|
||||
dist_env = env.Copy()
|
||||
if dist_env['PLATFORM'] == 'posix' or dist_env['PLATFORM'] == 'darwin':
|
||||
dist_list = []
|
||||
for module in self.__modules:
|
||||
for f in module.sources:
|
||||
dist_list.append(os.path.join(module.dir, f))
|
||||
for f in module.headers:
|
||||
dist_list.append(os.path.join(module.dir, f))
|
||||
for f in module.inst_headers:
|
||||
dist_list.append(os.path.join(module.dir, f))
|
||||
for f in module.extra_dist:
|
||||
dist_list.append(os.path.join(module.dir, f))
|
||||
for f in self.extra_dist:
|
||||
dist_list.append(f)
|
||||
dist_list.append (self.doxygen_config)
|
||||
dist_list.append('SConstruct')
|
||||
dist_list.append('build.py')
|
||||
|
||||
targets = []
|
||||
basename = self.distname + '-' + self.version
|
||||
for src in dist_list:
|
||||
tgt = os.path.join(basename, src)
|
||||
targets.append(dist_env.MyCopyBuilder(target=tgt, source=src))
|
||||
tar = basename + '.tar.gz'
|
||||
zip = basename + '.zip'
|
||||
tmp_tar = os.path.join(self.build_dir, tar)
|
||||
tmp_zip = os.path.join(self.build_dir, zip)
|
||||
dist_tgt = [tar, zip]
|
||||
dist_src = [tmp_tar, tmp_zip]
|
||||
dist_env.Tar(tmp_tar, targets)
|
||||
dist_env.Zip(tmp_zip, targets)
|
||||
dist_builder = dist_env.MyCopyBuilder(target=dist_tgt, source=dist_src)
|
||||
dist_env.Alias('dist', dist_builder)
|
||||
dist_env.Append(RM_DIR=basename)
|
||||
dist_env.AddPostAction(dist_builder, dist_env.Action(MyRmTree,
|
||||
strfunction=MyRmTreePrint))
|
||||
dist_builder = dist_env.MyCopyBuilder(target=dist_tgt, source=dist_src)
|
||||
dist_env.Alias('fastdist', dist_tgt)
|
||||
|
||||
# distcheck
|
||||
distcheck_list = []
|
||||
for src in dist_list:
|
||||
tgt = os.path.join(self.build_dir, basename, src)
|
||||
distcheck_list.append(tgt)
|
||||
untar = env.Command(distcheck_list, tar,
|
||||
['cd ' + self.build_dir + ' && tar -zxf ../' + tar])
|
||||
scons_dir = os.path.join(self.build_dir, basename)
|
||||
distcheck_builder = env.Command('x', distcheck_list,
|
||||
['cd ' + scons_dir + ' && scons'])
|
||||
env.AlwaysBuild(distcheck_builder)
|
||||
env.Alias('distcheck', distcheck_builder)
|
||||
if self.doxygen_config != '':
|
||||
doxy = env.Command('doc/html/*', self.doxygen_config,
|
||||
['doxygen ' + self.doxygen_config])
|
||||
env.AlwaysBuild(doxy)
|
||||
env.Alias('doc', doxy)
|
||||
@@ -1,91 +0,0 @@
|
||||
The main ns-3 build system is SCons. Read the file build.txt
|
||||
for SCons instructions.
|
||||
|
||||
Waf is an alternative build system, similar to SCons. ns-3 now is
|
||||
able to build with Waf, in parallel to SCons.
|
||||
|
||||
(http://www.freehackers.org/~tnagy/waf.html)
|
||||
|
||||
Note: the Waf build scripts are experimental at this stage.
|
||||
Gustavo Carneiro (gjcarneiro@gmail.com) is the maintainer.
|
||||
|
||||
=== Building with Waf ===
|
||||
|
||||
To build ns-3 with waf type the commands:
|
||||
1. ./waf configure [options]
|
||||
2. ./waf
|
||||
|
||||
[ Note: if ./waf does not exist, see the section "Note for developers" below ]
|
||||
|
||||
To see valid configure options, type ./waf --help. The most important
|
||||
option is -d <debug level>. Valid debug levels (which are listed in
|
||||
./waf --help) are: ultradebug, debug, release, and optimized.
|
||||
|
||||
The resulting binaries are placed in build/<debuglevel>/srcpath.
|
||||
|
||||
Other waf usages include:
|
||||
|
||||
1. ./waf check
|
||||
Runs the unit tests
|
||||
|
||||
2. ./waf --doxygen
|
||||
Run doxygen to generate documentation
|
||||
|
||||
3. ./waf --lcov-report
|
||||
Run code coverage analysis (assuming the project was configured
|
||||
with --enable-gcov)
|
||||
|
||||
=== Extending ns-3 ===
|
||||
|
||||
To add new modules:
|
||||
1. Create the module directory under src (or src/devices, or whatever);
|
||||
2. Add the source files to it;
|
||||
3. Add a 'wscript' describing it;
|
||||
4. Add the module subdirectory name to the all_modules list in src/wscript.
|
||||
|
||||
A module's wscript file is basically a regular Waf script. A ns-3
|
||||
module is created as a cpp/shlib object, like this:
|
||||
|
||||
def build(bld):
|
||||
obj = bld.create_obj('cpp', 'shlib')
|
||||
|
||||
## set module name; by convention it starts with ns3-
|
||||
obj.name = 'ns3-mymodule'
|
||||
obj.target = obj.name
|
||||
|
||||
## list dependencies to other modules
|
||||
obj.uselib_local = ['ns3-core']
|
||||
|
||||
## list source files (private or public header files excluded)
|
||||
obj.source = [
|
||||
'mymodule.cc',
|
||||
]
|
||||
|
||||
## list module public header files
|
||||
headers = bld.create_obj('ns3header')
|
||||
headers.source = [
|
||||
'mymodule-header.h',
|
||||
]
|
||||
|
||||
|
||||
=== Note for developers ===
|
||||
|
||||
The ns-3 code repository does not contain the waf script. Instead,
|
||||
developers should check it out from a subversion repository:
|
||||
|
||||
svn checkout http://waf.googlecode.com/svn/tags/ns3/ waf
|
||||
|
||||
[ note: 'tags/ns3' is a tag that represents the last svn version
|
||||
tested to work correctly with ns3, although 'trunk' will likely work
|
||||
as well ]
|
||||
|
||||
Then it can be installed system-wide with 'sudo ./waf-light install'.
|
||||
When preparing a distribution, the resulting 'waf' script, which is
|
||||
self contained (no external files needed), can be easily included in
|
||||
the tarball so that users downloading ns-3 can easily build it without
|
||||
having Waf installed (although Python >= 2.3 is still needed).
|
||||
|
||||
The command 'waf dist' can be used to create a distribution tarball.
|
||||
It includes all files in the source directory, except some particular
|
||||
extensions that are blacklisted, such as back files (ending in ~).
|
||||
|
||||
+71
-159
@@ -1,186 +1,98 @@
|
||||
If you want to build ns3, you need to install scons (see
|
||||
http://www.scons.org). scons takes care of building
|
||||
the whole source tree using your system compiler. scons
|
||||
0.91.1 and 0.91.96 have been tested and are known to
|
||||
work on linux FC5, Mac os X and MinGW.
|
||||
The Waf build system is used to build ns-3. Waf is a Python-based
|
||||
build system (http://www.freehackers.org/~tnagy/waf.html)
|
||||
|
||||
To start a build, you can just type 'scons' which
|
||||
will generate a debug shared build by default, located
|
||||
in the directory 'build-dir/dbg-shared/bin' and
|
||||
'build-dir/dbg-shared/lib'.
|
||||
=== Installing Waf ===
|
||||
|
||||
All builds are built with debugging symbols. Debugging
|
||||
builds enable asserts while optimized builds disable them.
|
||||
On platforms which support it, rpath is used which means that
|
||||
the executable binaries generated link explicitely against
|
||||
the right libraries. This saves you the pain of having to
|
||||
setup environment variables to point to the right libraries.
|
||||
The top-level ns-3 directory should contain a current waf script.
|
||||
|
||||
(Note: An alternative build system (Waf) is being
|
||||
evaluated in the development branch of ns-3-dev on our server
|
||||
only (i.e., not in the release tarballs)-- see doc/build-waf.txt)
|
||||
=== Building with Waf ===
|
||||
|
||||
1) Options
|
||||
----------
|
||||
To build ns-3 with waf type the commands from the top-level directory:
|
||||
1. ./waf configure [options]
|
||||
2. ./waf
|
||||
|
||||
- verbose: if you have installed scons 0.91.96 or higher,
|
||||
the default build output is terse. To get a more verbose
|
||||
output, you need to set the 'verbose' variable to 'y'.
|
||||
Example: scons verbose=y
|
||||
- cflags: flags for the C compiler.
|
||||
Example: scons cflags="-O3 -ffast-math"
|
||||
- cxxflags: flags for the C++ compiler.
|
||||
Example: scons cxxflags="-O3 -ffast-math"
|
||||
- ldflags: flags for the linker:
|
||||
Example: scons ldflags="-L/foo -L/bar"
|
||||
- cc: the C compiler to use:
|
||||
Example: scons cc=gcc-4.0
|
||||
- cxx: the C++ compiler to use:
|
||||
Example: scons cxx=g++-4.0
|
||||
- high-precision-as-double: set to 'y' to make sure that the
|
||||
high-precision arithmetics performed by the Time class on
|
||||
behalf of the user will use doubles. By default, the code
|
||||
uses 128 integers.
|
||||
Example: scons high-precision-as-double=y
|
||||
- inheritenv: set to 'y' if you want to make your compiler
|
||||
execute within the same environment (env vars) as your own
|
||||
shell. This is typically used to make colorgcc work.
|
||||
Example: scons inheritenv=y
|
||||
To see valid configure options, type ./waf --help. The most important
|
||||
option is -d <debug level>. Valid debug levels (which are listed in
|
||||
waf --help) are: "debug" or "optimized". It is
|
||||
also possible to change the flags used for compilation with (e.g.):
|
||||
CXXFLAGS="-O3" ./waf configure.
|
||||
|
||||
2) Targets
|
||||
----------
|
||||
[ Note: Unlike some other build tools, to change the build target,
|
||||
the option must be supplied during the configure stage rather than
|
||||
the build stage (i.e., "./waf -d optimized" will not work; instead, do
|
||||
"./waf -d optimized configure; ./waf" ]
|
||||
|
||||
- doc: build the doxygen documentation.
|
||||
Example: scons doc
|
||||
The resulting binaries are placed in build/<debuglevel>/srcpath.
|
||||
|
||||
- dbg-shared: a debug build using shared libraries.
|
||||
The files are built in 'build-dir/dbg-shared/'.
|
||||
Example: scons dbg-shared
|
||||
Other waf usages include:
|
||||
|
||||
- dbg-static: a debug build using static libraries
|
||||
The files are built in 'build-dir/dbg-static/'.
|
||||
Example: scons dbg-static
|
||||
1. ./waf check
|
||||
Runs the unit tests
|
||||
|
||||
- opt-shared: an optimized build using shared libraries.
|
||||
The files are built in 'build-dir/opt-shared/'.
|
||||
Example: scons opt-shared
|
||||
2. ./waf --doxygen
|
||||
Run doxygen to generate documentation
|
||||
|
||||
- opt-static: an optimized build using static libraries.
|
||||
The files are built in 'build-dir/opt-static/'.
|
||||
Example: scons opt-static
|
||||
3. ./waf --lcov-report
|
||||
Run code coverage analysis (assuming the project was configured
|
||||
with --enable-gcov)
|
||||
|
||||
- dbg: an alias for dbg-shared
|
||||
Example: scons dbg
|
||||
4. ./waf --run "program [args]"
|
||||
Run a ns3 program, given its target name, with the given
|
||||
arguments. This takes care of automatically modifying the the
|
||||
path for finding the ns3 dynamic libraries in the environment
|
||||
before running the program. Note: the "program [args]" string is
|
||||
parsed using POSIX shell rules.
|
||||
|
||||
- opt: an alias for opt-shared
|
||||
Example: scons opt
|
||||
4.1 ./waf --run programname --command-template "... %s ..."
|
||||
|
||||
- all: alias for dbg-shared, dbg-static, opt-shared
|
||||
and opt-static
|
||||
Example: scons all
|
||||
Same as --run, but uses a command template with %s replaced by the
|
||||
actual program (whose name is given by --run). This can be use to
|
||||
run ns-3 programs with helper tools. For example, to run unit
|
||||
tests with valgrind, use the command:
|
||||
|
||||
- gcov: code coverage analysis. Build a debugging version of
|
||||
the code for code coverage analysis in 'build-dir/gcov'. Once
|
||||
the code has been built, you can run various applications to
|
||||
exercise the code paths. To generate an html report from
|
||||
the gcov data, use the lcov-report target
|
||||
./waf --run run-tests --command-template "valgrind %s"
|
||||
|
||||
- lcov-report: generate html report of gcov data. The output
|
||||
is stored in 'build-dir/lcov-report/'.
|
||||
5. ./waf --shell
|
||||
Starts a nested system shell with modified environment to run ns3 programs.
|
||||
|
||||
- dist: generate a release tarball and zipfile from the
|
||||
source tree. The tarball and zipfile name are generated
|
||||
according to the version number stored in the SConstruct
|
||||
file.
|
||||
Example in SConstruct:
|
||||
ns3 = Ns3 ()
|
||||
ns3.name = 'foo'
|
||||
ns3.version = '0.0.10'
|
||||
Example command: scons dist
|
||||
Example output files:
|
||||
foo-0.0.10.tar.gz
|
||||
foo-0.0.10.zip
|
||||
6. ./waf distclean
|
||||
Cleans out the entire build/ directory
|
||||
|
||||
- distcheck: generate a release tarball and zipfile and
|
||||
attempt to run the 'all' target for the release tarball.
|
||||
Example: scons distcheck
|
||||
7. ./waf dist
|
||||
The command 'waf dist' can be used to create a distribution tarball.
|
||||
It includes all files in the source directory, except some particular
|
||||
extensions that are blacklisted, such as back files (ending in ~).
|
||||
|
||||
3) How the build system works
|
||||
-----------------------------
|
||||
|
||||
The current build system defines what are called "ns3 modules": each module
|
||||
is a set of source files, normal header files and installable header
|
||||
files. Each module also depends on a set of other modules. We build
|
||||
modules automatically in the correct order. That is, we always start
|
||||
from the module which does not depend on any other module (core) and
|
||||
proceed with the other modules and make sure that when a module is
|
||||
built, all the modules it depends upon have already been built.
|
||||
=== Extending ns-3 ===
|
||||
|
||||
To build a module, we:
|
||||
1) generate the .o files
|
||||
2) link the .o files together
|
||||
3) install the installable headers in the common directory
|
||||
top_build_dir/include/ns3.
|
||||
To add new modules:
|
||||
1. Create the module directory under src (or src/devices, or whatever);
|
||||
2. Add the source files to it;
|
||||
3. Add a 'wscript' describing it;
|
||||
4. Add the module subdirectory name to the all_modules list in src/wscript.
|
||||
|
||||
This means that if you want to use a header from your own module, you
|
||||
should just include it: #include "foo.h" but if you want to include a
|
||||
header from another module, you need to include it with #include
|
||||
"ns3/bar.h". This allows you to make sure that our "public" ns3 headers
|
||||
do not conflict with existing system-level headers. For instance,
|
||||
if you were to define a header called queue.h, you would include
|
||||
ns3/queue.h rather than queue.h, when including from a separate module,
|
||||
since many systems provide a queue.h system include file.
|
||||
A module's wscript file is basically a regular Waf script. A ns-3
|
||||
module is created as a cpp/shlib object, like this:
|
||||
|
||||
4) How to add files to a module ?
|
||||
---------------------------------
|
||||
def build(bld):
|
||||
obj = bld.create_obj('cpp', 'shlib')
|
||||
|
||||
In the main SConstruct file, you can add source code
|
||||
to the add_sources method. For example, to add a foo.cc
|
||||
file to the core module, we coud do this:
|
||||
core.add_sources ('foo.cc')
|
||||
Of course, if this file implements public API, its
|
||||
header should be installable:
|
||||
core.add_inst_headers ('foo.h')
|
||||
## set module name; by convention it starts with ns3-
|
||||
obj.name = 'ns3-mymodule'
|
||||
obj.target = obj.name
|
||||
|
||||
5) How to create a new module ?
|
||||
-------------------------------
|
||||
## list dependencies to other modules
|
||||
obj.uselib_local = ['ns3-core']
|
||||
|
||||
# create a new module. First arg is the name of
|
||||
# the new module. Second arg is the directory in
|
||||
# which all source files for this module reside.
|
||||
my_module = build.Ns3Module ('my', 'src/my_dir')
|
||||
# add it to build system
|
||||
ns3.add (my_module)
|
||||
# specify module dependencies. Here, depends
|
||||
# on the 'ipv4' and 'core' modules
|
||||
my_module.add_deps (['core', 'ipv4'])
|
||||
# add source code to build located in
|
||||
# src/my_dir
|
||||
my_module.add_sources ([
|
||||
'my_a.cc',
|
||||
'my_b.cc',
|
||||
'my_c.cc'
|
||||
])
|
||||
my_module.add_sources ([
|
||||
'my_d.cc'
|
||||
])
|
||||
# add headers which are not public
|
||||
my_module.add_headers ([
|
||||
'my_a.h',
|
||||
'my_c.h'
|
||||
])
|
||||
# add headers which are public
|
||||
my_module.add_inst_headers ([
|
||||
'my_b.h'
|
||||
])
|
||||
my_module.add_inst_headers ([
|
||||
'my_d.h'
|
||||
])
|
||||
# if you need to link against an external library,
|
||||
# you must add 'external' dependencies. Here, the
|
||||
# pthread library
|
||||
my_module.add_external_dep ('pthread')
|
||||
# by default, a module is conceptually a library. If you
|
||||
# want to generate an executable from a module you need to:
|
||||
my_module.set_executable ()
|
||||
## list source files (private or public header files excluded)
|
||||
obj.source = [
|
||||
'mymodule.cc',
|
||||
]
|
||||
|
||||
## list module public header files
|
||||
headers = bld.create_obj('ns3header')
|
||||
headers.source = [
|
||||
'mymodule-header.h',
|
||||
]
|
||||
|
||||
+158
-65
@@ -1,4 +1,4 @@
|
||||
# Doxyfile 1.4.4
|
||||
# Doxyfile 1.5.4
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# doxygen (www.doxygen.org) for a project
|
||||
@@ -14,10 +14,18 @@
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# This tag specifies the encoding used for all characters in the config file that
|
||||
# follow. The default is UTF-8 which is also the encoding used for all text before
|
||||
# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
|
||||
# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
|
||||
# possible encodings.
|
||||
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
|
||||
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
|
||||
# by quotes) that should identify the project.
|
||||
|
||||
PROJECT_NAME = "NS-3"
|
||||
PROJECT_NAME = "NS-3 "
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
|
||||
# This could be handy for archiving the generated documentation or
|
||||
@@ -45,24 +53,14 @@ CREATE_SUBDIRS = NO
|
||||
# documentation generated by doxygen is written. Doxygen will use this
|
||||
# information to generate all constant output in the proper language.
|
||||
# The default language is English, other supported languages are:
|
||||
# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
|
||||
# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
|
||||
# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
|
||||
# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
|
||||
# Swedish, and Ukrainian.
|
||||
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
|
||||
# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
|
||||
# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
|
||||
# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
|
||||
# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
|
||||
|
||||
OUTPUT_LANGUAGE = English
|
||||
|
||||
# This tag can be used to specify the encoding used in the generated output.
|
||||
# The encoding is not always determined by the language that is chosen,
|
||||
# but also whether or not the output is meant for Windows or non-Windows users.
|
||||
# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
|
||||
# forces the Windows encoding (this is the default for the Windows binary),
|
||||
# whereas setting the tag to NO uses a Unix-style encoding (the default for
|
||||
# all platforms other than Windows).
|
||||
|
||||
USE_WINDOWS_ENCODING = NO
|
||||
|
||||
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
|
||||
# include brief member descriptions after the members that are listed in
|
||||
# the file and class documentation (similar to JavaDoc).
|
||||
@@ -135,11 +133,19 @@ SHORT_NAMES = NO
|
||||
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
|
||||
# will interpret the first line (until the first dot) of a JavaDoc-style
|
||||
# comment as the brief description. If set to NO, the JavaDoc
|
||||
# comments will behave just like the Qt-style comments (thus requiring an
|
||||
# explicit @brief command for a brief description.
|
||||
# comments will behave just like regular Qt-style comments
|
||||
# (thus requiring an explicit @brief command for a brief description.)
|
||||
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
|
||||
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
|
||||
# interpret the first line (until the first dot) of a Qt-style
|
||||
# comment as the brief description. If set to NO, the comments
|
||||
# will behave just like regular Qt-style comments (thus requiring
|
||||
# an explicit \brief command for a brief description.)
|
||||
|
||||
QT_AUTOBRIEF = NO
|
||||
|
||||
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
|
||||
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
|
||||
# comments) as a brief description. This used to be the default behaviour.
|
||||
@@ -161,13 +167,6 @@ DETAILS_AT_TOP = NO
|
||||
|
||||
INHERIT_DOCS = YES
|
||||
|
||||
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
||||
# tag is set to YES, then doxygen will reuse the documentation of the first
|
||||
# member in the group (if any) for the other members of the group. By default
|
||||
# all members of a group must be documented explicitly.
|
||||
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
|
||||
# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
|
||||
# a new page for each member. If set to NO, the documentation of a member will
|
||||
# be part of the file/class/namespace that contains it.
|
||||
@@ -195,13 +194,40 @@ ALIASES =
|
||||
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
|
||||
# only. Doxygen will then generate output that is more tailored for Java.
|
||||
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
|
||||
# sources only. Doxygen will then generate output that is more tailored for Java.
|
||||
# For instance, namespaces will be presented as packages, qualified scopes
|
||||
# will look different, etc.
|
||||
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
|
||||
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
|
||||
# include (a tag file for) the STL sources as input, then you should
|
||||
# set this tag to YES in order to let doxygen match functions declarations and
|
||||
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
|
||||
# func(std::string) {}). This also make the inheritance and collaboration
|
||||
# diagrams that involve STL classes more complete and accurate.
|
||||
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
|
||||
# If you use Microsoft's C++/CLI language, you should set this option to YES to
|
||||
# enable parsing support.
|
||||
|
||||
CPP_CLI_SUPPORT = NO
|
||||
|
||||
# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
|
||||
# Doxygen will parse them like normal C++ but will assume all classes use public
|
||||
# instead of private inheritance when no explicit protection keyword is present.
|
||||
|
||||
SIP_SUPPORT = NO
|
||||
|
||||
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
||||
# tag is set to YES, then doxygen will reuse the documentation of the first
|
||||
# member in the group (if any) for the other members of the group. By default
|
||||
# all members of a group must be documented explicitly.
|
||||
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
|
||||
# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
|
||||
# the same type (for instance a group of public functions) to be put as a
|
||||
# subgroup of that type (e.g. under the Public Functions section). Set it to
|
||||
@@ -210,6 +236,16 @@ OPTIMIZE_OUTPUT_JAVA = NO
|
||||
|
||||
SUBGROUPING = YES
|
||||
|
||||
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct (or union) is
|
||||
# documented as struct with the name of the typedef. So
|
||||
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
|
||||
# with name TypeT. When disabled the typedef will appear as a member of a file,
|
||||
# namespace, or class. And the struct will be named TypeS. This can typically
|
||||
# be useful for C code where the coding convention is that all structs are
|
||||
# typedef'ed and only the typedef is referenced never the struct's name.
|
||||
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -244,6 +280,13 @@ EXTRACT_LOCAL_CLASSES = NO
|
||||
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
|
||||
# If this flag is set to YES, the members of anonymous namespaces will be extracted
|
||||
# and appear in the documentation as a namespace called 'anonymous_namespace{file}',
|
||||
# where file will be replaced with the base name of the file that contains the anonymous
|
||||
# namespace. By default anonymous namespace are hidden.
|
||||
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
|
||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
||||
# undocumented members of documented classes, files or namespaces.
|
||||
# If set to NO (the default) these members will be included in the
|
||||
@@ -376,7 +419,7 @@ SHOW_USED_FILES = YES
|
||||
|
||||
# If the sources in your project are distributed over multiple directories
|
||||
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
|
||||
# in the documentation. The default is YES.
|
||||
# in the documentation. The default is NO.
|
||||
|
||||
SHOW_DIRECTORIES = NO
|
||||
|
||||
@@ -385,7 +428,7 @@ SHOW_DIRECTORIES = NO
|
||||
# version control system). Doxygen will invoke the program by executing (via
|
||||
# popen()) the command <command> <input-file>, where <command> is the value of
|
||||
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
|
||||
# provided by doxygen. Whatever the progam writes to standard output
|
||||
# provided by doxygen. Whatever the program writes to standard output
|
||||
# is used as the file version. See the manual for examples.
|
||||
|
||||
FILE_VERSION_FILTER =
|
||||
@@ -397,7 +440,7 @@ FILE_VERSION_FILTER =
|
||||
# The QUIET tag can be used to turn on/off the messages that are generated
|
||||
# by doxygen. Possible values are YES and NO. If left blank NO is used.
|
||||
|
||||
QUIET = NO
|
||||
QUIET = YES
|
||||
|
||||
# The WARNINGS tag can be used to turn on/off the warning messages that are
|
||||
# generated by doxygen. Possible values are YES and NO. If left blank
|
||||
@@ -433,7 +476,7 @@ WARN_NO_PARAMDOC = NO
|
||||
# $version, which will be replaced by the version of the file (if it could
|
||||
# be obtained via FILE_VERSION_FILTER)
|
||||
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_FORMAT = "$file:$line: $text "
|
||||
|
||||
# The WARN_LOGFILE tag can be used to specify a file to which warning
|
||||
# and error messages should be written. If left blank the output is written
|
||||
@@ -450,16 +493,28 @@ WARN_LOGFILE =
|
||||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = src doc/main.txt
|
||||
INPUT = doc/modules \
|
||||
doc/main.h \
|
||||
doc/introspected-doxygen.h \
|
||||
doc/howtos/ \
|
||||
src
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files that
|
||||
# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
|
||||
# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
|
||||
# See http://www.gnu.org/software/libiconv for the list of possible encodings.
|
||||
|
||||
INPUT_ENCODING = UTF-8
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
# and *.h) to filter out the source-files in the directories. If left
|
||||
# blank the following patterns are tested:
|
||||
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
|
||||
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
|
||||
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
|
||||
|
||||
FILE_PATTERNS = *.h *.tcc
|
||||
FILE_PATTERNS = *.h \
|
||||
*.tcc
|
||||
|
||||
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
|
||||
# should be searched for input files as well. Possible values are YES and NO.
|
||||
@@ -471,10 +526,12 @@ RECURSIVE = YES
|
||||
# excluded from the INPUT source files. This way you can easily exclude a
|
||||
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||
|
||||
EXCLUDE = \
|
||||
src/simulator/high-precision.h \
|
||||
src/simulator/high-precision-128.h \
|
||||
src/simulator/high-precision-double.h
|
||||
EXCLUDE = src/routing/olsr/olsr-state.h \
|
||||
src/routing/olsr/repositories.h \
|
||||
src/routing/olsr/routing-table.h \
|
||||
src/simulator/high-precision.h \
|
||||
src/simulator/high-precision-128.h \
|
||||
src/simulator/high-precision-double.h
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
|
||||
# directories that are symbolic links (a Unix filesystem feature) are excluded
|
||||
@@ -490,6 +547,13 @@ EXCLUDE_SYMLINKS = NO
|
||||
|
||||
EXCLUDE_PATTERNS =
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the output.
|
||||
# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
|
||||
# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
|
||||
|
||||
EXCLUDE_SYMBOLS =
|
||||
|
||||
# The EXAMPLE_PATH tag can be used to specify one or more files or
|
||||
# directories that contain example code fragments that are included (see
|
||||
# the \include command).
|
||||
@@ -514,7 +578,7 @@ EXAMPLE_RECURSIVE = NO
|
||||
# directories that contain image that are included in the documentation (see
|
||||
# the \image command).
|
||||
|
||||
IMAGE_PATH =
|
||||
IMAGE_PATH = doc
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
@@ -548,7 +612,9 @@ FILTER_SOURCE_FILES = NO
|
||||
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
|
||||
# be generated. Documented entities will be cross-referenced with these sources.
|
||||
# Note: To get rid of all source code in the generated output, make sure also
|
||||
# VERBATIM_HEADERS is set to NO.
|
||||
# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH
|
||||
# then you must also enable this option. If you don't then doxygen will produce
|
||||
# a warning and turn it on anyway
|
||||
|
||||
SOURCE_BROWSER = NO
|
||||
|
||||
@@ -575,6 +641,13 @@ REFERENCED_BY_RELATION = YES
|
||||
|
||||
REFERENCES_RELATION = YES
|
||||
|
||||
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
|
||||
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
|
||||
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
|
||||
# link to the source code. Otherwise they will link to the documentstion.
|
||||
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
|
||||
# If the USE_HTAGS tag is set to YES then the references to source code
|
||||
# will point to the HTML generated by the htags(1) tool instead of doxygen
|
||||
# built-in source browser. The htags tool is part of GNU's global source
|
||||
@@ -667,6 +740,14 @@ HTML_ALIGN_MEMBERS = YES
|
||||
|
||||
GENERATE_HTMLHELP = NO
|
||||
|
||||
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||
# documentation will contain sections that can be hidden and shown after the
|
||||
# page has loaded. For this to work a browser that supports
|
||||
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
|
||||
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
|
||||
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
|
||||
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
|
||||
# be used to specify the file name of the resulting .chm file. You
|
||||
# can add a path in front of the file if the result should not be
|
||||
@@ -965,13 +1046,13 @@ ENABLE_PREPROCESSING = YES
|
||||
# compilation will be performed. Macro expansion can be done in a controlled
|
||||
# way by setting EXPAND_ONLY_PREDEF to YES.
|
||||
|
||||
MACRO_EXPANSION = NO
|
||||
MACRO_EXPANSION = YES
|
||||
|
||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
||||
# then the macro expansion is limited to the macros specified with the
|
||||
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
|
||||
# PREDEFINED and EXPAND_AS_DEFINED tags.
|
||||
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
|
||||
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
|
||||
# in the INCLUDE_PATH (see below) will be search if a #include is found.
|
||||
@@ -999,14 +1080,18 @@ INCLUDE_FILE_PATTERNS =
|
||||
# undefined via #undef or recursively expanded use the := operator
|
||||
# instead of the = operator.
|
||||
|
||||
PREDEFINED = RUN_SELF_TESTS NS3_DEBUG_ENABLE
|
||||
PREDEFINED = RUN_SELF_TESTS \
|
||||
NS3_ASSERT_ENABLE \
|
||||
NS3_LOG_ENABLE
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
# The macro definition that is found in the sources will be used.
|
||||
# Use the PREDEFINED tag if you want to use a different macro definition.
|
||||
|
||||
EXPAND_AS_DEFINED =
|
||||
EXPAND_AS_DEFINED = ATTRIBUTE_VALUE_DEFINE \
|
||||
ATTRIBUTE_VALUE_DEFINE_WITH_NAME \
|
||||
ATTRIBUTE_HELPER_HEADER_2
|
||||
|
||||
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
|
||||
# doxygen's preprocessor will remove all function-like macros that are alone
|
||||
@@ -1072,6 +1157,14 @@ PERL_PATH = /usr/bin/perl
|
||||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# You can define message sequence charts within doxygen comments using the \msc
|
||||
# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
|
||||
# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
|
||||
# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
|
||||
# be found in the default search path.
|
||||
|
||||
MSCGEN_PATH =
|
||||
|
||||
# If set to YES, the inheritance and collaboration graphs will hide
|
||||
# inheritance and usage relations if the target is undocumented
|
||||
# or is not a class.
|
||||
@@ -1129,7 +1222,7 @@ INCLUDE_GRAPH = YES
|
||||
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
|
||||
# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
|
||||
# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
|
||||
# generate a call dependency graph for every global function or class method.
|
||||
# Note that enabling this option will significantly increase the time of a run.
|
||||
# So in most cases it will be better to enable call graphs for selected
|
||||
@@ -1137,6 +1230,14 @@ INCLUDED_BY_GRAPH = YES
|
||||
|
||||
CALL_GRAPH = NO
|
||||
|
||||
# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
|
||||
# generate a caller dependency graph for every global function or class method.
|
||||
# Note that enabling this option will significantly increase the time of a run.
|
||||
# So in most cases it will be better to enable caller graphs for selected
|
||||
# functions only using the \callergraph command.
|
||||
|
||||
CALLER_GRAPH = NO
|
||||
|
||||
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
|
||||
# will graphical hierarchy of all classes instead of a textual one.
|
||||
|
||||
@@ -1166,31 +1267,23 @@ DOT_PATH =
|
||||
|
||||
DOTFILE_DIRS =
|
||||
|
||||
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
|
||||
# nodes that will be shown in the graph. If the number of nodes in a graph
|
||||
# becomes larger than this value, doxygen will truncate the graph, which is
|
||||
# visualized by representing a node as a red box. Note that doxygen if the number
|
||||
# of direct children of the root node in a graph is already larger than
|
||||
# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note
|
||||
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
|
||||
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
|
||||
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
|
||||
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
|
||||
# graphs generated by dot. A depth value of 3 means that only nodes reachable
|
||||
# from the root by following a path via at most 3 edges will be shown. Nodes
|
||||
# that lay further from the root node will be omitted. Note that setting this
|
||||
# option to 1 or 2 may greatly reduce the computation time needed for large
|
||||
# code bases. Also note that a graph may be further truncated if the graph's
|
||||
# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
|
||||
# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
|
||||
# the graph is not depth-constrained.
|
||||
# code bases. Also note that the size of a graph can be further restricted by
|
||||
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
|
||||
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
/*!
|
||||
\page application How to create a traffic generator ?
|
||||
\anchor howtos-application
|
||||
|
||||
<b>Question:</b> How do I create a new traffic generator ?
|
||||
|
||||
<b>Answer:</b> It is possible to instanciate \ref ns3::Packet "Packet"
|
||||
objects, schedule events, and call functions from any piece of code
|
||||
in ns-3 so, technically, there is no single answer to the question of
|
||||
how we can write a new traffic generator. However, the
|
||||
\ref ns3::Socket "Socket" API was really designed to be the single
|
||||
point of entry for traffic generators or traffic analysers and the
|
||||
\ref ns3::Application "Application" class was designed to hold
|
||||
together any number of sockets.
|
||||
|
||||
Implementing a new traffic generator thus boils down to:
|
||||
- implementing a new subclass of the \ref ns3::Application "Application"
|
||||
base class
|
||||
- instanciate one or many sockets within that application
|
||||
- start scheduling events when \ref ns3::Application::StartApplication "StartApplication"
|
||||
is called
|
||||
- stop scheduling events when \ref ns3::Application::StopApplication "StopApplication"
|
||||
is called
|
||||
- create packets and send them over one or many sockets in each event
|
||||
|
||||
The following "random" generator generates packets separated by a random
|
||||
delay and with a random size.
|
||||
|
||||
\code
|
||||
class RandomGenerator : public Application
|
||||
{
|
||||
public:
|
||||
RandomGenerator ();
|
||||
void SetDelay (RandomVariable delay);
|
||||
void SetSize (RandomVariable size);
|
||||
void SetRemote (std::string socketType,
|
||||
Address remote);
|
||||
private:
|
||||
virtual void StartApplication (void);
|
||||
virtual void StopApplication (void);
|
||||
void DoGenerate (void);
|
||||
|
||||
RandomVariable m_delay;
|
||||
RandomVariable m_size;
|
||||
Ptr<Socket> m_socket;
|
||||
};
|
||||
\endcode
|
||||
|
||||
The socket is created in the SetRemote method:
|
||||
\code
|
||||
void
|
||||
RandomGenerator::SetRemote (std::string socketType,
|
||||
Address remote)
|
||||
{
|
||||
TypeId tid = TypeId::LookupByName (socketType);
|
||||
m_socket = Socket::CreateSocket (GetNode (), tid);
|
||||
m_socket->Bind ();
|
||||
m_socket->ShutdownRecv ();
|
||||
m_socket->Connect (remote);
|
||||
}
|
||||
\endcode
|
||||
While the the crux of the logic is located in the DoGenerate method
|
||||
which is called from within StartApplication:
|
||||
\code
|
||||
void
|
||||
RandomGenerator::DoGenerate (void)
|
||||
{
|
||||
m_next = Simulator::Schedule (Seconds (m_delay.GetValue ()),
|
||||
&RandomGenerator::DoGenerate, this);
|
||||
Ptr<Packet> p = Create<Packet> (m_size.GetIntValue ());
|
||||
m_socket->Send (p);
|
||||
}
|
||||
\endcode
|
||||
|
||||
To make that application more integrated in ns-3, it needs an associated
|
||||
helper class:
|
||||
\code
|
||||
class RandomAppHelper
|
||||
{
|
||||
public:
|
||||
RandomAppHelper (std::string protocol, Address remote);
|
||||
void SetPacketSize (RandomVariable packetSize);
|
||||
void SetDelay (RandomVariable delay);
|
||||
ApplicationContainer Install (NodeContainer nodes);
|
||||
private:
|
||||
std::string m_protocol;
|
||||
Address m_remote;
|
||||
RandomVariable m_packetSize;
|
||||
RandomVariable m_delay;
|
||||
};
|
||||
\endcode
|
||||
|
||||
which could be trivially implemented as:
|
||||
\code
|
||||
ApplicationContainer
|
||||
RandomAppHelper::Install (NodeContainer nodes)
|
||||
{
|
||||
ApplicationContainer applications;
|
||||
for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
|
||||
{
|
||||
Ptr<RandomAppHelper> app = CreateObject<RandomAppHelper> ();
|
||||
app->SetSize (m_packetSize);
|
||||
app->SetDelay (m_delay);
|
||||
app->SetRemote (m_protocol, m_remote);
|
||||
(*i)->AddApplication (app);
|
||||
applications.Add (app);
|
||||
}
|
||||
return applications;
|
||||
}
|
||||
\endcode
|
||||
|
||||
Despite being functional, this API is not very consistant with the style of
|
||||
the other helper classes, all of which allow you to control the parameters
|
||||
of the underlying class through attributes and not explicit setters. The
|
||||
following API thus replaces the pair SetPacketSize/SetDelay with a single
|
||||
method SetAttribute:
|
||||
\code
|
||||
class RandomAppHelper
|
||||
{
|
||||
public:
|
||||
RandomAppHelper (std::string protocol, Address remote);
|
||||
void SetAttribute (std::string name, const AttributeValue &value);
|
||||
ApplicationContainer Install (NodeContainer c);
|
||||
private:
|
||||
std::string m_protocol;
|
||||
Address m_remote;
|
||||
ObjectFactory m_factory;
|
||||
};
|
||||
\endcode
|
||||
|
||||
And which can be used as follows:
|
||||
\code
|
||||
RandomAppHelper app = RandomAppHelper ("ns3::TcpSocketFactory",
|
||||
InetSocketAddress (Ipv4Address ("192.168.1.10"), 10));
|
||||
app.SetAttribute ("Delay", StringValue ("Constant:2.5"));
|
||||
app.SetAttribute ("Size", StringValue ("Constant:2100"));
|
||||
app.Install (nodes);
|
||||
\endcode
|
||||
|
||||
The implementation, in this case, is not necessarily longer but its
|
||||
simplicity hides a lot of behind-the-scenes complexity:
|
||||
|
||||
\code
|
||||
void
|
||||
RandomAppHelper::SetAttribute (std::string name, const AttributeValue &value)
|
||||
{
|
||||
m_factory.Set (name, value);
|
||||
}
|
||||
ApplicationContainer
|
||||
RandomAppHelper::Install (NodeContainer nodes)
|
||||
{
|
||||
ApplicationContainer applications;
|
||||
for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
|
||||
{
|
||||
Ptr<RandomAppHelper> app = m_factory.Create<RandomAppHelper> ();
|
||||
app->SetRemote (m_socketType, m_remote);
|
||||
(*i)->AddApplication (app);
|
||||
applications.Add (app);
|
||||
}
|
||||
return applications;
|
||||
}
|
||||
\endcode
|
||||
|
||||
The key difference between this implementation and the previous one
|
||||
is that this helper does not handle explicitely the attributes
|
||||
delay and packet size. Instead, it stores them in an
|
||||
\ref ns3::ObjectFactory "ObjectFactory" object. This, of course,
|
||||
does not work magically, and requires extra support from the
|
||||
underlying RandomGenerator class. Specifically, it requires
|
||||
that the underlying RandomGenerator defines its attributes
|
||||
in its \ref ns3::TypeId "TypeId" in a new public static method:
|
||||
|
||||
\code
|
||||
class RandomGenerator
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
};
|
||||
\endcode
|
||||
|
||||
The corresponding implementation is shown below:
|
||||
|
||||
\code
|
||||
TypeId
|
||||
RandomGenerator::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("RandomGenerator")
|
||||
.SetParent<Application> ()
|
||||
.AddConstructor<RandomGenerator> ()
|
||||
.AddAttribute ("Delay", "The delay between two packets (s)",
|
||||
RandomVariableValue (ConstantVariable (1.0)),
|
||||
MakeRandomVariableAccessor (&RandomGenerator::m_delay),
|
||||
MakeRandomVariableChecker ())
|
||||
.AddAttribute ("PacketSize", "The size of each packet (bytes)",
|
||||
RandomVariableValue (ConstantVariable (2000)),
|
||||
MakeRandomVariableAccessor (&RandomGenerator::m_size),
|
||||
MakeRandomVariableChecker ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,38 @@
|
||||
/*!
|
||||
\page callbacks Using ns-3 callbacks
|
||||
\anchor howtos-callbacks
|
||||
|
||||
\section null_callbacks Null Callbacks
|
||||
|
||||
<b>Question:</b> The API I am using calls for using a callback (in the
|
||||
function signature), but I do not
|
||||
want to provide one. Is there a way to provide a null callback?
|
||||
|
||||
<b>Answer:</b> Use the ns3::MakeNullCallback construct:
|
||||
\code
|
||||
template<typename R>
|
||||
Callback< R, T1, T2, T3, T4, T5, T6 > ns3::MakeNullCallback (void)
|
||||
\endcode
|
||||
|
||||
Example usage: The ns3::Socket class uses callbacks to indicate completion
|
||||
of events such as a successful TCP connect(). These callbacks are set
|
||||
in the following function:
|
||||
\code
|
||||
void Socket::SetConnectCallback (Callback<void, Ptr<Socket> > connectionSucceeded,
|
||||
Callback<void, Ptr<Socket> > connectionFailed,
|
||||
Callback<void, Ptr<Socket> > halfClose);
|
||||
|
||||
\endcode
|
||||
But suppose you do not care about registering a callback for the
|
||||
halfClose event (but you want to register one for the
|
||||
connectionSucceeded and connectionFailed cases). In that case, you
|
||||
can pass a null callback as the third argument. You just need to
|
||||
pass a callback with the matching signature, as follows:
|
||||
\code
|
||||
localSocket->SetConnectCallback (
|
||||
MakeCallback (&ConnectionSucceededCallback),
|
||||
MakeCallback (&ConnectionFailedCallback),
|
||||
MakeNullCallback<void, Ptr<Socket> > () );
|
||||
\endcode
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,162 @@
|
||||
/*!
|
||||
\page net-device How to create a new OSI layer 1 + 2 implementation ?
|
||||
\anchor howtos-net-device
|
||||
|
||||
<b>Question:</b> How do I integrate a new OSI layer 1 + 2 implementation ?
|
||||
|
||||
<b>Answer:</b> The OSI layers 1 and 2 are represented by the ns3::NetDevice
|
||||
and ns3::Channel classes. To plug transparently in ns-3, a new layer 1+2 model
|
||||
thus simply needs to provide two new subclasses of these two base classes.
|
||||
|
||||
To make that subclassing process easy, two skeleton classes are provided in
|
||||
the src/node directory: simple-net-device.h (ns3::SimpleNetDevice) and
|
||||
simple-channel.h (ns3::SimpleChannel) implement a broadcast passthru medium
|
||||
using 48bit MAC addresses without any kind of MAC access algorithm or PHY
|
||||
layer modeling.
|
||||
|
||||
The ns3::SimpleChannel class is really very simple: it provides
|
||||
an implementation for the ns3::Channel::GetNDevices and ns3::Channel::GetDevice
|
||||
methods defined in the Channel base class and, then defines the channel-specific
|
||||
send and add methods:
|
||||
- The Add method is used by SimpleNetDevice::SetChannel to register a new
|
||||
SimpleNetDevice with its associated channel.
|
||||
- The Send method is used by SimpleNetDevice::Send to send a packet over the
|
||||
broadcast medium and ensure that it gets delivered to all associated devices
|
||||
(except the sender).
|
||||
|
||||
\code
|
||||
class SimpleChannel : public Channel
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
SimpleChannel ();
|
||||
|
||||
void Send (Ptr<Packet> p, uint16_t protocol, Mac48Address to, Mac48Address from,
|
||||
Ptr<SimpleNetDevice> sender);
|
||||
|
||||
void Add (Ptr<SimpleNetDevice> device);
|
||||
|
||||
// inherited from ns3::Channel
|
||||
virtual uint32_t GetNDevices (void) const;
|
||||
virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
|
||||
|
||||
private:
|
||||
std::vector<Ptr<SimpleNetDevice> > m_devices;
|
||||
};
|
||||
\endcode
|
||||
|
||||
The SimpleNetDevice class is also trivial since it implements no special
|
||||
MAC-layer processing:
|
||||
\code
|
||||
class SimpleNetDevice : public NetDevice
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
SimpleNetDevice ();
|
||||
|
||||
void Receive (Ptr<Packet> packet, uint16_t protocol, Mac48Address to, Mac48Address from);
|
||||
void SetChannel (Ptr<SimpleChannel> channel);
|
||||
void SetAddress (Mac48Address address);
|
||||
|
||||
// inherited from NetDevice base class.
|
||||
virtual void SetName(const std::string name);
|
||||
...
|
||||
};
|
||||
\endcode
|
||||
|
||||
The code below illustrates how the three model-specific methods defined above are
|
||||
implemented:
|
||||
|
||||
\code
|
||||
void
|
||||
SimpleNetDevice::Receive (Ptr<Packet> packet, uint16_t protocol,
|
||||
Mac48Address to, Mac48Address from)
|
||||
{
|
||||
if (to == m_address || to == Mac48Address::GetBroadcast ())
|
||||
{
|
||||
m_rxCallback (this, packet, protocol, from);
|
||||
}
|
||||
}
|
||||
void
|
||||
SimpleNetDevice::SetChannel (Ptr<SimpleChannel> channel)
|
||||
{
|
||||
m_channel = channel;
|
||||
m_channel->Add (this);
|
||||
}
|
||||
void
|
||||
SimpleNetDevice::SetAddress (Mac48Address address)
|
||||
{
|
||||
m_address = address;
|
||||
}
|
||||
\endcode
|
||||
|
||||
Building a topology with such a device is then a matter of
|
||||
instanciating a set of SimpleNetDevice objects connected on a shared
|
||||
SimpleChannel:
|
||||
\code
|
||||
NodeContainer nodes;
|
||||
nodes.Create (10);
|
||||
Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
|
||||
for (uint32_t i = 0; i < nodes.GetN (); ++i)
|
||||
{
|
||||
CreateSimpleDevice (nodes.Get (i), channel);
|
||||
}
|
||||
\endcode
|
||||
|
||||
With the following CreateSimpleDevice function:
|
||||
\code
|
||||
static Ptr<SimpleNetDevice>
|
||||
CreateSimpleDevice (Ptr<Node> node, Ptr<SimpleChannel> channel)
|
||||
{
|
||||
Ptr<SimpleNetDevice> device = CreateObject<SimpleNetDevice> ();
|
||||
device->SetAddress (Mac48Address:Allocate ());
|
||||
device->SetChannel (channel);
|
||||
node->AddDevice (device);
|
||||
return device;
|
||||
}
|
||||
\endcode
|
||||
|
||||
Of course, ultimately, you need to provide a helper class for this new device and channel
|
||||
to save each user from having to re-implement their own CreateSimpleDevice helper
|
||||
function:
|
||||
|
||||
\code
|
||||
class SimpleHelper
|
||||
{
|
||||
public:
|
||||
NetDeviceContainer Install (NodeContainer nodes, Ptr<SimpleChannel> channel);
|
||||
NetDeviceContainer Install (NodeContainer nodes);
|
||||
};
|
||||
\endcode
|
||||
|
||||
with the following straightforward implementation, inspired by the CreateSimpleDevice
|
||||
function defined above:
|
||||
|
||||
\code
|
||||
NetDeviceContainer
|
||||
SimpleHelper::Install (NodeContainer nodes, Ptr<SimpleChannel> channel)
|
||||
{
|
||||
NetDeviceContainer devices;
|
||||
for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
|
||||
{
|
||||
Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice> ();
|
||||
dev->SetAddress (Mac48Address::Allocate ());
|
||||
dev->SetChannel (channel);
|
||||
(*i)->AddDevice (dev);
|
||||
devices.Add (dev);
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
NetDeviceContainer
|
||||
SimpleHelper::Install (NodeContainer nodes)
|
||||
{
|
||||
return Install (nodes, CreateObject<SimpleChannel> ());
|
||||
}
|
||||
\endcode
|
||||
|
||||
Of course, at some point, this device helper class should also contain a couple of
|
||||
ascii and pcap tracing helper functions but, since the default SimpleNetDevice
|
||||
class we used as an example here does not report any trace event, it would
|
||||
be of little use.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,119 @@
|
||||
/*!
|
||||
\page packet-header-trailer How to create a new type of protocol header or trailer
|
||||
\anchor howtos-packet-header-trailer
|
||||
|
||||
<b>Question:</b> I want to implement a new protocol X which uses a new
|
||||
type of header Y. How do I implement and use this new header Y in ns-3 ?
|
||||
|
||||
<b>Answer:</b> The key is to implement a new subclass of the ns3::Header
|
||||
base class to represent your protocol header:
|
||||
\code
|
||||
class YHeader : public Header
|
||||
{
|
||||
public:
|
||||
// must be implemented to become a valid new header.
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
virtual void Print (std::ostream &os) const;
|
||||
|
||||
// allow protocol-specific access to the header data.
|
||||
void SetData (uint32_t data);
|
||||
uint32_t GetData (void) const;
|
||||
private:
|
||||
uint32_t m_data;
|
||||
};
|
||||
\endcode
|
||||
|
||||
Once this class is implemented, you can easily store your protocol
|
||||
header into a packet:
|
||||
\code
|
||||
Ptr<Packet> p = ...;
|
||||
YHeader yHeader;
|
||||
yHeader.SetData (0xdeadbeaf);
|
||||
// copy the header into the packet
|
||||
p->AddHeader (yHeader);
|
||||
\endcode
|
||||
and get it out of a packet:
|
||||
\code
|
||||
Ptr<Packet> p = ...;
|
||||
YHeader yHeader;
|
||||
// copy the header from the packet
|
||||
p->RemoveHeader (yHeader);
|
||||
uint32_t data = yHeader.GetData ();
|
||||
\endcode
|
||||
|
||||
The implementation of the new header is very simple. First, you need
|
||||
to give a TypeId to your YHeader class:
|
||||
\code
|
||||
TypeId
|
||||
YHeader::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("YHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<YHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
YHeader::GetInstanceTypeId (void)
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
\endcode
|
||||
|
||||
Then, you need to allow your header to serialize and deserialize itself
|
||||
to a byte buffer in its network representation. Here, our new protocol
|
||||
header contains first a 2-byte constant, and, then, the data field so,
|
||||
the total size of the header is 2+4=6 bytes.
|
||||
\code
|
||||
uint32_t
|
||||
YHeader::GetSerializedSize (void) const
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
void
|
||||
YHeader::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
// The 2 byte-constant
|
||||
start.WriteU8 (0xfe);
|
||||
start.WriteU8 (0xef);
|
||||
// The data.
|
||||
start.WriteHtonU32 (m_data);
|
||||
}
|
||||
uint32_t
|
||||
YHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
uint8_t tmp;
|
||||
tmp = start.ReadU8 ();
|
||||
NS_ASSERT (tmp == 0xfe);
|
||||
tmp = start.ReadU8 ();
|
||||
NS_ASSERT (tmp == 0xef);
|
||||
m_data = start.ReadNtohU32 ();
|
||||
return 6; // the number of bytes consumed.
|
||||
}
|
||||
\endcode
|
||||
|
||||
Finally, to make sure that Packet::Print also prints the content
|
||||
of your header, just as it prints the content of the other
|
||||
headers of the system, you need to provide a Print method:
|
||||
\code
|
||||
void
|
||||
YHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "data=" << m_data;
|
||||
}
|
||||
\endcode
|
||||
|
||||
The code will look the same if you want to implement a trailer,
|
||||
that is, a protocol data structure which will be appended to the
|
||||
end of the packet, not its start: you need to make sure that
|
||||
you derive from the ns3::Trailer base class and that you call
|
||||
Packet::AddTrailer and Packet::RemoveTrailer. Another important
|
||||
detail is that you must make sure to rewind the iterator in your
|
||||
Serialize and Deserialize methods writing to or reading from
|
||||
the underlying buffer.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,20 @@
|
||||
/*!
|
||||
\page howtos ns-3 HOWTOs
|
||||
\anchor howtos-anchor
|
||||
|
||||
This is an organized set of frequently asked questions (FAQ) and HOWTOs
|
||||
for ns-3. This complements the following wiki pages:
|
||||
|
||||
- <a href="http://www.nsnam.org/wiki/index.php/User_FAQ">User FAQ</a>
|
||||
- <a href="http://www.nsnam.org/wiki/index.php/Developer_FAQ">Developer FAQ</a>
|
||||
|
||||
Please consider contributing tips to either the wiki (yourself) or
|
||||
by submitting a patch to this maintained documentation.
|
||||
|
||||
- \subpage callbacks
|
||||
- \subpage packet-header-trailer
|
||||
- \subpage net-device
|
||||
- \subpage application
|
||||
|
||||
*/
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* \mainpage ns-3 Documentation
|
||||
*
|
||||
* \section intro-sec Introduction
|
||||
* <a href="http://www.nsnam.org/">ns-3</a> documentation is maintained using
|
||||
* <a href="http://www.doxygen.org">Doxygen</a>.
|
||||
* Doxygen is typically used for
|
||||
* API documentation, and organizes such documentation across different
|
||||
* modules. This project uses Doxygen both for building the manual around
|
||||
* the API documentation, and a separate GNU texinfo document is used for
|
||||
* the manual.
|
||||
*
|
||||
* The ns-3 project documentation is organized as follows:
|
||||
* - <b><a href="modules.html">modules</a></b>: The "Modules" tab (above)
|
||||
* organizes all of the public API and supporting manual text
|
||||
* along the source code directory structure. This forms the
|
||||
* "ns-3 manual", and it is available in HTML and PDF forms.
|
||||
* - \ref howtos-anchor "HOWTOs": A set of HOWTOs and FAQs is
|
||||
* maintained on another Doxygen "Related Page"
|
||||
* - <a href="http://www.nsnam.org/docs/tutorial/tutorial.html">tutorial</a>: The ns-3 tutorial is a separate document maintained in <a href="http://www.gnu.org/software/texinfo/"> GNU Texinfo</a>.
|
||||
* - The <b><a href="http://www.nsnam.org/wiki/index.php/Main_Page">ns-3 wiki</a></b>
|
||||
* contains additional user-contributed material. Some wiki-contributed
|
||||
* material may migrate to and overlap with the Doxygen information.
|
||||
*
|
||||
* \section install-sec Building the Documentation
|
||||
*
|
||||
* ns-3 requires Doxygen version 1.5.4 or greater to fully build all items,
|
||||
* although earlier versions of Doxygen will mostly work.
|
||||
*
|
||||
* Type "./waf check" followed by "./waf --doxygen" to build the documentation.
|
||||
* There is a program that runs during "./waf check" that builds pieces of
|
||||
* the documentation through introspection. The doc/ directory contains
|
||||
* configuration for Doxygen (doxygen.conf and main.txt). The Doxygen
|
||||
* build process puts html files into the doc/html/ directory, and latex
|
||||
* filex into the doc/latex/ directory.
|
||||
*
|
||||
* \section module-sec Module overview
|
||||
*
|
||||
* The ns-3 library is split across multiple modules:
|
||||
* - core: located in src/core and contains a number of facilities which
|
||||
* do not depend on any other module. Some of these facilities are
|
||||
* OS-dependent.
|
||||
* - simulator: located in src/simulator and contains event scheduling
|
||||
* facilities.
|
||||
* - common: located in src/common and contains facilities specific
|
||||
* to network simulations but shared by pretty much every model
|
||||
* of a network component.
|
||||
* - node: located in src/node. Defines the abstract interfaces which
|
||||
* must be implemented by every node and more specifically, by ipv4 nodes.
|
||||
* - devices: located in src/devices. Contains a set of MAC-level models
|
||||
*
|
||||
* More detail can be found in the <b><a href="modules.html">Modules</a></b>
|
||||
* tab.
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \namespace ns3
|
||||
* \brief Every class exported by the ns3 library is enclosed in the
|
||||
* ns3 namespace.
|
||||
*/
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* \mainpage An Introduction to ns-3
|
||||
*
|
||||
* The ns-3 library is split across multiple modules:
|
||||
* - core: located in src/core and contains a number of facilities which
|
||||
* do not depend on any other module. Some of these facilities are
|
||||
* OS-dependent.
|
||||
* - simulator: located in src/simulator and contains event scheduling
|
||||
* facilities.
|
||||
* - common: located in src/common and contains facilities specific
|
||||
* to network simulations but shared by pretty much every model
|
||||
* of a network component.
|
||||
* - node: located in src/node. Defines the abstract interfaces which
|
||||
* must be implemented by every node and more specifically, by ipv4 nodes.
|
||||
* - devices: located in src/devices. Contains a set of MAC-level models
|
||||
*
|
||||
* The "core" module contains:
|
||||
* - a Functor class: ns3::Callback
|
||||
* - an os-independent interface to get access to the elapsed wall clock time: ns3::SystemWallClockMs
|
||||
* - a class to register regression tests with the test manager: ns3::Test and ns3::TestManager
|
||||
* - debugging facilities: \ref debugging, \ref assert, \ref error
|
||||
* - \ref randomvariable
|
||||
* - \ref config
|
||||
* - a base class for objects which need to support reference counting
|
||||
* and QueryInterface: ns3::Interface and ns3::InterfaceId
|
||||
* - a smart-pointer class ns3::Ptr designed to work together with ns3::Interface
|
||||
*
|
||||
* The "simulator" module contains:
|
||||
* - a time management class to hold a time and convert between various time units: ns3::Time
|
||||
* - a scheduler base class used to implement new simulation event schedulers:
|
||||
* ns3::Scheduler and ns3::SchedulerFactory
|
||||
* - a simulator class used to create, schedule and cancel events: ns3::Simulator
|
||||
*
|
||||
* The "common" module contains:
|
||||
* - a packet class to create and manipulate simulation packets: ns3::Packet, ns3::Header,
|
||||
* and ns3::Trailer. This packet class also supports per-packet ns3::Tag which are
|
||||
* globs of data which can be attached to any packet.
|
||||
* - a set of low-level trace facilities: \ref lowleveltracing
|
||||
*
|
||||
* The "node" module contains:
|
||||
* - a ns3::INode base class which should be subclassed by any new type of
|
||||
* network Node.
|
||||
* - models which abstract the MAC-layer from the IP layer protocols:
|
||||
* ns3::NetDevice and ns3::Channel.
|
||||
* - models which abstract the application-layer API: ns3::Application,
|
||||
* ns3::Socket, ns3::ISocketFactory, and, ns3::IUdp
|
||||
*
|
||||
* The "internet-node" module contains a set of classes which implement the
|
||||
* APIs defined in the "node" module:
|
||||
* - an Ipv4/Udp stack with socket support
|
||||
* - an ARP module
|
||||
* - an INode subclass.
|
||||
* - and finally, a function used to instantiate nodes
|
||||
* which contain this implementation: ns3::MakeInternetNode
|
||||
*
|
||||
* The "devices" module contains:
|
||||
* - a PointToPoint MAC device: ns3::PointToPointNetDevice, ns3::PointToPointChannel,
|
||||
* and ns3::PointToPointTopology.
|
||||
*/
|
||||
/**
|
||||
* \namespace ns3
|
||||
* \brief Every class exported by the ns3 library is enclosed in the
|
||||
* ns3 namespace.
|
||||
*/
|
||||
/**
|
||||
* \defgroup constants Constants
|
||||
* \brief Constants you can change
|
||||
*/
|
||||
@@ -0,0 +1,48 @@
|
||||
TEXI2HTML = texi2html
|
||||
TEXI2PDF = texi2dvi --pdf
|
||||
EPSTOPDF = epstopdf
|
||||
TGIF = tgif
|
||||
DIA = dia
|
||||
CONVERT = convert
|
||||
CSS = --css-include=manual.css
|
||||
SPLIT = --split section
|
||||
|
||||
DIA_SOURCES = buffer.dia sockets-overview.dia
|
||||
TGIF_SOURCES = packet.obj node.obj internet-node-send.obj internet-node-recv.obj
|
||||
DIA_EPS = ${DIA_SOURCES:.dia=.eps}
|
||||
DIA_PNG = ${DIA_SOURCES:.dia=.png}
|
||||
DIA_PDF = ${DIA_SOURCES:.dia=.pdf}
|
||||
|
||||
TGIF_EPS = ${TGIF_SOURCES:.obj=.eps}
|
||||
TGIF_PNG = ${TGIF_SOURCES:.obj=.png}
|
||||
TGIF_PDF = ${TGIF_SOURCES:.obj=.pdf}
|
||||
|
||||
all: images html split-html pdf
|
||||
|
||||
# Note: tgif requires a valid x display to convert from .obj to .png.
|
||||
# If running this makefile on a remote console, the X virtual frame
|
||||
# buffer may be needed (xorg-x11-server-Xvfb) to provide a "fake"
|
||||
# display
|
||||
images:
|
||||
cd figures/; $(DIA) -t png $(DIA_SOURCES)
|
||||
cd figures/; $(DIA) -t eps $(DIA_SOURCES)
|
||||
cd figures/; $(foreach FILE,$(DIA_EPS),$(EPSTOPDF) $(FILE);)
|
||||
cd figures/; $(TGIF) -print -png $(TGIF_SOURCES)
|
||||
cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES)
|
||||
cd figures/; $(foreach FILE,$(TGIF_EPS),$(EPSTOPDF) $(FILE);)
|
||||
|
||||
html: images
|
||||
$(TEXI2HTML) ${CSS} manual.texi
|
||||
|
||||
split-html: images
|
||||
$(TEXI2HTML) ${CSS} ${SPLIT} manual.texi
|
||||
|
||||
pdf: images
|
||||
$(TEXI2PDF) manual.texi
|
||||
|
||||
figures-clean:
|
||||
cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF)
|
||||
cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF)
|
||||
|
||||
clean: figures-clean
|
||||
rm -rf manual.aux manual.cp manual.cps manual.fn manual.ky manual.pg manual.tp manual.vr manual.toc manual.log manual.pdf manual.html manual/
|
||||
@@ -0,0 +1,559 @@
|
||||
@node Attributes
|
||||
@chapter Attributes
|
||||
@anchor{chap:Attributes}
|
||||
|
||||
In ns-3 simulations, there are two main aspects to configuration:
|
||||
@itemize @bullet
|
||||
@item the simulation topology and how objects are connected
|
||||
@item the values used by the models instantiated in the topology
|
||||
@end itemize
|
||||
|
||||
This chapter focuses on the second item above: how the many values
|
||||
in use in ns-3 are organized, documented, and modifiable by ns-3 users.
|
||||
The ns-3 attribute system is also the underpinning of how traces
|
||||
and statistics are gathered in the simulator.
|
||||
|
||||
Before delving into details of the attribute value system,
|
||||
it will help to review some basic properties of @code{class ns3::Object}.
|
||||
|
||||
@node Object Overview
|
||||
@section Object Overview
|
||||
|
||||
ns-3 is fundamentally a C++ object-based system. By this we mean that
|
||||
new C++ classes (types) can be declared, defined, and subclassed
|
||||
as usual.
|
||||
|
||||
Many ns-3 objects inherit from the @code{ns3::Object} base class. These
|
||||
objects have some additional properties that we exploit for
|
||||
organizing the system and improving the memory management
|
||||
of our objects:
|
||||
|
||||
@itemize @bullet
|
||||
@item a "metadata" system that links the class name to a lot of
|
||||
meta-information about the object, including the base class of the subclass,
|
||||
the set of accessible constructors in the subclass, and the set of
|
||||
"attributes" of the subclass
|
||||
@item a reference counting smart pointer implementation, for memory
|
||||
management.
|
||||
@end itemize
|
||||
|
||||
ns-3 objects that use the attribute system derive from either
|
||||
@code{ns3::Object} or @code{ns3::ObjectBase}. Most ns-3 objects
|
||||
we will discuss derive from @code{ns3::Object}, but a few that
|
||||
are outside the smart pointer memory management framework derive
|
||||
from @code{ns3::ObjectBase}.
|
||||
|
||||
Let's review a couple of properties of these objects.
|
||||
|
||||
@node Smart pointers
|
||||
@subsection Smart pointers
|
||||
|
||||
As introduced above in @ref{Smart Pointers 101}, ns-3 objects
|
||||
are memory managed by a
|
||||
@uref{http://en.wikipedia.org/wiki/Smart_pointer,,reference counting smart pointer implementation}, @code{class ns3::Ptr}.
|
||||
|
||||
Smart pointers are used extensively in the ns-3 APIs, to avoid passing
|
||||
references to heap-allocated objects that may cause memory leaks.
|
||||
For most basic usage (syntax), treat a smart pointer like a regular pointer:
|
||||
@verbatim
|
||||
Ptr<WifiNetDevice> nd = ...;
|
||||
nd->CallSomeFunction ();
|
||||
// etc.
|
||||
@end verbatim
|
||||
|
||||
@node CreateObject
|
||||
@subsection CreateObject
|
||||
|
||||
As we discussed above in @ref{Object Creation},
|
||||
at the lowest-level API, objects of type @code{ns3::Object} are
|
||||
not instantiated using @code{operator new} as usual but instead by
|
||||
a templated function called @code{CreateObject()}.
|
||||
|
||||
A typical way to create such an object is as follows:
|
||||
@verbatim
|
||||
Ptr<WifiNetDevice> nd = CreateObject<WifiNetDevice> ();
|
||||
@end verbatim
|
||||
|
||||
You can think of this as being functionally equivalent to:
|
||||
@verbatim
|
||||
WifiNetDevice* nd = new WifiNetDevice ();
|
||||
@end verbatim
|
||||
|
||||
Objects that derive from @code{ns3::Object} must be allocated
|
||||
on the heap using CreateObject(). Those deriving from
|
||||
@code{ns3::ObjectBase}, such as ns-3 helper functions and packet
|
||||
headers and trailers, can be allocated on the stack.
|
||||
|
||||
In some scripts, you may not see a lot of CreateObject() calls
|
||||
in the code;
|
||||
this is because there are some helper objects in effect that
|
||||
are doing the CreateObject()s for you.
|
||||
|
||||
@node TypeId
|
||||
@subsection TypeId
|
||||
|
||||
ns-3 classes that derive from class ns3::Object can include
|
||||
a metadata class called @code{TypeId} that records meta-information
|
||||
about the class, for use in the object aggregation and component
|
||||
manager systems:
|
||||
@itemize @bullet
|
||||
@item a unique string identifying the class
|
||||
@item the base class of the subclass, within the metadata system
|
||||
@item the set of accessible constructors in the subclass
|
||||
@end itemize
|
||||
|
||||
@node Object Summary
|
||||
@subsection Object Summary
|
||||
|
||||
Putting all of these concepts together, let's look at a specific
|
||||
example: @code{class ns3::Node}.
|
||||
|
||||
The public header file node.h has a declaration that includes
|
||||
a static GetTypeId function call:
|
||||
@verbatim
|
||||
class Node : public Object
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
...
|
||||
@end verbatim
|
||||
|
||||
This is defined in the node.cc file as follows:
|
||||
@verbatim
|
||||
TypeId
|
||||
Node::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::Node")
|
||||
.SetParent<Object> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@end verbatim
|
||||
Finally, when users want to create Nodes, they call:
|
||||
@verbatim
|
||||
Ptr<Node> n = CreateObject<Node> ();
|
||||
@end verbatim
|
||||
|
||||
We next discuss how attributes (values associated with member variables
|
||||
or functions of the class) are plumbed into the above TypeId.
|
||||
|
||||
@node Attribute Overview
|
||||
@section Attribute Overview
|
||||
|
||||
The goal of the attribute system is to organize the access of
|
||||
internal member objects of a simulation. This goal arises because,
|
||||
typically in simulation, users will cut and paste/modify existing
|
||||
simulation scripts, or will use higher-level simulation constructs,
|
||||
but often will be interested in studying or tracing particular
|
||||
internal variables. For instance, use cases such as:
|
||||
@itemize @bullet
|
||||
@item "I want to trace the packets on the wireless interface only on
|
||||
the first access point"
|
||||
@item "I want to trace the value of the TCP congestion window (every
|
||||
time it changes) on a particular TCP socket"
|
||||
@item "I want a dump of all values that were used in my simulation."
|
||||
@end itemize
|
||||
|
||||
Similarly, users may want fine-grained access to internal
|
||||
variables in the simulation, or may want to broadly change the
|
||||
initial value used for a particular parameter in all subsequently
|
||||
created objects. Finally, users may wish to know what variables
|
||||
are settable and retrievable in a simulation configuration. This
|
||||
is not just for direct simulation interaction on the command line;
|
||||
consider also a (future) graphical user interface
|
||||
that would like to be able to provide a feature whereby a user
|
||||
might right-click on an node on the canvas and see a hierarchical,
|
||||
organized list of parameters that are settable on the node and its
|
||||
constituent member objects, and help text and default values for
|
||||
each parameter.
|
||||
|
||||
@node Functional overview
|
||||
@subsection Functional overview
|
||||
|
||||
We provide a way for users to access values deep in the system, without
|
||||
having to plumb accessors (pointers) through the system and walk
|
||||
pointer chains to get to them. Consider a class DropTailQueue that
|
||||
has a member variable that is an unsigned integer @code{m_maxPackets};
|
||||
this member variable controls the depth of the queue.
|
||||
|
||||
If we look at the declaration of DropTailQueue, we see the following:
|
||||
@verbatim
|
||||
class DropTailQueue : public Queue {
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
...
|
||||
|
||||
private:
|
||||
std::queue<Ptr<Packet> > m_packets;
|
||||
uint32_t m_maxPackets;
|
||||
};
|
||||
@end verbatim
|
||||
|
||||
Let's consider things that a user may want to do with the value of
|
||||
m_maxPackets:
|
||||
|
||||
@itemize @bullet
|
||||
@item Set a default value for the system, such that whenever a new
|
||||
DropTailQueue is created, this member is initialized to that default.
|
||||
@item Set or get the value on an already instantiated queue.
|
||||
@end itemize
|
||||
|
||||
The above things typically require providing Set() and Get() functions,
|
||||
and some type of global default value.
|
||||
|
||||
In the ns-3 attribute system, these value definitions and accessor
|
||||
functions are moved into the TypeId class; e.g.:
|
||||
@verbatim
|
||||
TypeId DropTailQueue::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::DropTailQueue")
|
||||
.SetParent<Queue> ()
|
||||
.AddConstructor<DropTailQueue> ()
|
||||
.AddAttribute ("MaxPackets",
|
||||
"The maximum number of packets accepted by this DropTailQueue.",
|
||||
UintegerValue (100),
|
||||
MakeUintegerAccessor (&DropTailQueue::m_maxPackets),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
;
|
||||
|
||||
return tid;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
The AddAttribute() method is performing a number of things with this
|
||||
value:
|
||||
@itemize @bullet
|
||||
@item Binding the variable m_maxPackets to a string "MaxPackets"
|
||||
@item Providing a default value (100 packets)
|
||||
@item Providing some help text defining the value
|
||||
@item Providing a "checker" (not used in this example) that can be used to set
|
||||
bounds on the allowable range of values
|
||||
@end itemize
|
||||
|
||||
The key point is that now the value of this variable and its default
|
||||
value are accessible in the attribute namespace, which is based on
|
||||
strings such as "MaxPackets" and TypeId strings. In the next
|
||||
section, we will provide an example script that shows how users
|
||||
may manipulate these values.
|
||||
|
||||
@node Basic usage
|
||||
@subsection Basic usage
|
||||
|
||||
Let's look at how a user script might access these values.
|
||||
This is based on the script found at @code{samples/main-attribute-value.cc},
|
||||
with some details stripped out.
|
||||
@verbatim
|
||||
//
|
||||
// This is a basic example of how to use the attribute system to
|
||||
// set and get a value in the underlying system; namely, an unsigned
|
||||
// integer of the maximum number of packets in a queue
|
||||
//
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
// By default, the MaxPackets attribute has a value of 100 packets
|
||||
// (this default can be observed in the function DropTailQueue::GetTypeId)
|
||||
//
|
||||
// Here, we set it to 80 packets. We could use one of two value types:
|
||||
// a string-based value or a Uinteger value
|
||||
Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("80"));
|
||||
// The below function call is redundant
|
||||
Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (80));
|
||||
|
||||
// Allow the user to override any of the defaults and the above
|
||||
// SetDefaults() at run-time, via command-line arguments
|
||||
CommandLine cmd;
|
||||
cmd.Parse (argc, argv);
|
||||
@end verbatim
|
||||
|
||||
The main thing to notice in the above are the two calls to
|
||||
@code{Config::SetDefault}. This is how we set the default value
|
||||
for all subsequently instantiated DropTailQueues. We illustrate
|
||||
that two types of Value classes, a StringValue and a UintegerValue class,
|
||||
can be used to assign the value to the attribute named by
|
||||
"ns3::DropTailQueue::MaxPackets".
|
||||
|
||||
Now, we will create a few objects using the low-level API; here,
|
||||
our newly created queues will not have a m_maxPackets initialized to
|
||||
100 packets but to 80 packets, because of what we did above with
|
||||
default values.
|
||||
@verbatim
|
||||
Ptr<Node> n0 = CreateObject<Node> ();
|
||||
|
||||
Ptr<PointToPointNetDevice> net0 = CreateObject<PointToPointNetDevice> ();
|
||||
n0->AddDevice (net0);
|
||||
|
||||
Ptr<Queue> q = CreateObject<DropTailQueue> ();
|
||||
net0->AddQueue(q);
|
||||
@end verbatim
|
||||
|
||||
At this point, we have created a single node (Node 0) and a
|
||||
single PointToPointNetDevice (NetDevice 0) and added a
|
||||
DropTailQueue to it.
|
||||
|
||||
Now, we can manipulate the MaxPackets value of the already
|
||||
instantiated DropTailQueue. Here are various ways to do that.
|
||||
|
||||
@subsubsection Pointer-based access
|
||||
|
||||
We assume that a smart pointer (Ptr) to a relevant network device is
|
||||
in hand; here, it is the net0 pointer.
|
||||
|
||||
One way to change the value is to access a pointer to the
|
||||
underlying queue and modify its attribute.
|
||||
|
||||
First, we observe that we can get a pointer to the (base class)
|
||||
queue via the PointToPointNetDevice attributes, where it is called
|
||||
TxQueue
|
||||
@verbatim
|
||||
PointerValue tmp;
|
||||
net0->GetAttribute ("TxQueue", tmp);
|
||||
Ptr<Object> txQueue = tmp.GetObject ();
|
||||
@end verbatim
|
||||
|
||||
Using the GetObject function, we can perform a safe downcast
|
||||
to a DropTailQueue, where MaxPackets is a member
|
||||
@verbatim
|
||||
Ptr<DropTailQueue> dtq = txQueue->GetObject <DropTailQueue> ();
|
||||
NS_ASSERT (dtq != 0);
|
||||
@end verbatim
|
||||
|
||||
Next, we can get the value of an attribute on this queue.
|
||||
We have introduced wrapper "Value" classes for the underlying
|
||||
data types, similar to Java wrappers around these types, since
|
||||
the attribute system stores values and not disparate types.
|
||||
Here, the attribute value is assigned to a UintegerValue, and
|
||||
the Get() method on this value produces the (unwrapped) uint32_t.
|
||||
@verbatim
|
||||
UintegerValue limit;
|
||||
dtq->GetAttribute ("MaxPackets", limit);
|
||||
NS_LOG_INFO ("1. dtq limit: " << limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
Note that the above downcast is not really needed; we could have
|
||||
done the same using the Ptr<Queue> even though the attribute
|
||||
is a member of the subclass
|
||||
@verbatim
|
||||
txQueue->GetAttribute ("MaxPackets", limit);
|
||||
NS_LOG_INFO ("2. txQueue limit: " << limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
Now, let's set it to another value (60 packets)
|
||||
@verbatim
|
||||
txQueue->SetAttribute("MaxPackets", UintegerValue (60));
|
||||
txQueue->GetAttribute ("MaxPackets", limit);
|
||||
NS_LOG_INFO ("3. txQueue limit changed: " << limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
@subsubsection Namespace-based access
|
||||
|
||||
An alternative way to get at the attribute is to use the configuration
|
||||
namespace. Here, this attribute resides on a known path in this
|
||||
namespace; this approach is useful if one doesn't have access to
|
||||
the underlying pointers and would like to configure a specific
|
||||
attribute with a single statement.
|
||||
@verbatim
|
||||
Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", UintegerValue (25));
|
||||
txQueue->GetAttribute ("MaxPackets", limit);
|
||||
NS_LOG_INFO ("4. txQueue limit changed through namespace: " <<
|
||||
limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
We could have also used wildcards to set this value for all nodes
|
||||
and all net devices (which in this simple example has the same
|
||||
effect as the previous Set())
|
||||
@verbatim
|
||||
Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", UintegerValue (15));
|
||||
txQueue->GetAttribute ("MaxPackets", limit);
|
||||
NS_LOG_INFO ("5. txQueue limit changed through wildcarded namespace: " <<
|
||||
limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
@node Setting through constructors and helper classes
|
||||
@subsection Setting through constructors helper classes
|
||||
|
||||
Arbitrary combinations of attributes can be set and fetched from
|
||||
the helper and low-level APIs; either from the constructors themselves:
|
||||
@verbatim
|
||||
Ptr<Object> p = CreateObject<MyNewObject> ("n1", v1, "n2", v2, ...);
|
||||
@end verbatim
|
||||
or from the higher-level helper APIs, such as:
|
||||
@verbatim
|
||||
mobility.SetPositionAllocator ("GridPositionAllocator",
|
||||
"MinX", DoubleValue (-100.0),
|
||||
"MinY", DoubleValue (-100.0),
|
||||
"DeltaX", DoubleValue (5.0),
|
||||
"DeltaY", DoubleValue (20.0),
|
||||
"GridWidth", UintegerValue (20),
|
||||
"LayoutType", StringValue ("RowFirst"));
|
||||
@end verbatim
|
||||
|
||||
@node Value classes
|
||||
@subsection Value classes
|
||||
Readers will note the new FooValue classes which are subclasses of the
|
||||
AttributeValue base class. These can be thought of as
|
||||
an intermediate class that can be used to convert from raw types to the
|
||||
Values that are used by the attribute system. Recall that this database is holding
|
||||
objects of many types with a single generic type. Conversions to this
|
||||
type can either be done using an intermediate class (IntegerValue, DoubleValue for
|
||||
"floating point") or via strings. Direct implicit conversion of types
|
||||
to Value is not really practical. So in the above, users have a choice
|
||||
of using strings or values:
|
||||
@verbatim
|
||||
p->Set ("cwnd", StringValue ("100")); // string-based setter
|
||||
p->Set ("cwnd", IntegerValue (100)); // integer-based setter
|
||||
@end verbatim
|
||||
|
||||
The system provides some macros that help users declare and define
|
||||
new AttributeValue subclasses for new types that they want to introduce into
|
||||
the attribute system:
|
||||
@itemize @bullet
|
||||
@item ATTRIBUTE_HELPER_HEADER
|
||||
@item ATTRIBUTE_HELPER_CPP
|
||||
@end itemize
|
||||
|
||||
@node Extending attributes
|
||||
@section Extending attributes
|
||||
|
||||
The ns-3 system will place a number of internal values under the
|
||||
attribute system, but undoubtedly users will want to extend this
|
||||
to pick up ones we have missed, or to add their own classes to this.
|
||||
|
||||
@subsection Adding an existing internal variable to the metadata system
|
||||
|
||||
Consider this variable in class TcpSocket:
|
||||
@verbatim
|
||||
uint32_t m_cWnd; // Congestion window
|
||||
@end verbatim
|
||||
|
||||
Suppose that someone working with Tcp wanted to get or set the
|
||||
value of that variable using the metadata system. If it were not
|
||||
already provided by ns-3, the user could declare the following addition
|
||||
in the metadata system (to the TypeId declaration for TcpSocket):
|
||||
@verbatim
|
||||
.AddParameter ("Congestion window",
|
||||
"Tcp congestion window (bytes)",
|
||||
Uinteger (1),
|
||||
MakeUintegerAccessor (&TcpSocket::m_cWnd),
|
||||
MakeUintegerChecker<uint16_t> ());
|
||||
|
||||
@end verbatim
|
||||
|
||||
Now, the user with a pointer to the TcpSocket can perform operations
|
||||
such as setting and getting the value, without having to add these
|
||||
functions explicitly. Furthermore, access controls can be applied, such
|
||||
as allowing the parameter to be read and not written, or bounds
|
||||
checking on the permissible values can be applied.
|
||||
|
||||
@subsection Adding a new TypeId
|
||||
|
||||
Here, we discuss the impact on a user who wants to add a new class to
|
||||
ns-3; what additional things must be done to hook it into this system.
|
||||
|
||||
We've already introduced what a TypeId definition looks like:
|
||||
@verbatim
|
||||
TypeId
|
||||
RandomWalk2dMobilityModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::RandomWalk2dMobilityModel")
|
||||
.SetParent<MobilityModel> ()
|
||||
.SetGroupName ("Mobility")
|
||||
.AddConstructor<RandomWalk2dMobilityModel> ()
|
||||
.AddAttribute ("Bounds",
|
||||
"Bounds of the area to cruise.",
|
||||
RectangleValue (Rectangle (0.0, 0.0, 100.0, 100.0)),
|
||||
MakeRectangleAccessor (&RandomWalk2dMobilityModel::m_bounds),
|
||||
MakeRectangleChecker ())
|
||||
.AddAttribute ("Time",
|
||||
"Change current direction and speed after moving for this delay.",
|
||||
TimeValue (Seconds (1.0)),
|
||||
MakeTimeAccessor (&RandomWalk2dMobilityModel::m_modeTime),
|
||||
MakeTimeChecker ())
|
||||
// etc (more parameters).
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
The declaration for this in the class declaration is one-line public
|
||||
member method:
|
||||
@verbatim
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
@end verbatim
|
||||
|
||||
Typical mistakes here involve:
|
||||
@itemize @bullet
|
||||
@item Not calling the SetParent method or calling it with the wrong type
|
||||
@item Not calling the AddConstructor method of calling it with the wrong type
|
||||
@item Introducing a typographical error in the name of the TypeId in its constructor
|
||||
@item Not using the fully-qualified c++ typename of the enclosing c++ class as the
|
||||
name of the TypeId
|
||||
@end itemize
|
||||
None of these mistakes can be detected by the ns-3 codebase so, users
|
||||
are advised to check carefully multiple times that they got these right.
|
||||
|
||||
|
||||
@section Adding new class type to the attribute system
|
||||
|
||||
From the perspective of the user who writes a new class in the system and
|
||||
wants to hook it in to the attribute system, there is mainly the matter
|
||||
of writing
|
||||
the conversions to/from strings and attribute values. Most of this can be
|
||||
copy/pasted with macro-ized code. For instance, consider class
|
||||
Rectangle in the @code{src/mobility/} directory:
|
||||
|
||||
One line is added to the class declaration:
|
||||
@verbatim
|
||||
/**
|
||||
* \brief a 2d rectangle
|
||||
*/
|
||||
class Rectangle
|
||||
{
|
||||
...
|
||||
|
||||
};
|
||||
@end verbatim
|
||||
|
||||
One macro call and two operators, are added below the class declaration:
|
||||
|
||||
@verbatim
|
||||
std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
|
||||
std::istream &operator >> (std::istream &is, Rectangle &rectangle);
|
||||
|
||||
ATTRIBUTE_HELPER_HEADER (Rectangle);
|
||||
@end verbatim
|
||||
|
||||
In the class definition, the code looks like this:
|
||||
|
||||
@verbatim
|
||||
ATTRIBUTE_HELPER_CPP (Rectangle);
|
||||
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, const Rectangle &rectangle)
|
||||
{
|
||||
os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax;
|
||||
return os;
|
||||
}
|
||||
std::istream &
|
||||
operator >> (std::istream &is, Rectangle &rectangle)
|
||||
{
|
||||
char c1, c2, c3;
|
||||
is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax;
|
||||
if (c1 != '|' ||
|
||||
c2 != '|' ||
|
||||
c3 != '|')
|
||||
{
|
||||
is.setstate (std::ios_base::failbit);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
These stream operators simply convert from a string representation of the
|
||||
Rectangle ("xMin|xMax|yMin|yMax") to the underlying Rectangle, and the
|
||||
modeler must specify these operators and the string syntactical representation
|
||||
of an instance of the new class.
|
||||
|
||||
@@ -0,0 +1,330 @@
|
||||
@node Callbacks
|
||||
@chapter Callbacks
|
||||
|
||||
Some new users to @command{ns-3} are unfamiliar with an extensively used
|
||||
programming idiom used throughout the code: the ``ns-3 callback''. This
|
||||
chapter provides some motivation on the callback, guidance on how to use
|
||||
it, and details on its implementation.
|
||||
|
||||
@menu
|
||||
* Motivation::
|
||||
* Using the Callback API::
|
||||
* Callback locations in ns-3::
|
||||
* Implementation details::
|
||||
@end menu
|
||||
|
||||
@node Motivation
|
||||
@section Motivation
|
||||
|
||||
Consider that you have two simulation models A and B, and you wish
|
||||
to have them pass information between them during the simulation. One
|
||||
way that you can do that is that you can make A and B each explicitly
|
||||
knowledgable about the other, so that they can invoke methods on each
|
||||
other.
|
||||
|
||||
@verbatim
|
||||
class A {
|
||||
public:
|
||||
void ReceiveInput ( // parameters );
|
||||
...
|
||||
}
|
||||
|
||||
(in another source file:)
|
||||
|
||||
class B {
|
||||
public:
|
||||
void ReceiveInput ( // parameters);
|
||||
void DoSomething (void);
|
||||
...
|
||||
|
||||
private:
|
||||
A* a_instance; // pointer to an A
|
||||
}
|
||||
|
||||
void
|
||||
B::DoSomething()
|
||||
{
|
||||
// Tell a_instance that something happened
|
||||
a_instance->ReceiveInput ( // parameters);
|
||||
...
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
This certainly works, but it has the drawback that it introduces a
|
||||
dependency on A and B to know about the other at compile time (this
|
||||
makes it harder to have independent compilation units in the simulator)
|
||||
and is not generalized; if in a later usage scenario, B needs to talk
|
||||
to a completely different C object, the source code for B needs to be
|
||||
changed to add a ``c_instance'' and so forth. It is easy to see that
|
||||
this is a brute force mechanism of communication that can lead to
|
||||
programming cruft in the models.
|
||||
|
||||
This is not to say that objects should not know about one another
|
||||
if there is a hard dependency between them, but that often the model
|
||||
can be made more flexible if its interactions are less constrained at
|
||||
compile time.
|
||||
|
||||
This is not an abstract problem for network simulation research,
|
||||
but rather it has been a source of problems in previous simulators,
|
||||
when researchers want to extend or modify the system to do different
|
||||
things (as they are apt to do in research). Consider, for example,
|
||||
a user who wants to add an IPsec security protocol sublayer
|
||||
between TCP and IP:
|
||||
@verbatim
|
||||
------------ -----------
|
||||
| TCP | | TCP |
|
||||
------------ -----------
|
||||
| becomes -> |
|
||||
----------- -----------
|
||||
| IP | | IPsec |
|
||||
----------- -----------
|
||||
|
|
||||
-----------
|
||||
| IP |
|
||||
-----------
|
||||
@end verbatim
|
||||
If the simulator has
|
||||
made assumptions, and hard coded into the code, that IP always talks
|
||||
to a transport protocol above, the user may be forced to hack the
|
||||
system to get the desired interconnections.
|
||||
|
||||
An alternative that provides this flexibility is to use a level of
|
||||
indirection that is commonly known in programming as a callback.
|
||||
A callback function is not invoked explicitly by the caller but is
|
||||
rather delegated to another function that receives the callback
|
||||
function's address and can call it.
|
||||
|
||||
You may be familiar with function pointers in C or C++; these can
|
||||
be used to implement callbacks. For more information on introductory
|
||||
callbacks, an online reference is:
|
||||
@uref{http://www.inquiry.com/techtips/cpp_pro/10min/10min0300.asp,,Declaring Function Pointers and Implementing Callbacks} and
|
||||
@uref{http://en.wikipedia.org/wiki/Callback_(computer_science),,Callback (computer science)-- Wikipedia}.
|
||||
|
||||
The callback API in @command{ns-3} is designed to minimize the overall
|
||||
coupling between various pieces of of the simulator
|
||||
by making each module depend on the callback API
|
||||
itself rather than depend on other modules. It acts as a sort of
|
||||
third-party to which work is delegated and which forwards this
|
||||
work to the proper target module. This callback API, being based
|
||||
on C++ templates,
|
||||
is type-safe; that is, it performs static type checks to enforce
|
||||
proper signature compatibility between callers and callees. It
|
||||
is therefore more type-safe to use than traditional function
|
||||
pointers, but the syntax may look imposing at first. This section
|
||||
is designed to walk you through the callback system so that you
|
||||
can be comfortable using it in @command{ns-3}.
|
||||
|
||||
@node Using the Callback API
|
||||
@section Using the Callback API
|
||||
|
||||
The Callback API is fairly minimal, providing only two services:
|
||||
@itemize @bullet
|
||||
@item callback type declaration: a way to declare a type of callback
|
||||
with a given signature, and,
|
||||
@item callback instantiation: a way to instantiate a
|
||||
template-generated forwarding callback which can forward any calls
|
||||
to another C++ class member method or C++ function.
|
||||
@end itemize
|
||||
|
||||
This is best observed via walking through an example, based on
|
||||
@code{samples/main-callback.cc}.
|
||||
|
||||
@node Using the Callback API with static functions
|
||||
@subsection Using the Callback API with static functions
|
||||
|
||||
Consider a function:
|
||||
@verbatim
|
||||
static double
|
||||
CbOne (double a, double b)
|
||||
{
|
||||
std::cout << "invoke cbOne a=" << a << ", b=" << b << std::endl;
|
||||
return a;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
Consider also the following main program snippett:
|
||||
@verbatim
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
// return type: double
|
||||
// first arg type: double
|
||||
// second arg type: double
|
||||
Callback<double, double, double> one;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
This class template Callback implements what is known as the Functor
|
||||
Design Pattern. It is used to declare the type of a callback. It contains
|
||||
one mandatory argument (the return type of the function to be assigned
|
||||
to this callback) and up to five optional arguments, which each specify
|
||||
the type of the arguments (if your function has more than five arguments,
|
||||
then this can be handled by extending the callback implementation).
|
||||
|
||||
So in the above, we have a declared a callback named "one" that will
|
||||
eventually hold a function pointer. The function that it will hold
|
||||
must return double and must support two double arguments. If one
|
||||
tries to pass a function whose signature does not match the declared
|
||||
callback, the compilation will fail.
|
||||
|
||||
Now, we need to tie together this callback instance and the actual
|
||||
target function (CbOne). Notice above that CbOne has the same function
|
||||
signature types as the callback-- this is important. We can
|
||||
pass in any such properly-typed function to this callback. Let's
|
||||
look at this more closely:
|
||||
@verbatim
|
||||
static double CbOne (double a, double b) {}
|
||||
^ ^ ^
|
||||
| ---| ------|
|
||||
| | |
|
||||
Callback<double, double, double> one;
|
||||
@end verbatim
|
||||
You can only bind a function to a callback if they have the matching
|
||||
signature. The first template argument is the return type, and the
|
||||
additional template arguments are the types of the arguments of
|
||||
the function signature.
|
||||
|
||||
Now, let's bind our callback "one" to the function that matches its
|
||||
signature:
|
||||
@verbatim
|
||||
// build callback instance which points to cbOne function
|
||||
one = MakeCallback (&CbOne);
|
||||
@end verbatim
|
||||
|
||||
Then, later in the program, if the callback is to be used, it can be
|
||||
used as follows:
|
||||
@verbatim
|
||||
// this is not a null callback
|
||||
NS_ASSERT (!one.IsNull ());
|
||||
// invoke cbOne function through callback instance
|
||||
double retOne;
|
||||
retOne = one (10.0, 20.0);
|
||||
@end verbatim
|
||||
|
||||
The check @code{IsNull()} ensures that the callback is not null; that there
|
||||
is a function to call behind this callback. Then, @code{one()} returns the
|
||||
same result as if @code{CbOne()} had been called directly.
|
||||
|
||||
|
||||
@node Using the Callback API with member functions
|
||||
@subsection Using the Callback API with member functions
|
||||
|
||||
Generally, you will not be calling static functions but instead
|
||||
public member functions of an object. In this case, an extra
|
||||
argument is needed to the MakeCallback function, to tell the system
|
||||
on which object the function should be invoked. Consider this example,
|
||||
also from main-callback.cc:
|
||||
|
||||
@verbatim
|
||||
class MyCb {
|
||||
public:
|
||||
int CbTwo (double a) {
|
||||
std::cout << "invoke cbTwo a=" << a << std::endl;
|
||||
return -5;
|
||||
}
|
||||
};
|
||||
|
||||
int main ()
|
||||
{
|
||||
...
|
||||
// return type: int
|
||||
// first arg type: double
|
||||
Callback<int, double> two;
|
||||
MyCb cb;
|
||||
// build callback instance which points to MyCb::cbTwo
|
||||
two = MakeCallback (&MyCb::CbTwo, &cb);
|
||||
...
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
Here, we pass a (raw) pointer to the @code{MakeCallback<>} function,
|
||||
that says, when @code{two ()} is invoked, to call the @code{CbTwo} function
|
||||
on the object pointed to by @code{&cb}.
|
||||
|
||||
A variation of this is used when objects are referred to by ns-3 smart
|
||||
pointers. The MakeCallback API takes a raw pointer, so we need to
|
||||
call @code{PeekPointer ()} to obtain this raw pointer. So the example
|
||||
above would look like:
|
||||
|
||||
@verbatim
|
||||
class MyCb : public Object {
|
||||
public:
|
||||
int CbTwo (double a) {
|
||||
std::cout << "invoke cbTwo a=" << a << std::endl;
|
||||
return -5;
|
||||
}
|
||||
};
|
||||
|
||||
int main ()
|
||||
{
|
||||
...
|
||||
// return type: int
|
||||
// first arg type: double
|
||||
Callback<int, double> two;
|
||||
Ptr<MyCb> cb = CreateObject<MyCb> ();
|
||||
// build callback instance which points to MyCb::cbTwo
|
||||
two = MakeCallback (&MyCb::CbTwo, PeekPointer (cb));
|
||||
...
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
@node Building Null Callbacks
|
||||
@subsection Building Null Callbacks
|
||||
|
||||
It is possible for callbacks to be null; hence it may be wise to
|
||||
check before using them. There is a special construct for a null
|
||||
callback, which is preferable to simply passing "0" as an argument;
|
||||
it is the @code{MakeNullCallback<>} construct:
|
||||
@verbatim
|
||||
two = MakeNullCallback<int, double> ();
|
||||
// invoking a null callback is just like
|
||||
// invoking a null function pointer:
|
||||
// it will crash at runtime.
|
||||
//int retTwoNull = two (20.0);
|
||||
NS_ASSERT (two.IsNull ());
|
||||
@end verbatim
|
||||
|
||||
@node Callback locations in ns-3
|
||||
@section Callback locations in @command{ns-3}
|
||||
|
||||
Where are callbacks frequently used in @command{ns-3}? Here are some of the
|
||||
more visible ones to typical users:
|
||||
|
||||
@subsection Socket API
|
||||
@subsection Layer-2/Layer-3 API
|
||||
@subsection Tracing subsystem
|
||||
@subsection Routing
|
||||
Route Reply
|
||||
|
||||
@node Implementation details
|
||||
@section Implementation details
|
||||
|
||||
This section is advanced explanation for C++ experts interested in
|
||||
the implementation, and may be skipped by most users.
|
||||
|
||||
This code was originally written based on the techniques described
|
||||
@uref{http://www.codeproject.com/cpp/TTLFunction.asp,,here}.
|
||||
It was subsequently rewritten to follow the architecture
|
||||
outlined in
|
||||
@uref{http://www.amazon.com/Modern-C\%2B\%2B-Design-Programming-Patterns/dp/0201704315/ref=pd_bbs_sr_1/102-0157303-1900156?ie=UTF8\&s=books\&qid=1187982662\&sr=1-1,,Modern C++ Design: Generic Programming and Design Patterns Applied-- Alexandrescu}, chapter 5, "Generalized Functors".
|
||||
|
||||
This code uses:
|
||||
@itemize @bullet
|
||||
@item default template parameters to saves users from having to
|
||||
specify empty parameters when the number of parameters
|
||||
is smaller than the maximum supported number
|
||||
@item the pimpl idiom: the Callback class is passed around by
|
||||
value and delegates the crux of the work to its pimpl pointer.
|
||||
@item two pimpl implementations which derive from CallbackImpl
|
||||
FunctorCallbackImpl can be used with any functor-type
|
||||
while MemPtrCallbackImpl can be used with pointers to
|
||||
member functions.
|
||||
@item a reference list implementation to implement the Callback's
|
||||
value semantics.
|
||||
@end itemize
|
||||
|
||||
This code most notably departs from the Alexandrescu
|
||||
implementation in that it does not use type lists to specify
|
||||
and pass around the types of the callback arguments.
|
||||
Of course, it also does not use copy-destruction semantics
|
||||
and relies on a reference list rather than autoPtr to hold
|
||||
the pointer.
|
||||
@@ -0,0 +1,18 @@
|
||||
Please write image files in a vector graphics format, when possible, and
|
||||
generate the .png and .pdf versions on the fly (see ../Makefile).
|
||||
|
||||
Currently supported tools are dia and tgif. xfig could be added similarly
|
||||
if someone wants to add it. The main requirement for adding another format
|
||||
is that the tool to edit it is freely available and that a cron script can
|
||||
autogenerate the pdf and png from the figure source.
|
||||
|
||||
Store the .dia, or .obj versions in mercurial, but not the .png or .pdfs.
|
||||
If the figure is not available in a vector graphics format, store both
|
||||
a .png and a .pdf version in this directory.
|
||||
|
||||
If you add a source (.dia, .obj) file here, remember to add it to
|
||||
the list of figure sources in the Makefile in the directory above
|
||||
|
||||
Note: tgif can convert from .obj to .pdf, but the pdf that results takes
|
||||
up a whole page. Instead, we convert to an intermediate .eps step, and
|
||||
then run epstopdf.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,380 @@
|
||||
%TGIF 4.1.43-QPL
|
||||
state(0,37,100.000,154,78,0,16,0,9,1,1,0,0,3,0,1,0,'Times-Roman',0,80640,0,3,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0).
|
||||
%
|
||||
% @(#)$Header$
|
||||
% %W%
|
||||
%
|
||||
unit("1 pixel/pixel").
|
||||
color_info(11,65535,0,[
|
||||
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
|
||||
"red", 65535, 0, 0, 65535, 0, 0, 1,
|
||||
"green", 0, 65535, 0, 0, 65535, 0, 1,
|
||||
"blue", 0, 0, 65535, 0, 0, 65535, 1,
|
||||
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
|
||||
"pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
|
||||
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
|
||||
"CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
|
||||
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
|
||||
"black", 0, 0, 0, 0, 0, 0, 1,
|
||||
"DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1
|
||||
]).
|
||||
script_frac("0.6").
|
||||
fg_bg_colors('black','white').
|
||||
dont_reencode("FFDingbests:ZapfDingbats").
|
||||
page(1,"",1,'').
|
||||
group([
|
||||
rcbox('black','',161,586,241,634,2,1,1,0,16,125,0,0,0,0,'1',0,[
|
||||
]),
|
||||
text('black',161,605,1,0,1,72,18,124,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,618,'',[
|
||||
minilines(72,18,0,0,0,0,0,[
|
||||
mini_line(72,13,5,0,0,0,[
|
||||
str_block(0,72,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0,
|
||||
"NetDevice")])
|
||||
])
|
||||
])])
|
||||
],
|
||||
141,0,0,[
|
||||
]).
|
||||
group([
|
||||
rcbox('black','',147,77,255,125,2,1,1,0,16,354,0,0,0,0,'1',0,[
|
||||
]),
|
||||
text('black',163,96,1,0,1,88,18,353,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,109,'',[
|
||||
minilines(88,18,0,0,0,0,0,[
|
||||
mini_line(88,13,5,0,0,0,[
|
||||
str_block(0,88,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0,
|
||||
"Application")])
|
||||
])
|
||||
])])
|
||||
],
|
||||
352,0,0,[
|
||||
]).
|
||||
text('black',202,172,1,1,1,90,17,473,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,186,'',[
|
||||
minilines(90,17,0,0,1,0,0,[
|
||||
mini_line(90,14,3,0,0,0,[
|
||||
str_block(0,90,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0,
|
||||
"UdpSocketImpl")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',132,165,269,198,0,1,1,0,16,474,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',202,241,1,1,1,78,17,475,14,3,2,0,0,0,2,78,17,0,0,"",0,0,0,0,255,'',[
|
||||
minilines(78,17,0,0,1,0,0,[
|
||||
mini_line(78,14,3,0,0,0,[
|
||||
str_block(0,78,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,78,14,3,0,0,0,0,0,0,0,
|
||||
"Ipv4EndPoint")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',132,234,269,267,0,1,1,0,16,476,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',202,338,1,1,1,88,17,488,14,3,2,0,0,0,2,88,17,0,0,"",0,0,0,0,352,'',[
|
||||
minilines(88,17,0,0,1,0,0,[
|
||||
mini_line(88,14,3,0,0,0,[
|
||||
str_block(0,88,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0,
|
||||
"UdpL4Protocol")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',132,331,269,364,0,1,1,0,16,489,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',202,434,1,1,1,90,17,490,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,448,'',[
|
||||
minilines(90,17,0,0,1,0,0,[
|
||||
mini_line(90,14,3,0,0,0,[
|
||||
str_block(0,90,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0,
|
||||
"Ipv4L3Protocol")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',132,427,269,460,0,1,1,0,16,491,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',585,11,1,0,1,179,17,496,14,3,0,0,0,0,2,179,17,0,0,"",0,0,0,0,25,'',[
|
||||
minilines(179,17,0,0,0,0,0,[
|
||||
mini_line(179,14,3,0,0,0,[
|
||||
str_block(0,179,14,3,0,-2,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,179,14,3,0,-2,1,0,0,0,0,
|
||||
"Step in packet receive process:")])
|
||||
])
|
||||
])]).
|
||||
text('black',480,595,1,0,1,408,17,498,14,3,0,0,0,0,2,408,17,0,0,"",0,0,0,0,609,'',[
|
||||
minilines(408,17,0,0,0,0,0,[
|
||||
mini_line(408,14,3,0,0,0,[
|
||||
str_block(0,408,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,408,14,3,0,0,0,0,0,0,0,
|
||||
"1. NetDevice calls the function registered at Node::m_receiveCallback")])
|
||||
])
|
||||
])]).
|
||||
text('black',480,572,1,0,1,346,17,520,14,3,0,0,0,0,2,346,17,0,0,"",0,0,0,0,586,'',[
|
||||
minilines(346,17,0,0,0,0,0,[
|
||||
mini_line(346,14,3,0,0,0,[
|
||||
str_block(0,346,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,346,14,3,0,0,0,0,0,0,0,
|
||||
"2. This is typically the Node::ReceiveFromDevice() function")])
|
||||
])
|
||||
])]).
|
||||
text('black',479,509,3,0,1,460,51,524,14,3,0,0,0,0,2,460,51,0,0,"",0,0,0,0,523,'',[
|
||||
minilines(460,51,0,0,0,0,0,[
|
||||
mini_line(426,14,3,0,0,0,[
|
||||
str_block(0,426,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,426,14,3,0,-1,0,0,0,0,0,
|
||||
"3. Node::ReceiveFromDevice stores a set of callbacks (protocol handlers)")])
|
||||
]),
|
||||
mini_line(460,14,3,0,0,0,[
|
||||
str_block(0,460,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,460,14,3,0,-1,0,0,0,0,0,
|
||||
" that are looked up based on protocol number and device. In this case, the lookup")])
|
||||
]),
|
||||
mini_line(300,14,3,0,0,0,[
|
||||
str_block(0,300,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,300,14,3,0,-1,0,0,0,0,0,
|
||||
"will result in Ipv4L3Protocol::Receive() being called.")])
|
||||
])
|
||||
])]).
|
||||
text('black',480,425,4,0,1,499,68,531,14,3,0,0,0,0,2,499,68,0,0,"",0,0,0,0,439,'',[
|
||||
minilines(499,68,0,0,0,0,0,[
|
||||
mini_line(475,14,3,0,0,0,[
|
||||
str_block(0,475,14,3,0,-2,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,475,14,3,0,-2,0,0,0,0,0,
|
||||
"4. Ipv4L3Protocol removes the IP header, checks checksum (if implemented), and ")])
|
||||
]),
|
||||
mini_line(467,14,3,0,0,0,[
|
||||
str_block(0,467,14,3,0,-2,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,467,14,3,0,-2,0,0,0,0,0,
|
||||
"either Forwards the packet or calls ForwardUp(). ForwardUp() then looks up the ")])
|
||||
]),
|
||||
mini_line(499,14,3,0,0,0,[
|
||||
str_block(0,499,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,499,14,3,0,-1,0,0,0,0,0,
|
||||
"IP protocol number in an IPv4L4Demux to obtain a pointer to an Ipv4L4Protocol object,")])
|
||||
]),
|
||||
mini_line(191,14,3,0,0,0,[
|
||||
str_block(0,191,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,191,14,3,0,-1,0,0,0,0,0,
|
||||
"and calls the ::Receive() method.")])
|
||||
])
|
||||
])]).
|
||||
text('black',281,548,1,0,1,140,17,541,14,3,2,0,0,0,2,140,17,0,0,"",0,0,0,0,562,'',[
|
||||
minilines(140,17,0,0,0,0,0,[
|
||||
mini_line(140,14,3,0,0,0,[
|
||||
str_block(0,140,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,140,14,3,0,-1,0,0,0,0,0,
|
||||
"Node::ProtocolHandlers")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',261,541,398,574,0,1,1,2,16,542,0,0,0,0,'1',0,[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
236,596,327,576],1,1,1,548,0,0,2,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',272,590,1,0,1,112,17,550,14,3,0,0,0,0,2,112,17,0,0,"",0,0,0,0,604,'',[
|
||||
minilines(112,17,0,0,0,0,0,[
|
||||
mini_line(112,14,3,0,0,0,[
|
||||
str_block(0,112,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,112,14,3,0,0,0,0,0,0,0,
|
||||
"m_receiveCallback")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
306,541,202,460],1,1,1,555,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
280,447,367,423],3,1,1,566,0,0,3,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',185,499,1,0,1,65,17,575,14,3,0,0,0,0,2,65,17,0,0,"",0,0,0,0,513,'',[
|
||||
minilines(65,17,0,0,0,0,0,[
|
||||
mini_line(65,14,3,0,0,0,[
|
||||
str_block(0,65,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,65,14,3,0,-1,0,0,0,0,0,
|
||||
"::Receive()")])
|
||||
])
|
||||
])]).
|
||||
text('black',315,438,1,0,1,135,17,585,14,3,0,0,0,0,2,135,17,0,0,"",0,0,0,0,452,'',[
|
||||
minilines(135,17,0,0,0,0,0,[
|
||||
mini_line(135,14,3,0,0,0,[
|
||||
str_block(0,135,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,135,14,3,0,-1,0,0,0,0,0,
|
||||
"::GetProtocol(protocol)")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
201,426,201,366],1,1,1,593,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',211,390,1,0,1,65,17,597,14,3,0,0,0,0,2,65,17,0,0,"",0,0,0,0,404,'',[
|
||||
minilines(65,17,0,0,0,0,0,[
|
||||
mini_line(65,14,3,0,0,0,[
|
||||
str_block(0,65,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,65,14,3,0,-1,0,0,0,0,0,
|
||||
"::Receive()")])
|
||||
])
|
||||
])]).
|
||||
text('black',480,291,6,0,1,438,102,612,14,3,0,0,0,0,2,438,102,0,0,"",0,0,0,0,305,'',[
|
||||
minilines(438,102,0,0,0,0,0,[
|
||||
mini_line(293,14,3,0,0,0,[
|
||||
str_block(0,293,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,293,14,3,0,0,0,0,0,0,0,
|
||||
"5. UdpL4Protocol is where the socket-independent")])
|
||||
]),
|
||||
mini_line(428,14,3,0,0,0,[
|
||||
str_block(0,428,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,428,14,3,0,0,0,0,0,0,0,
|
||||
"protocol logic for UDP is implemented. The Receive() method removes the")])
|
||||
]),
|
||||
mini_line(420,14,3,0,0,0,[
|
||||
str_block(0,420,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,420,14,3,0,0,0,0,0,0,0,
|
||||
"UDP header and looks up the per-flow context state, which is one or more")])
|
||||
]),
|
||||
mini_line(438,14,3,0,0,0,[
|
||||
str_block(0,438,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,438,14,3,0,-1,0,0,0,0,0,
|
||||
"Ipv4EndPoint objects stored in an Ipv4EndPointDemux (indexed by src addr,")])
|
||||
]),
|
||||
mini_line(405,14,3,0,0,0,[
|
||||
str_block(0,405,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,405,14,3,0,-1,0,0,0,0,0,
|
||||
"src port, dest addr, dest port). It then calls Ipv4EndPoint::ForwardUp()")])
|
||||
]),
|
||||
mini_line(66,14,3,0,0,0,[
|
||||
str_block(0,66,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,66,14,3,0,-1,0,0,0,0,0,
|
||||
"when done.")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
201,331,201,271],1,1,1,619,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',211,295,1,0,1,85,17,620,14,3,0,0,0,0,2,85,17,0,0,"",0,0,0,0,309,'',[
|
||||
minilines(85,17,0,0,0,0,0,[
|
||||
mini_line(85,14,3,0,0,0,[
|
||||
str_block(0,85,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,85,14,3,0,-1,0,0,0,0,0,
|
||||
"::ForwardUp()")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
282,335,369,311],3,1,1,630,0,0,3,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',317,326,1,0,1,62,17,631,14,3,0,0,0,0,2,62,17,0,0,"",0,0,0,0,340,'',[
|
||||
minilines(62,17,0,0,0,0,0,[
|
||||
mini_line(62,14,3,0,0,0,[
|
||||
str_block(0,62,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,62,14,3,0,-1,0,0,0,0,0,
|
||||
"::Lookup()")])
|
||||
])
|
||||
])]).
|
||||
text('black',211,208,1,0,1,181,17,650,14,3,0,0,0,0,2,181,17,0,0,"",0,0,0,0,222,'',[
|
||||
minilines(181,17,0,0,0,0,0,[
|
||||
mini_line(181,14,3,0,0,0,[
|
||||
str_block(0,181,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,181,14,3,0,-1,0,0,0,0,0,
|
||||
"(m_rxCallback)->ForwardUp()")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
201,233,201,196],1,1,1,652,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',211,138,1,0,1,144,17,656,14,3,0,0,0,0,2,144,17,0,0,"",0,0,0,0,152,'',[
|
||||
minilines(144,17,0,0,0,0,0,[
|
||||
mini_line(144,14,3,0,0,0,[
|
||||
str_block(0,144,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,144,14,3,0,-1,0,0,0,0,0,
|
||||
"(m_rxCallback)->Recv()")])
|
||||
])
|
||||
])]).
|
||||
text('black',149,17,1,0,1,321,21,683,17,4,0,0,0,0,2,321,21,0,0,"",0,0,0,0,34,'',[
|
||||
minilines(321,21,0,0,0,0,0,[
|
||||
mini_line(321,17,4,0,0,0,[
|
||||
str_block(0,321,17,4,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,103680,321,17,4,0,0,0,0,0,0,0,
|
||||
"Function/object trace for receiving a packet")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
199,163,199,126],1,1,1,691,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
group([
|
||||
text('black',311,280,1,0,1,120,17,484,14,3,0,0,0,0,2,120,17,0,0,"",0,0,0,0,294,'',[
|
||||
minilines(120,17,0,0,0,0,0,[
|
||||
mini_line(120,14,3,0,0,0,[
|
||||
str_block(0,120,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,120,14,3,0,0,0,0,0,0,0,
|
||||
"Ipv4EndPointDemux")])
|
||||
])
|
||||
])]),
|
||||
polygon('black','',6,[
|
||||
309,276,324,305,419,305,439,277,309,277,309,276],0,1,1,0,485,0,0,0,0,0,'1',0,
|
||||
"00",[
|
||||
])
|
||||
],
|
||||
704,0,0,[
|
||||
]).
|
||||
text('black',480,190,3,0,1,363,51,708,14,3,0,0,0,0,2,363,51,0,0,"",0,0,0,0,204,'',[
|
||||
minilines(363,51,0,0,0,0,0,[
|
||||
mini_line(363,14,3,0,0,0,[
|
||||
str_block(0,363,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,363,14,3,0,-1,0,0,0,0,0,
|
||||
"6. Ipv4EndPoint has a callback where a Socket object is able to")])
|
||||
]),
|
||||
mini_line(304,14,3,0,0,0,[
|
||||
str_block(0,304,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,304,14,3,0,-1,0,0,0,0,0,
|
||||
"register a receive method. Here, this callback calls to")])
|
||||
]),
|
||||
mini_line(175,14,3,0,0,0,[
|
||||
str_block(0,175,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,175,14,3,0,-1,0,0,0,0,0,
|
||||
"UdpSocketImpl::ForwardUp()")])
|
||||
])
|
||||
])]).
|
||||
text('black',480,106,3,0,1,446,51,712,14,3,0,0,0,0,2,446,51,0,0,"",0,0,0,0,120,'',[
|
||||
minilines(446,51,0,0,0,0,0,[
|
||||
mini_line(407,14,3,0,0,0,[
|
||||
str_block(0,407,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,407,14,3,0,0,0,0,0,0,0,
|
||||
"7. UdpSocketImpl itself calls the Recv() callback set by the Application")])
|
||||
]),
|
||||
mini_line(402,14,3,0,0,0,[
|
||||
str_block(0,402,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,402,14,3,0,0,0,0,0,0,0,
|
||||
"when data is ready to be read. The application can then call the socket")])
|
||||
]),
|
||||
mini_line(446,14,3,0,0,0,[
|
||||
str_block(0,446,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,446,14,3,0,-1,0,0,0,0,0,
|
||||
"Recv() or RecvFrom() methods to read data (or dummy data) from the socket.")])
|
||||
])
|
||||
])]).
|
||||
group([
|
||||
text('black',308,393,1,0,1,96,17,772,14,3,0,0,0,0,2,96,17,0,0,"",0,0,0,0,407,'',[
|
||||
minilines(96,17,0,0,0,0,0,[
|
||||
mini_line(96,14,3,0,0,0,[
|
||||
str_block(0,96,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,96,14,3,0,0,0,0,0,0,0,
|
||||
" Ipv4L4Demux")])
|
||||
])
|
||||
])]),
|
||||
polygon('black','',6,[
|
||||
306,389,321,418,416,418,436,390,306,390,306,389],0,1,1,0,771,0,0,0,0,0,'1',0,
|
||||
"00",[
|
||||
])
|
||||
],
|
||||
770,0,0,[
|
||||
]).
|
||||
@@ -0,0 +1,352 @@
|
||||
%TGIF 4.1.43-QPL
|
||||
state(0,37,100.000,83,0,0,16,0,9,1,1,0,0,3,2,1,0,'Times-Roman',0,80640,0,3,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0).
|
||||
%
|
||||
% @(#)$Header$
|
||||
% %W%
|
||||
%
|
||||
unit("1 pixel/pixel").
|
||||
color_info(11,65535,0,[
|
||||
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
|
||||
"red", 65535, 0, 0, 65535, 0, 0, 1,
|
||||
"green", 0, 65535, 0, 0, 65535, 0, 1,
|
||||
"blue", 0, 0, 65535, 0, 0, 65535, 1,
|
||||
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
|
||||
"pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
|
||||
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
|
||||
"CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
|
||||
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
|
||||
"black", 0, 0, 0, 0, 0, 0, 1,
|
||||
"DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1
|
||||
]).
|
||||
script_frac("0.6").
|
||||
fg_bg_colors('black','white').
|
||||
dont_reencode("FFDingbests:ZapfDingbats").
|
||||
page(1,"",1,'').
|
||||
group([
|
||||
rcbox('black','',158,451,238,499,2,1,1,0,16,125,0,0,0,0,'1',0,[
|
||||
]),
|
||||
text('black',158,470,1,0,1,72,18,124,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,483,'',[
|
||||
minilines(72,18,0,0,0,0,0,[
|
||||
mini_line(72,13,5,0,0,0,[
|
||||
str_block(0,72,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0,
|
||||
"NetDevice")])
|
||||
])
|
||||
])])
|
||||
],
|
||||
141,0,0,[
|
||||
]).
|
||||
group([
|
||||
rcbox('black','',147,77,255,125,2,1,1,0,16,354,0,0,0,0,'1',0,[
|
||||
]),
|
||||
text('black',163,96,1,0,1,88,18,353,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,109,'',[
|
||||
minilines(88,18,0,0,0,0,0,[
|
||||
mini_line(88,13,5,0,0,0,[
|
||||
str_block(0,88,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0,
|
||||
"Application")])
|
||||
])
|
||||
])])
|
||||
],
|
||||
352,0,0,[
|
||||
]).
|
||||
text('black',202,172,1,1,1,90,17,473,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,186,'',[
|
||||
minilines(90,17,0,0,1,0,0,[
|
||||
mini_line(90,14,3,0,0,0,[
|
||||
str_block(0,90,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0,
|
||||
"UdpSocketImpl")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',132,165,269,198,0,1,1,0,16,474,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',202,241,1,1,1,88,17,475,14,3,2,0,0,0,2,88,17,0,0,"",0,0,0,0,255,'',[
|
||||
minilines(88,17,0,0,1,0,0,[
|
||||
mini_line(88,14,3,0,0,0,[
|
||||
str_block(0,88,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0,
|
||||
"UdpL4Protocol")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',132,234,269,267,0,1,1,0,16,476,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',201,317,1,1,1,90,17,490,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,331,'',[
|
||||
minilines(90,17,0,0,1,0,0,[
|
||||
mini_line(90,14,3,0,0,0,[
|
||||
str_block(0,90,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0,
|
||||
"Ipv4L3Protocol")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',131,310,268,343,0,1,1,0,16,491,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',540,56,1,0,1,180,17,496,14,3,0,0,0,0,2,180,17,0,0,"",0,0,0,0,70,'',[
|
||||
minilines(180,17,0,0,0,0,0,[
|
||||
mini_line(180,14,3,0,0,0,[
|
||||
str_block(0,180,14,3,0,-2,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,180,14,3,0,-2,1,0,0,0,0,
|
||||
"Step in packet sending process:")])
|
||||
])
|
||||
])]).
|
||||
text('black',480,420,4,0,1,460,68,524,14,3,0,0,0,0,2,460,68,0,0,"",0,0,0,0,434,'',[
|
||||
minilines(460,68,0,0,0,0,0,[
|
||||
mini_line(457,14,3,0,0,0,[
|
||||
str_block(0,457,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,457,14,3,0,0,0,0,0,0,0,
|
||||
"5. Ipv4Interface is an abstract base class; here, we depict the ArpIpv4Interface")])
|
||||
]),
|
||||
mini_line(460,14,3,0,0,0,[
|
||||
str_block(0,460,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,460,14,3,0,-1,0,0,0,0,0,
|
||||
"concrete class. This object looks up the MAC address if Arp is supported on this")])
|
||||
]),
|
||||
mini_line(454,14,3,0,0,0,[
|
||||
str_block(0,454,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,454,14,3,0,0,0,0,0,0,0,
|
||||
"NetDevice technology, and if there is a cache hit, it sends it to the NetDevice, or")])
|
||||
]),
|
||||
mini_line(197,14,3,0,0,0,[
|
||||
str_block(0,197,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,197,14,3,0,-1,0,0,0,0,0,
|
||||
"else it first initiates an Arp request.")])
|
||||
])
|
||||
])]).
|
||||
text('black',479,354,3,0,1,476,51,531,14,3,0,0,0,0,2,476,51,0,0,"",0,0,0,0,368,'',[
|
||||
minilines(476,51,0,0,0,0,0,[
|
||||
mini_line(469,14,3,0,0,0,[
|
||||
str_block(0,469,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,469,14,3,0,0,0,0,0,0,0,
|
||||
"4. Ipv4L3Protocol adds the IP header, looks up a route, and sends the packet to an")])
|
||||
]),
|
||||
mini_line(476,14,3,0,0,0,[
|
||||
str_block(0,476,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,476,14,3,0,-1,0,0,0,0,0,
|
||||
"appropriate Ipv4Interface instance. In this example, the device is one that supports")])
|
||||
]),
|
||||
mini_line(322,14,3,0,0,0,[
|
||||
str_block(0,322,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,322,14,3,0,-1,0,0,0,0,0,
|
||||
"Arp, so the packet is sent to an ArpIpv4Interface object.")])
|
||||
])
|
||||
])]).
|
||||
text('black',478,261,4,0,1,437,68,612,14,3,0,0,0,0,2,437,68,0,0,"",0,0,0,0,275,'',[
|
||||
minilines(437,68,0,0,0,0,0,[
|
||||
mini_line(293,14,3,0,0,0,[
|
||||
str_block(0,293,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,293,14,3,0,0,0,0,0,0,0,
|
||||
"3. UdpL4Protocol is where the socket-independent")])
|
||||
]),
|
||||
mini_line(387,14,3,0,0,0,[
|
||||
str_block(0,387,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,387,14,3,0,0,0,0,0,0,0,
|
||||
"protocol logic for UDP is implemented. The Send() method adds the")])
|
||||
]),
|
||||
mini_line(437,14,3,0,0,0,[
|
||||
str_block(0,437,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,437,14,3,0,-1,0,0,0,0,0,
|
||||
"UDP header, initializes the checksum, and sends the packet to the Ipv4 layer.")])
|
||||
]),
|
||||
mini_line(431,14,3,0,0,0,[
|
||||
str_block(0,431,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,431,14,3,0,-1,0,0,0,0,0,
|
||||
"Here, the Ipv4L3Protocol object is queried, and the Send() method is called.")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
201,308,201,271],2,1,1,619,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',208,278,1,0,1,47,17,620,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,292,'',[
|
||||
minilines(47,17,0,0,0,0,0,[
|
||||
mini_line(47,14,3,0,0,0,[
|
||||
str_block(0,47,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0,
|
||||
"::Send()")])
|
||||
])
|
||||
])]).
|
||||
text('black',211,208,1,0,1,47,17,650,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,222,'',[
|
||||
minilines(47,17,0,0,0,0,0,[
|
||||
mini_line(47,14,3,0,0,0,[
|
||||
str_block(0,47,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0,
|
||||
"::Send()")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
201,233,201,196],2,1,1,652,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',211,138,1,0,1,87,17,656,14,3,0,0,0,0,2,87,17,0,0,"",0,0,0,0,152,'',[
|
||||
minilines(87,17,0,0,0,0,0,[
|
||||
mini_line(87,14,3,0,0,0,[
|
||||
str_block(0,87,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,87,14,3,0,-1,0,0,0,0,0,
|
||||
"Socket::Send()")])
|
||||
])
|
||||
])]).
|
||||
text('black',149,17,1,0,1,310,21,683,17,4,0,0,0,0,2,310,21,0,0,"",0,0,0,0,34,'',[
|
||||
minilines(310,21,0,0,0,0,0,[
|
||||
mini_line(310,17,4,0,0,0,[
|
||||
str_block(0,310,17,4,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,103680,310,17,4,0,0,0,0,0,0,0,
|
||||
"Function/object trace for sending a packet")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
199,163,199,126],2,1,1,691,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',480,153,6,0,1,524,102,708,14,3,0,0,0,0,2,524,102,0,0,"",0,0,0,0,167,'',[
|
||||
minilines(524,102,0,0,0,0,0,[
|
||||
mini_line(399,14,3,0,0,0,[
|
||||
str_block(0,399,14,3,0,-2,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,399,14,3,0,-2,0,0,0,0,0,
|
||||
"2. Socket::Send() forwards to UdpSocketImpl::DoSend() and later to ")])
|
||||
]),
|
||||
mini_line(173,14,3,0,0,0,[
|
||||
str_block(0,173,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,173,14,3,0,-1,0,0,0,0,0,
|
||||
"UdpSocketImpl::DoSendTo().")])
|
||||
]),
|
||||
mini_line(479,14,3,0,0,0,[
|
||||
str_block(0,479,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,479,14,3,0,-1,0,0,0,0,0,
|
||||
"These functions set the proper source and destination addresses, handle socket calls")])
|
||||
]),
|
||||
mini_line(524,14,3,0,0,0,[
|
||||
str_block(0,524,14,3,0,-2,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,524,14,3,0,-2,0,0,0,0,0,
|
||||
"such as bind() and connect() and then the UdpL4Protocol::Send() function is called. As in a ")])
|
||||
]),
|
||||
mini_line(505,14,3,0,0,0,[
|
||||
str_block(0,505,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,505,14,3,0,-1,0,0,0,0,0,
|
||||
"real implementation, the socket must query the Ipv4 layer to find the right source address")])
|
||||
]),
|
||||
mini_line(187,14,3,0,0,0,[
|
||||
str_block(0,187,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,187,14,3,0,-1,0,0,0,0,0,
|
||||
"to match the destination address.")])
|
||||
])
|
||||
])]).
|
||||
text('black',480,106,2,0,1,434,34,712,14,3,0,0,0,0,2,434,34,0,0,"",0,0,0,0,120,'',[
|
||||
minilines(434,34,0,0,0,0,0,[
|
||||
mini_line(413,14,3,0,0,0,[
|
||||
str_block(0,413,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,413,14,3,0,-1,0,0,0,0,0,
|
||||
"1. The Application has previously created a socket (here, a UdpSocket).")])
|
||||
]),
|
||||
mini_line(434,14,3,0,0,0,[
|
||||
str_block(0,434,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,434,14,3,0,-1,0,0,0,0,0,
|
||||
"It calls Socket::Send(). Either real data or dummy data is passed at the API.")])
|
||||
])
|
||||
])]).
|
||||
text('black',377,315,1,1,1,60,17,774,14,3,2,0,0,0,2,60,17,0,0,"",0,0,0,0,329,'',[
|
||||
minilines(60,17,0,0,1,0,0,[
|
||||
mini_line(60,14,3,0,0,0,[
|
||||
str_block(0,60,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,60,14,3,0,0,0,0,0,0,0,
|
||||
"Ipv4Route")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',307,308,444,341,0,1,1,0,16,775,0,0,0,0,'1',0,[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
267,325,304,325],3,1,1,787,0,0,3,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',278,299,1,0,1,62,17,796,14,3,2,0,0,0,2,62,17,0,0,"",0,0,0,0,313,'',[
|
||||
minilines(62,17,0,0,0,0,0,[
|
||||
mini_line(62,14,3,0,0,0,[
|
||||
str_block(0,62,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,62,14,3,0,-1,0,0,0,0,0,
|
||||
"::Lookup()")])
|
||||
])
|
||||
])]).
|
||||
text('black',200,385,1,1,1,102,17,803,14,3,2,0,0,0,2,102,17,0,0,"",0,0,0,0,399,'',[
|
||||
minilines(102,17,0,0,1,0,0,[
|
||||
mini_line(102,14,3,0,0,0,[
|
||||
str_block(0,102,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,102,14,3,0,0,0,0,0,0,0,
|
||||
"ArpIpv4Interface")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',130,378,267,411,0,1,1,0,16,804,0,0,0,0,'1',0,[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
199,380,199,343],2,1,1,810,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',206,350,1,0,1,47,17,811,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,364,'',[
|
||||
minilines(47,17,0,0,0,0,0,[
|
||||
mini_line(47,14,3,0,0,0,[
|
||||
str_block(0,47,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0,
|
||||
"::Send()")])
|
||||
])
|
||||
])]).
|
||||
text('black',378,388,1,1,1,71,17,817,14,3,2,0,0,0,2,71,17,0,0,"",0,0,0,0,402,'',[
|
||||
minilines(71,17,0,0,1,0,0,[
|
||||
mini_line(71,14,3,0,0,0,[
|
||||
str_block(0,71,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,71,14,3,0,0,0,0,0,0,0,
|
||||
"ArpProtocol")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',308,381,445,414,0,1,1,0,16,818,0,0,0,0,'1',0,[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
268,398,305,398],3,1,1,819,0,0,3,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',279,372,1,0,1,62,17,820,14,3,2,0,0,0,2,62,17,0,0,"",0,0,0,0,386,'',[
|
||||
minilines(62,17,0,0,0,0,0,[
|
||||
mini_line(62,14,3,0,0,0,[
|
||||
str_block(0,62,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,62,14,3,0,-1,0,0,0,0,0,
|
||||
"::Lookup()")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
199,448,199,411],2,1,1,837,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',206,418,1,0,1,47,17,838,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,432,'',[
|
||||
minilines(47,17,0,0,0,0,0,[
|
||||
mini_line(47,14,3,0,0,0,[
|
||||
str_block(0,47,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0,
|
||||
"::Send()")])
|
||||
])
|
||||
])]).
|
||||
text('black',371,173,1,1,1,26,17,842,14,3,2,0,0,0,2,26,17,0,0,"",0,0,0,0,187,'',[
|
||||
minilines(26,17,0,0,1,0,0,[
|
||||
mini_line(26,14,3,0,0,0,[
|
||||
str_block(0,26,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,26,14,3,0,-1,0,0,0,0,0,
|
||||
"Ipv4")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',301,166,438,199,0,1,1,0,16,843,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',272,157,1,0,1,148,17,844,14,3,2,0,0,0,2,148,17,0,0,"",0,0,0,0,171,'',[
|
||||
minilines(148,17,0,0,0,0,0,[
|
||||
mini_line(148,14,3,0,0,0,[
|
||||
str_block(0,148,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,148,14,3,0,-1,0,0,0,0,0,
|
||||
"::GetAddress(outgoing if)")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
269,182,306,182],3,1,1,846,0,0,3,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
@@ -0,0 +1,211 @@
|
||||
%TGIF 4.1.43-QPL
|
||||
state(0,37,100.000,0,0,0,16,0,9,1,1,0,0,3,2,1,0,'Times-Italic',2,80640,0,8,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0).
|
||||
%
|
||||
% @(#)$Header$
|
||||
% %W%
|
||||
%
|
||||
unit("1 pixel/pixel").
|
||||
color_info(11,65535,0,[
|
||||
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
|
||||
"red", 65535, 0, 0, 65535, 0, 0, 1,
|
||||
"green", 0, 65535, 0, 0, 65535, 0, 1,
|
||||
"blue", 0, 0, 65535, 0, 0, 65535, 1,
|
||||
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
|
||||
"pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
|
||||
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
|
||||
"CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
|
||||
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
|
||||
"black", 0, 0, 0, 0, 0, 0, 1,
|
||||
"DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1
|
||||
]).
|
||||
script_frac("0.6").
|
||||
fg_bg_colors('black','white').
|
||||
dont_reencode("FFDingbests:ZapfDingbats").
|
||||
page(1,"",1,'').
|
||||
rcbox('black','',64,64,400,384,0,1,1,0,16,0,0,0,0,0,'1',0,[
|
||||
]).
|
||||
box('black','',280,432,555,464,0,1,1,17,0,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',384,435,1,0,1,56,18,18,13,5,0,0,0,0,2,56,18,0,0,"",0,0,0,0,448,'',[
|
||||
minilines(56,18,0,0,0,0,0,[
|
||||
mini_line(56,13,5,0,0,0,[
|
||||
str_block(0,56,13,5,0,-1,0,0,0,[
|
||||
str_seg('black','Courier-Bold',1,80640,56,13,5,0,-1,0,0,0,0,0,
|
||||
"Channel")])
|
||||
])
|
||||
])]).
|
||||
text('black',76,42,1,0,1,208,18,108,13,5,2,0,0,0,2,208,18,0,0,"",0,0,0,0,55,'',[
|
||||
minilines(208,18,0,0,0,0,0,[
|
||||
mini_line(208,13,5,0,0,0,[
|
||||
str_block(0,208,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier-Bold',1,80640,208,13,5,0,0,0,0,0,0,0,
|
||||
"class Node : public Object")])
|
||||
])
|
||||
])]).
|
||||
group([
|
||||
rcbox('black','',112,304,192,352,2,1,1,0,16,134,0,0,0,0,'1',0,[
|
||||
]),
|
||||
text('black',112,323,1,0,1,72,18,135,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,336,'',[
|
||||
minilines(72,18,0,0,0,0,0,[
|
||||
mini_line(72,13,5,0,0,0,[
|
||||
str_block(0,72,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0,
|
||||
"NetDevice")])
|
||||
])
|
||||
])])
|
||||
],
|
||||
138,0,0,[
|
||||
]).
|
||||
group([
|
||||
rcbox('black','',266,304,346,352,2,1,1,0,16,125,0,0,0,0,'1',0,[
|
||||
]),
|
||||
text('black',266,323,1,0,1,72,18,124,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,336,'',[
|
||||
minilines(72,18,0,0,0,0,0,[
|
||||
mini_line(72,13,5,0,0,0,[
|
||||
str_block(0,72,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0,
|
||||
"NetDevice")])
|
||||
])
|
||||
])])
|
||||
],
|
||||
141,0,0,[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
304,351,304,430],3,1,1,167,0,2,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',219,304,1,0,1,24,37,177,30,7,2,0,0,0,2,24,37,0,0,"",0,0,0,0,334,'',[
|
||||
minilines(24,37,0,0,0,0,0,[
|
||||
mini_line(24,30,7,0,0,0,[
|
||||
str_block(0,24,30,7,0,-2,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,195840,24,30,7,0,-2,0,0,0,0,0,
|
||||
"...")])
|
||||
])
|
||||
])]).
|
||||
text('black',220,98,1,0,1,24,37,182,30,7,2,0,0,0,2,24,37,0,0,"",0,0,0,0,128,'',[
|
||||
minilines(24,37,0,0,0,0,0,[
|
||||
mini_line(24,30,7,0,0,0,[
|
||||
str_block(0,24,30,7,0,-2,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,195840,24,30,7,0,-2,0,0,0,0,0,
|
||||
"...")])
|
||||
])
|
||||
])]).
|
||||
text('black',420,116,2,0,1,136,36,183,13,5,2,0,0,0,2,136,36,0,0,"",0,0,0,0,129,'',[
|
||||
minilines(136,36,0,0,0,0,0,[
|
||||
mini_line(136,13,5,0,0,0,[
|
||||
str_block(0,136,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier-Bold',1,80640,136,13,5,0,0,0,0,0,0,0,
|
||||
"Unix-like C-based")])
|
||||
]),
|
||||
mini_line(80,13,5,0,0,0,[
|
||||
str_block(0,80,13,5,0,-1,0,0,0,[
|
||||
str_seg('black','Courier-Bold',1,80640,80,13,5,0,-1,0,0,0,0,0,
|
||||
"socket API")])
|
||||
])
|
||||
])]).
|
||||
text('black',414,212,3,0,1,232,54,198,13,5,2,0,0,0,2,232,54,0,0,"",0,0,0,0,225,'',[
|
||||
minilines(232,54,0,0,0,0,0,[
|
||||
mini_line(112,13,5,0,0,0,[
|
||||
str_block(0,112,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier-Bold',1,80640,112,13,5,0,0,0,0,0,0,0,
|
||||
"Callback-based")])
|
||||
]),
|
||||
mini_line(176,13,5,0,0,0,[
|
||||
str_block(0,176,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier-Bold',1,80640,176,13,5,0,0,0,0,0,0,0,
|
||||
"protocol demultiplexer")])
|
||||
]),
|
||||
mini_line(232,13,5,0,0,0,[
|
||||
str_block(0,8,13,5,0,-1,0,0,0,[
|
||||
str_seg('black','Courier-Bold',1,80640,8,13,5,0,-1,0,0,0,0,0,
|
||||
"(")]),
|
||||
str_block(0,216,13,3,0,-2,0,0,0,[
|
||||
str_seg('black','Courier-Oblique',2,80640,216,13,3,0,-2,0,0,0,0,0,
|
||||
"list of ProtocolHandlers")]),
|
||||
str_block(0,8,13,5,0,-2,0,0,0,[
|
||||
str_seg('black','Courier-Bold',1,80640,8,13,5,0,-2,0,0,0,0,0,
|
||||
")")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
410,231,222,259],1,1,1,200,0,2,2,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
box('black','',56,401,229,433,0,1,1,250,0,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',119,409,1,0,1,56,18,251,13,5,0,0,0,0,2,56,18,0,0,"",0,0,0,0,422,'',[
|
||||
minilines(56,18,0,0,0,0,0,[
|
||||
mini_line(56,13,5,0,0,0,[
|
||||
str_block(0,56,13,5,0,-1,0,0,0,[
|
||||
str_seg('black','Courier-Bold',1,80640,56,13,5,0,-1,0,0,0,0,0,
|
||||
"Channel")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
154,353,154,400],3,1,1,254,0,2,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
group([
|
||||
rcbox('black','',98,96,206,144,2,1,1,0,16,1,0,0,0,0,'1',0,[
|
||||
]),
|
||||
text('black',114,115,1,0,1,88,18,2,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,128,'',[
|
||||
minilines(88,18,0,0,0,0,0,[
|
||||
mini_line(88,13,5,0,0,0,[
|
||||
str_block(0,88,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0,
|
||||
"Application")])
|
||||
])
|
||||
])])
|
||||
],
|
||||
348,0,0,[
|
||||
]).
|
||||
group([
|
||||
rcbox('black','',257,96,365,144,2,1,1,0,16,354,0,0,0,0,'1',0,[
|
||||
]),
|
||||
text('black',273,115,1,0,1,88,18,353,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,128,'',[
|
||||
minilines(88,18,0,0,0,0,0,[
|
||||
mini_line(88,13,5,0,0,0,[
|
||||
str_block(0,88,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0,
|
||||
"Application")])
|
||||
])
|
||||
])])
|
||||
],
|
||||
352,0,0,[
|
||||
]).
|
||||
text('black',155,73,1,0,1,110,18,426,14,4,2,0,0,0,2,110,18,0,0,"",0,0,0,0,87,'',[
|
||||
minilines(110,18,0,0,0,0,0,[
|
||||
mini_line(110,14,4,0,0,0,[
|
||||
str_block(0,110,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Italic',2,80640,110,14,4,0,-1,0,0,0,0,0,
|
||||
"list of Applications")])
|
||||
])
|
||||
])]).
|
||||
text('black',161,357,1,0,1,106,18,443,14,4,2,0,0,0,2,106,18,0,0,"",0,0,0,0,371,'',[
|
||||
minilines(106,18,0,0,0,0,0,[
|
||||
mini_line(106,14,4,0,0,0,[
|
||||
str_block(0,106,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Italic',2,80640,106,14,4,0,-1,0,0,0,0,0,
|
||||
"list of NetDevices")])
|
||||
])
|
||||
])]).
|
||||
text('black',79,194,2,0,1,55,36,482,14,4,2,0,0,0,2,55,36,0,0,"",0,0,0,0,208,'',[
|
||||
minilines(55,36,0,0,0,0,0,[
|
||||
mini_line(53,14,4,0,0,0,[
|
||||
str_block(0,53,14,4,0,0,0,0,0,[
|
||||
str_seg('black','Times-Italic',2,80640,53,14,4,0,0,0,0,0,0,0,
|
||||
"unique id")])
|
||||
]),
|
||||
mini_line(55,14,4,0,0,0,[
|
||||
str_block(0,55,14,4,0,0,0,0,0,[
|
||||
str_seg('black','Times-Italic',2,80640,55,14,4,0,0,0,0,0,0,0,
|
||||
"system id")])
|
||||
])
|
||||
])]).
|
||||
polygon('black','',7,[
|
||||
158,271,305,271,288,291,173,291,159,273,160,273,158,271],2,1,1,0,493,8,0,0,0,0,'1',0,
|
||||
"00",[
|
||||
]).
|
||||
@@ -0,0 +1,227 @@
|
||||
%TGIF 4.1.43-QPL
|
||||
state(0,37,100.000,0,64,0,32,0,9,1,1,1,0,0,0,1,0,'Courier-Bold',1,103680,0,3,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0).
|
||||
%
|
||||
% @(#)$Header$
|
||||
% %W%
|
||||
%
|
||||
unit("1 pixel/pixel").
|
||||
color_info(11,65535,0,[
|
||||
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
|
||||
"red", 65535, 0, 0, 65535, 0, 0, 1,
|
||||
"green", 0, 65535, 0, 0, 65535, 0, 1,
|
||||
"blue", 0, 0, 65535, 0, 0, 65535, 1,
|
||||
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
|
||||
"pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
|
||||
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
|
||||
"CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
|
||||
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
|
||||
"black", 0, 0, 0, 0, 0, 0, 1,
|
||||
"DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1
|
||||
]).
|
||||
script_frac("0.6").
|
||||
fg_bg_colors('black','white').
|
||||
dont_reencode("FFDingbests:ZapfDingbats").
|
||||
page(1,"",1,'').
|
||||
box('black','',32,48,240,256,0,3,1,0,0,0,0,0,0,'3',0,[
|
||||
]).
|
||||
text('black',64,10,1,0,1,121,28,3,22,6,0,0,0,0,2,121,28,0,0,"",0,0,0,0,32,'',[
|
||||
minilines(121,28,0,0,0,0,0,[
|
||||
mini_line(121,22,6,0,0,0,[
|
||||
str_block(0,121,22,6,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,138240,121,22,6,0,0,0,0,0,0,0,
|
||||
"class Packet")])
|
||||
])
|
||||
])]).
|
||||
text('black',416,100,1,0,1,116,28,15,22,6,0,0,0,0,2,116,28,0,0,"",0,0,0,0,122,'',[
|
||||
minilines(116,28,0,0,0,0,0,[
|
||||
mini_line(116,22,6,0,0,0,[
|
||||
str_block(0,116,22,6,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,138240,116,22,6,0,0,0,0,0,0,0,
|
||||
"class Buffer")])
|
||||
])
|
||||
])]).
|
||||
text('black',48,178,4,0,1,83,69,32,14,4,0,0,0,0,2,83,69,0,0,"",0,0,0,0,192,'',[
|
||||
minilines(83,69,0,0,0,0,0,[
|
||||
mini_line(80,14,4,0,0,0,[
|
||||
str_block(0,80,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
|
||||
"private data:")])
|
||||
]),
|
||||
mini_line(59,14,3,0,0,0,[
|
||||
str_block(0,59,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,59,14,3,0,0,0,0,0,0,0,
|
||||
"- unique id")])
|
||||
]),
|
||||
mini_line(83,14,3,0,0,0,[
|
||||
str_block(0,83,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,83,14,3,0,0,0,0,0,0,0,
|
||||
"- Buffer object")])
|
||||
]),
|
||||
mini_line(76,14,3,0,0,0,[
|
||||
str_block(0,76,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,76,14,3,0,0,0,0,0,0,0,
|
||||
"- Tags object")])
|
||||
])
|
||||
])]).
|
||||
text('black',112,288,1,0,1,103,28,82,22,6,0,0,0,0,2,103,28,0,0,"",0,0,0,0,310,'',[
|
||||
minilines(103,28,0,0,0,0,0,[
|
||||
mini_line(103,22,6,0,0,0,[
|
||||
str_block(0,103,22,6,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,138240,103,22,6,0,-1,0,0,0,0,0,
|
||||
"class Tags")])
|
||||
])
|
||||
])]).
|
||||
text('black',48,50,5,0,1,175,86,176,14,4,0,0,0,0,2,175,86,0,0,"",0,0,0,0,64,'',[
|
||||
minilines(175,86,0,0,0,0,0,[
|
||||
mini_line(105,14,4,0,0,0,[
|
||||
str_block(0,105,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
|
||||
"public functions:")])
|
||||
]),
|
||||
mini_line(80,14,3,0,0,0,[
|
||||
str_block(0,80,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0,
|
||||
"- constructors")])
|
||||
]),
|
||||
mini_line(175,14,3,0,0,0,[
|
||||
str_block(0,175,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,175,14,3,0,-1,0,0,0,0,0,
|
||||
"- add/remove/peek at Headers")])
|
||||
]),
|
||||
mini_line(155,14,3,0,0,0,[
|
||||
str_block(0,155,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0,
|
||||
"- add/remove/peek at Tags")])
|
||||
]),
|
||||
mini_line(88,14,3,0,0,0,[
|
||||
str_block(0,88,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0,
|
||||
"- fragmentation")])
|
||||
])
|
||||
])]).
|
||||
box('black','',384,144,614,352,0,3,1,245,0,0,0,0,0,'3',0,[
|
||||
]).
|
||||
text('black',400,274,4,0,1,204,69,246,14,4,0,0,0,0,2,204,69,0,0,"",0,0,0,0,288,'',[
|
||||
minilines(204,69,0,0,0,0,0,[
|
||||
mini_line(80,14,4,0,0,0,[
|
||||
str_block(0,80,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
|
||||
"private data:")])
|
||||
]),
|
||||
mini_line(193,14,3,0,0,0,[
|
||||
str_block(0,193,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,193,14,3,0,0,0,0,0,0,0,
|
||||
"- struct BufferData, a dynamically")])
|
||||
]),
|
||||
mini_line(160,14,3,0,0,0,[
|
||||
str_block(0,160,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,160,14,3,0,0,0,0,0,0,0,
|
||||
"varying byte buffer to which")])
|
||||
]),
|
||||
mini_line(204,14,3,0,0,0,[
|
||||
str_block(0,204,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,204,14,3,0,0,0,0,0,0,0,
|
||||
"data can be prepended or appended")])
|
||||
])
|
||||
])]).
|
||||
text('black',400,146,5,0,1,188,86,247,14,4,0,0,0,0,2,188,86,0,0,"",0,0,0,0,160,'',[
|
||||
minilines(188,86,0,0,0,0,0,[
|
||||
mini_line(105,14,4,0,0,0,[
|
||||
str_block(0,105,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
|
||||
"public functions:")])
|
||||
]),
|
||||
mini_line(172,14,3,0,0,0,[
|
||||
str_block(0,172,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,172,14,3,0,0,0,0,0,0,0,
|
||||
"- Iterators to move byte buffer")])
|
||||
]),
|
||||
mini_line(171,14,3,0,0,0,[
|
||||
str_block(0,171,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,171,14,3,0,0,0,0,0,0,0,
|
||||
"pointers forward or backward")])
|
||||
]),
|
||||
mini_line(188,14,3,0,0,0,[
|
||||
str_block(0,188,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,188,14,3,0,0,0,0,0,0,0,
|
||||
"- functions to read and write data")])
|
||||
]),
|
||||
mini_line(132,14,3,0,0,0,[
|
||||
str_block(0,132,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,132,14,3,0,-1,0,0,0,0,0,
|
||||
"of various sized chunks")])
|
||||
])
|
||||
])]).
|
||||
box('black','',96,324,304,532,0,3,1,264,0,0,0,0,0,'3',0,[
|
||||
]).
|
||||
text('black',112,454,4,0,1,167,69,265,14,4,0,0,0,0,2,167,69,0,0,"",0,0,0,0,468,'',[
|
||||
minilines(167,69,0,0,0,0,0,[
|
||||
mini_line(80,14,4,0,0,0,[
|
||||
str_block(0,80,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
|
||||
"private data:")])
|
||||
]),
|
||||
mini_line(167,14,3,0,0,0,[
|
||||
str_block(0,167,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,167,14,3,0,0,0,0,0,0,0,
|
||||
"- singly linked-list of TagData")])
|
||||
]),
|
||||
mini_line(158,14,3,0,0,0,[
|
||||
str_block(0,158,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,158,14,3,0,0,0,0,0,0,0,
|
||||
"structures, with a reference")])
|
||||
]),
|
||||
mini_line(32,14,3,0,0,0,[
|
||||
str_block(0,32,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,32,14,3,0,0,0,0,0,0,0,
|
||||
"count")])
|
||||
])
|
||||
])]).
|
||||
text('black',112,326,5,0,1,155,86,266,14,4,0,0,0,0,2,155,86,0,0,"",0,0,0,0,340,'',[
|
||||
minilines(155,86,0,0,0,0,0,[
|
||||
mini_line(105,14,4,0,0,0,[
|
||||
str_block(0,105,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
|
||||
"public functions:")])
|
||||
]),
|
||||
mini_line(80,14,3,0,0,0,[
|
||||
str_block(0,80,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0,
|
||||
"- constructors")])
|
||||
]),
|
||||
mini_line(155,14,3,0,0,0,[
|
||||
str_block(0,155,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0,
|
||||
"- templates to add, remove,")])
|
||||
]),
|
||||
mini_line(148,14,3,0,0,0,[
|
||||
str_block(0,148,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,148,14,3,0,-1,0,0,0,0,0,
|
||||
"or peek at Tags of various")])
|
||||
]),
|
||||
mini_line(31,14,3,0,0,0,[
|
||||
str_block(0,31,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,31,14,3,0,-1,0,0,0,0,0,
|
||||
"types")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
59,245,96,320],0,2,1,272,0,0,3,0,0,0,0,'2',0,0,
|
||||
"0","",[
|
||||
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
123,246,288,320],0,2,1,280,0,0,3,0,0,0,0,'2',0,0,
|
||||
"0","",[
|
||||
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
141,219,379,147],0,2,1,286,0,0,3,0,0,0,0,'2',0,0,
|
||||
"0","",[
|
||||
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
132,226,375,335],0,2,1,287,0,0,3,0,0,0,0,'2',0,0,
|
||||
"0","",[
|
||||
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
|
||||
]).
|
||||
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
@node Logging
|
||||
@chapter Logging
|
||||
@anchor{chap:Logging}
|
||||
|
||||
This chapter is the first in a series of chapters discussing things that
|
||||
one can do to modify the input or output of existing ns-3 scripts.
|
||||
|
||||
Examples:
|
||||
@itemize @bullet
|
||||
@item Enable or disable the generation of log messages, with fine granularity
|
||||
@item Set default values for configuration values in the system
|
||||
@item Generate a report of all configuration values used during a simulation
|
||||
run (not yet implemented)
|
||||
@item Set or get values of member variables on objects already instantiated
|
||||
@item Customizing the tracing output of the script
|
||||
@item Generate statistics on (not yet implemented)
|
||||
@item Perform a large number of independent runs of the same simulation
|
||||
@end itemize
|
||||
|
||||
@node Logging Basics
|
||||
@section Logging Basics
|
||||
|
||||
@node Enabling Log Output
|
||||
@section Enabling Log Output
|
||||
@@ -0,0 +1,156 @@
|
||||
body {
|
||||
font-family: "Trebuchet MS", "Bitstream Vera Sans", verdana, lucida, arial, helvetica, sans-serif;
|
||||
background: white;
|
||||
color: black;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
# color: #990000;
|
||||
color: #009999;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 10pt;
|
||||
background: #e0e0e0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
font-weight: normal;
|
||||
text-decoration: underline;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#main th {
|
||||
font-size: 12pt;
|
||||
background: #b0b0b0;
|
||||
}
|
||||
|
||||
.odd {
|
||||
font-size: 12pt;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.even {
|
||||
font-size: 12pt;
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
.answer {
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.answer p {
|
||||
font-size: 12pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.answer ul {
|
||||
font-size: 12pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#container {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#feedback {
|
||||
color: #b0b0b0;
|
||||
font-size: 9pt;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#header {
|
||||
position: absolute;
|
||||
margin: 0px;
|
||||
top: 10px;
|
||||
height:96px;
|
||||
left: 175px;
|
||||
right: 10em;
|
||||
bottom: auto;
|
||||
background: white;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#middle {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#main {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
left: 175px;
|
||||
right: 100px;
|
||||
background: white;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
position: absolute;
|
||||
top: 75px;
|
||||
left: 0em;
|
||||
width: 146px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
#navbar a:link, #navbar a:visited {
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
#navbar a:hover {
|
||||
font-weight: normal;
|
||||
text-decoration: underline;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
#navbar dl {
|
||||
width: 146px;
|
||||
padding: 0;
|
||||
margin: 0 0 10px 0px;
|
||||
background: #99ffff url(images/box_bottom2.gif) no-repeat bottom left;
|
||||
}
|
||||
|
||||
#navbar dt {
|
||||
padding: 6px 10px;
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
background: #009999;
|
||||
margin: 0px;
|
||||
border-bottom: 1px solid #fff;
|
||||
color: white;
|
||||
background: #009999 url(images/box_top2.gif) no-repeat top left;
|
||||
}
|
||||
|
||||
#navbar dd {
|
||||
font-size: 100%;
|
||||
margin: 0 0 0 0px;
|
||||
padding: 6px 10px;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
dd#selected {
|
||||
background: #99ffff url(images/arrow.gif) no-repeat;
|
||||
background-position: 4px 10px;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
@setfilename ns-3.info
|
||||
@settitle ns-3 manual
|
||||
@c @setchapternewpage odd
|
||||
@c %**end of header
|
||||
|
||||
@ifinfo
|
||||
Primary documentation for the @command{ns-3} project is available in
|
||||
four forms:
|
||||
@itemize @bullet
|
||||
@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator
|
||||
@item @uref{http://www.nsnam.org/tutorial/index.html,,ns-3 Tutorial}
|
||||
@item Reference Manual (this document)
|
||||
@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki}
|
||||
@end itemize
|
||||
|
||||
This document is written in GNU Texinfo and is to be maintained in
|
||||
revision control on the @command{ns-3} code server. Both PDF and HTML versions
|
||||
should be available on the server. Changes to
|
||||
the document should be discussed on the ns-developers@@isi.edu mailing list.
|
||||
@end ifinfo
|
||||
|
||||
@copying
|
||||
|
||||
This is an @command{ns-3} reference manual.
|
||||
Primary documentation for the @command{ns-3} project is available in
|
||||
four forms:
|
||||
@itemize @bullet
|
||||
@item @uref{http://www.nsnam.org/tutorial/index.html,,ns-3 Tutorial}
|
||||
@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen}: Documentation of the public APIs of the simulator
|
||||
@item Reference Manual (this document)
|
||||
@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki}
|
||||
@end itemize
|
||||
|
||||
This document is written in GNU Texinfo and is to be maintained in
|
||||
revision control on the @command{ns-3} code server. Both PDF and HTML
|
||||
versions should be available on the server. Changes to
|
||||
the document should be discussed on the ns-developers@@isi.edu mailing list.
|
||||
|
||||
This software is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see @uref{http://www.gnu.org/licenses/}.
|
||||
@end copying
|
||||
|
||||
@titlepage
|
||||
@title ns-3 Reference Manual
|
||||
@author ns-3 project
|
||||
@author feedback: ns-developers@@isi.edu
|
||||
@today{}
|
||||
|
||||
@c @page
|
||||
@vskip 0pt plus 1filll
|
||||
@insertcopying
|
||||
@end titlepage
|
||||
|
||||
@c So the toc is printed at the start.
|
||||
@anchor{Full Table of Contents}
|
||||
@contents
|
||||
|
||||
@ifnottex
|
||||
@node Top, Overview, Full Table of Contents
|
||||
@top ns-3 Manual (html version)
|
||||
|
||||
For a pdf version of this manual,
|
||||
see @uref{http://www.nsnam.org/docs/manual.pdf}.
|
||||
|
||||
@insertcopying
|
||||
@end ifnottex
|
||||
|
||||
@menu
|
||||
* Random variables::
|
||||
* Callbacks::
|
||||
* Attributes::
|
||||
* Packets::
|
||||
* Sockets APIs::
|
||||
* Node and Internet Stack::
|
||||
* Routing overview::
|
||||
* Troubleshooting
|
||||
@end menu
|
||||
|
||||
@include random.texi
|
||||
@include callbacks.texi
|
||||
@include attributes.texi
|
||||
@include packets.texi
|
||||
@include sockets.texi
|
||||
@include node.texi
|
||||
@c @include output.texi
|
||||
@include routing.texi
|
||||
@c @include other.texi
|
||||
@include troubleshoot.texi
|
||||
|
||||
@printindex cp
|
||||
|
||||
@bye
|
||||
@@ -0,0 +1,358 @@
|
||||
@node Node and Internet Stack
|
||||
@chapter Node and Internet Stack
|
||||
@anchor{chap:Node}
|
||||
|
||||
This chapter describes how ns-3 nodes are put together, and provides
|
||||
a walk-through of how packets traverse an internet-based Node.
|
||||
|
||||
@float Figure,fig:node
|
||||
@caption{High-level node architecture.}
|
||||
@image{figures/node,5in}
|
||||
@end float
|
||||
|
||||
In ns-3, nodes are instances of @code{class Node}. This class
|
||||
may be subclassed, but instead, the conceptual model is that
|
||||
we @emph{aggregate} or insert objects to it rather than define
|
||||
subclasses.
|
||||
|
||||
One might think of a bare ns-3 node as a shell of a computer,
|
||||
to which one may add NetDevices (cards) and other innards including
|
||||
the protocols and applications. @ref{fig:node} illustrates
|
||||
that Node objects contain a list of Applications (initially,
|
||||
the list is empty), a list of NetDevices (initially, the list
|
||||
is empty), a unique integer ID, and a system ID (for
|
||||
distributed simulation).
|
||||
|
||||
The design tries to avoid putting too many dependencies on the
|
||||
base class Node, Application, or NetDevice for the following:
|
||||
@itemize @bullet
|
||||
@item IP version, or whether IP is at all even used in the Node.
|
||||
@item implementation details of the IP stack
|
||||
@end itemize
|
||||
|
||||
From a software perspective, the lower interface of applications
|
||||
corresponds to the C-based sockets API. The upper interface
|
||||
of NetDevice objects corresponds to the device independent
|
||||
sublayer of the Linux stack. Everything in between can be
|
||||
aggregated and plumbed together as needed.
|
||||
|
||||
Let's look more closely at the protocol demultiplexer. We want
|
||||
incoming frames at layer-2 to be delivered to the right layer-3
|
||||
protocol such as Ipv4. The
|
||||
function of this demultiplexer is to register callbacks for
|
||||
receiving packets. The callbacks are indexed based on the
|
||||
@uref{http://en.wikipedia.org/wiki/EtherType,,EtherType}
|
||||
in the layer-2 frame.
|
||||
|
||||
Many different types of higher-layer protocols may be
|
||||
connected to the NetDevice, such as IPv4, IPv6, ARP,
|
||||
MPLS, IEEE 802.1x, and packet sockets. Therefore, the
|
||||
use of a callback-based demultiplexer avoids the need to
|
||||
use a common base class for all of these protocols, which
|
||||
is problematic because of the different types of objects
|
||||
(including packet sockets) expected to be registered there.
|
||||
|
||||
Each NetDevice delivers packets to a callback with the following
|
||||
signature:
|
||||
@verbatim
|
||||
/**
|
||||
* \param device a pointer to the net device which is calling this callback
|
||||
* \param packet the packet received
|
||||
* \param protocol the 16 bit protocol number associated with this packet.
|
||||
* This protocol number is expected to be the same protocol number
|
||||
* given to the Send method by the user on the sender side.
|
||||
* \param address the address of the sender
|
||||
* \returns true if the callback could handle the packet successfully,
|
||||
* false otherwise.
|
||||
*/
|
||||
typedef Callback<bool, Ptr<NetDevice>, Ptr<Packet>, uint16_t,
|
||||
const Address &> ReceiveCallback;
|
||||
@end verbatim
|
||||
|
||||
There is a function in class Node that matches that signature:
|
||||
@verbatim
|
||||
private:
|
||||
bool ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet>,
|
||||
uint16_t protocol, const Address &from);
|
||||
@end verbatim
|
||||
|
||||
However, users do not need to access this function directly. Instead,
|
||||
when users call @code{uint32_t AddDevice (Ptr<NetDevice> device)},
|
||||
the implementation of this function sets the callback (and the
|
||||
function returns the ifIndex of the NetDevice on that Node).
|
||||
|
||||
But what does the ReceiveFromDevice function do? Here, it looks
|
||||
up another callback, in its list of callbacks, corresponding to the
|
||||
matching EtherType. This callback is called a ProtocolHandler, and
|
||||
is specified as follows:
|
||||
@verbatim
|
||||
typedef Callback<void, Ptr<NetDevice>, Ptr<Packet>, uint16_t,
|
||||
const Address &> ProtocolHandler;
|
||||
@end verbatim
|
||||
|
||||
Upper-layer protocols or objects are expected to provide such a function.
|
||||
and register it with the list of ProtocolHandlers by calling
|
||||
@code{Node::RegisterProtocolHandler ();}
|
||||
For instance, if Ipv4 is aggregated to a Node, then the Ipv4 receive
|
||||
function can be registered with the protocol handler by calling:
|
||||
@verbatim
|
||||
RegisterProtocolHandler (
|
||||
MakeCallback (&Ipv4L3Protocol::Receive, ipv4),
|
||||
Ipv4L3Protocol::PROT_NUMBER, 0);
|
||||
@end verbatim
|
||||
and likewise for Ipv6, Arp, etc.
|
||||
|
||||
@section NodeList
|
||||
|
||||
Every Node created is automatically added to the ns-3 @code{NodeList}.
|
||||
The NodeList class provides an @code{Add()} method and C++ iterators
|
||||
to allow one to walk the node list or fetch a Node pointer by
|
||||
its integer identifier.
|
||||
|
||||
@section Internet stack aggregation
|
||||
|
||||
The above @code{class Node} is not very useful as-is; other objects
|
||||
must be aggregated to it to provide useful node functionality.
|
||||
|
||||
The ns-3 source code directory @code{src/internet-stack} provides
|
||||
implmentation of TCP/IPv4-related components. These include IPv4,
|
||||
ARP, UDP, TCP, and other related protocols.
|
||||
|
||||
Internet Nodes are not subclasses of class Node; they are simply Nodes
|
||||
that have had a bunch of IPv4-related
|
||||
objects aggregated to them. They can be put together by hand, or
|
||||
via a helper function @code{AddInternetStack ()} which does the
|
||||
following:
|
||||
@verbatim
|
||||
void AddInternetStack (Ptr<Node> node)
|
||||
{
|
||||
// Create layer-3 protocols
|
||||
Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
|
||||
Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol> ();
|
||||
ipv4->SetNode (node);
|
||||
arp->SetNode (node);
|
||||
|
||||
// Create an L4 demux
|
||||
Ptr<Ipv4L4Demux> ipv4L4Demux = CreateObject<Ipv4L4Demux> ();
|
||||
|
||||
// Create transport protocols and insert them into the demux
|
||||
Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
|
||||
Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
|
||||
|
||||
ipv4L4Demux->SetNode (node);
|
||||
udp->SetNode (node);
|
||||
tcp->SetNode (node);
|
||||
|
||||
ipv4L4Demux->Insert (udp);
|
||||
ipv4L4Demux->Insert (tcp);
|
||||
|
||||
// Add factories for instantiating transport protocol sockets
|
||||
Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
|
||||
Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
|
||||
Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> ();
|
||||
|
||||
udpFactory->SetUdp (udp);
|
||||
tcpFactory->SetTcp (tcp);
|
||||
ipv4Impl->SetIpv4 (ipv4);
|
||||
|
||||
// Aggregate all of these new objects to the node
|
||||
node->AggregateObject (ipv4);
|
||||
node->AggregateObject (arp);
|
||||
node->AggregateObject (ipv4Impl);
|
||||
node->AggregateObject (udpFactory);
|
||||
node->AggregateObject (tcpFactory);
|
||||
node->AggregateObject (ipv4L4Demux);
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
@subsection Internet Node structure
|
||||
|
||||
The Internet Node (an ns-3 Node augmented by aggregation to have one or more
|
||||
IP stacks) has the following internal structure.
|
||||
|
||||
@subsubsection Layer-3 protocols
|
||||
At the lowest layer, sitting above the NetDevices, are the "layer 3"
|
||||
protocols, including IPv4, IPv6, and ARP. These protocols provide
|
||||
the following key methods and data members:
|
||||
|
||||
@verbatim
|
||||
class Ipv4L3Protocol : public Object
|
||||
{
|
||||
public:
|
||||
// Add an Ipv4 interface corresponding to the provided NetDevice
|
||||
uint32_t AddInterface (Ptr<NetDevice> device);
|
||||
|
||||
// Receive function that can be bound to a callback, for receiving
|
||||
// packets up the stack
|
||||
void Receive( Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol,
|
||||
const Address &from);
|
||||
|
||||
// Higher-level layers call this method to send a packet
|
||||
// down the stack to the MAC and PHY layers
|
||||
//
|
||||
void Send (Ptr<Packet> packet, Ipv4Address source,
|
||||
Ipv4Address destination, uint8_t protocol);
|
||||
|
||||
private:
|
||||
Ipv4InterfaceList m_interfaces;
|
||||
|
||||
// Protocol handlers
|
||||
}
|
||||
@end verbatim
|
||||
There are many more functions (such as @code{Forward ()}) but we will
|
||||
focus on the above four items from an architectural perspective.
|
||||
|
||||
First, note that the @code{Receive ()} function has a matching signature
|
||||
to the ReceiveCallback in the @code{class Node}. This function pointer
|
||||
is inserted into the the Node's protocol handler when
|
||||
@code{AddInterface ()} is called. The actual registration is done
|
||||
with a statement such as:
|
||||
follows:
|
||||
@verbatim
|
||||
RegisterProtocolHandler ( MakeCallback (&Ipv4Protocol::Receive, ipv4),
|
||||
Ipv4L3Protocol::PROT_NUMBER, 0);
|
||||
@end verbatim
|
||||
|
||||
The Ipv4L3Protocol object is aggregated to the Node; there is only one
|
||||
such Ipv4L3Protocol object. Higher-layer protocols that have a packet
|
||||
to send down to the Ipv4L3Protocol object can call
|
||||
@code{GetObject<Ipv4L3Protocol> ()} to obtain a pointer, as follows:
|
||||
@verbatim
|
||||
Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
|
||||
if (ipv4 != 0)
|
||||
{
|
||||
ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
This class nicely demonstrates two techniques we exploit in
|
||||
ns-3 to bind objects together: callbacks, and object aggregation.
|
||||
|
||||
Once IPv4 has determined that a packet is for the local node, it
|
||||
forwards it up the stack. This is done with the following function:
|
||||
|
||||
@verbatim
|
||||
void
|
||||
Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
|
||||
Ptr<Ipv4Interface> incomingInterface)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << p << &ip);
|
||||
|
||||
Ptr<Ipv4L4Demux> demux = m_node->GetObject<Ipv4L4Demux> ();
|
||||
Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
|
||||
protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
The first step is to find the aggregated Ipv4L4Demux object. Then, this
|
||||
object is consulted to look up the right Ipv4L4Protocol, based on IP protocol
|
||||
number. For instance, TCP is registered in the demux as protocol number 6.
|
||||
Finally, the @code{Receive()} function on the Ipv4L4Protocol (such as
|
||||
@code{TcpL4Protocol::Receive} is called.
|
||||
|
||||
We have not yet introduced the class Ipv4Interface. Basically,
|
||||
each NetDevice is paired with an IPv4 representation of such device.
|
||||
In Linux, this @code{class Ipv4Interface} roughly corresponds to
|
||||
the @code{struct in_device}; the main purpose is to provide
|
||||
address-family specific information (addresses) about an interface.
|
||||
|
||||
@subsubsection Layer-4 protocols and sockets
|
||||
|
||||
We next describe how the transport protocols, sockets, and applications
|
||||
tie together. In summary, each transport protocol implementation is
|
||||
a socket factory. An application that needs a new socket
|
||||
|
||||
For instance, to create a UDP socket, an application would use a code
|
||||
snippet such as the following:
|
||||
@verbatim
|
||||
Ptr<Udp> udpSocketFactory = GetNode ()->GetObject<Udp> ();
|
||||
Ptr<Socket> m_socket = socketFactory->CreateSocket ();
|
||||
m_socket->Bind (m_local_address);
|
||||
...
|
||||
@end verbatim
|
||||
The above will query the node to get a pointer to its UDP socket
|
||||
factory, will create one such socket, and will use the socket with
|
||||
an API similar to the C-based sockets API, such as @code{Connect ()}
|
||||
and @code{Send ()}. See the chapter on ns-3 sockets for more information.
|
||||
|
||||
We have described so far a socket factory (e.g. @code{class Udp}) and
|
||||
a socket, which may be specialized (e.g., @code{class UdpSocket}).
|
||||
There are a few more key objects that relate to the specialized
|
||||
task of demultiplexing a packet to one or more receiving sockets.
|
||||
The key object in this task is @code{class Ipv4EndPointDemux}.
|
||||
This demultiplexer stores objects of @code{class Ipv4EndPoint}.
|
||||
This class holds the addressing/port tuple (local port, local address,
|
||||
destination port, destination address) associated with the socket,
|
||||
and a receive callback. This receive callback has a receive
|
||||
function registered by the socket. The @code{Lookup ()} function to
|
||||
Ipv4EndPointDemux returns a list of Ipv4EndPoint objects (there may
|
||||
be a list since more than one socket may match the packet). The
|
||||
layer-4 protocol copies the packet to each Ipv4EndPoint and calls
|
||||
its @code{ForwardUp ()} method, which then calls the @code{Receive ()}
|
||||
function registered by the socket.
|
||||
|
||||
An issue that arises when working with the sockets API on real
|
||||
systems is the need to manage the reading from a socket, using
|
||||
some type of I/O (e.g., blocking, non-blocking, asynchronous, ...).
|
||||
ns-3 implements an asynchronous model for socket I/O; the application
|
||||
sets a callback to be notified of received data ready to be read, and the
|
||||
callback is invoked by the transport protocol when data is available.
|
||||
This callback is specified as follows:
|
||||
@verbatim
|
||||
void Socket::SetRecvCallback (Callback<void, Ptr<Socket>,
|
||||
Ptr<Packet>, const Address&> receivedData);
|
||||
@end verbatim
|
||||
The data being received is conveyed in the Packet data buffer. An example
|
||||
usage is in @code{class PacketSink}:
|
||||
@verbatim
|
||||
m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this));
|
||||
@end verbatim
|
||||
|
||||
To summarize, internally, the UDP implementation is organized as follows:
|
||||
@itemize @bullet
|
||||
@item a @code{UdpImpl} class that implements the Udp socket factory
|
||||
functionality
|
||||
@item a @code{UdpL4Protocol} class that implements the protocol logic
|
||||
that is socket-independent
|
||||
@item a @code{UdpSocketImpl} class that implements socket-specific aspects
|
||||
of UDP
|
||||
@item a class called @code{Ipv4EndPoint} that stores the
|
||||
addressing tuple (local port, local address, destination port, destination
|
||||
address) associated with the socket, and a receive callback for the socket.
|
||||
@end itemize
|
||||
|
||||
@subsection Internet Node interfaces
|
||||
|
||||
Many of the implementation details, or internal objects themselves,
|
||||
of Internet Node objects are not exposed at the simulator public
|
||||
API. This allows for different implementations; for instance,
|
||||
replacing the native ns-3 models with ported TCP/IP stack code.
|
||||
|
||||
The C++ public APIs of all of these objects is found in the
|
||||
@code{src/node} directory, including principally:
|
||||
@itemize @bullet
|
||||
@item @code{socket.h}
|
||||
@item @code{tcp.h}
|
||||
@item @code{udp.h}
|
||||
@item @code{ipv4.h}
|
||||
@end itemize
|
||||
These are typically base class objects that implement the default
|
||||
values used in the implementation, implement access methods to get/set
|
||||
state variables, host attributes, and implement publicly-available methods
|
||||
exposed to clients such as @code{CreateSocket}.
|
||||
|
||||
@subsection Example path of a packet
|
||||
|
||||
These two figures show an example stack trace of how packets flow
|
||||
through the Internet Node objects.
|
||||
|
||||
@float Figure,fig:internet-node-send
|
||||
@caption{Send path of a packet.}
|
||||
@image{figures/internet-node-send,5in}
|
||||
@end float
|
||||
|
||||
@float Figure,fig:internet-node-recv
|
||||
@caption{Receive path of a packet.}
|
||||
@image{figures/internet-node-recv,5in}
|
||||
@end float
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,462 @@
|
||||
|
||||
@c ========================================================================
|
||||
@c Simulation Output
|
||||
@c ========================================================================
|
||||
|
||||
@node Simulation Output
|
||||
@chapter Simulation Output
|
||||
|
||||
At this point, you should be able to execute any of the built-in
|
||||
programs distributed with @command{ns-3}. Next, we will look at
|
||||
how to generate and tailor the simulation output, before turning
|
||||
to how to modify simulation scripts to do different things.
|
||||
|
||||
@node Tracing Basics
|
||||
@section Tracing Basics
|
||||
|
||||
The whole point of simulation is to generate output for further
|
||||
study, and the @command{ns-3} tracing system is a primary
|
||||
mechanism for this.
|
||||
Since @command{ns-3} is a C++ program, standard facilities for
|
||||
generating output from C++ programs apply:
|
||||
|
||||
@verbatim
|
||||
#include <iostream>
|
||||
...
|
||||
int main ()
|
||||
{
|
||||
...
|
||||
std::cout << "The value of x is " << x << std::endl;
|
||||
...
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
The goal of the @command{ns-3} tracing system is to
|
||||
provide a structured way to configure the simulator to output results
|
||||
in standard or modifiable formats.
|
||||
@itemize @bullet
|
||||
@item For basic tasks, the tracing system should allow the user to
|
||||
generate standard tracing for popular tracing sources, and to customize
|
||||
which objects generate the tracing.
|
||||
@item Intermediate users will be able to extend the tracing system to
|
||||
modify the output format generated, or to insert new tracing sources,
|
||||
without modifying the core of the simulator.
|
||||
@item Advanced users can modify the simulator core to add new
|
||||
tracing sources and sinks.
|
||||
@end itemize
|
||||
|
||||
The @command{ns-3} tracing system is fundamentally built on the
|
||||
concept of separating tracing sources from sinks.
|
||||
@enumerate
|
||||
@item Trace sources (e.g., provide access to every packet received)
|
||||
@item Trace sinks (e.g., print out the packet)
|
||||
@item A mechanism to tie together sources and sinks
|
||||
@end enumerate
|
||||
The rationale for this division is to allow users to attach new
|
||||
types of sinks to existing tracing sources, without requiring
|
||||
users to edit and recompile the core of the simulator.
|
||||
Thus, in the example above, a user could write a new tracing sink
|
||||
and attach it to an existing tracing source. What remains to
|
||||
be defined is a way for users to find these hooks (tracing sources)
|
||||
and attach sinks to them. A new tracing namespace is defined for
|
||||
this purpose.
|
||||
|
||||
We will first walk through how some pre-defined sources and sinks
|
||||
are provided and may be customized with little user effort. We
|
||||
return later in this chapter to advanced tracing configuration including
|
||||
extending the tracing namespace and creating new tracing sources.
|
||||
|
||||
@subsection ASCII tracing
|
||||
@cindex ASCII
|
||||
For Internet nodes, the ASCII trace wrapper is a wrapper around
|
||||
the @command{ns-3} low-level
|
||||
tracing system that lets you get access to underlying trace events easily.
|
||||
The output of a trace of a simulation run is an ASCII file --- thus the name.
|
||||
In the spririt of keeping things simple, you won't be able to control or
|
||||
configure the output at this stage.
|
||||
|
||||
For those familiar with @command{ns-2} output, this type of trace is
|
||||
analogous to the @command{out.tr} generated by many scripts.
|
||||
|
||||
@cindex tracing packets
|
||||
Let's just jump right in. As usual, we need to include the definitions
|
||||
related to using ASCII tracing (don't edit any files quite yet):
|
||||
|
||||
@verbatim
|
||||
#include "ns3/ascii-trace.h"
|
||||
@end verbatim
|
||||
|
||||
We then need to add the code to the script to actually enable the ASCII tracing
|
||||
code. The following code must be inserted before the call to
|
||||
@code{Simulator::Run ();}:
|
||||
|
||||
@verbatim
|
||||
AsciiTrace asciitrace ("tutorial.tr");
|
||||
asciitrace.TraceAllQueues ();
|
||||
asciitrace.TraceAllNetDeviceRx ();
|
||||
@end verbatim
|
||||
|
||||
The first line declares an object of type @code{AsciiTrace} named
|
||||
@code{asciitrace} and passes a string parameter to its constructor. This
|
||||
parameter is a file name to which all of the trace information will be written.
|
||||
The second line, @code{asciitrace.TraceAllQueues ();} asks the trace object to
|
||||
arrange that all queue operations (enqueue, dequeue, drop) on the queues
|
||||
in all of the nodes of the system be traced. On the receive side,
|
||||
@code{asciitrace.TraceAlllNetDeviceRx ()} traces packets received by
|
||||
a NetDevice. For those familiar with @command{ns-2}, these are equivalent
|
||||
to the popular trace points that log "+", "-", "d", and "r" events.
|
||||
|
||||
Try running the following program from the command line:
|
||||
@verbatim
|
||||
./waf --run tutorial-csma-echo-ascii-trace
|
||||
@end verbatim
|
||||
|
||||
@cindex tutorial.tr
|
||||
Just as you have seen previously, you will see some messages from @emph{Waf}
|
||||
and then the ``Compilation finished successfully'' message. The
|
||||
next message, @code{UDP Echo Simulation} is from the running program. When
|
||||
it ran, the program will have created a file named @code{tutorial.tr}.
|
||||
Because of the way that Waf works, the file is not created in the local
|
||||
directory, it is created at the top-level directory of the repository. So,
|
||||
change into the top level directory and take a look at the file
|
||||
@code{tutorial.tr} in your favorite editor.
|
||||
|
||||
@subsubsection Parsing Ascii Traces
|
||||
@cindex parsing ascii traces
|
||||
|
||||
This section parses in detail the structure of the ascii tracing
|
||||
output. If you find this output format self explanatory (it
|
||||
resembles tcpdump output), you may skip to the next
|
||||
section on pcap tracing.
|
||||
|
||||
@cindex trace event
|
||||
There's a lot of information there in a pretty dense form, but the first thing
|
||||
to notice is that there are a number of distinct lines in this file. It may
|
||||
be difficult to see this clearly unless you widen your windows considerably.
|
||||
Each line in the file corresponds to a @emph{trace event}. A trace event
|
||||
happens whenever specific conditions happen in the simulation. In this case
|
||||
we are tracing events on the @emph{device queue} present in every net device
|
||||
on every node in the simulation. The device queue is a queue through which
|
||||
every packet destined for a channel must pass --- it is the device
|
||||
@emph{transmit} queue. Note that each line in the trace file begins with a
|
||||
lone character (has a space after it). This character will have the following
|
||||
meaning:
|
||||
|
||||
@cindex enqueue
|
||||
@cindex dequeue
|
||||
@cindex drop
|
||||
@itemize @bullet
|
||||
@item @code{+}: An enqueue operation occurred on the device queue;
|
||||
@item @code{-}: A dequeue operation occurred on the device queue;
|
||||
@item @code{d}: A packet was dropped, typically because the queue was full.
|
||||
@end itemize
|
||||
|
||||
Let's take a more detailed view of the first line. I'll break it down into
|
||||
sections (indented for clarity) with a two digit reference number on the
|
||||
left side:
|
||||
|
||||
@verbatim
|
||||
00 +
|
||||
01 2
|
||||
02 nodeid=0
|
||||
03 device=0
|
||||
04 queue-enqueue
|
||||
05 pkt-uid=9
|
||||
06 ETHERNET
|
||||
07 length/type=0x806,
|
||||
08 source=08:00:2e:00:00:00,
|
||||
09 destination=ff:ff:ff:ff:ff:ff
|
||||
10 ARP(request
|
||||
11 source mac: 08:00:2e:00:00:00
|
||||
12 source ipv4: 10.1.1.1
|
||||
13 dest ipv4: 10.1.1.2)
|
||||
14 ETHERNET fcs=0
|
||||
@end verbatim
|
||||
|
||||
@cindex trace event
|
||||
@cindex simulation time
|
||||
The first line of this expanded trace event (reference number 00) is the
|
||||
queue operation. We have a @code{+} character, so this corresponds to an
|
||||
@emph{enqueue} operation. The second line (reference 01) is the simulation
|
||||
time expressed in seconds. You may recall that we asked the
|
||||
@code{UdpEchoClient} to start sending packets at two seconds. Here we see
|
||||
confirmation that this is, indeed, happening.
|
||||
|
||||
@cindex node number
|
||||
@cindex net device number
|
||||
@cindex smart pointer
|
||||
The next lines of the example listing (references 02 and 03) tell us that
|
||||
this trace event originated in a given node and net device. Each time a node
|
||||
is created it is given an identifying number that monotonically increases from
|
||||
zero. Therefore, @code{nodeid=0} means that the node in which the given trace
|
||||
event originated is the first node we created. In the case of our script,
|
||||
this first node is is the node pointed to by the smart pointer @code{n0}. Not
|
||||
too surpsisingly, this is also the node to which we attached the
|
||||
@code{UdpEchoClient}. The device number is local to each node, and so the
|
||||
device given by @code{device=0} is the first net device that we added to the
|
||||
node in question. In our simulation, this corresponds to the
|
||||
@code{CsmaNetDevice} we added to node zero (@code{n0}).
|
||||
|
||||
@cindex uid
|
||||
@cindex unique ID
|
||||
@cindex packet
|
||||
The next line (reference 04) is a more readable form of the operation code
|
||||
seen in the first line --- i.e., the character @code{+} means
|
||||
@code{queue-enqueue}. Reference number 05 indicates that the @emph{unique id}
|
||||
of the packet being enqueued is @code{9}. The fact that the first packet we
|
||||
see has a unique ID of 9 should indicates to you that other things have
|
||||
happened in the protocol stack before we got to this point. This will become
|
||||
clear momentarily.
|
||||
|
||||
@cindex Ethernet
|
||||
@cindex MAC address
|
||||
Reference items 06 and 14 indicate that this is an Ethernet packet with
|
||||
a zero (not computed) checksum (note the indentation to make parsing this
|
||||
trace event a little easier). Reference 08 and 09 are the source and
|
||||
destination addresses of this packet. The packet is from the MAC address we
|
||||
assigned to the node zero net device in the script, and is destined for the
|
||||
broadcast address --- this is a broadcast packet.
|
||||
|
||||
@cindex Address Resolution Protocol
|
||||
@cindex ARP
|
||||
@cindex ARP|request
|
||||
Reference items 10 through 13 make clear what is happening. This is an ARP
|
||||
(Address Resolution Protocol) request for the MAC address of the node on
|
||||
which the @code{UdpEchoServer} resides. The protocol stack can't send a UDP
|
||||
packet to be echoed until it knows (resolves) the MAC address; and this trace
|
||||
event corresponds to an ARP request being queued for transmission to the local
|
||||
network. The next line in the trace file (partially expanded),
|
||||
|
||||
@verbatim
|
||||
00 -
|
||||
01 2
|
||||
02 nodeid=0
|
||||
03 device=0
|
||||
04 queue-dequeue
|
||||
05 pkt-uid=9
|
||||
...
|
||||
@end verbatim
|
||||
|
||||
shows the (same) ARP request packet being dequeued from the device queue by
|
||||
the net device and (implicitly) being sent down the channel to the broadcast
|
||||
MAC address. We are not tracing net device reception events so we don't
|
||||
actually see all of the net devices receiving the broadcast packet. We do,
|
||||
however see the following in the third line of the trace file:
|
||||
|
||||
@verbatim
|
||||
00 +
|
||||
01 2.00207
|
||||
02 nodeid=1
|
||||
03 device=0
|
||||
04 queue-enqueue
|
||||
05 pkt-uid=10
|
||||
06 ETHERNET
|
||||
07 length/type=0x806,
|
||||
08 source=08:00:2e:00:00:01,
|
||||
09 destination=08:00:2e:00:00:00,
|
||||
10 ARP(reply
|
||||
11 source mac: 08:00:2e:00:00:01
|
||||
12 source ipv4: 10.1.1.2
|
||||
13 dest mac: 08:00:2e:00:00:00
|
||||
14 dest ipv4: 10.1.1.1)
|
||||
15 ETHERNET fcs=0
|
||||
@end verbatim
|
||||
|
||||
@cindex simulation time
|
||||
@cindex ARP|response
|
||||
Notice that this is a queue-enqueue operation (references 00 and 04) happening
|
||||
on node one (reference 02) at simulation time 2.00207 seconds (reference 01).
|
||||
Looking at the packet payload (references 10-14) we see that this is an ARP
|
||||
reply to the request sent by node one. Note that the simulation time
|
||||
(reference 01) is now 2.00207 seconds. This is direct result of the data rate
|
||||
(5 mb/s) and latency (2 ms) parameters that we passed to the
|
||||
@code{CsmaChannel} when we created it. Clearly the ARP request packet was
|
||||
sent over the channel and received approximately 2 ms later by node one. A
|
||||
corresponding ARP response packet was created and enqueued on node one's net
|
||||
device. It is this enqueue trace event that has being logged.
|
||||
|
||||
@cindex queue
|
||||
@cindex queue|transmit
|
||||
@cindex echo
|
||||
Given the current state of affairs, the next thing you may expect to see is
|
||||
this ARP request being received by node zero, but remember we are only looking
|
||||
at trace events on the device @emph{transmit} queue. The reception of the ARP
|
||||
response by node zero will not directly trigger any trace event in this case,
|
||||
but it will enable the protocol stack to continue what it was originally doing
|
||||
(trying to send an echo packet). Thus, the next line we see in the trace file
|
||||
(@code{tutorial.tr}) is the first UDP echo packet being sent to the net device.
|
||||
|
||||
@verbatim
|
||||
00 +
|
||||
01 2.00415
|
||||
02 nodeid=0
|
||||
03 device=0
|
||||
04 queue-enqueue
|
||||
05 pkt-uid=7
|
||||
06 ETHERNET
|
||||
07 length/type=0x800,
|
||||
08 source=08:00:2e:00:00:00,
|
||||
09 destination=08:00:2e:00:00:01
|
||||
10 IPV4(
|
||||
11 tos 0x0
|
||||
12 ttl 64
|
||||
13 id 0
|
||||
14 offset 0
|
||||
15 flags [none]
|
||||
16 length: 1052) 10.1.1.1 > 10.1.1.2
|
||||
17 UDP(length: 1032)
|
||||
18 49153 > 7
|
||||
19 DATA (length 1024)
|
||||
20 ETHERNET fcs=0
|
||||
@end verbatim
|
||||
|
||||
@cindex simulation time
|
||||
@cindex echo
|
||||
@cindex ARP
|
||||
@cindex ARP|request
|
||||
@cindex ARP|response
|
||||
@cindex IP
|
||||
@cindex Ipv4
|
||||
I won't go into too much detail about this packet, but I will point out a
|
||||
few key items in the trace. First, the packet was enqueued at simulation time
|
||||
of 2.00415 seconds. This time reflects the fact that the echo client
|
||||
application started at 2. seconds and there were two ARP packets transmitted
|
||||
across the network (two milliseconds + data transmission time each way). The
|
||||
packet unique identifier (reference 05) is 7. Notice that this is a lower
|
||||
number than the ARP request packet, which had a unique ID of 9. This tells
|
||||
us that the UDP packet was actually created before the ARP request packet ---
|
||||
which makes perfect sense since it was the attempt to send packet 7 that
|
||||
triggered sending the ARP request packet 9. Note that this an Ethernet
|
||||
packet (reference 06) like all other packets in this simulation, however this
|
||||
particular packet carries an IPV4 payload and therefore has an IP version 4
|
||||
header (indicated by references 10-16). This Ipv4 in turn contains a UDP
|
||||
header (references 17, 18) and finally 1024 bytes of data (reference 20).
|
||||
Clearly, this is the UDP echo packet emitted by the
|
||||
@code{UdpEchoClient Application}.
|
||||
|
||||
The next trace event is an ARP request from node one. We can infer that node
|
||||
one has received the UDP echo packet and the @code{UdpEchoServer Application}
|
||||
on that node has turned the packet around. Just as node zero needed to ARP
|
||||
for the MAC address of node one, now node one must ARP for the MAC address of
|
||||
node zero. We see the ARP request enqueued on the transmit queue of node one;
|
||||
then we see the ARP request dequeued from the tranmit queue of node one (and
|
||||
implicitly transmitted to node zero). Then we see an ARP response enqueued
|
||||
on the transmit queue of node zero; and finally the ARP response dequeued (and
|
||||
implicitly transmitted back to node one).
|
||||
|
||||
This exchange is summarized in the following trace event excerpts,
|
||||
|
||||
@verbatim
|
||||
+ 2.00786 nodeid=1 ... ARP(request ...
|
||||
- 2.00786 nodeid=1 ... ARP(request ...
|
||||
+ 2.00994 nodeid=0 ... ARP(reply ...
|
||||
- 2.00994 nodeid=0 ... ARP(reply ...
|
||||
@end verbatim
|
||||
|
||||
The final two trace events in the @code{tutorial.tr} file correspond to the
|
||||
echoed packet being enqueued for transmission on the net device for node one,
|
||||
and that packet being dequeued (and implicitly transmitted back to node zero).
|
||||
|
||||
@cindex AsciiTrace!TraceAllNetDeviceRx
|
||||
@cindex ARP!request
|
||||
If you look at the trace file (@code{tutorial.tr}) you will also see some
|
||||
entries with an @code{r} event, indicating a
|
||||
@emph{receive} trace event. Recall that the first packet sent on the network
|
||||
was a broadcast ARP request. We should then see all four nodes receive a
|
||||
copy of this request. This is the case, as the first four receive trace
|
||||
events are,
|
||||
|
||||
@verbatim
|
||||
r 2.00207 nodeid=0 device=0 dev-rx pkt-uid=9 ARP(request ...
|
||||
r 2.00207 nodeid=1 device=0 dev-rx pkt-uid=9 ARP(request ...
|
||||
r 2.00207 nodeid=2 device=0 dev-rx pkt-uid=9 ARP(request ...
|
||||
r 2.00207 nodeid=3 device=0 dev-rx pkt-uid=9 ARP(request ...
|
||||
@end verbatim
|
||||
|
||||
@cindex unique ID
|
||||
You can see that a copy of the broadcast packet with unique ID 9 was received
|
||||
by the net devices on nodes 0, 1, 2 and 3. We leave it up to you to parse the
|
||||
rest of the trace file and understand the remaining reception events.
|
||||
|
||||
@subsection PCAP Trace Wrapper
|
||||
@cindex pcap
|
||||
@cindex Wireshark
|
||||
The @command{ns-3} @emph{pcap trace wrapper} is used to create trace files in
|
||||
@code{.pcap} format. The acronym pcap (usually written in lower case) stands
|
||||
for @emph{p}acket @emph{cap}ture, and is actually an API that includes the
|
||||
definition of a @code{.pcap} file format. The most popular program that can
|
||||
read and display this format is Wireshark (formerly called Ethereal).
|
||||
However, there are many traffic trace analyzers that use this packet
|
||||
format, including X, Y, and Z. We encourage users to exploit the
|
||||
many tools available for analyzing pcap traces; below, we show how
|
||||
tcpdump and Wireshark can be used..
|
||||
|
||||
@cindex tutorial-csma-echo-ascii-trace.cc
|
||||
@cindex tutorial-csma-echo-pcap-trace.cc
|
||||
The code used to enable pcap tracing is similar to that for ASCII tracing.
|
||||
We have provided another file, @code{tutorial-csma-echo-pcap-trace.cc} that
|
||||
uses the pcap trace wrapper. We have added the code to include the pcap
|
||||
trace wrapper defintions:
|
||||
|
||||
@verbatim
|
||||
#include "ns3/pcap-trace.h"
|
||||
@end verbatim
|
||||
|
||||
And then added the following code below the AsciiTrace methods:
|
||||
|
||||
@cindex PcapTrace
|
||||
@cindex PcapTrace!TraceAllIp
|
||||
@verbatim
|
||||
PcapTrace pcaptrace ("tutorial.pcap");
|
||||
pcaptrace.TraceAllIp ();
|
||||
@end verbatim
|
||||
|
||||
The first line of the code immediately above declares an object of type
|
||||
@code{PcapTrace} named @code{pcaptrace} and passes a string parameter to its
|
||||
constructor. This object is used to hide the details of the actual tracing
|
||||
subsystem. The parameter is a base file name from which the actual trace file
|
||||
names will be built. The second line of code tells the @code{PcamTrace}
|
||||
object to trace all IP activity in all of the nodes present in the simulation.
|
||||
|
||||
@cindex interface index
|
||||
Trace files are not created until trace activity is detected. Each file name
|
||||
is composed of the base file name, followed by a @code{'-'}, a node id followed
|
||||
by a @code{'-}', and an IP interface index. You will soon see a file named
|
||||
@code{tutorial.pcap-0-1}, for example. This will be the trace file generated
|
||||
as events are detected on node zero, interface index one. N.B. Interface
|
||||
indices are different that net device indices --- interface index zero
|
||||
corresponds to the loopback interface and interface index one corresponds to
|
||||
the first net device you added to a node.
|
||||
|
||||
You may run the new program just like all of the others so far:
|
||||
|
||||
@cindex Waf
|
||||
@verbatim
|
||||
./waf --run tutorial-csma-echo-pcap-trace
|
||||
@end verbatim
|
||||
|
||||
If you look at the top level directory of your distribution, you should now
|
||||
see three log files: @code{tutorial.tr} is the ASCII trace file we have
|
||||
previously examined. @code{tutorial.pcap-0-1} and @code{tutorial.pcap-1-1}
|
||||
are the new pcap files we just generated. There will not be files
|
||||
corresponding to nodes two and three since we have not sent any IP packets to
|
||||
those nodes.
|
||||
|
||||
@subsubsection Reading output with tcpdump
|
||||
@cindex tcpdump
|
||||
|
||||
@subsubsection Reading output with Wireshark
|
||||
@cindex Wireshark
|
||||
If you are unfamilar with Wireshark, there is a web site available from which
|
||||
you can download programs and documentation: @uref{http://www.wireshark.org/}.
|
||||
|
||||
If you have Wireshark available, you can open each of the trace files and
|
||||
display the contents as if you had captured the packets using a
|
||||
@emph{packet sniffer}. Note that only IP packets are traced using this
|
||||
wrapper, so you will not see the ARP exchanges that were logged when using
|
||||
the ASCII trace wrapper. You are encouraged to take a look at the contents
|
||||
of these pcap files using your favorite pcap software (or Wireshark).
|
||||
|
||||
@node Advanced Tracing
|
||||
@section Advanced Tracing
|
||||
|
||||
@@ -0,0 +1,620 @@
|
||||
@node Packets
|
||||
@chapter Packets
|
||||
|
||||
The design of the Packet framework of @emph{ns} was heavily guided by a few
|
||||
important use-cases:
|
||||
@itemize @bullet
|
||||
@item avoid changing the core of the simulator to introduce
|
||||
new types of packet headers or trailers
|
||||
@item maximize the ease of integration with real-world code
|
||||
and systems
|
||||
@item make it easy to support fragmentation, defragmentation,
|
||||
and, concatenation which are important, especially in wireless systems.
|
||||
@item make memory management of this object efficient
|
||||
@item allow actual application data or dummy application bytes for
|
||||
emulated applications
|
||||
@end itemize
|
||||
|
||||
@emph{ns} Packet objects contain a buffer of bytes: protocol headers and
|
||||
trailers are serialized in this buffer of bytes using user-provided
|
||||
serialization and deserialization routines. The content of this byte
|
||||
buffer is expected to match bit-for-bit the content of a real packet on
|
||||
a real network implementing the protocol of interest.
|
||||
|
||||
Fragmentation and defragmentation are quite natural to implement within
|
||||
this context: since we have a buffer of real bytes, we can split it in
|
||||
multiple fragments and re-assemble these fragments. We expect that this
|
||||
choice will make it really easy to wrap our Packet data structure within
|
||||
Linux-style skb or BSD-style mbuf to integrate real-world kernel code in
|
||||
the simulator. We also expect that performing a real-time plug of the
|
||||
simulator to a real-world network will be easy.
|
||||
|
||||
Because we understand that simulation developers often wish to store in
|
||||
packet objects data which is not found in the real packets (such as
|
||||
timestamps or any kind of similar in-band data), the @emph{ns} Packet class
|
||||
can also store extra per-packet "Tags" which are 16 bytes blobs of data.
|
||||
Any Packet can store any number of unique Tags, each of which is
|
||||
uniquely identified by its C++ type. These tags make it easy to attach
|
||||
per-model data to a packet without having to patch the main Packet
|
||||
class or Packet facilities.
|
||||
|
||||
Memory management of Packet objects is entirely automatic and extremely
|
||||
efficient: memory for the application-level payload can be modelized by
|
||||
a virtual buffer of zero-filled bytes for which memory is never allocated
|
||||
unless explicitely requested by the user or unless the packet is fragmented.
|
||||
Furthermore, copying, adding, and, removing headers or trailers to a packet
|
||||
has been optimized to be virtually free through a technique known as
|
||||
Copy On Write.
|
||||
|
||||
Packets (messages) are fundamental objects in the simulator and
|
||||
their design is important from a performance and resource management
|
||||
perspective. There
|
||||
are various ways to design the simulation packet, and tradeoffs
|
||||
among the different approaches. In particular, there is a
|
||||
tension between ease-of-use, performance, and safe interface
|
||||
design.
|
||||
|
||||
There are a few requirements on this object design:
|
||||
@itemize @bullet
|
||||
@item Creation, management, and deletion of this object
|
||||
should be as simple as possible, while avoiding the
|
||||
chance for memory leaks and/or heap corruption;
|
||||
@item Packets should support serialization and deserialization
|
||||
so that network emulation is supported;
|
||||
@item Packets should support fragmentation and concatenation
|
||||
(multiple packets in a data link frame), especially for wireless
|
||||
support;
|
||||
@item It should be natural for packets to carry actual application
|
||||
data, or if there is only an emulated application and there is
|
||||
no need to carry dummy bytes, smaller packets could be used with
|
||||
just the headers and a record of the payload size, but not actual
|
||||
application bytes, conveyed in the simulated packet.
|
||||
@item Packets should facilitate BSD-like operations on mbufs, for
|
||||
support of ported operating system stacks.
|
||||
@item Additional side-information should be supported, such as
|
||||
a tag for cross-layer information.
|
||||
@end itemize
|
||||
|
||||
@section Packet design overview
|
||||
|
||||
Unlike @emph{ns-2}, in which Packet objects contain a buffer of C++
|
||||
structures corresponding to protocol headers, each network packet in
|
||||
@emph{ns-3} contains a byte Buffer and a list of Tags:
|
||||
@itemize @bullet
|
||||
@item The byte buffer stores the serialized content of the chunks
|
||||
added to a packet. The serialized representation of these chunks is
|
||||
expected to match that of real network packets bit for bit
|
||||
(although nothing forces you to do this) which means that the content
|
||||
of a packet buffer is expected to be that of a real packet.
|
||||
Packets can also be created with an arbitrary zero-filled payload
|
||||
for which no real memory is allocated.
|
||||
@item The list of tags stores an arbitrarily large set of arbitrary
|
||||
user-provided data structures in the packet. Each Tag is uniquely
|
||||
identified by its type; only one instance of each
|
||||
type of data structure is allowed in a list of tags. These tags typically
|
||||
contain per-packet cross-layer information or flow identifiers (i.e.,
|
||||
things that you wouldn't find in the bits on the wire). Each tag
|
||||
stored in the tag list can be at most 16 bytes.
|
||||
Trying to attach bigger data structures will trigger
|
||||
crashes at runtime. The 16 byte limit is a modifiable compilation
|
||||
constant.
|
||||
@end itemize
|
||||
|
||||
@float Figure,fig:packets
|
||||
@caption{Implementation overview of Packet class.}
|
||||
@image{figures/packet}
|
||||
@end float
|
||||
|
||||
Figure @ref{fig:packets} is a high-level overview of the Packet
|
||||
implementation; more detail on the byte Buffer implementation
|
||||
is provided later in Figure @ref{fig:buffer}.
|
||||
In \nsthree, the Packet byte buffer is analogous to a Linux skbuff
|
||||
or BSD mbuf; it is a serialized representation of the actual
|
||||
data in the packet. The tag list is a container for extra
|
||||
items useful for simulation convenience; if a Packet is converted
|
||||
to an emulated packet and put over an actual network, the tags
|
||||
are stripped off and the byte buffer is copied directly
|
||||
into a real packet.
|
||||
|
||||
The Packet class has value semantics: it can be freely copied around,
|
||||
allocated on the stack, and passed to functions as arguments. Whenever
|
||||
an instance is copied, the full underlying data is not copied; it
|
||||
has ``copy-on-write'' (COW) semantics. Packet instances can be passed
|
||||
by value to function arguments without any performance hit.
|
||||
|
||||
The fundamental classes for adding to and removing from the byte
|
||||
buffer are @code{class Header} and @code{class Trailer}.
|
||||
Headers are more common but the below discussion also largely applies to
|
||||
protocols using trailers. Every protocol header that needs to
|
||||
be inserted and removed from a Packet instance should derive from
|
||||
the abstract Header base class and implement the private pure
|
||||
virtual methods listed below:
|
||||
@itemize @bullet
|
||||
@item @code{ns3::Header::SerializeTo()}
|
||||
@item @code{ns3::Header::DeserializeFrom()}
|
||||
@item @code{ns3::Header::GetSerializedSize()}
|
||||
@item @code{ns3::Header::PrintTo()}
|
||||
@end itemize
|
||||
Basically, the first three functions are used to serialize and deserialize
|
||||
protocol control information to/from a Buffer. For example,
|
||||
one may define @code{class TCPHeader : public Header}. The
|
||||
TCPHeader object will typically consist of some private data
|
||||
(like a sequence number) and public interface access functions
|
||||
(such as checking the bounds of an input). But the underlying
|
||||
representation of the TCPHeader in a Packet Buffer is 20 serialized
|
||||
bytes (plus TCP options). The TCPHeader::SerializeTo() function would
|
||||
therefore be designed to write these 20 bytes properly into
|
||||
the packet, in network byte order. The last function is used
|
||||
to define how the Header object prints itself onto an output stream.
|
||||
|
||||
Similarly, user-defined Tags can be appended to the packet.
|
||||
Unlike Headers, Tags are not serialized into a contiguous buffer
|
||||
but are stored in an array. By default, Tags are limited to 16 bytes in
|
||||
size. Tags can be flexibly defined to be any type, but there
|
||||
can only be one instance of any particular object type in
|
||||
the Tags buffer at any time. The implementation makes use
|
||||
of templates to generate the proper set of Add(), Remove(),
|
||||
and Peek() functions for each Tag type.
|
||||
|
||||
@section Packet interface
|
||||
|
||||
The public member functions of a Packet object are as follows:
|
||||
|
||||
@subsection Constructors
|
||||
@verbatim
|
||||
/**
|
||||
* Create an empty packet with a new uid (as returned
|
||||
* by getUid).
|
||||
*/
|
||||
Packet ();
|
||||
/**
|
||||
* Create a packet with a zero-filled payload.
|
||||
* The memory necessary for the payload is not allocated:
|
||||
* it will be allocated at any later point if you attempt
|
||||
* to fragment this packet or to access the zero-filled
|
||||
* bytes. The packet is allocated with a new uid (as
|
||||
* returned by getUid).
|
||||
*
|
||||
* \param size the size of the zero-filled payload
|
||||
*/
|
||||
Packet (uint32_t size);
|
||||
@end verbatim
|
||||
|
||||
@subsection Adding and removing Buffer data
|
||||
The below code is reproduced for Header class only; similar functions
|
||||
exist for Trailers.
|
||||
@verbatim
|
||||
/**
|
||||
* Add header to this packet. This method invokes the
|
||||
* ns3::Header::serializeTo method to request the header to serialize
|
||||
* itself in the packet buffer.
|
||||
*
|
||||
* \param header a reference to the header to add to this packet.
|
||||
*/
|
||||
void Add (Header const &header);
|
||||
/**
|
||||
* Deserialize header from this packet. This method invokes the
|
||||
* ns3::Header::deserializeFrom method to request the header to deserialize
|
||||
* itself from the packet buffer. This method does not remove
|
||||
* the data from the buffer. It merely reads it.
|
||||
*
|
||||
* \param header a reference to the header to deserialize from the buffer
|
||||
*/
|
||||
void Peek (Header &header);
|
||||
/**
|
||||
* Remove a deserialized header from the internal buffer.
|
||||
* This method removes the bytes read by Packet::peek from
|
||||
* the packet buffer.
|
||||
*
|
||||
* \param header a reference to the header to remove from the internal buffer.
|
||||
*/
|
||||
void Remove (Header const &header);
|
||||
/**
|
||||
* Add trailer to this packet. This method invokes the
|
||||
* ns3::Trailer::serializeTo method to request the trailer to serialize
|
||||
* itself in the packet buffer.
|
||||
*
|
||||
* \param trailer a reference to the trailer to add to this packet.
|
||||
*/
|
||||
@end verbatim
|
||||
|
||||
@subsection Adding and removing Tags
|
||||
@verbatim
|
||||
/**
|
||||
* Attach a tag to this packet. The tag is fully copied
|
||||
* in a packet-specific internal buffer. This operation
|
||||
* is expected to be really fast.
|
||||
*
|
||||
* \param tag a pointer to the tag to attach to this packet.
|
||||
*/
|
||||
template <typename T>
|
||||
void AddTag (T const &tag);
|
||||
/**
|
||||
* Remove a tag from this packet. The data stored internally
|
||||
* for this tag is copied in the input tag if an instance
|
||||
* of this tag type is present in the internal buffer. If this
|
||||
* tag type is not present, the input tag is not modified.
|
||||
*
|
||||
* This operation can be potentially slow and might trigger
|
||||
* unexpectedly large memory allocations. It is thus
|
||||
* usually a better idea to create a copy of this packet,
|
||||
* and invoke removeAllTags on the copy to remove all
|
||||
* tags rather than remove the tags one by one from a packet.
|
||||
*
|
||||
* \param tag a pointer to the tag to remove from this packet
|
||||
* \returns true if an instance of this tag type is stored
|
||||
* in this packet, false otherwise.
|
||||
*/
|
||||
template <typename T>
|
||||
bool RemoveTag (T &tag);
|
||||
/**
|
||||
* Copy a tag stored internally to the input tag. If no instance
|
||||
* of this tag is present internally, the input tag is not modified.
|
||||
*
|
||||
* \param tag a pointer to the tag to read from this packet
|
||||
* \returns true if an instance of this tag type is stored
|
||||
* in this packet, false otherwise.
|
||||
*/
|
||||
template <typename T>
|
||||
bool PeekTag (T &tag) const;
|
||||
/**
|
||||
* Remove all the tags stored in this packet. This operation is
|
||||
* much much faster than invoking removeTag n times.
|
||||
*/
|
||||
void RemoveAllTags (void);
|
||||
@end verbatim
|
||||
|
||||
@subsection Fragmentation
|
||||
@verbatim
|
||||
/**
|
||||
* Create a new packet which contains a fragment of the original
|
||||
* packet. The returned packet shares the same uid as this packet.
|
||||
*
|
||||
* \param start offset from start of packet to start of fragment to create
|
||||
* \param length length of fragment to create
|
||||
* \returns a fragment of the original packet
|
||||
*/
|
||||
Packet CreateFragment (uint32_t start, uint32_t length) const;
|
||||
|
||||
/**
|
||||
* Concatenate the input packet at the end of the current
|
||||
* packet. This does not alter the uid of either packet.
|
||||
*
|
||||
* \param packet packet to concatenate
|
||||
*/
|
||||
void addAtEnd (Packet packet);
|
||||
|
||||
/oncatenate the input packet at the end of the current
|
||||
* packet. This does not alter the uid of either packet.
|
||||
*
|
||||
* \param packet packet to concatenate
|
||||
*/
|
||||
void AddAtEnd (Packet packet);
|
||||
/**
|
||||
* Concatenate the fragment of the input packet identified
|
||||
* by the offset and size parameters at the end of the current
|
||||
* packet. This does not alter the uid of either packet.
|
||||
*
|
||||
* \param packet to concatenate
|
||||
* \param offset offset of fragment to copy from the start of the input packet
|
||||
* \param size size of fragment of input packet to copy.
|
||||
*/
|
||||
void AddAtEnd (Packet packet, uint32_t offset, uint32_t size);
|
||||
/**
|
||||
* Remove size bytes from the end of the current packet
|
||||
* It is safe to remove more bytes that what is present in
|
||||
* the packet.
|
||||
*
|
||||
* \param size number of bytes from remove
|
||||
*/
|
||||
void RemoveAtEnd (uint32_t size);
|
||||
/**
|
||||
* Remove size bytes from the start of the current packet.
|
||||
* It is safe to remove more bytes that what is present in
|
||||
* the packet.
|
||||
*
|
||||
* \param size number of bytes from remove
|
||||
*/
|
||||
void RemoveAtStart (uint32_t size);
|
||||
@end verbatim
|
||||
|
||||
@subsection Miscellaneous
|
||||
@verbatim
|
||||
/**
|
||||
* \returns the size in bytes of the packet (including the zero-filled
|
||||
* initial payload)
|
||||
*/
|
||||
uint32_t GetSize (void) const;
|
||||
/**
|
||||
* If you try to change the content of the buffer
|
||||
* returned by this method, you will die.
|
||||
*
|
||||
* \returns a pointer to the internal buffer of the packet.
|
||||
*/
|
||||
uint8_t const *PeekData (void) const;
|
||||
/**
|
||||
* A packet is allocated a new uid when it is created
|
||||
* empty or with zero-filled payload.
|
||||
*
|
||||
* \returns an integer identifier which uniquely
|
||||
* identifies this packet.
|
||||
*/
|
||||
uint32_t GetUid (void) const;
|
||||
@end verbatim
|
||||
|
||||
@section Using Headers
|
||||
@emph{walk through an example of adding a UDP header}
|
||||
|
||||
@section Using Tags
|
||||
@emph{walk through an example of adding a flow ID}
|
||||
|
||||
@section Using Fragmentation
|
||||
@emph{walk through an example of link-layer fragmentation/reassembly}
|
||||
|
||||
@section Sample program
|
||||
The below sample program (from @code{ns3/samples/main-packet.cc}) illustrates
|
||||
some use of the Packet, Header, and Tag classes.
|
||||
|
||||
@verbatim
|
||||
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/header.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
/* A sample Header implementation
|
||||
*/
|
||||
class MyHeader : public Header {
|
||||
public:
|
||||
MyHeader ();
|
||||
virtual ~MyHeader ();
|
||||
|
||||
void SetData (uint16_t data);
|
||||
uint16_t GetData (void) const;
|
||||
private:
|
||||
virtual void PrintTo (std::ostream &os) const;
|
||||
virtual void SerializeTo (Buffer::Iterator start) const;
|
||||
virtual void DeserializeFrom (Buffer::Iterator start);
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
|
||||
uint16_t m_data;
|
||||
};
|
||||
|
||||
MyHeader::MyHeader ()
|
||||
{}
|
||||
MyHeader::~MyHeader ()
|
||||
{}
|
||||
void
|
||||
MyHeader::PrintTo (std::ostream &os) const
|
||||
{
|
||||
os << "MyHeader data=" << m_data << std::endl;
|
||||
}
|
||||
uint32_t
|
||||
MyHeader::GetSerializedSize (void) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
void
|
||||
MyHeader::SerializeTo (Buffer::Iterator start) const
|
||||
{
|
||||
// serialize in head of buffer
|
||||
start.WriteHtonU16 (m_data);
|
||||
}
|
||||
void
|
||||
MyHeader::DeserializeFrom (Buffer::Iterator start)
|
||||
{
|
||||
// deserialize from head of buffer
|
||||
m_data = start.ReadNtohU16 ();
|
||||
}
|
||||
|
||||
void
|
||||
MyHeader::SetData (uint16_t data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
uint16_t
|
||||
MyHeader::GetData (void) const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
/* A sample Tag implementation
|
||||
*/
|
||||
struct MyTag {
|
||||
uint16_t m_streamId;
|
||||
};
|
||||
|
||||
static TagRegistration<struct MyTag> g_MyTagRegistration ("ns3::MyTag", 0);
|
||||
|
||||
|
||||
static void
|
||||
Receive (Packet p)
|
||||
{
|
||||
MyHeader my;
|
||||
p.Peek (my);
|
||||
p.Remove (my);
|
||||
std::cout << "received data=" << my.GetData () << std::endl;
|
||||
struct MyTag myTag;
|
||||
p.PeekTag (myTag);
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
Packet p;
|
||||
MyHeader my;
|
||||
my.SetData (2);
|
||||
std::cout << "send data=2" << std::endl;
|
||||
p.Add (my);
|
||||
struct MyTag myTag;
|
||||
myTag.m_streamId = 5;
|
||||
p.AddTag (myTag);
|
||||
Receive (p);
|
||||
return 0;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
@section Implementation details
|
||||
|
||||
@subsection Private member variables
|
||||
|
||||
A Packet object's interface provides access to some private
|
||||
data:
|
||||
@verbatim
|
||||
Buffer m_buffer;
|
||||
Tags m_tags;
|
||||
uint32_t m_uid;
|
||||
static uint32_t m_global_uid;
|
||||
@end verbatim
|
||||
Each Packet has a Buffer and a Tags object, and a 32-bit unique ID (m\_uid).
|
||||
A static member variable keeps track of the UIDs allocated. Note
|
||||
that real network packets do not have a UID; the UID is therefore an
|
||||
instance of data that normally would be stored as a Tag in the packet.
|
||||
However, it was felt that a UID is a special case that is so often
|
||||
used in simulations that it would be more convenient to store it
|
||||
in a member variable.
|
||||
|
||||
@subsection Buffer implementation
|
||||
|
||||
Class Buffer represents a buffer of bytes. Its size is
|
||||
automatically adjusted to hold any data prepended
|
||||
or appended by the user. Its implementation is optimized
|
||||
to ensure that the number of buffer resizes is minimized,
|
||||
by creating new Buffers of the maximum size ever used.
|
||||
The correct maximum size is learned at runtime during use by
|
||||
recording the maximum size of each packet.
|
||||
|
||||
Authors of new Header or Trailer classes need to know the public
|
||||
API of the Buffer class. (add summary here)
|
||||
|
||||
The byte buffer is implemented as follows:
|
||||
@verbatim
|
||||
struct BufferData {
|
||||
uint32_t m_count;
|
||||
uint32_t m_size;
|
||||
uint32_t m_initialStart;
|
||||
uint32_t m_dirtyStart;
|
||||
uint32_t m_dirtySize;
|
||||
uint8_t m_data[1];
|
||||
};
|
||||
struct BufferData *m_data;
|
||||
uint32_t m_zeroAreaSize;
|
||||
uint32_t m_start;
|
||||
uint32_t m_size;
|
||||
@end verbatim
|
||||
|
||||
@itemize @bullet
|
||||
@item @code{BufferData::m_count}: reference count for BufferData structure
|
||||
@item @code{BufferData::m_size}: size of data buffer stored in BufferData structure
|
||||
@item @code{BufferData::m_initialStart}: offset from start of data buffer where data was first inserted
|
||||
@item @code{BufferData::m_dirtyStart}: offset from start of buffer where every Buffer which holds a reference to this BufferData instance have written data so far
|
||||
@item @code{BufferData::m_dirtySize}: size of area where data has been written so far
|
||||
@item @code{BufferData::m_data}: pointer to data buffer
|
||||
@item @code{Buffer::m_zeroAreaSize}: size of zero area which extends before @code{m_initialStart}
|
||||
@item @code{Buffer::m_start}: offset from start of buffer to area used by this buffer
|
||||
@item @code{Buffer::m_size}: size of area used by this Buffer in its BufferData structure
|
||||
@end itemize
|
||||
|
||||
@float Figure,fig:buffer
|
||||
@caption{Implementation overview of a packet's byte Buffer.}
|
||||
@image{figures/buffer,15cm}
|
||||
@end float
|
||||
|
||||
This data structure is summarized in Figure @ref{fig:buffer}.
|
||||
Each Buffer holds a pointer to an instance of a BufferData. Most
|
||||
Buffers should be able to share the same underlying BufferData and
|
||||
thus simply increase the BufferData's reference count. If they have to
|
||||
change the content of a BufferData inside the Dirty Area, and if the
|
||||
reference count is not one, they first create a copy of the BufferData and
|
||||
then complete their state-changing operation.
|
||||
|
||||
@subsection Tags implementation
|
||||
Tags are implemented by a single pointer which points to the start of a
|
||||
linked list ofTagData data structures. Each TagData structure points
|
||||
to the next TagData in the list (its next pointer contains zero to
|
||||
indicate the end of the linked list). Each TagData contains an integer
|
||||
unique id which identifies the type of the tag stored in the TagData.
|
||||
@verbatim
|
||||
struct TagData {
|
||||
struct TagData *m_next;
|
||||
uint32_t m_id;
|
||||
uint32_t m_count;
|
||||
uint8_t m_data[Tags::SIZE];
|
||||
};
|
||||
class Tags {
|
||||
struct TagData *m_next;
|
||||
};
|
||||
@end verbatim
|
||||
|
||||
Adding a tag is a matter of inserting a new TagData at the head of
|
||||
the linked list. Looking at a tag requires you to find the relevant
|
||||
TagData in the linked list and copy its data into the user data
|
||||
structure. Removing a tag and updating the content of a tag
|
||||
requires a deep copy of the linked list before performing this operation.
|
||||
On the other hand, copying a Packet and its tags is a matter of
|
||||
copying the TagData head pointer and incrementing its reference count.
|
||||
|
||||
Tags are found by the unique mapping betweent the Tag type and
|
||||
its underlying id. This is why at most one instance of any Tag
|
||||
can be stored in a packet. The mapping between Tag type and
|
||||
underlying id is performed by a registration as follows:
|
||||
@verbatim
|
||||
/* A sample Tag implementation
|
||||
*/
|
||||
struct MyTag {
|
||||
uint16_t m_streamId;
|
||||
};
|
||||
@end verbatim
|
||||
|
||||
@emph{add description of TagRegistration for printing}
|
||||
|
||||
@subsection Memory management
|
||||
|
||||
@emph{Describe free list.}
|
||||
|
||||
@emph{Describe dataless vs. data-full packets.}
|
||||
|
||||
@subsection Copy-on-write semantics
|
||||
The current implementation of the byte buffers and tag list is based
|
||||
on COW (Copy On Write). An introduction to COW can be found in Scott
|
||||
Meyer's "More Effective C++", items 17 and 29). This design feature
|
||||
and aspects of the public interface borrows from the packet design
|
||||
of the Georgia Tech Network Simulator.
|
||||
This implementation of COW uses a customized reference counting
|
||||
smart pointer class.
|
||||
|
||||
What COW means is that
|
||||
copying packets without modifying them is very cheap (in terms of CPU
|
||||
and memory usage) and modifying them can be also very cheap. What is
|
||||
key for proper COW implementations is being
|
||||
able to detect when a given modification of the state of a packet triggers
|
||||
a full copy of the data prior to the modification: COW systems need
|
||||
to detect when an operation is ``dirty'' and must therefore invoke
|
||||
a true copy.
|
||||
|
||||
Dirty operations:
|
||||
@itemize @bullet
|
||||
@item Packet::RemoveTag()
|
||||
@item Packet::Add()
|
||||
@item both versions of ns3::Packet::AddAtEnd()
|
||||
@end itemize
|
||||
|
||||
Non-dirty operations:
|
||||
@itemize @bullet
|
||||
@item Packet::AddTag()
|
||||
@item Packet::RemoveAllTags()
|
||||
@item Packet::PeekTag()
|
||||
@item Packet::Peek()
|
||||
@item Packet::Remove()
|
||||
@item Packet::CreateFragment()
|
||||
@item Packet::RemoveAtStart()
|
||||
@item Packet::RemoveAtEnd()
|
||||
@end itemize
|
||||
|
||||
Dirty operations will always be slower than non-dirty operations,
|
||||
sometimes by several orders of magnitude. However, even the
|
||||
dirty operations have been optimized for common use-cases which
|
||||
means that most of the time, these operations will not trigger
|
||||
data copies and will thus be still very fast.
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
@anchor{chap:rv}
|
||||
@node Random variables
|
||||
@chapter Random variables
|
||||
|
||||
ns-3 contains a built-in pseudo-random number generator (PRNG).
|
||||
It is important for serious users of the simulator to understand
|
||||
the functionality, configuration, and usage of this PRNG, and
|
||||
to decide whether it is sufficient for his or her research use.
|
||||
|
||||
@node Quick Overview
|
||||
@section Quick Overview
|
||||
|
||||
ns-3 random numbers are provided via instances of @code{class RandomVariable}.
|
||||
@itemize @bullet
|
||||
@item @strong{by default, ns-3 simulations use a random seed}; if there is any
|
||||
randomness in the simulation, each run of the program will yield different results. To use a fixed seed, users must call
|
||||
@code{RandomVariable::UseGlobalSeed ()} at the beginning of the program;
|
||||
see section @xref{Seeding and independent replications}
|
||||
@item each RandomVariable used in ns-3 has a virtual random number
|
||||
generator associated with it; all random variables use either a fixed
|
||||
or random seed based on the use of the global seed (previous bullet);
|
||||
@item if you intend to perform multiple runs of the same scenario, with
|
||||
different random numbers, please be sure to read the section on how to
|
||||
perform independent replications: @xref{Seeding and independent replications}.
|
||||
@end itemize
|
||||
|
||||
Read further for more explanation about the random number facility for
|
||||
ns-3.
|
||||
|
||||
@node Background
|
||||
@section Background
|
||||
|
||||
Simulations use a lot of random numbers; the study in [cite]
|
||||
found that most network simulations spend as much as 50%
|
||||
of the CPU generating random numbers. Simulation users need
|
||||
to be concerned with the quality of the (pseudo) random numbers and
|
||||
the independence between different streams of random numbers.
|
||||
|
||||
Users need to be concerned with a few issues, such as:
|
||||
@itemize @bullet
|
||||
@item the seeding of the random number generator and whether a
|
||||
simulation run is deterministic or not,
|
||||
@item how to acquire different streams of random numbers that are
|
||||
independent from one another, and
|
||||
@item how long it takes for streams to cycle
|
||||
@end itemize
|
||||
|
||||
We will introduce a few terms here: a RNG provides a long sequence
|
||||
of (pseudo) random numbers.
|
||||
The length of this sequence is called the @emph{cycle length}
|
||||
or @emph{period}, after which the RNG will repeat itself.
|
||||
This sequence can
|
||||
be partitioned into disjoint @emph{streams}. A stream of a
|
||||
RNG is a contiguous subset or block of the RNG sequence.
|
||||
For instance, if the
|
||||
RNG period is of length N, and two streams are provided from this
|
||||
RNG, then
|
||||
the first stream might use the first N/2 values and the second
|
||||
stream might produce the second N/2 values. An important property
|
||||
here is that the two streams are uncorrelated. Likewise, each
|
||||
stream can be partitioned disjointly to a number of
|
||||
uncorrelated @emph{substreams}. The underlying RNG hopefully
|
||||
produces a pseudo-random sequence of numbers with a very long
|
||||
cycle length, and partitions this into streams and substreams in an
|
||||
efficient manner.
|
||||
|
||||
ns-3 uses the same underlying random number generator as does
|
||||
ns-2: the MRG32k3a generator from Pierre L'Ecuyer. A
|
||||
detailed description can be found in
|
||||
@uref{http://www.iro.umontreal.ca/~lecuyer/myftp/papers/streams00.pdf,,}.
|
||||
The MRG32k3a generator provides 1.8x10^19 independent
|
||||
streams of random numbers, each of which consists of
|
||||
2.3x10^15 substreams. Each substream has a period
|
||||
(@emph{i.e.}, the number of random numbers before overlap) of
|
||||
7.6x10^22. The period of the entire generator is
|
||||
3.1x10^57. Figure ref-streams provides a graphical idea of
|
||||
how the streams and substreams fit together.
|
||||
|
||||
Class @code{ns3::RandomVariable} is the public interface to this
|
||||
underlying random number generator. When users create new
|
||||
RandomVariables (such as UniformVariable, ExponentialVariable,
|
||||
etc.), they create an object that uses one of the distinct, independent
|
||||
streams of the random number generator. Therefore, each
|
||||
object of type RandomVariable has, conceptually, its own "virtual" RNG.
|
||||
Furthermore, each RandomVariable can be configured to use
|
||||
one of the set of substreams drawn from the main stream.
|
||||
|
||||
An alternate implementation would be to allow each RandomVariable
|
||||
to have its own (differently seeded) RNG. However, we cannot
|
||||
guarantee as strongly that the different sequences would be
|
||||
uncorrelated in such a case; hence, we prefer to use a single RNG
|
||||
and streams and substreams from it.
|
||||
|
||||
@anchor{chap:rv:indeprep}
|
||||
@node Seeding and independent replications
|
||||
@section Seeding and independent replications
|
||||
|
||||
ns-3 simulations can be configured to produce deterministic or
|
||||
random results. If the ns-3 simulation is configured to use
|
||||
a fixed, deterministic seed with the same run number, it should give
|
||||
the same output each time it is run.
|
||||
|
||||
By default, ns-3 simulations use random seeds where the seeding
|
||||
is drawn from @code{/dev/random} (if it is available) or else from
|
||||
the time of day. A user who wants to fix the initial seeding
|
||||
of the PRNG must call the following static method during simulation
|
||||
configuration:
|
||||
@verbatim
|
||||
RandomVariable::UseGlobalSeed (uint32_t s0, s1, s2, s3, s4, s5);
|
||||
@end verbatim
|
||||
where the six parameters are each of type uint32_t.
|
||||
|
||||
A typical use case is to run a simulation as a sequence of independent
|
||||
trials, so as to compute statistics on a large number of independent
|
||||
runs. The user can either change the global seed and rerun the
|
||||
simulation, or can advance the substream state of the RNG.
|
||||
This seeding and substream state setting must be called before any
|
||||
random variables are created; e.g.
|
||||
|
||||
@verbatim
|
||||
RandomVariable::UseGlobalSeed(1,2,3,4,5,6);
|
||||
int N = atol(argv[1]); //read in run number from command line
|
||||
RandomVariable::SetRunNumber(N);
|
||||
// Now, create random variables
|
||||
UniformVariable x(0,10);
|
||||
ExponentialVariable y(2902);
|
||||
...
|
||||
@end verbatim
|
||||
|
||||
Which is better, setting a new seed or advancing the substream state?
|
||||
There is no guarantee that the streams
|
||||
produced by two random seeds will not overlap. The only way to
|
||||
guarantee that two streams do not overlap is to use the substream
|
||||
capability provided by the RNG implementation.
|
||||
@strong{Therefore, use the substream capability to produce
|
||||
multiple independent runs of the same simulation.}
|
||||
In other words, the more statistically rigorous way to configure
|
||||
multiple independent replications is not to simply ignore the
|
||||
seeding (and use /dev/random to seed the generator each time) but
|
||||
instead to use a fixed seed and to iterate the run number.
|
||||
This implementation allows for a maximum of
|
||||
2.3x10^15 independent replications using the substreams.
|
||||
|
||||
@node class RandomVariable
|
||||
@section class RandomVariable
|
||||
|
||||
All random variables should derive from @code{class RandomVariable}.
|
||||
This base class provides a few static methods for globally configuring
|
||||
the behavior of the random number generator. Derived classes
|
||||
provide API for drawing random variates from the particular
|
||||
distribution being supported.
|
||||
|
||||
Each RandomVariable created in the simulation is given a generator
|
||||
that is a new RNGStream from the underlying PRNG.
|
||||
Used in this manner, the L'Ecuyer implementation allows for a maximum of
|
||||
1.8x10^19 random variables. Each random variable in
|
||||
a single replication can produce up to 7.6x10^22 random
|
||||
numbers before overlapping.
|
||||
|
||||
@node Base class public API
|
||||
@section Base class public API
|
||||
|
||||
Below are excerpted a few public methods of @code{class RandomVariable}
|
||||
that deal with the global configuration and state of the RNG.
|
||||
@verbatim
|
||||
/**
|
||||
* \brief Set seeding behavior
|
||||
*
|
||||
* Specify whether the POSIX device /dev/random is to
|
||||
* be used for seeding. When this is used, the underlying
|
||||
* generator is seeded with data from /dev/random instead of
|
||||
* being seeded based upon the time of day. Defaults to true.
|
||||
*/
|
||||
static void UseDevRandom(bool udr = true);
|
||||
|
||||
/**
|
||||
* \brief Use the global seed to force precisely reproducible results.
|
||||
*/
|
||||
static void UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2,
|
||||
uint32_t s3, uint32_t s4, uint32_t s5);
|
||||
|
||||
/**
|
||||
* \brief Set the run number of this simulation
|
||||
*/
|
||||
static void SetRunNumber(uint32_t n);
|
||||
|
||||
/**
|
||||
* \brief Get the internal state of the RNG
|
||||
*
|
||||
* This function is for power users who understand the inner workings
|
||||
* of the underlying RngStream method used. It returns the internal
|
||||
* state of the RNG via the input parameter.
|
||||
* \param seed Output parameter; gets overwritten with the internal state
|
||||
* of the RNG.
|
||||
*/
|
||||
void GetSeed(uint32_t seed[6]) const;
|
||||
@end verbatim
|
||||
|
||||
We have already described the seeding configuration above.
|
||||
|
||||
@node Types of RandomVariables
|
||||
@section Types of RandomVariables
|
||||
|
||||
The following types of random variables are provided, and are documented
|
||||
in the ns-3 Doxygen or by reading @code{src/core/random-variable.h}. Users
|
||||
can also create their own custom random variables by deriving from
|
||||
class RandomVariable.
|
||||
@itemize @bullet
|
||||
@item @code{class UniformVariable }
|
||||
@item @code{class ConstantVariable }
|
||||
@item @code{class SequentialVariable }
|
||||
@item @code{class ExponentialVariable }
|
||||
@item @code{class ParetoVariable }
|
||||
@item @code{class WeibullVariable }
|
||||
@item @code{class NormalVariable }
|
||||
@item @code{class EmpiricalVariable }
|
||||
@item @code{class IntEmpiricalVariable }
|
||||
@item @code{class DeterministicVariable }
|
||||
@item @code{class LogNormalVariable }
|
||||
@item @code{class TriangularVariable }
|
||||
@end itemize
|
||||
|
||||
@node Semantics of RandomVariable objects
|
||||
@section Semantics of RandomVariable objects
|
||||
|
||||
RandomVariable objects have value semantics. This means that they
|
||||
can be passed by value to functions. The can also be passed by
|
||||
reference to const. RandomVariables do not derive from
|
||||
@code{ns3::Object} and we do not use smart pointers to manage them;
|
||||
they are either allocated on the stack or else users explicitly manage
|
||||
any heap-allocated RandomVariables.
|
||||
|
||||
RandomVariable objects can also be used in ns-3 attributes, which means
|
||||
that values can be set for them through the ns-3 attribute system.
|
||||
An example is in the propagation models for WifiNetDevice:
|
||||
@verbatim
|
||||
TypeId
|
||||
RandomPropagationDelayModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::RandomPropagationDelayModel")
|
||||
.SetParent<PropagationDelayModel> ()
|
||||
.AddConstructor<RandomPropagationDelayModel> ()
|
||||
.AddAttribute ("Variable",
|
||||
"The random variable which generates random delays (s).",
|
||||
RandomVariableValue (UniformVariable (0.0, 1.0)),
|
||||
MakeRandomVariableAccessor (&RandomPropagationDelayModel::m_variable),
|
||||
MakeRandomVariableChecker ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@end verbatim
|
||||
Here, the ns-3 user can change the default random variable for this
|
||||
delay model (which is a UniformVariable ranging from 0 to 1) through
|
||||
the attribute system.
|
||||
|
||||
@node Using other PRNG
|
||||
@section Using other PRNG
|
||||
|
||||
There is presently no support for substituting a different underlying
|
||||
random number generator (e.g., the GNU Scientific Library or the Akaroa
|
||||
package). Patches are welcome.
|
||||
|
||||
@node More advanced usage
|
||||
@section More advanced usage
|
||||
|
||||
@emph{To be completed}
|
||||
|
||||
@node Publishing your results
|
||||
@section Publishing your results
|
||||
|
||||
When you publish simulation results, a key piece of configuration
|
||||
information that you should always state is how you used the
|
||||
the random number generator.
|
||||
@itemize @bullet
|
||||
@item what seeds you used,
|
||||
@item what RNG you used if not the default,
|
||||
@item how were independent runs performed,
|
||||
@item for large simulations, how did you check that you did not cycle.
|
||||
@end itemize
|
||||
|
||||
It is incumbent on the researcher publishing results to include enough
|
||||
information to allow others to reproduce his or her results. It is
|
||||
also incumbent on the researcher to convince oneself that the random
|
||||
numbers used were statistically valid, and to state in the paper why
|
||||
such confidence is assumed.
|
||||
|
||||
@node Summary
|
||||
@section Summary
|
||||
|
||||
Let's review what things you should do when creating a simulation.
|
||||
|
||||
@itemize @bullet
|
||||
@item Decide whether you are running with a fixed seed or random seed;
|
||||
a random seed is the default,
|
||||
@item Decide how you are going to manage independent replications, if
|
||||
applicable,
|
||||
@item Convince yourself that you are not drawing more random values
|
||||
than the cycle length, if you are running a long simulation, and
|
||||
@item When you publish, follow the guidelines above about documenting your
|
||||
use of the random number generator.
|
||||
@end itemize
|
||||
|
||||
The program @emph{samples/main-random.cc} has some examples of usage.
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
@node Routing overview
|
||||
@chapter Routing overview
|
||||
|
||||
This chapter describes the overall design of routing in the
|
||||
@code{src/internet-stack}
|
||||
module, and some details about the routing approachs currently
|
||||
implemented.
|
||||
|
||||
@node Routing-Overview
|
||||
@section Overview
|
||||
|
||||
We intend to support traditional routing approaches and protocols,
|
||||
ports of open source routing implementations, and facilitate research
|
||||
into unorthodox routing techniques.
|
||||
For simulations that are not primarily focused on routing and that
|
||||
simply want correct routing tables to occur somehow, we have an
|
||||
global centralized routing capability. A singleton object
|
||||
(GlobalRouteManager) be instantiated, builds a network map, and
|
||||
populates a forwarding table on each node at time t=0 in the
|
||||
simulation. Simulation script writers can use the same node
|
||||
API to manually enter routes as well.
|
||||
|
||||
@node Support for multiple routing protocols
|
||||
@section Support for multiple routing protocols
|
||||
|
||||
Typically, multiple routing protocols are supported in user space and
|
||||
coordinate to write a single forwarding table in the kernel. Presently
|
||||
in @command{ns-3}, the implementation instead allows for multiple routing
|
||||
protocols to build/keep their own routing state, and the IPv4 implementation
|
||||
will query each one of these routing protocols (in some order determined
|
||||
by the simulation author) until a route is found.
|
||||
|
||||
We chose this approach because it may better
|
||||
faciliate the integration of disparate routing approaches that may
|
||||
be difficult to coordinate the writing to a single table, approaches
|
||||
where more information than destination IP address (e.g., source
|
||||
routing) is used to determine the next hop, and on-demand
|
||||
routing approaches where packets must be cached.
|
||||
|
||||
There are presently two routing protocols defined:
|
||||
@itemize @bullet
|
||||
@item class Ipv4StaticRouting (covering both unicast and multicast)
|
||||
@item Optimized Link State Routing (a MANET protocol defined in
|
||||
@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626})
|
||||
@end itemize
|
||||
but first we describe how multiple routing protocols are supported.
|
||||
|
||||
@subsection class Ipv4RoutingProtocol
|
||||
|
||||
@code{class Ipv4RoutingProtocol} derives from ns-3 Object which means
|
||||
that it supports interface aggregation and reference counting. Routing
|
||||
protocols should inherit from this class, defined in src/node/ipv4.cc.
|
||||
|
||||
The main function that must be supported by these protocols is called
|
||||
@code{RequestRoute}.
|
||||
@verbatim
|
||||
* This method is called whenever a node's IPv4 forwarding engine
|
||||
* needs to lookup a route for a given packet and IP header.
|
||||
*
|
||||
* The routing protocol implementation may determine immediately it
|
||||
* should not be handling this particular the route request. For
|
||||
* instance, a routing protocol may decline to search for routes for
|
||||
* certain classes of addresses, like link-local. In this case,
|
||||
* RequestRoute() should return false and the routeReply callback
|
||||
* must not be invoked.
|
||||
*
|
||||
* If the routing protocol implementations assumes it can provide
|
||||
* the requested route, then it should return true, and the
|
||||
* routeReply callback must be invoked, either immediately before
|
||||
* returning true (synchronously), or in the future (asynchronous).
|
||||
* The routing protocol may use any information available in the IP
|
||||
* header and packet as routing key, although most routing protocols
|
||||
* use only the destination address (as given by
|
||||
* ipHeader.GetDestination ()). The routing protocol is also
|
||||
* allowed to add a new header to the packet, which will appear
|
||||
* immediately after the IP header, although most routing do not
|
||||
* insert any extra header.
|
||||
*/
|
||||
virtual bool RequestRoute (uint32_t ifIndex,
|
||||
const Ipv4Header &ipHeader,
|
||||
Ptr<Packet> packet,
|
||||
RouteReplyCallback routeReply) = 0;
|
||||
@end verbatim
|
||||
|
||||
This class also provides a typedef (used above) for a special Callback
|
||||
that will pass to the callback function the Ipv4Route that is found (see the
|
||||
Doxygen documentation):
|
||||
@verbatim
|
||||
typedef Callback<void, bool, const Ipv4Route&, Ptr<Packet>, const Ipv4Header&> RouteReplyCallback;
|
||||
@end verbatim
|
||||
|
||||
@subsection Ipv4::AddRoutingProtocol
|
||||
|
||||
Class Ipv4 provides a pure virtual function declaration for the
|
||||
method that allows one to add a routing protocol:
|
||||
@verbatim
|
||||
void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
|
||||
int16_t priority);
|
||||
@end verbatim
|
||||
This method is implemented by class Ipv4L3Protocol in the internet-stack
|
||||
module.
|
||||
|
||||
The priority variable above governs the priority in which the routing
|
||||
protocols are inserted. Notice that it is a signed int.
|
||||
When the class Ipv4L3Protocol is instantiated, a single routing
|
||||
protocol (Ipv4StaticRouting, introduced below) is added at priority
|
||||
zero. Internally, a list of Ipv4RoutingProtocols is stored, and
|
||||
and the routing protocols are each consulted in decreasing order
|
||||
of priority to see whether a match is found. Therefore, if you
|
||||
want your Ipv4RoutingProtocol to have priority lower than the static
|
||||
routing, insert it with priority less than 0; e.g.:
|
||||
@verbatim
|
||||
m_ipv4->AddRoutingProtocol (m_routingTable, -10);
|
||||
@end verbatim
|
||||
|
||||
@subsection Ipv4L3Protocol::Lookup
|
||||
|
||||
The main function for obtaining a route is shown below:
|
||||
@verbatim
|
||||
Ipv4L3Protocol::Lookup (
|
||||
uint32_t ifIndex,
|
||||
Ipv4Header const &ipHeader,
|
||||
Ptr<Packet> packet,
|
||||
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
|
||||
@end verbatim
|
||||
|
||||
This function will search the list of routing protocols, in priority order,
|
||||
until a route is found. It will then invoke the RouteReplyCallback
|
||||
and no further routing protocols will be searched. If the caller does
|
||||
not want to constrain the possible interface, it can be wildcarded
|
||||
as such:
|
||||
@verbatim
|
||||
Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
|
||||
@end verbatim
|
||||
|
||||
@node Roadmap and Future work
|
||||
@section Roadmap and Future work
|
||||
|
||||
Some goals for future support are:
|
||||
|
||||
Users should be able to trace (either debug print, or redirect to a trace
|
||||
file) the routing table in a format such as used in an
|
||||
Unix implementation:
|
||||
@verbatim
|
||||
# netstat -nr (or # route -n)
|
||||
Kernel IP routing table
|
||||
Destination Gateway Genmask Flags MSS Window irtt Iface
|
||||
127.0.0.1 * 255.255.255.255 UH 0 0 0 lo
|
||||
172.16.1.0 * 255.255.255.0 U 0 0 0 eth0
|
||||
172.16.2.0 172.16.1.1 255.255.255.0 UG 0 0 0 eth0
|
||||
|
||||
# ip route show
|
||||
192.168.99.0/24 dev eth0 scope link
|
||||
127.0.0.0/8 dev lo scope link
|
||||
default via 192.168.99.254 dev eth0
|
||||
@end verbatim
|
||||
|
||||
Global computation of multicast routing should be implemented as well.
|
||||
This would ignore group membership and ensure that a copy of every
|
||||
sourced multicast datagram would be delivered to each node.
|
||||
This might be implemented as an RPF mechanism that functioned on-demand
|
||||
by querying the forwarding table,
|
||||
and perhaps optimized by a small multicast forwarding cache. It is
|
||||
a bit trickier to implement over wireless links where the input
|
||||
interface is the same as the output interface; other aspects of the
|
||||
packet must be considered and the forwarding logic slightly changed
|
||||
to allow for forwarding out the same interface.
|
||||
|
||||
In the future, work on bringing XORP or quagga routing to ns, but it will
|
||||
take several months to port and enable.
|
||||
|
||||
There are presently no roadmap plans for IPv6.
|
||||
|
||||
@node Static routing
|
||||
@section Static routing
|
||||
|
||||
The internet-stack module provides one routing protocol (Ipv4StaticRouting)
|
||||
by default. This routing protocol allows one to add unicast or multicast
|
||||
static routes to a node.
|
||||
|
||||
@node Unicast routing
|
||||
@section Unicast routing
|
||||
|
||||
The unicast static routing API may be accessed via the functions
|
||||
@verbatim
|
||||
void Ipv4::AddHostRouteTo ()
|
||||
void Ipv4::AddNetworkRouteTo ()
|
||||
void Ipv4::SetDefaultRoute ()
|
||||
uint32_t Ipv4::GetNRoutes ()
|
||||
Ipv4Route Ipv4::GetRoute ()
|
||||
@end verbatim
|
||||
|
||||
@uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation
|
||||
provides full documentation of these methods. These methods are forwarding
|
||||
functions to the actual implementation in Ipv4StaticRouting, when using
|
||||
the internet-stack module.
|
||||
|
||||
@node Multicast routing
|
||||
@section Multicast routing
|
||||
|
||||
The following function is used to add a static multicast route
|
||||
to a node:
|
||||
@verbatim
|
||||
void
|
||||
Ipv4StaticRouting::AddMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces);
|
||||
@end verbatim
|
||||
|
||||
A multicast route must specify an origin IP address, a multicast group and
|
||||
an input network interface index as conditions and provide a vector of
|
||||
output network interface indices over which packets matching the conditions
|
||||
are sent.
|
||||
|
||||
Typically there are two main types of multicast routes: routes of the
|
||||
first kind are used during forwarding. All of the conditions must be
|
||||
exlicitly provided. The second kind of routes are used to get packets off
|
||||
of a local node. The difference is in the input interface. Routes for
|
||||
forwarding will always have an explicit input interface specified. Routes
|
||||
off of a node will always set the input interface to a wildcard specified
|
||||
by the index Ipv4RoutingProtocol::IF\_INDEX\_ANY.
|
||||
|
||||
For routes off of a local node wildcards may be used in the origin and
|
||||
multicast group addresses. The wildcard used for Ipv4Adresses is that
|
||||
address returned by Ipv4Address::GetAny () -- typically "0.0.0.0". Usage
|
||||
of a wildcard allows one to specify default behavior to varying degrees.
|
||||
|
||||
For example, making the origin address a wildcard, but leaving the
|
||||
multicast group specific allows one (in the case of a node with multiple
|
||||
interfaces) to create different routes using different output interfaces
|
||||
for each multicast group.
|
||||
|
||||
If the origin and multicast addresses are made wildcards, you have created
|
||||
essentially a default multicast address that can forward to multiple
|
||||
interfaces. Compare this to the actual default multicast address that is
|
||||
limited to specifying a single output interface for compatibility with
|
||||
existing functionality in other systems.
|
||||
|
||||
Another command sets the default multicast route:
|
||||
@verbatim
|
||||
void
|
||||
Ipv4StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface);
|
||||
@end verbatim
|
||||
|
||||
This is the multicast equivalent of the unicast version SetDefaultRoute.
|
||||
We tell the routing system what to do in the case where a specific route
|
||||
to a destination multicast group is not found. The system forwards
|
||||
packets out the specified interface in the hope that "something out there"
|
||||
knows better how to route the packet. This method is only used in
|
||||
initially sending packets off of a host. The default multicast route is
|
||||
not consulted during forwarding -- exact routes must be specified using
|
||||
AddMulticastRoute for that case.
|
||||
|
||||
Since we're basically sending packets to some entity we think may know
|
||||
better what to do, we don't pay attention to "subtleties" like origin
|
||||
address, nor do we worry about forwarding out multiple interfaces. If the
|
||||
default multicast route is set, it is returned as the selected route from
|
||||
LookupStatic irrespective of origin or multicast group if another specific
|
||||
route is not found.
|
||||
|
||||
Finally, a number of additional functions are provided to fetch and
|
||||
remove multicast routes:
|
||||
@verbatim
|
||||
uint32_t GetNMulticastRoutes (void) const;
|
||||
|
||||
Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;
|
||||
|
||||
Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const;
|
||||
|
||||
bool RemoveMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface);
|
||||
|
||||
void RemoveMulticastRoute (uint32_t index);
|
||||
@end verbatim
|
||||
|
||||
@node Global centralized routing
|
||||
@section Global centralized routing
|
||||
|
||||
Presently, global centralized IPv4 @emph{unicast} routing over both
|
||||
point-to-point and shared (CSMA) links is supported.
|
||||
The global centralized routing will be modified in the future to
|
||||
reduce computations once profiling finds the performance bottlenecks.
|
||||
|
||||
@node Global Unicast Routing API
|
||||
@section Global Unicast Routing API
|
||||
|
||||
The public API is very minimal. User scripts include the following:
|
||||
@verbatim
|
||||
#include "ns3/global-route-manager.h"
|
||||
@end verbatim
|
||||
|
||||
After IP addresses are configured, the following function call will
|
||||
cause all of the nodes that have an Ipv4 interface to receive
|
||||
forwarding tables entered automatically by the GlobalRouteManager:
|
||||
@verbatim
|
||||
GlobalRouteManager::PopulateRoutingTables ();
|
||||
@end verbatim
|
||||
|
||||
@emph{Note:} A reminder that the wifi NetDevice is not yet supported
|
||||
(only CSMA and PointToPoint).
|
||||
|
||||
@node Global Routing Implementation
|
||||
@section Global Routing Implementation
|
||||
|
||||
A singleton object (GlobalRouteManager) is responsible for populating
|
||||
the static routes on each node, using the public Ipv4 API of that node.
|
||||
It queries each node in the topology for a "globalRouter" interface.
|
||||
If found, it uses the API of that interface to obtain a "link state
|
||||
advertisement (LSA)" for the router. Link State Advertisements
|
||||
are used in OSPF routing, and we follow their formatting.
|
||||
|
||||
The GlobalRouteManager populates a link state database with LSAs
|
||||
gathered from the entire topology. Then, for each router in the topology,
|
||||
the GlobalRouteManager executes the OSPF shortest path first (SPF)
|
||||
computation on the database, and populates the routing tables on each
|
||||
node.
|
||||
|
||||
The quagga (http://www.quagga.net) OSPF implementation was used as the
|
||||
basis for the routing computation logic.
|
||||
One benefit of following an existing OSPF SPF implementation is that
|
||||
OSPF already has defined link state advertisements for all common
|
||||
types of network links:
|
||||
@itemize @bullet
|
||||
@item point-to-point (serial links)
|
||||
@item point-to-multipoint (Frame Relay, ad hoc wireless)
|
||||
@item non-broadcast multiple access (ATM)
|
||||
@item broadcast (Ethernet)
|
||||
@end itemize
|
||||
Therefore, we think that enabling these other link types will be more
|
||||
straightforward now that the underlying OSPF SPF framework is in place.
|
||||
|
||||
Presently, we can handle IPv4 point-to-point, numbered links, as well
|
||||
as shared broadcast (CSMA) links, and we do not do equal-cost multipath.
|
||||
|
||||
The GlobalRouteManager first walks the list of nodes and aggregates
|
||||
a GlobalRouter interface to each one as follows:
|
||||
@verbatim
|
||||
typedef std::vector < Ptr<Node> >::iterator Iterator;
|
||||
for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
|
||||
{
|
||||
Ptr<Node> node = *i;
|
||||
Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> (node);
|
||||
node->AggregateObject (globalRouter);
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
This interface is later queried and used to generate a Link State
|
||||
Advertisement for each router, and this link state database is
|
||||
fed into the OSPF shortest path computation logic. The Ipv4 API
|
||||
is finally used to populate the routes themselves.
|
||||
|
||||
@node Optimized Link State Routing (OLSR)
|
||||
@section Optimized Link State Routing (OLSR)
|
||||
|
||||
This is the first dynamic routing protocol for @command{ns-3}. The implementation
|
||||
is found in the src/routing/olsr directory, and an example script is in
|
||||
examples/simple-point-to-point-olsr.cc.
|
||||
|
||||
The following commands will enable OLSR in a simulation.
|
||||
|
||||
@verbatim
|
||||
olsr::EnableAllNodes (); // Start OLSR on all nodes
|
||||
olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on
|
||||
// a list of nodes
|
||||
olsr::EnableNode (Ptr<Node> node); // Start OLSR on "node" only
|
||||
@end verbatim
|
||||
|
||||
Once instantiated, the agent can be started with the Start() command,
|
||||
and the OLSR "main interface" can be set with the SetMainInterface()
|
||||
command. A number of protocol constants are defined in olsr-agent-impl.cc.
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
@node Sockets APIs
|
||||
@chapter Sockets APIs
|
||||
|
||||
The @uref{http://en.wikipedia.org/wiki/Berkeley_sockets,,sockets API}
|
||||
is a long-standing API used by user-space applications to access
|
||||
network services in the kernel. A ``socket'' is an abstraction, like
|
||||
a Unix file handle, that allows applications to connect to other
|
||||
Internet hosts and exchange reliable byte streams and unreliable
|
||||
datagrams, among other services.
|
||||
|
||||
ns-3 provides two types of sockets APIs, and it is important to
|
||||
understand the differences between them. The first is a @emph{native}
|
||||
ns-3 API, while the second uses the services of the native API to
|
||||
provide a @uref{http://en.wikipedia.org/wiki/POSIX,,POSIX-like}
|
||||
API as part of an overall application process. Both APIs strive
|
||||
to be close to the typical sockets API that application writers
|
||||
on Unix systems are accustomed to, but the POSIX variant is much
|
||||
closer to a real system's sockets API.
|
||||
|
||||
@section ns-3 sockets API
|
||||
|
||||
The native sockets API for ns-3 provides an interface to various
|
||||
types of transport protocols (TCP, UDP) as well as to packet sockets
|
||||
and, in the future, Netlink-like sockets. However, users are cautioned
|
||||
to understand that the semantics are @strong{not} the exact same as
|
||||
one finds in a real system (for an API which is very much aligned
|
||||
to real systems, see the next section).
|
||||
|
||||
@code{class ns3::Socket} is defined in @code{src/node/socket.cc,h}.
|
||||
Readers will note that many public member functions are aligned
|
||||
with real sockets function calls, and all other things being equal,
|
||||
we have tried to align with a Posix sockets API. However, note that:
|
||||
|
||||
@itemize @bullet
|
||||
@item ns-3 applications handle a smart pointer to a Socket object, not
|
||||
a file descriptor;
|
||||
@item there is no notion of synchronous API or a ``blocking'' API;
|
||||
in fact, the model for interaction between application and socket is
|
||||
one of asynchronous I/O, which is not typically found in real systems
|
||||
(more on this below);
|
||||
@item the C-style socket address structures are not used;
|
||||
@item the API is not a complete sockets API, such as supporting
|
||||
all socket options or all function variants;
|
||||
@item many calls use @code{ns3::Packet} class to transfer data
|
||||
between application and socket. This may seem a little funny to
|
||||
people to pass ``Packets'' across a stream socket API, but think
|
||||
of these packets as just fancy byte buffers at this level (more
|
||||
on this also below).
|
||||
@end itemize
|
||||
|
||||
@subsection Basic operation and calls
|
||||
|
||||
@float Figure,fig:sockets-overview
|
||||
@caption{Implementation overview of native sockets API}
|
||||
@image{figures/sockets-overview, 10cm}
|
||||
@end float
|
||||
|
||||
@subsubsection Creating sockets
|
||||
|
||||
An application that wants to use sockets must first create one.
|
||||
On real systems, this is accomplished by calling socket():
|
||||
@verbatim
|
||||
int
|
||||
socket(int domain, int type, int protocol);
|
||||
@end verbatim
|
||||
which creates a socket in the system and returns an integer descriptor.
|
||||
|
||||
In ns-3, we have no equivalent of a system call at the lower layers,
|
||||
so we adopt the following model. There are certain @emph{factory}
|
||||
objects that can create sockets. Each factory is capable of creating
|
||||
one type of socket, and if sockets of a particular type are able to
|
||||
be created on a given node, then a factory that can create such sockets
|
||||
must be aggregated to the Node.
|
||||
@verbatim
|
||||
static Ptr<Socket> CreateSocket (Ptr<Node> node, TypeId tid);
|
||||
@end verbatim
|
||||
Examples of TypeIds to pass to this method are @code{TcpSocketFactory},
|
||||
@code{PacketSocketFactory}, and @code{UdpSocketFactory}.
|
||||
|
||||
This method returns a smart pointer to a Socket object. Here is an
|
||||
example:
|
||||
@verbatim
|
||||
Ptr<Node> n0;
|
||||
// Do some stuff to build up the Node's internet stack
|
||||
Ptr<Socket> localSocket = Socket::CreateSocket (n0, TcpSocketFactory::GetTypeId ());
|
||||
@end verbatim
|
||||
|
||||
In some ns-3 code, sockets will not be explicitly created by user's
|
||||
main programs, if an ns-3 application does it. For instance, for
|
||||
@code{class ns3::OnOffApplication}, the function @code{StartApplication()}
|
||||
performs the socket creation, and the application holds the socket
|
||||
pointer.
|
||||
|
||||
@subsubsection Using sockets
|
||||
|
||||
Below is a typical sequence of socket calls for a TCP client in a
|
||||
real implementation:
|
||||
@itemize @bullet
|
||||
@item @code{sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);}
|
||||
@item @code{bind(sock, ...);}
|
||||
@item @code{connect(sock, ...);}
|
||||
@item @code{send(sock, ...);}
|
||||
@item @code{recv(sock, ...);}
|
||||
@item @code{close(sock);}
|
||||
@end itemize
|
||||
|
||||
There are analogs to all of these calls in ns-3, but we will focus on
|
||||
two aspects here. First, most usage of sockets in real systems
|
||||
requires a way to manage I/O between the application and kernel.
|
||||
These models include @emph{blocking sockets}, @emph{signal-based I/O},
|
||||
and @emph{non-blocking sockets} with polling. In ns-3, we make use
|
||||
of the callback mechanisms to support a fourth mode, which is
|
||||
analogous to POSIX @emph{asynchronous I/O}.
|
||||
|
||||
In this model, on the sending side, if the @code{send()} call were to
|
||||
fail because of insufficient buffers, the application suspends the
|
||||
sending of more data until a function registered at the
|
||||
@code{SetSendCallback()} callback is invoked. An application can
|
||||
also ask the socket how much space is available by calling
|
||||
@code{GetTxAvailable ()}. A typical sequence of events for
|
||||
sending data (ignoring connection setup) might be:
|
||||
|
||||
@itemize @bullet
|
||||
@item @code{SetSendCallback (MakeCallback(&HandleSendCallback));}
|
||||
@item @code{Send ();}
|
||||
@item @code{Send ();}
|
||||
@item ...
|
||||
@item @code{// Send fails because buffer is full}
|
||||
@item (wait until HandleSendCallback() is called)
|
||||
@item (HandleSendCallback() is called by socket, since space now available)
|
||||
@item @code{Send (); // Start sending again}
|
||||
@end itemize
|
||||
|
||||
Similarly, on the receive side, the socket user does not block on
|
||||
a call to @code{recv()}. Instead, the application sets a callback
|
||||
with @code{SetRecvCallback ()} in which the socket will notify the
|
||||
application when (and how much) there is data to be read, and
|
||||
the application then calls @code{Recv()} to read the data until
|
||||
no more can be read.
|
||||
|
||||
@subsection Packet vs. buffer variants
|
||||
|
||||
There are two basic variants of @code{Send()} and @code{Recv()} supported:
|
||||
@verbatim
|
||||
virtual int Send (Ptr<Packet> p) = 0;
|
||||
int Send (const uint8_t* buf, uint32_t size);
|
||||
|
||||
Ptr<Packet> Recv (void);
|
||||
int Recv (uint8_t* buf, uint32_t size);
|
||||
@end verbatim
|
||||
|
||||
The non-Packet variants are left for legacy API reasons. When calling
|
||||
the raw buffer variant of @code{Send()}, the buffer is immediately
|
||||
written into a Packet and the @code{Send (Ptr<Packet> p)} is invoked.
|
||||
|
||||
Users may find it semantically odd to pass a Packet to a stream socket
|
||||
such as TCP. However, do not let the name bother you; think of
|
||||
@code{ns3::Packet} to be a fancy byte buffer. There are a few reasons why
|
||||
the Packet variants are more likely to be preferred in ns-3:
|
||||
|
||||
@itemize @bullet
|
||||
@item Users can use the Tags facility of packets to, for example, encode
|
||||
a flow ID or other helper data.
|
||||
@item Users can exploit the copy-on-write implementation to avoid
|
||||
memory copies (on the receive side, the conversion back to a
|
||||
@code{uint8_t* buf} may sometimes incur an additional copy).
|
||||
@item Use of Packet is more aligned with the rest of the ns-3 API
|
||||
@end itemize
|
||||
|
||||
@subsection Sending dummy data
|
||||
|
||||
Sometimes, users want the simulator to just pretend that there is an
|
||||
actual data payload in the packet (e.g. to calculate transmission delay)
|
||||
but do not want to actually produce or consume the data. This is
|
||||
straightforward to support in ns-3; have applications call
|
||||
@code{Create<Packet> (size);} instead of @code{Create<Packet> (buffer, size);}.
|
||||
Similarly, passing in a zero to the pointer argument in the raw buffer
|
||||
variants has the same effect. Note that, if some subsequent code tries
|
||||
to read the Packet data buffer, the fake buffer will be converted to
|
||||
a real (zero'ed) buffer on the spot, and the efficiency will be lost there.
|
||||
|
||||
@subsection Socket options
|
||||
|
||||
@emph{to be completed}
|
||||
|
||||
@subsection Socket errno
|
||||
|
||||
@emph{to be completed}
|
||||
|
||||
@subsection Example programs
|
||||
|
||||
@emph{to be completed}
|
||||
|
||||
@section POSIX-like sockets API
|
||||
|
||||
@emph{this capability is under development and is scheduled for
|
||||
inclusion in August 2008 timeframe; see the repository
|
||||
http://code.nsnam.org/mathieu/ns-3-simu for details}
|
||||
|
||||
The below is excerpted from Mathieu's post to ns-developers list
|
||||
on April 4, 2008.
|
||||
|
||||
"To summarize, the goal is that the full posix/socket API is defined in
|
||||
src/process/simu.h: each posix type and function is re-defined there
|
||||
with a simu_ or SIMU_ prefix to avoid ugly name clashes and collisions
|
||||
(feel free to come up with a better prefix).
|
||||
|
||||
Each process is created with a call to ProcessManager::Create and is
|
||||
attached to that ProcessManager instance. So, if the ProcessManager
|
||||
(which is aggregated to a Node in src/helper/process-helper.cc) is
|
||||
killed when the simulation ends, the system will automatically reclaim
|
||||
all the resources of each process associated to each manager. The same
|
||||
happens when an application "exits" from its main function.
|
||||
|
||||
The example application defines two posix "processes": the function
|
||||
ClientProgram creates a udp socket on the localhost port 2000 and the
|
||||
function ServerProgram creates a udp socket on the localhost port 2000.
|
||||
The code does not work right now because I did not get the details of
|
||||
simu_read right yet but, I do plan to make this work at some point.
|
||||
|
||||
I really think that this approach is worthwhile for many reasons, a few
|
||||
of which are outlined below:
|
||||
@itemize @bullet
|
||||
@item makes porting real world application code _much_ easier
|
||||
|
||||
@item makes write applications for new users much easier because they can
|
||||
read the bsd socket api reference and documentation and write code
|
||||
directly.
|
||||
|
||||
@item can be used to write applications which work in both simulation and
|
||||
in the real world at the same time. To do this, all you have to do is
|
||||
write your application to use the simu_ API, and, then, you can chose at
|
||||
compile-time which implementation of that API you want to use: you can
|
||||
pick one implementation which forwards all calls to the system BSD
|
||||
socket API or another one which forwards all calls to the attached
|
||||
ProcessManager. Arguably, I did not implement the version which forwards
|
||||
to system BSD sockets but, that should be pretty trivial.
|
||||
@end itemize
|
||||
|
||||
So, anyway, comments about the overall API would be welcome. Students
|
||||
interested in the gsoc project for real-world code integration should
|
||||
consider looking at this also."
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
@node Statistics
|
||||
@chapter Statistics
|
||||
@anchor{chap:Statistics}
|
||||
|
||||
ns-3 does not presently have support for statistics (automatically generated
|
||||
statistical output). This is planned
|
||||
for development later in 2008. If you are interested in contributing,
|
||||
please see @uref{http://www.nsnam.org/wiki/index.php/Suggested_Projects,,our suggested projects page} or contact the ns-developers
|
||||
list.
|
||||
@@ -0,0 +1,82 @@
|
||||
@node Troubleshooting
|
||||
@chapter Troubleshooting
|
||||
|
||||
This chapter posts some information about possibly common errors in building
|
||||
or running ns-3 programs.
|
||||
|
||||
Please note that the wiki (@uref{http://www.nsnam.org/wiki/index.php/Troubleshooting}) may have contributed items.
|
||||
|
||||
@node Build errors
|
||||
@section Build errors
|
||||
|
||||
@node Run-time errors
|
||||
@section Run-time errors
|
||||
|
||||
Sometimes, errors can occur with a program after a successful build. These
|
||||
are run-time errors, and can commonly occur when memory is corrupted or
|
||||
pointer values are unexpectedly null.
|
||||
|
||||
Here is an example of what might occur:
|
||||
|
||||
@verbatim
|
||||
ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point
|
||||
Entering directory `/home/tomh/ns-3-nsc/build'
|
||||
Compilation finished successfully
|
||||
Command ['/home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point'] exited with code -11
|
||||
@end verbatim
|
||||
|
||||
The error message says that the program terminated unsuccessfully, but it is
|
||||
not clear from this information what might be wrong. To examine more
|
||||
closely, try running it under the @uref{http://sources.redhat.com/gdb/,,gdb debugger}:
|
||||
|
||||
@verbatim
|
||||
ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="gdb %s"
|
||||
Entering directory `/home/tomh/ns-3-nsc/build'
|
||||
Compilation finished successfully
|
||||
GNU gdb Red Hat Linux (6.3.0.0-1.134.fc5rh)
|
||||
Copyright 2004 Free Software Foundation, Inc.
|
||||
GDB is free software, covered by the GNU General Public License, and you are
|
||||
welcome to change it and/or distribute copies of it under certain conditions.
|
||||
Type "show copying" to see the conditions.
|
||||
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
||||
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
|
||||
|
||||
(gdb) run
|
||||
Starting program: /home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point
|
||||
Reading symbols from shared object read from target memory...done.
|
||||
Loaded system supplied DSO at 0xf5c000
|
||||
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
0x0804aa12 in main (argc=1, argv=0xbfdfefa4)
|
||||
at ../examples/tcp-point-to-point.cc:136
|
||||
136 Ptr<Socket> localSocket = socketFactory->CreateSocket ();
|
||||
(gdb) p localSocket
|
||||
$1 = {m_ptr = 0x3c5d65}
|
||||
(gdb) p socketFactory
|
||||
$2 = {m_ptr = 0x0}
|
||||
(gdb) quit
|
||||
The program is running. Exit anyway? (y or n) y
|
||||
@end verbatim
|
||||
|
||||
Note first the way the program was invoked-- pass the command to run as
|
||||
an argument to the command template "gdb %s".
|
||||
|
||||
This tells us that there was an attempt to dereference a null pointer
|
||||
socketFactory.
|
||||
|
||||
Let's look around line 136 of tcp-point-to-point, as gdb suggests:
|
||||
@verbatim
|
||||
Ptr<SocketFactory> socketFactory = n2->GetObject<SocketFactory> (Tcp::iid);
|
||||
Ptr<Socket> localSocket = socketFactory->CreateSocket ();
|
||||
localSocket->Bind ();
|
||||
@end verbatim
|
||||
|
||||
The culprit here is that the return value of GetObject is not being
|
||||
checked and may be null.
|
||||
|
||||
Sometimes you may need to use the @uref{http://valgrind.org,,valgrind memory
|
||||
checker} for more subtle errors. Again, you invoke the use of valgrind
|
||||
similarly:
|
||||
@verbatim
|
||||
ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="valgrind %s"
|
||||
@end verbatim
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @anchor modules_anchor
|
||||
*
|
||||
* @defgroup simulator Simulator
|
||||
* The "simulator" module contains:
|
||||
* - a time management class to hold a time and convert between various time units: ns3::Time
|
||||
* - a scheduler base class used to implement new simulation event schedulers:
|
||||
* ns3::Scheduler and ns3::SchedulerFactory
|
||||
* - a simulator class used to create, schedule and cancel events: ns3::Simulator
|
||||
*
|
||||
* @defgroup core Core
|
||||
* \brief The "core" module contains:
|
||||
* - a Functor class: ns3::Callback
|
||||
* - an os-independent interface to get access to the elapsed wall clock time: ns3::SystemWallClockMs
|
||||
* - a class to register regression tests with the test manager: ns3::Test and ns3::TestManager
|
||||
* - debugging facilities: \ref logging, \ref assert
|
||||
* - \ref randomvariable
|
||||
* - a base class for objects which need to support per-instance "attributes" and
|
||||
* trace sources: ns3::ObjectBase
|
||||
* - a base class for objects which need to support reference counting
|
||||
* and dynamic object aggregation: ns3::Object
|
||||
* - a smart-pointer class ns3::Ptr designed to work together with ns3::Object
|
||||
* - a configuration class used to set and control all attributes and trace sources
|
||||
* in a simulation: ns3::Config.
|
||||
*
|
||||
* @defgroup common Common
|
||||
* The "common" module contains:
|
||||
* - a packet class to create and manipulate simulation packets:
|
||||
* ns3::Packet, ns3::Header, and ns3::Trailer. This packet class
|
||||
* also supports per-packet ns3::Tag which are globs of data
|
||||
* which can be attached to any packet.
|
||||
*
|
||||
* @defgroup node Node
|
||||
* The "node" module contains:
|
||||
* - a ns3::Node base class which should be subclassed by any new type of
|
||||
* network Node.
|
||||
* - models which abstract the MAC-layer from the IP layer protocols:
|
||||
* ns3::NetDevice and ns3::Channel.
|
||||
* - models which abstract the application-layer API: ns3::Application,
|
||||
* ns3::Socket, ns3::SocketFactory, and, ns3::Udp
|
||||
*
|
||||
*
|
||||
* @defgroup devices Devices
|
||||
*
|
||||
* @defgroup internetStack InternetStack
|
||||
*
|
||||
* The "internet-stack" module contains:
|
||||
* - an Ipv4 stack
|
||||
* - an ARP module
|
||||
* - a UDP and a TCP implementation
|
||||
*
|
||||
* @defgroup helper Helpers
|
||||
*
|
||||
* @defgroup applications Applications
|
||||
*
|
||||
* @defgroup mobility Mobility
|
||||
*
|
||||
* @defgroup routing Routing
|
||||
*
|
||||
* @defgroup constants Constants
|
||||
* @brief Constants you can change
|
||||
*
|
||||
* @defgroup contrib Contrib
|
||||
*/
|
||||
+1658
File diff suppressed because it is too large.
Load diff
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
@@ -0,0 +1,78 @@
|
||||
Steps in doing an ns-3 release
|
||||
|
||||
1. check out a clean ns-3-dev somewhere
|
||||
2. prepare the source files
|
||||
- revise and check in AUTHORS, if needed
|
||||
- revise and check in RELEASE_NOTES
|
||||
- DO NOT change VERSION at this time
|
||||
- confirm that Doxygen builds cleanly and without warnings
|
||||
(./waf check; ./waf --doxygen), and check in any necessary changes
|
||||
- ensure no regressions (./waf --regression)
|
||||
3. ./waf configure; ./waf dist
|
||||
- this will create an ns-3-dev.tar.bz2 tarball
|
||||
- this will also create a ns-3-dev-ref-traces.tar.bz2 tarball
|
||||
4. test dev tarball on release platforms (waf check and maybe some other
|
||||
scripts)
|
||||
5. once you are happy with the tarball, tag ns-3-dev and ns-3-dev-ref-traces
|
||||
- hg tag "ns-3.x"
|
||||
- hg push
|
||||
- cd into regression/ns-3-dev-ref-traces
|
||||
- hg tag "ns-3.x"
|
||||
- hg push
|
||||
6. clone the tagged ns-3-dev and place it on the repository
|
||||
- ssh code.nsnam.org; sudo tcsh; su code;
|
||||
- cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.1x
|
||||
- cd /home/code/repos/ns-3.x/.hg and edit the hgrc appropriately:
|
||||
"description = ns-3.x release
|
||||
name = ns-3.x"
|
||||
- clone the ns-3-dev-ref-traces and place it on the repository as above
|
||||
but use the name ns-3.x-ref-traces and edit the hgrc appropriately
|
||||
7. check out a clean version of the new release (ns-3.x) somewhere
|
||||
8. Update the VERSION for this new release
|
||||
- change the string 3-dev in the VERSION file to the real version
|
||||
(e.g. 3.2) This must agree with the version name you chose in the clone
|
||||
for the regression tests to work.
|
||||
- hg commit
|
||||
- hg push
|
||||
9. Run the regression tests on the new release (debug and optimized)
|
||||
- ./waf -d debug configure
|
||||
- ./waf
|
||||
- ./waf --regression
|
||||
- ./waf --valgrind --regression (for valgrind version)
|
||||
- ./waf -d optimized configure
|
||||
- ./waf
|
||||
- ./waf --regression
|
||||
- ./waf --valgrind --regression (for valgrind version)
|
||||
- There should be no regression errors at this time
|
||||
10. Create final tarballs
|
||||
- ./waf configure; ./waf dist
|
||||
- this will create an ns-3.x.tar.bz2 tarball
|
||||
- this will also create a ns-3.x-ref-traces.tar.bz2 tarball
|
||||
11. upload "ns-3.x.tar.bz2" to the /var/www/html/releases/ directory on
|
||||
the www.nsnam.org server
|
||||
- give it 644 file permissions, and user/group = apache
|
||||
12. upload "ns-3.x-ref-traces.tar.bz2" to the /var/www/html/releases/
|
||||
directory on the www.nsnam.org server
|
||||
- give it 644 file permissions, and user/group = apache
|
||||
13. update web pages on www.nsnam.org (source is in the www/ module)
|
||||
- clone the source repo (hg clone http://code.nsnam.org/www)
|
||||
- update index.html
|
||||
- add link to news.html
|
||||
- update getting_started.html
|
||||
- update documents.html
|
||||
- update roadmap on wiki
|
||||
- commit and push changes
|
||||
- build and update HTML directory on the server
|
||||
-- ssh www.nsnam.org; sudo tcsh; su nsnam;
|
||||
-- run ~/bin/update-html
|
||||
- build and update Doxygen directory on the server
|
||||
-- edit ~/bin/update-doxygen-release file and change RELEASE variable
|
||||
to the right version number
|
||||
-- run ~/bin/update-doxygen-release
|
||||
14. Final checks
|
||||
- download tarball from web, build and run regression tests for as many
|
||||
targets as you can
|
||||
- download release from mercurial, build and run regression tests for as
|
||||
many targets as you can
|
||||
- test and verify until you're confident the release is solid.
|
||||
15. announce to ns-developers, with summary of release notes
|
||||
@@ -0,0 +1,49 @@
|
||||
TEXI2HTML = texi2html
|
||||
TEXI2PDF = texi2dvi --pdf
|
||||
EPSTOPDF = epstopdf
|
||||
TGIF = tgif
|
||||
DIA = dia
|
||||
CONVERT = convert
|
||||
CSS = --css-include=tutorial.css
|
||||
SPLIT = --split section
|
||||
|
||||
DIA_SOURCES = pp.dia dumbbell.dia star.dia
|
||||
TGIF_SOURCES = helpers.obj
|
||||
|
||||
DIA_EPS = ${DIA_SOURCES:.dia=.eps}
|
||||
DIA_PNG = ${DIA_SOURCES:.dia=.png}
|
||||
DIA_PDF = ${DIA_SOURCES:.dia=.pdf}
|
||||
|
||||
TGIF_EPS = ${TGIF_SOURCES:.obj=.eps}
|
||||
TGIF_PNG = ${TGIF_SOURCES:.obj=.png}
|
||||
TGIF_PDF = ${TGIF_SOURCES:.obj=.pdf}
|
||||
|
||||
all: html split-html pdf
|
||||
|
||||
# Note: tgif requires a valid x display to convert from .obj to .png.
|
||||
# If running this makefile on a remote console, the X virtual frame
|
||||
# buffer may be needed (xorg-x11-server-Xvfb) to provide a "fake"
|
||||
# display
|
||||
images:
|
||||
cd figures/; $(DIA) -t png $(DIA_SOURCES)
|
||||
cd figures/; $(DIA) -t eps $(DIA_SOURCES)
|
||||
cd figures/; $(foreach FILE,$(DIA_EPS),$(EPSTOPDF) $(FILE);)
|
||||
cd figures/; $(TGIF) -print -png $(TGIF_SOURCES)
|
||||
cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES)
|
||||
cd figures/; $(foreach FILE,$(TGIF_EPS),$(EPSTOPDF) $(FILE);)
|
||||
|
||||
html:
|
||||
$(TEXI2HTML) ${CSS} tutorial.texi
|
||||
|
||||
split-html:
|
||||
$(TEXI2HTML) ${CSS} ${SPLIT} tutorial.texi
|
||||
|
||||
pdf:
|
||||
$(TEXI2PDF) tutorial.texi
|
||||
|
||||
figures-clean:
|
||||
cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF)
|
||||
cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF)
|
||||
|
||||
clean: # figures-clean
|
||||
rm -rf tutorial.aux tutorial.cp tutorial.cps tutorial.fn tutorial.ky tutorial.pg tutorial.tp tutorial.vr tutorial.toc tutorial.log tutorial.pdf tutorial.html tutorial/
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,812 @@
|
||||
|
||||
@c ========================================================================
|
||||
@c Begin document body here
|
||||
@c ========================================================================
|
||||
|
||||
@c ========================================================================
|
||||
@c Conceptual Overview
|
||||
@c ========================================================================
|
||||
@node Conceptual Overview
|
||||
@chapter Conceptual Overview
|
||||
|
||||
@menu
|
||||
* Key Abstractions::
|
||||
* A First ns-3 Script::
|
||||
@end menu
|
||||
|
||||
The first thing we need to do before actually starting to look at or write
|
||||
@command{ns-3} code is to explain a few core concepts and abstractions in the
|
||||
system. Much of this may appear transparently obvious to some, but we
|
||||
recommend taking the time to read through this section just to ensure you
|
||||
are starting on a firm foundation.
|
||||
|
||||
@node Key Abstractions
|
||||
@section Key Abstractions
|
||||
|
||||
In this section, we'll review some terms that are commonly used in
|
||||
networking, but have a specific meaning in @command{ns-3}.
|
||||
|
||||
@subsection Node
|
||||
@cindex Node
|
||||
In Internet jargon, a computing device that connects to a network is called
|
||||
a @emph{host} or sometimes an @emph{end system}. Because @command{ns-3} is a
|
||||
@emph{network} simulator, not specifically an @emph{Internet} simulator, we
|
||||
intentionally do not use the term host since it is closely associated with
|
||||
the Internet and its protocols. Instead, we use a more generic term also
|
||||
used by other simulators that originates in Graph Theory --- the @emph{node}.
|
||||
|
||||
@cindex class Node
|
||||
In @command{ns-3} the basic computing device abstraction is called the
|
||||
node. This abstraction is represented in C++ by the class @code{Node}. The
|
||||
@code{Node} class provides methods for managing the representations of
|
||||
computing devices in simulations.
|
||||
|
||||
You should think of a @code{Node} as a computer to which you will add
|
||||
functionality. One adds things like applications, protocol stacks and
|
||||
peripheral cards with their associated drivers to enable the computer to do
|
||||
useful work. We use the same basic model in @command{ns-3}.
|
||||
|
||||
@subsection Application
|
||||
@cindex Application
|
||||
Typically, computer software is divided into two broad classes. @emph{System
|
||||
Software} organizes various computer resources such as memory, processor
|
||||
cycles, disk, network, etc., according to some computing model. System
|
||||
software usually does not use those resources to complete tasks that directly
|
||||
benefit a user. A user would typically run an @emph{application} that acquires
|
||||
and uses the resources controlled by the system software to accomplish some
|
||||
goal.
|
||||
|
||||
@cindex system call
|
||||
Often, the line of separation between system and application software is made
|
||||
at the privilege level change that happens in operating system traps.
|
||||
In @command{ns-3} there is no real concept of operating system and especially
|
||||
no concept of privilege levels or system calls. We do, however, have the
|
||||
idea of an application. Just as software applications run on computers to
|
||||
perform tasks in the ``real world,'' @command{ns-3} applications run on
|
||||
@command{ns-3} @code{Nodes} to drive simulations in the simulated world.
|
||||
|
||||
@cindex class Application
|
||||
In @command{ns-3} the basic abstraction for a user program that generates some
|
||||
activity to be simulated is the application. This abstraction is represented
|
||||
in C++ by the class @code{Application}. The @code{Application} class provides
|
||||
methods for managing the representations of our version of user-level
|
||||
applications in simulations. Developers are expected to specialize the
|
||||
@code{Application} class in the object-oriented programming sense to create new
|
||||
applications. In this tutorial, we will use specializations of class
|
||||
@code{Application} called @code{UdpEchoClientApplication} and
|
||||
@code{UdpEchoServerApplication}. As you might expect, these applications
|
||||
compose a client/server application set used to generate and echo simulated
|
||||
network packets
|
||||
|
||||
@subsection Channel
|
||||
@cindex Channel
|
||||
|
||||
In the real world, one can connect a computer to a network. Often the media
|
||||
over which data flows in these netowrks are called @emph{channels}. When
|
||||
you connect your Ethernet cable to the plug in the wall, you are connecting
|
||||
your computer to an Ethernet communication channel. In the simulated world
|
||||
of @command{ns-3}, one connects a @code{Node} to an object representing a
|
||||
communication channel. Here the basic communication subnetwork abstraction
|
||||
is called the channel and is represented in C++ by the class @code{Channel}.
|
||||
|
||||
The @code{Channel} class provides methods for managing communication
|
||||
subnetwork objects and connecting nodes to them. @code{Channels} may also be
|
||||
specialized by developers in the object oriented programming sense. A
|
||||
@code{Channel} specialization may model something as simple as a wire. The
|
||||
specialized @code{Channel} can also model things as complicated as a large
|
||||
Ethernet switch, or three-dimensional space full of obstructions in the case
|
||||
of wireless networks.
|
||||
|
||||
We will use specialized versions of the @code{Channel} called
|
||||
@code{CsmaChannel}, @code{PointToPointChannel} and @code{WifiChannel} in this
|
||||
tutorial. The @code{CsmaChannel}, for example, models a version of a
|
||||
communication subnetwork that implements a @emph{carrier sense multiple
|
||||
access} communication medium. This gives us Ethernet-like functionality.
|
||||
|
||||
@subsection Net Device
|
||||
@cindex NetDevice
|
||||
@cindex Ethernet
|
||||
It used to be the case that if you wanted to connect a computers to a network,
|
||||
you had to buy a specific kind of network cable and a hardware device called
|
||||
(in PC terminology) a @emph{peripheral card} that needed to be installed in
|
||||
your computer. If the peripheral card implemented some networking function,
|
||||
theys were called Network Interface Cards, or @emph{NICs}. Today most
|
||||
computers come with the network interface hardware built in and users don't
|
||||
see these building blocks.
|
||||
|
||||
A NIC will not work without a software driver to control the hardware. In
|
||||
Unix (or Linux), a piece of peripheral hardware is classified as a
|
||||
@emph{device}. Devices are controlled using @emph{device drivers}, and network
|
||||
devices (NICs) are controlled using @emph{network device drivers}
|
||||
collectively known as @emph{net devices}. In Unix and Linux you refer
|
||||
to these net devices by names such as @emph{eth0}.
|
||||
|
||||
In @command{ns-3} the @emph{net device} abstraction covers both the software
|
||||
driver and the simulated hardware. A net device is ``installed'' in a
|
||||
@code{Node} in order to enable the @code{Node} to communicate with other
|
||||
@code{Nodes} in the simulation via @code{Channels}. Just as in a real
|
||||
computer, a @code{Node} may be connected to more than one @code{Channel} via
|
||||
multiple @code{NetDevices}.
|
||||
|
||||
The net device abstraction is represented in C++ by the class @code{NetDevice}.
|
||||
The @code{NetDevice} class provides methods for managing connections to
|
||||
@code{Node} and @code{Channel} objects; and may be specialized by developers
|
||||
in the object-oriented programming sense. We will use the several specialized
|
||||
versions of the @code{NetDevice} called @code{CsmaNetDevice},
|
||||
@code{PointToPointNetDevice}, and @code{WifiNetDevice} in this tutorial.
|
||||
Just as an Ethernet NIC is designed to work with an Ethernet network, the
|
||||
@code{CsmaNetDevice} is designed to work with a @code{CsmaChannel}; the
|
||||
@code{PointToPointNetDevice} is designed to work with a
|
||||
@code{PointToPointChannel} and a @code{WifiNetNevice} is designed to work with
|
||||
a @code{WifiChannel}.
|
||||
|
||||
@subsection Topology Helpers
|
||||
@cindex helper
|
||||
@cindex topology
|
||||
@cindex topology helper
|
||||
In a real network, you will find host computers with added (or built-in)
|
||||
NICs. In @command{ns-3} we would say that you will find @code{Nodes} with
|
||||
attached @code{NetDevices}. In a large simulated network you will need to
|
||||
arrange many connections between @code{Nodes}, @code{NetDevices} and
|
||||
@code{Channels}.
|
||||
|
||||
Since connecting @code{NetDevices} to @code{Nodes}, @code{NetDevices}
|
||||
to @code{Channels}, assigning IP addresses, etc., are such common tasks
|
||||
in @command{ns-3}, we provide what we call @emph{topology helpers} to make
|
||||
this as easy as possible. For example, it may take many distinct
|
||||
@command{ns-3} core operations to create a NetDevice, add a MAC address,
|
||||
install that net device on a @code{Node}, configure the node's protocol stack,
|
||||
and then connect the @code{NetDevice} to a @code{Channel}. Even more
|
||||
operations would be required to connect multiple devices onto multipoint
|
||||
channels and then to connect individual networks together into internetworks.
|
||||
We provide topology helper objects that combine those many distinct operations
|
||||
into an easy to use model for your convenience.
|
||||
|
||||
@c ========================================================================
|
||||
@c A First ns-3 script
|
||||
@c ========================================================================
|
||||
@node A First ns-3 Script
|
||||
@section A First ns-3 Script
|
||||
@cindex first script
|
||||
If you downloaded the system as was suggested above, you will have a release
|
||||
of @command{ns-3} in a directory called @code{repos} under your home
|
||||
directory. Change into that release directory, and you should find a
|
||||
directory structure something like the following:
|
||||
|
||||
@verbatim
|
||||
AUTHORS examples/ README samples/ utils/ waf.bat*
|
||||
build/ LICENSE regression/ scratch/ VERSION wscript
|
||||
doc/ ns3/ RELEASE_NOTES src/ waf*
|
||||
@end verbatim
|
||||
|
||||
@cindex first.cc
|
||||
Change into the examples directory. You should see a file named
|
||||
@code{first.cc} located there. This is a script that will create a simple
|
||||
point-to-point link between two nodes and echo a single packet between the
|
||||
nodes. Let's take a look at that script line by line, so go ahead and open
|
||||
@code{first.cc} in your favorite editor.
|
||||
|
||||
@subsection Boilerplate
|
||||
The first line in the file is an emacs mode line. This tells emacs about the
|
||||
formatting conventions (coding style) we use in our source code.
|
||||
|
||||
@verbatim
|
||||
/* -*- Mode:C++; c-file-style:''gnu''; indent-tabs-mode:nil; -*- */
|
||||
@end verbatim
|
||||
|
||||
This is always a somewhat controversial subject, so we might as well get it
|
||||
out of the way immediately. The @code{ns-3} project, like most large
|
||||
projects, has adopted a coding style to which all contributed code must
|
||||
adhere. If you want to contribute your code to the project, you will
|
||||
eventually have to conform to the @command{ns-3} coding standard as described
|
||||
in the file @code{doc/codingstd.txt} or shown on the project web page
|
||||
@uref{http://www.nsnam.org/codingstyle.html,,here}.
|
||||
|
||||
We recommend that you, well, just get used to the look and feel of @code{ns-3}
|
||||
code and adopt this standard whenever you are working with our code. All of
|
||||
the development team and contributors have done so with various amounts of
|
||||
grumbling. The emacs mode line above makes it easier to get the formatting
|
||||
correct if you use the emacs editor.
|
||||
|
||||
The @command{ns-3} simulator is licensed using the GNU General Public
|
||||
License. You will see the appropriate GNU legalese at the head of every file
|
||||
in the @command{ns-3} distribution. Often you will see a copyright notice for
|
||||
one of the institutions involved in the @code{ns-3} project above the GPL
|
||||
text and an author listed below.
|
||||
|
||||
@verbatim
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
@end verbatim
|
||||
|
||||
@subsection Module Includes
|
||||
The code proper starts with a number of include statements.
|
||||
|
||||
@verbatim
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/simulator-module.h"
|
||||
#include "ns3/node-module.h"
|
||||
#include "ns3/helper-module.h"
|
||||
@end verbatim
|
||||
|
||||
To help our high-level script users deal with the large number of include
|
||||
files present in the system, we group includes according to relatively large
|
||||
modules. We provide a single include file that will recursively load all of
|
||||
the include files used in each module. Rather than having to look up exactly
|
||||
what header you need, and possibly have to get a number of dependencies right,
|
||||
we give you the ability to load a group of files at a large granularity. This
|
||||
is not the most efficient approach but it certainly makes writing scripts much
|
||||
easier.
|
||||
|
||||
Each of the @command{ns-3} include files is placed in a directory called
|
||||
@code{ns3} (under the build directory) during the build process to help avoid
|
||||
include file name collisions. The @code{ns3/core-module.h} file corresponds
|
||||
to the ns-3 module you will find in the directory @code{src/core} in your
|
||||
downloaded release distribution. If you list this directory you will find a
|
||||
large number of header files. When you do a build, Waf will place public
|
||||
header files in an @code{ns3} directory under the appropriate
|
||||
@code{build/debug} or @code{build/optimized} directory depending on your
|
||||
configuration. Waf will also automatically generate a module include file to
|
||||
load all of the public header files.
|
||||
|
||||
Since you are, of course, following this tutorial religiously, you will
|
||||
already have done a
|
||||
|
||||
@verbatim
|
||||
./waf -d debug configure
|
||||
@end verbatim
|
||||
|
||||
in order to configure the project to perform debug builds. You will also have
|
||||
done a
|
||||
|
||||
@verbatim
|
||||
./waf
|
||||
@end verbatim
|
||||
|
||||
to build the project. So now if you look in the directory
|
||||
@code{build/debug/ns-3} you will find the four module include files shown
|
||||
above. You can take a look at the contents of these files and find that they
|
||||
do include all of the public include files in their respective modules.
|
||||
|
||||
@subsection Ns3 Namespace
|
||||
The next line in the @code{first.cc} script is a namespace declaration.
|
||||
|
||||
@verbatim
|
||||
using namespace ns3;
|
||||
@end verbatim
|
||||
|
||||
The @command{ns-3} project is implemented in a C++ namespace called
|
||||
@code{ns3}. This groups all @command{ns-3}-related declarations in a scope
|
||||
outside the global namespace, which we hope will help with integration with
|
||||
other code. The C++ @code{using} statement introduces the @code{ns-3}
|
||||
namespace into the current (global) declarative region. This is a fancy way
|
||||
of saying that after this declaration, you will not have to type @code{ns3::}
|
||||
scope resolution operator before all of the @code{ns-3} code in order to use
|
||||
it. If you are unfamiliar with namespaces, please consult almost any C++
|
||||
tutorial and compare the @code{ns3} namespace and usage here with instances of
|
||||
the @code{std} namespace and the @code{using namespace std;} statements you
|
||||
will often find in discussions of @code{cout} and streams.
|
||||
|
||||
@subsection Logging
|
||||
The next line of the script is the following,
|
||||
|
||||
@verbatim
|
||||
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
|
||||
@end verbatim
|
||||
|
||||
We will use this statement as a convenient place to talk about our Doxygen
|
||||
documentation system. If you look at the project web site,
|
||||
@uref{http://www.nsnam.org,,ns-3 project}, you will find a link to ``APIs
|
||||
(Doxygen)'' in the navigation bar. If you select this link, you will be
|
||||
taken to our documentation page.
|
||||
|
||||
Along the left side, you will find a graphical representation of the structure
|
||||
of the documentation. A good place to start is the @code{NS-3 Modules}
|
||||
``book.'' If you expand @code{Modules} you will see a list of @command{ns-3}
|
||||
module documentation. The concept of module here ties directly into the
|
||||
module include files discussed above. It turns out that the @command{ns-3}
|
||||
logging subsystem is part of the @code{core} module, so go ahead and expand
|
||||
that documentation node. Now, expand the @code{Debugging} book and then
|
||||
select the @code{Logging} page.
|
||||
|
||||
You should now be looking at the Doxygen documentation for the Logging module.
|
||||
In the list of @code{#define}s at the top of the page you will see the entry
|
||||
for @code{NS_LOG_COMPONENT_DEFINE}. Before jumping in, it would probably be
|
||||
good to look for the ``Detailed Description'' of the logging module to get a
|
||||
feel for the overall operation. You can either scroll down or select the
|
||||
``More...'' link under the collaboration diagram to do this.
|
||||
|
||||
Once you have a general idea of what is going on, go ahead and take a look at
|
||||
the specific @code{NS_LOG_COMPONENT_DEFINE} documentation. I won't duplicate
|
||||
the documentation here, but to summarize, this line declares a logging
|
||||
component called @code{FirstScriptExample} that allows you to enable and
|
||||
disable console message logging by reference to the name.
|
||||
|
||||
@subsection Main Function
|
||||
The next lines of the script you will find are,
|
||||
|
||||
@verbatim
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@end verbatim
|
||||
|
||||
This is just the declaration of the main function of your program (script).
|
||||
Just as in any C++ program, you need to define a main function that will be
|
||||
the first function run. There is nothing at all special here. Your
|
||||
@command{ns-3} script is just a C++ program.
|
||||
|
||||
The next two lines of the script are used to enable two logging components that
|
||||
are built into the Echo Client and Echo Server applications:
|
||||
|
||||
@verbatim
|
||||
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
|
||||
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
|
||||
@end verbatim
|
||||
|
||||
If you have read over the Logging component documentation you will have seen
|
||||
that there are a number of levels of logging verbosity/detail that you can
|
||||
enable on each component. These two lines of code enable debug logging at the
|
||||
INFO level for echo clients and servers. This will result in the application
|
||||
printing out messages as packets are sent and received during the simulation.
|
||||
|
||||
Now we will get directly to the business of creating a topology and running
|
||||
a simulation. We use the topology helper objects to make this job as
|
||||
easy as possible.
|
||||
|
||||
@subsection Topology Helpers
|
||||
@subsubsection NodeContainer
|
||||
The next two lines of code in our script will actually create the
|
||||
@command{ns-3} @code{Node} objects that will represent the computers in the
|
||||
simulation.
|
||||
|
||||
@verbatim
|
||||
NodeContainer nodes;
|
||||
nodes.Create (2);
|
||||
@end verbatim
|
||||
|
||||
Let's find the documentation for the @code{NodeContainer} class before we
|
||||
continue. Another way to get into the documentation for a given class is via
|
||||
the @code{Classes} tab in the Doxygen pages. If you still have the Doxygen
|
||||
handy, just scroll up to the top of the page and select the @code{Classes}
|
||||
tab. You should see a new set of tabs appear, one of which is
|
||||
@code{Class List}. Under that tab you will see a list of all of the
|
||||
@command{ns-3} classes. Scroll down, looking for @code{ns3::NodeContainer}.
|
||||
When you find the class, go ahead and select it to go to the documentation for
|
||||
the class.
|
||||
|
||||
You may recall that one of our key abstractions is the @code{Node}. This
|
||||
represents a computer to which we are going to add things like protocol stacks,
|
||||
applications and peripheral cards. The @code{NodeContainer} topology helper
|
||||
provides a convenient way to create, manage and access any @code{Node} objects
|
||||
that we create in order to run a simulation. The first line above just
|
||||
declares a NodeContainer which we call @code{nodes}. The second line calls the
|
||||
@code{Create} method on the @code{nodes} object and asks the container to
|
||||
create two nodes. As described in the Doxygen, the container calls down into
|
||||
the @command{ns-3} system proper to create two @code{Node} objects and stores
|
||||
pointers to those objects internally.
|
||||
|
||||
The nodes as they stand in the script do nothing. The next step in
|
||||
constructing a topology is to connect our nodes together into a network.
|
||||
The simplest form of network we support is a single point-to-point link
|
||||
between two nodes. We'll construct one of those links here.
|
||||
|
||||
@subsubsection PointToPointHelper
|
||||
We are constructing a point to point link, and, in a pattern which will become
|
||||
quite familiar to you, we use a topology helper object to do the low-level
|
||||
work required to put the link together. Recall that two of our key
|
||||
abstractions are the @code{NetDevice} and the @code{Channel}. In the real
|
||||
world, these terms correspond roughly to peripheral cards and network cables.
|
||||
Typically these two things are intimately tied together and one cannot expect
|
||||
to interchange, for example, Ethernet devices and wireless channels. Our
|
||||
Topology Helpers follow this intimate coupling and therefore you will use a
|
||||
single @code{PointToPointHelper} to configure and connect @command{ns-3}
|
||||
@code{PointToPointNetDevice} and @code{PointToPointChannel} objects in this
|
||||
script.
|
||||
|
||||
The next three lines in the script are,
|
||||
|
||||
@verbatim
|
||||
PointToPointHelper pointToPoint;
|
||||
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
|
||||
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
|
||||
@end verbatim
|
||||
|
||||
The first line
|
||||
|
||||
@verbatim
|
||||
PointToPointHelper pointToPoint;
|
||||
@end verbatim
|
||||
|
||||
instantiates a @code{PointToPointHelper} object on the stack. From a
|
||||
high-level perspective the next line,
|
||||
|
||||
@verbatim
|
||||
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
|
||||
@end verbatim
|
||||
|
||||
tells the @code{PointToPointHelper} object to use the value ``5mbps''
|
||||
(five megabits per second) as the ``DataRate'' when it creates a
|
||||
@code{PointToPointNetDevice} object.
|
||||
|
||||
From a more detailed perspective, the string ``DataRate'' corresponds
|
||||
to what we call an @code{Attribute} of the @code{PointToPointNetDevice}.
|
||||
If you look at the Doxygen for class @code{ns3::PointToPointNetDevice} and
|
||||
find the documentation for the @code{GetTypeId} method, you will find a list
|
||||
of @code{Attributes} defined for the device. Among these is the ``DataRate''
|
||||
attribute. Most user-visible @command{ns-3} objects have similar lists of
|
||||
attributes. We use this mechanism to easily configure simulations without
|
||||
recompiling as you will see in a following section.
|
||||
|
||||
Similar to the ``DataRate'' on the @code{PointToPointNetDevice} you will find a
|
||||
``Delay'' attribute associated with the @code{PointToPointChannel}. The
|
||||
final line,
|
||||
|
||||
@verbatim
|
||||
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
|
||||
@end verbatim
|
||||
|
||||
tells the @code{PointToPointHelper} to use the value ``2ms'' (two milliseconds)
|
||||
as the value of the transmission delay of every point to point channel it
|
||||
subsequently creates.
|
||||
|
||||
@subsubsection NetDeviceContainer
|
||||
At this point in the script, we have a @code{NodeContainer} that contains
|
||||
two nodes. We have a @code{PointToPointHelper} that is primed and ready to
|
||||
make @code{PointToPointNetDevices} and wire @code{PointToPointChannel} objects
|
||||
between them. Just as we used the @code{NodeContainer} topology helper object
|
||||
to create the @code{Nodes} for our simulation, we will ask the
|
||||
@code{PointToPointHelper} to do the work involved in creating, configuring and
|
||||
installing our devices for us. We will need to have a list of all of the
|
||||
NetDevice objects that are created, so we use a NetDeviceContainer to hold
|
||||
them just as we used a NodeContainer to hold the nodes we created. The
|
||||
following two lines of code,
|
||||
|
||||
@verbatim
|
||||
NetDeviceContainer devices;
|
||||
devices = pointToPoint.Install (nodes);
|
||||
@end verbatim
|
||||
|
||||
will finish configuring the devices and channel. The first line declares the
|
||||
device container mentioned above and the second does the heavy lifting. The
|
||||
@code{Install} method of the @code{PointToPointHelper} takes a
|
||||
@code{NodeContainer} as a parameter. Internally, a @code{NetDeviceContainer}
|
||||
is created. For each node in the @code{NodeContainer} (there must be exactly
|
||||
two for a point-to-point link) a @code{PointToPointNetDevice} is created and
|
||||
saved in the device container. A @code{PointToPointChannel} is created and
|
||||
the two @code{PointToPointNetDevices} are attached. When objects are created
|
||||
by the @code{PointToPointHelper}, the attributes previously set in the helper
|
||||
are used to initialize the corresponding attributes in the created objects.
|
||||
|
||||
After executing the the @code{pointToPoint.Install (nodes)} call we will have
|
||||
two nodes, each with an installed point-to-point net device and a
|
||||
point-to-point channel between them. Both devices will be configured to
|
||||
transmit data at five megabits per second over the channel which has a two
|
||||
millisecond transmission delay.
|
||||
|
||||
@subsubsection InternetStackHelper
|
||||
We now have nodes and devices configured, but we don't have any protocol stacks
|
||||
installed on our nodes. The next two lines of code will take care of that.
|
||||
|
||||
@verbatim
|
||||
InternetStackHelper stack;
|
||||
stack.Install (nodes);
|
||||
@end verbatim
|
||||
|
||||
The @code{InternetStackHelper} is a topology helper that is to internet stacks
|
||||
what the @code{PointToPointHelper} is to point-to-point net devices. The
|
||||
@code{Install} method takes a @code{NodeContainer} as a parameter. When it is
|
||||
executed, it will install an Internet Stack (TCP, UDP, IP, etc.) on each of
|
||||
the nodes in the node container.
|
||||
|
||||
@subsubsection Ipv4AddressHelper
|
||||
Next we need to associate the devices on our nodes with IP addresses. We
|
||||
provide a topology helper to manage the allocation of IP addresses. The only
|
||||
user-visible API is to set the base IP address and network mask to use when
|
||||
performing the actual address allocation (which is done at a lower level
|
||||
inside the helper).
|
||||
|
||||
The next two lines of code in our example script, @code{first.cc},
|
||||
|
||||
@verbatim
|
||||
Ipv4AddressHelper address;
|
||||
address.SetBase ("10.1.1.0", "255.255.255.0");
|
||||
@end verbatim
|
||||
|
||||
declare an address helper object and tell it that it should begin allocating IP
|
||||
addresses from the network 10.1.1.0 using the mask 255.255.255.0 to define
|
||||
the allocatable bits. By default the addresses allocated will start at one
|
||||
and increase monotonically, so the first address allocated from this base will
|
||||
be 10.1.1.1, followed by 10.1.1.2, etc. The low level @command{ns-3} system
|
||||
actually remembers all of the IP addresses allocated and will generate a
|
||||
fatal error if you accidentally cause the same address to be generated twice
|
||||
(which is a very hard to debug error, by the way).
|
||||
|
||||
The next line of code,
|
||||
|
||||
@verbatim
|
||||
Ipv4InterfaceContainer interfaces = address.Assign (devices);
|
||||
@end verbatim
|
||||
|
||||
performs the actual address assignment. In @command{ns-3} we make the
|
||||
association between an IP address and a device using an @code{Ipv4Interface}
|
||||
object. Just as we sometimes need a list of net devices created by a helper
|
||||
for future reference we sometimes need a list of @code{Ipv4Interface} objects.
|
||||
The @code{Ipv4InterfaceContainer} provides this functionality.
|
||||
|
||||
Now we have a point-to-point network built, with stacks installed and IP
|
||||
addresses assigned. What we need at this point are applications to generate
|
||||
traffic.
|
||||
|
||||
@subsection Applications
|
||||
Another one of the core abstractions of the ns-3 system is the
|
||||
@code{Application}. In this script we use two specializations of the core
|
||||
@command{ns-3} class @code{Application} called @code{UdpEchoServerApplication}
|
||||
and @code{UdpEchoClientApplication}. Just as we have in our previous
|
||||
explanations, we use helper objects to help configure and manage the
|
||||
underlying objects. Here, we use @code{UdpEchoServerHelper} and
|
||||
@code{UdpEchoClientHelper} objects to make our lives easier.
|
||||
|
||||
@subsubsection UdpEchoServerHelper
|
||||
The following lines of code in our example script, @code{first.cc}, are used
|
||||
to set up a UDP echo server application on one of the nodes we have previously
|
||||
created.
|
||||
|
||||
@verbatim
|
||||
UdpEchoServerHelper echoServer (9);
|
||||
|
||||
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
|
||||
serverApps.Start (Seconds (1.0));
|
||||
serverApps.Stop (Seconds (10.0));
|
||||
@end verbatim
|
||||
|
||||
The first line of code in the above snippet declares the
|
||||
@code{UdpEchoServerHelper}. As usual, this isn't the application itself, it
|
||||
is an object used to help us create the actual applications. One of our
|
||||
conventions is to place required attributes in the helper constructor. In this
|
||||
case, the helper can't do anything useful unless it is provided with a port
|
||||
number that the client also knows about. Rather than just picking one and
|
||||
hoping it all works out, we require the port number as a parameter to the
|
||||
constructor. The constructor, in turn, simply does a @code{SetAttribute}
|
||||
with the passed value. You can, if desired, set the ``Port'' attribute to
|
||||
another value later.
|
||||
|
||||
Similar to many other helper objects, the @code{UdpEchoServerHelper} object
|
||||
has an @code{Install} method. It is the execution of this method that actually
|
||||
causes the underlying echo server application to be instantiated and attached
|
||||
to a node. Interestingly, the @code{Install} method takes a
|
||||
@code{NodeContainter} as a parameter just as the other @code{Install} methods
|
||||
we have seen. This is actually what is passed to the method even though it
|
||||
doesn't look so in this case. There is a C++ @emph{implicit conversion} at
|
||||
work here.
|
||||
|
||||
We now see that @code{echoServer.Install} is going to install a
|
||||
@code{UdpEchoServerApplication} on the node found at index number one of the
|
||||
@code{NodeContainer} we used to manage our nodes. @code{Install} will return
|
||||
a container that holds pointers to all of the applications (one in this case
|
||||
since we passed a @code{NodeContainer} containing one node) created by the
|
||||
helper.
|
||||
|
||||
Applications require a time to ``start'' generating traffic and may take an
|
||||
optional time to ``stop.'' We provide both. These times are set using the
|
||||
@code{ApplicationContainer} methods @code{Start} and @code{Stop}. These
|
||||
methods take @code{Time} parameters. In this case, we use an explicit C++
|
||||
conversion sequence to take the C++ double 1.0 and convert it to an
|
||||
@command{ns-3} @code{Time} object using a @code{Seconds} cast. The two lines,
|
||||
|
||||
@verbatim
|
||||
serverApps.Start (Seconds (1.0));
|
||||
serverApps.Stop (Seconds (10.0));
|
||||
@end verbatim
|
||||
|
||||
will cause the echo server application to @code{Start} (enable itself) at one
|
||||
second into the simulation and to @code{Stop} (disable itself) at ten seconds
|
||||
into the simulation. By virtue of the fact that we have implicilty declared
|
||||
a simulation event (the application stop event) to be executed at ten seconds,
|
||||
the simulation will last at least ten seconds.
|
||||
|
||||
@subsubsection UdpEchoClientHelper
|
||||
|
||||
The echo client application is set up in a method substantially similar to
|
||||
that for the server. There is an underlying @code{UdpEchoClientApplication}
|
||||
that is managed by an @code{UdpEchoClientHelper}.
|
||||
|
||||
@verbatim
|
||||
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
|
||||
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
|
||||
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
|
||||
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
|
||||
|
||||
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
|
||||
clientApps.Start (Seconds (2.0));
|
||||
clientApps.Stop (Seconds (10.0));
|
||||
@end verbatim
|
||||
|
||||
For the echo client, however, we need to set five different attributes. The
|
||||
first two attributes are set during construction of the
|
||||
@code{UdpEchoClientHelper}. We pass parameters that are used (internally to
|
||||
the helper) to set the ``RemoteAddress'' and ``RemotePort'' attributes in
|
||||
accordance with our convention to make required attributes parameters in the
|
||||
helper constructors.
|
||||
|
||||
Recall that we used an @code{Ipv4InterfaceContainer} to keep track of the IP
|
||||
addresses we assigned to our devices. The zeroth interface in the
|
||||
@code{interfaces} container is going to coorespond to the IP address of the
|
||||
zeroth node in the @code{nodes} container. The first interface in the
|
||||
@code{interfaces} container cooresponds to the IP address of the first node
|
||||
in the @code{nodes} container. So, in the first line of code (from above), we
|
||||
are creating the helper and telling it so set the remote address of the client
|
||||
to be the IP address assigned to the node on which the server resides. We
|
||||
also tell it to arrange to send packets to port nine.
|
||||
|
||||
The ``MaxPackets'' attribute tells the client the maximum number of packets
|
||||
we allow it to send during the simulation. The ``Interval'' attribute tells
|
||||
the client how long to wait between packets, and the ``PacketSize'' attribute
|
||||
tells the client how large its packet payloads should be. With this
|
||||
particular combination of attributes, we are telling the client to send one
|
||||
1024-byte packet.
|
||||
|
||||
Just as in the case of the echo server, we tell the echo client to @code{Start}
|
||||
and @code{Stop}, but here we start the client one second after the server is
|
||||
enabled (at two seconds into the simulation).
|
||||
|
||||
@subsection Simulator
|
||||
What we need to do at this point is to actually run the simulation. This is
|
||||
done using the global function @code{Simulator::Run}.
|
||||
|
||||
@verbatim
|
||||
Simulator::Run ();
|
||||
@end verbatim
|
||||
|
||||
When we previously called the methods,
|
||||
|
||||
@verbatim
|
||||
serverApps.Start (Seconds (1.0));
|
||||
serverApps.Stop (Seconds (10.0));
|
||||
...
|
||||
clientApps.Start (Seconds (2.0));
|
||||
clientApps.Stop (Seconds (10.0));
|
||||
@end verbatim
|
||||
|
||||
we actually scheduled events in the simulator at 1.0 seconds, 2.0 seconds and
|
||||
10.0 seconds. When @code{Simulator::Run} is called, the ssytem will begin
|
||||
looking through the list of scheduled events and executing them. First it
|
||||
will run the event at 1.0 seconds, which will enable the echo server
|
||||
application. Then it will run the event scheduled for t=2.0 seconds which
|
||||
will start the echo client application. The start event implementation in
|
||||
the echo client application will begin the data transfer phase of the
|
||||
simulation by sending a packet to the server.
|
||||
|
||||
The act of sending the packet to the server will trigger a chain of events
|
||||
that will be automatically scheduled behind the scenes and which will perform
|
||||
the mechanics of the packet echo according to the various timing parameters
|
||||
that we have set in the script.
|
||||
|
||||
Eventually, since we only send one packet, the chain of events triggered by
|
||||
that single client echo request will taper off and the simulation will go
|
||||
idle. Once this happens, the remaining events will be the @code{Stop} events
|
||||
for the server and the client. When these events are executed, there are
|
||||
no further events to process and @code{Simulator::Run} returns. The simulation
|
||||
is complete.
|
||||
|
||||
All that remains is to clean up. This is done by calling the global function
|
||||
@code{Simulator::Destroy}. As the helper functions (or low level
|
||||
@command{ns-3} code) executed, they arranged it so that hooks were inserted in
|
||||
the simulator to destroy all of the objects that were created. You did not
|
||||
have to keep track of any of these objects yourself --- all you had to do
|
||||
was to call @code{Simulator::Destroy} and exit. The @command{ns-3} system
|
||||
took care of the hard part for you. The remaining lines of our first
|
||||
@command{ns-3} script, @code{first.cc}, do just that:
|
||||
|
||||
@verbatim
|
||||
Simulator::Destroy ();
|
||||
return 0;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
@subsection Building Your Script
|
||||
We have made it trivial to build your simple scripts. All you have to do is
|
||||
to drop your script into the scratch directory and it will automatically be
|
||||
built if you run Waf. Let's try it. Copy @code{examples/first.cc} into
|
||||
the @code{scratch} directory.
|
||||
|
||||
@verbatim
|
||||
~/repos/ns-3-dev > cp examples/first.cc scratch/
|
||||
@end verbatim
|
||||
|
||||
and then build it using waf,
|
||||
|
||||
@verbatim
|
||||
~/repos/ns-3-dev > ./waf
|
||||
Entering directory `/home/craigdo/repos/ns-3-dev/build'
|
||||
[432/477] cxx: scratch/first.cc -> build/debug/scratch/first_2.o
|
||||
[475/477] cxx_link: build/debug/scratch/first_2.o ...
|
||||
Compilation finished successfully
|
||||
~/repos/ns-3-dev >
|
||||
@end verbatim
|
||||
|
||||
You can now run the example (note that if you build your program in the scratch
|
||||
directory you must run it out of the scratch direcory):
|
||||
|
||||
@verbatim
|
||||
~/repos/ns-3-dev > ./waf --run scratch/first
|
||||
Entering directory `/home/craigdo/repos/ns-3-dev/build'
|
||||
Compilation finished successfully
|
||||
Sent 1024 bytes to 10.1.1.2
|
||||
Received 1024 bytes from 10.1.1.1
|
||||
Received 1024 bytes from 10.1.1.2
|
||||
~/repos/ns-3-dev >
|
||||
@end verbatim
|
||||
|
||||
Here you see that the build system checks to make sure that the file has been
|
||||
build and then runs it. You see the logging component on the echo client
|
||||
indicate that it has sent one 1024 byte packet to the Echo Server on
|
||||
10.1.1.2. You also see the logging component on the echo server say that
|
||||
it has received the 1024 bytes from 10.1.1.1. The echo server silently
|
||||
echoes the packet and you see the echo client log that it has received its
|
||||
packet back from the server.
|
||||
|
||||
@c ========================================================================
|
||||
@c Browsing ns-3
|
||||
@c ========================================================================
|
||||
|
||||
@node Ns-3 Source Code
|
||||
@section Ns-3 Source Code
|
||||
|
||||
Now that you have used some of the @command{ns-3} helpers you may want to
|
||||
have a look at some of the source code that implements that functionality.
|
||||
The most recent code can be browsed on our web server at the following link:
|
||||
@uref{http://code.nsnam.org/?sort=lastchange}. If you click on the bold
|
||||
repository names on the left of the page, you will see @emph{changelogs} for
|
||||
these repositories, and links to the @emph{manifest}. From the manifest
|
||||
links, one can browse the source tree.
|
||||
|
||||
The top-level directory for one of our @emph{repositories} will look
|
||||
something like:
|
||||
@verbatim
|
||||
drwxr-xr-x [up]
|
||||
drwxr-xr-x doc manifest
|
||||
drwxr-xr-x examples manifest
|
||||
drwxr-xr-x ns3 manifest
|
||||
drwxr-xr-x regression manifest
|
||||
drwxr-xr-x samples manifest
|
||||
drwxr-xr-x scratch manifest
|
||||
drwxr-xr-x src manifest
|
||||
drwxr-xr-x tutorial manifest
|
||||
drwxr-xr-x utils manifest
|
||||
-rw-r--r-- 135 .hgignore file | revisions | annotate
|
||||
-rw-r--r-- 891 .hgtags file | revisions | annotate
|
||||
-rw-r--r-- 441 AUTHORS file | revisions | annotate
|
||||
-rw-r--r-- 17987 LICENSE file | revisions | annotate
|
||||
-rw-r--r-- 4948 README file | revisions | annotate
|
||||
-rw-r--r-- 4917 RELEASE_NOTES file | revisions | annotate
|
||||
-rw-r--r-- 7 VERSION file | revisions | annotate
|
||||
-rwxr-xr-x 99143 waf file | revisions | annotate
|
||||
-rwxr-xr-x 28 waf.bat file | revisions | annotate
|
||||
-rw-r--r-- 30584 wscript file | revisions | annotate
|
||||
@end verbatim
|
||||
|
||||
The source code is mainly in the @code{src} directory. You can view source
|
||||
code by clicking on the @code{manifest} link to the right of the directory
|
||||
name. If you click on the @code{manifest} link to the right of the src
|
||||
directory you will find a subdirectory. If you click on the @code{manifest}
|
||||
link next to the @code{core} subdirectory in under @code{src}, you will find
|
||||
a list of files. The first file you will find is @code{assert.h}. If you
|
||||
click on the @code{file} link, you will be sent to the source file for
|
||||
@code{assert.h}.
|
||||
|
||||
Our example scripts are in the @code{examples} directory. The source code for
|
||||
the helpers we have used in this chapter can be found in the
|
||||
@code{src/helpers} directory.
|
||||
@@ -0,0 +1,18 @@
|
||||
Please write image files in a vector graphics format, when possible, and
|
||||
generate the .png and .pdf versions on the fly (see ../Makefile).
|
||||
|
||||
Currently supported tools are dia and tgif. xfig could be added similarly
|
||||
if someone wants to add it. The main requirement for adding another format
|
||||
is that the tool to edit it is freely available and that a cron script can
|
||||
autogenerate the pdf and png from the figure source.
|
||||
|
||||
Store the .dia, or .obj versions in mercurial, but not the .png or .pdfs.
|
||||
If the figure is not available in a vector graphics format, store both
|
||||
a .png and a .pdf version in this directory.
|
||||
|
||||
If you add a source (.dia, .obj) file here, remember to add it to
|
||||
the list of figure sources in the Makefile in the directory above
|
||||
|
||||
Note: tgif can convert from .obj to .pdf, but the pdf that results takes
|
||||
up a whole page. Instead, we convert to an intermediate .eps step, and
|
||||
then run epstopdf.
|
||||
Binary file not shown.
@@ -0,0 +1,115 @@
|
||||
%TGIF 4.1.43-QPL
|
||||
state(0,37,100.000,0,0,0,32,1,9,1,1,0,0,1,2,1,0,'Courier',0,80640,0,2,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0).
|
||||
%
|
||||
% @(#)$Header$
|
||||
% %W%
|
||||
%
|
||||
unit("1 pixel/pixel").
|
||||
color_info(11,65535,0,[
|
||||
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
|
||||
"red", 65535, 0, 0, 65535, 0, 0, 1,
|
||||
"green", 0, 65535, 0, 0, 65535, 0, 1,
|
||||
"blue", 0, 0, 65535, 0, 0, 65535, 1,
|
||||
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
|
||||
"pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
|
||||
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
|
||||
"CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
|
||||
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
|
||||
"black", 0, 0, 0, 0, 0, 0, 1,
|
||||
"DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1
|
||||
]).
|
||||
script_frac("0.6").
|
||||
fg_bg_colors('black','white').
|
||||
dont_reencode("FFDingbests:ZapfDingbats").
|
||||
page(1,"",1,'').
|
||||
text('black',272,195,2,0,1,248,36,0,13,5,0,0,0,0,2,248,36,0,0,"",0,0,0,0,208,'',[
|
||||
minilines(248,36,0,0,0,0,0,[
|
||||
mini_line(200,13,5,0,0,0,[
|
||||
str_block(0,200,13,5,0,-8,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,200,13,5,0,-8,0,0,0,0,0,
|
||||
"low-level APIs (all src/ ")])
|
||||
]),
|
||||
mini_line(248,13,5,0,0,0,[
|
||||
str_block(0,248,13,5,0,-2,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,248,13,5,0,-2,0,0,0,0,0,
|
||||
"directories except src/helper/)")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',96,240,384,288,5,1,1,0,16,2,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',192,259,1,0,1,112,18,3,13,5,2,0,0,0,2,112,18,0,0,"",0,0,0,0,272,'',[
|
||||
minilines(112,18,0,0,0,0,0,[
|
||||
mini_line(112,13,5,0,0,0,[
|
||||
str_block(0,112,13,5,0,0,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,112,13,5,0,0,0,0,0,0,0,
|
||||
"ns-3 simulator")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
272,208,240,240],0,1,1,17,0,0,2,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
240,176,240,240],1,1,1,18,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
rcbox('black','',176,128,384,176,5,1,1,0,16,25,0,0,0,0,'1',0,[
|
||||
]).
|
||||
text('black',192,131,2,0,1,120,36,26,13,5,2,0,0,0,2,120,36,0,0,"",0,0,0,0,144,'',[
|
||||
minilines(120,36,0,0,0,0,0,[
|
||||
mini_line(120,13,5,0,0,0,[
|
||||
str_block(0,120,13,5,0,-1,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,120,13,5,0,-1,0,0,0,0,0,
|
||||
"ns-3 helper API")])
|
||||
]),
|
||||
mini_line(96,13,5,0,0,0,[
|
||||
str_block(0,96,13,5,0,-2,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,96,13,5,0,-2,0,0,0,0,0,
|
||||
"(src/helper)")])
|
||||
])
|
||||
])]).
|
||||
rcbox('black','',96,16,384,64,0,1,1,0,16,32,0,0,0,0,'1',0,[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
240,64,240,128],1,1,1,36,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',272,83,2,0,1,200,36,40,13,5,0,0,0,0,2,200,36,0,0,"",0,0,0,0,96,'',[
|
||||
minilines(200,36,0,0,0,0,0,[
|
||||
mini_line(200,13,5,0,0,0,[
|
||||
str_block(0,200,13,5,0,-2,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,200,13,5,0,-2,0,0,0,0,0,
|
||||
"helper APIs (src/helper/)")])
|
||||
]),
|
||||
mini_line(192,13,5,0,0,0,[
|
||||
str_block(0,192,13,5,0,-1,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,192,13,5,0,-1,0,0,0,0,0,
|
||||
"call into low-level APIs")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
272,96,240,128],0,1,1,41,0,0,2,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
text('black',128,19,2,0,1,232,36,47,13,5,0,0,0,0,2,232,36,0,0,"",0,0,0,0,32,'',[
|
||||
minilines(232,36,0,0,0,0,0,[
|
||||
mini_line(224,13,5,0,0,0,[
|
||||
str_block(0,224,13,5,0,-2,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,224,13,5,0,-2,0,0,0,0,0,
|
||||
"ns-3 scripts (main programs)")])
|
||||
]),
|
||||
mini_line(232,13,5,0,0,0,[
|
||||
str_block(0,232,13,5,0,-1,0,0,0,[
|
||||
str_seg('black','Courier',0,80640,232,13,5,0,-1,0,0,0,0,0,
|
||||
"- may use either or both APIs")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
144,64,144,240],1,1,1,50,0,0,0,0,0,0,0,'1',0,0,
|
||||
"0","",[
|
||||
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
|
||||
]).
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,299 @@
|
||||
|
||||
@c ========================================================================
|
||||
@c Begin document body here
|
||||
@c ========================================================================
|
||||
|
||||
@c ========================================================================
|
||||
@c PART: Getting Started
|
||||
@c ========================================================================
|
||||
@c The below chapters are under the major heading "Getting Started"
|
||||
@c This is similar to the Latex \part command
|
||||
@c
|
||||
@c ========================================================================
|
||||
@c Getting Started
|
||||
@c ========================================================================
|
||||
@node Getting Started
|
||||
@chapter Getting Started
|
||||
|
||||
@menu
|
||||
* Downloading ns-3::
|
||||
* Building ns-3::
|
||||
* Testing ns-3::
|
||||
* Running a Script::
|
||||
@end menu
|
||||
|
||||
@c ========================================================================
|
||||
@c Downloading ns-3
|
||||
@c ========================================================================
|
||||
|
||||
@node Downloading ns-3
|
||||
@section Downloading ns-3
|
||||
|
||||
@cindex Linux
|
||||
@cindex Cygwin
|
||||
@cindex GNU
|
||||
@cindex toolchain
|
||||
@cindex Mercurial
|
||||
@cindex Waf
|
||||
From this point forward, we are going to assume that the reader is working in
|
||||
Linux or a Linux emulation environment (Linux, Cygwin, etc.) and has the GNU
|
||||
toolchain installed and verified. We are also going to assume that you have
|
||||
Mercurial and Waf installed and running on the target system as described in
|
||||
the Getting Started section of the @command{ns-3} web site:
|
||||
@uref{http://www.nsnam.org/getting_started.html}.
|
||||
|
||||
@cindex tarball
|
||||
The @command{ns-3} code is available in Mercurial repositories on the server
|
||||
code.nsnam.org. You can download a tarball, but we recommend working with
|
||||
Mercurial --- it will make your life easier in the long run.
|
||||
|
||||
@cindex repository
|
||||
If you go to the following link: @uref{http://code.nsnam.org/},
|
||||
you will see a number of repositories. Many are the private repositories of
|
||||
the @command{ns-3} development team. The repositories of interest to you will
|
||||
be prefixed with ``ns-3''. The current development snapshot (unreleased)
|
||||
of @command{ns-3} may be found at: @uref{http://code.nsnam.org/ns-3-dev/}.
|
||||
Official releases of @command{ns-3} will be numbered as @code{ns-3.<release>}
|
||||
with any requred hotfixes added as minor release numbers. For example, a
|
||||
second hotfix to a hypothetical release nine of @command{ns-3} would be
|
||||
numbered @code{ns-3.9.2}.
|
||||
|
||||
The current development snapshot (unreleased) of @command{ns-3} may be found
|
||||
at: @uref{http://code.nsnam.org/ns-3-dev/}. The developers attempt to keep
|
||||
this repository in a consistent, working state but it is a development area
|
||||
with unreleased code present, so you may want to consider staying with an
|
||||
official release.
|
||||
|
||||
Since the release numbers are going to be changing, I will stick with
|
||||
the more constant ns-3-dev here in the tutorial, but you can replace the
|
||||
string ``ns-3-dev'' with your choice of release (e.g., ns-3.1) in the text
|
||||
below. You can find the latest version of the code either by inspection of
|
||||
the repository list or by going to the ``Getting Started'' web page and
|
||||
looking for the latest release identifier.
|
||||
|
||||
One practice is to create a directory called @code{repos} in one's home
|
||||
directory under which one can keep local Mercurial repositories.
|
||||
@emph{Hint: we will assume you do this later in the tutorial.} If you adopt
|
||||
that approach, you can get a copy of the development version of
|
||||
@command{ns-3} by typing the following into your Linux shell (assuming you
|
||||
have installed Mercurial):
|
||||
|
||||
@verbatim
|
||||
cd
|
||||
mkdir repos
|
||||
cd repos
|
||||
hg clone http://code.nanam.org/ns-3-dev
|
||||
@end verbatim
|
||||
|
||||
As the hg (Mercurial) command executes, you should see something like the
|
||||
following,
|
||||
|
||||
@verbatim
|
||||
destination directory: ns-3-dev
|
||||
requesting all changes
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 3276 changesets with 12301 changes to 1353 files
|
||||
594 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
@end verbatim
|
||||
|
||||
After the clone command completes, you should have a directory called
|
||||
ns-3-dev under your @code{~/repos} directory, the contents of which should
|
||||
look something like the following:
|
||||
|
||||
@verbatim
|
||||
AUTHORS examples/ README samples/ utils/ waf.bat*
|
||||
build/ LICENSE regression/ scratch/ VERSION wscript
|
||||
doc/ ns3/ RELEASE_NOTES src/ waf*
|
||||
@end verbatim
|
||||
|
||||
You are now ready to build the @command{ns-3} distribution.
|
||||
|
||||
@c ========================================================================
|
||||
@c Building ns-3
|
||||
@c ========================================================================
|
||||
|
||||
@node Building ns-3
|
||||
@section Building ns-3
|
||||
|
||||
@cindex building with Waf
|
||||
@cindex configuring Waf
|
||||
@cindex building debug version with Waf
|
||||
@cindex compiling with Waf
|
||||
@cindex unit tests with Waf
|
||||
@cindex regression tests with Waf
|
||||
We use Waf to build the @command{ns-3} project. The first thing you will need
|
||||
to do is to configure the build. For reasons that will become clear later,
|
||||
we are going to work with debug builds in the tutorial. To explain to Waf
|
||||
that it should do debug builds you will need to execute the following command,
|
||||
|
||||
@verbatim
|
||||
./waf -d debug configure
|
||||
@end verbatim
|
||||
|
||||
This runs Waf out of the local directory (which is provided as a convenience
|
||||
for you). As the build system checks for various dependencies you should see
|
||||
output that looks similar to the following,
|
||||
|
||||
@verbatim
|
||||
~/repos/ns-3-dev >./waf -d debug configure
|
||||
Checking for program g++ : ok /usr/bin/g++
|
||||
Checking for compiler version : ok Version 4.1.2
|
||||
Checking for program cpp : ok /usr/bin/cpp
|
||||
Checking for program ar : ok /usr/bin/ar
|
||||
Checking for program ranlib : ok /usr/bin/ranlib
|
||||
Checking for compiler could create programs : ok
|
||||
Checking for compiler could create shared libs : ok
|
||||
Checking for compiler could create static libs : ok
|
||||
Checking for flags -O2 -DNDEBUG : ok
|
||||
Checking for flags -g -DDEBUG : ok
|
||||
Checking for flags -g3 -O0 -DDEBUG : ok
|
||||
Checking for flags -Wall : ok
|
||||
Checking for g++ : ok
|
||||
Checking for header stdlib.h : ok
|
||||
Checking for header stdlib.h : ok
|
||||
Checking for header signal.h : ok
|
||||
Checking for high precision time implementation : 128-bit integer
|
||||
Checking for header stdint.h : ok
|
||||
Checking for header inttypes.h : ok
|
||||
Checking for header sys/inttypes.h : not found
|
||||
Checking for package gtk+-2.0 >= 2.12 : not found
|
||||
Checking for package goocanvas gthread-2.0 : not found
|
||||
Checking for program diff : ok /usr/bin/diff
|
||||
Configuration finished successfully; project is now ready to build.
|
||||
~/repos/ns-3-dev >
|
||||
@end verbatim
|
||||
|
||||
The build system is now configured and you can build the debug versions of
|
||||
the @command{ns-3} programs by simply typing,
|
||||
|
||||
@verbatim
|
||||
./waf
|
||||
@end verbatim
|
||||
|
||||
You will see many Waf status messages displayed as the system compiles. The
|
||||
most important is the last one,
|
||||
|
||||
@verbatim
|
||||
Compilation finished successfully
|
||||
@end verbatim
|
||||
|
||||
@c ========================================================================
|
||||
@c Testing ns-3
|
||||
@c ========================================================================
|
||||
|
||||
@node Testing ns-3
|
||||
@section Testing ns-3
|
||||
|
||||
@cindex unit tests
|
||||
You can run the unit tests of the @command{ns-3} distribution by running the ``check''
|
||||
command,
|
||||
|
||||
@verbatim
|
||||
./waf check
|
||||
@end verbatim
|
||||
|
||||
You should see a report from each unit test that executes indicating that the
|
||||
test has passed.
|
||||
|
||||
@verbatim
|
||||
~/repos/ns-3-dev > ./waf check
|
||||
Entering directory `/home/craigdo/repos/ns-3-dev/build'
|
||||
Compilation finished successfully
|
||||
PASS AddressHelper
|
||||
PASS Wifi
|
||||
PASS DcfManager
|
||||
|
||||
...
|
||||
|
||||
PASS Object
|
||||
PASS Ptr
|
||||
PASS Callback
|
||||
~/repos/ns-3-dev >
|
||||
@end verbatim
|
||||
|
||||
@cindex regression tests
|
||||
This command is typically run by @code{users} to quickly verify that an
|
||||
@command{ns-3} distribution has built correctly.
|
||||
|
||||
You can also run our regression test suite to ensure that your distribution and
|
||||
tool chain have produced binaries that generate output that is identical to
|
||||
reference output files stored in a central location. To run the regression
|
||||
tests, you provide Waf with the regression flag.
|
||||
|
||||
@verbatim
|
||||
./waf --regression
|
||||
@end verbatim
|
||||
|
||||
Waf will verify that the current files in the @command{ns-3} distribution are
|
||||
built and will then look for trace files in the aforementioned centralized
|
||||
location. If your tool chain includes Mercurial, the regression tests will
|
||||
be downloaded from a repository at @code{code.nsnam.org}. If you do not have
|
||||
Mercurial installed, the reference traces will be downloaded from a tarball
|
||||
located in the releases section of @code{www.nsnam.org}. The particular name
|
||||
of the reference trace location is built from the @command{ns-3} version
|
||||
located in the VERSION file, so don't change that string yourself unless you
|
||||
know what you are doing.
|
||||
|
||||
Once the reference traces are downloaded to your local machine, Waf will run
|
||||
a number of tests that generate what we call trace files. The content of
|
||||
these trace files are compared with the reference traces just downloaded. If
|
||||
they are identical, the regression tests report a PASS status. If the
|
||||
regression tests pass, you should see something like,
|
||||
|
||||
@verbatim
|
||||
~/repos/ns-3-dev > ./waf --regression
|
||||
Entering directory `/home/craigdo/repos/ns-3-dev/build'
|
||||
Compilation finished successfully
|
||||
========== Running Regression Tests ==========
|
||||
Synchronizing reference traces using Mercurial.
|
||||
http://code.nsnam.org/ns-3-dev-ref-traces
|
||||
Done.
|
||||
PASS test-csma-broadcast
|
||||
PASS test-csma-multicast
|
||||
PASS test-csma-one-subnet
|
||||
PASS test-csma-packet-socket
|
||||
PASS test-simple-error-model
|
||||
PASS test-simple-global-routing
|
||||
PASS test-simple-point-to-point-olsr
|
||||
PASS test-tcp-large-transfer
|
||||
PASS test-udp-echo
|
||||
~/repos/ns-3-dev >
|
||||
@end verbatim
|
||||
|
||||
If a regression tests fails you will see a FAIL indication along with a
|
||||
pointer to the offending trace file and its associated reference trace file
|
||||
along with a suggestion on diff parameters and options in order to see what
|
||||
has gone awry.
|
||||
|
||||
@c ========================================================================
|
||||
@c Running a Script
|
||||
@c ========================================================================
|
||||
|
||||
@node Running a Script
|
||||
@section Running a Script
|
||||
@cindex running a script with Waf
|
||||
We typically run scripts under the control of Waf. This allows the build
|
||||
system to ensure that the shared library paths are set correctly and that
|
||||
the libraries are available at run time. To run a program, simply use the
|
||||
@code{--run} option in Waf. Let's run the @command{ns-3} equivalent of the
|
||||
ubiquitous hello world program by typing the following:
|
||||
|
||||
@verbatim
|
||||
./waf --run hello-simulator
|
||||
@end verbatim
|
||||
|
||||
Waf first checks to make sure that the program is built correctly and
|
||||
executes a build if required. Waf then then executes the program, which
|
||||
produces the following output.
|
||||
|
||||
@verbatim
|
||||
Hello Simulator
|
||||
@end verbatim
|
||||
|
||||
@emph{Congratulations. You are now an ns-3 user.}
|
||||
|
||||
If you want to run programs under another tool such as gdb or valgrind,
|
||||
see this @uref{http://www.nsnam.org/wiki/index.php/User_FAQ#How_to_run_NS-3_programs_under_another_tool,,wiki entry}.
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
TEXI2HTML = texi2html
|
||||
TEXI2PDF = texi2dvi --pdf
|
||||
EPSTOPDF = epstopdf
|
||||
TGIF = tgif
|
||||
DIA = dia
|
||||
CONVERT = convert
|
||||
CSS = --css-include=tutorial.css
|
||||
SPLIT = --split section
|
||||
|
||||
DIA_SOURCES = pp.dia dumbbell.dia star.dia
|
||||
TGIF_SOURCES = helpers.obj
|
||||
|
||||
DIA_EPS = ${DIA_SOURCES:.dia=.eps}
|
||||
DIA_PNG = ${DIA_SOURCES:.dia=.png}
|
||||
DIA_PDF = ${DIA_SOURCES:.dia=.pdf}
|
||||
|
||||
TGIF_EPS = ${TGIF_SOURCES:.obj=.eps}
|
||||
TGIF_PNG = ${TGIF_SOURCES:.obj=.png}
|
||||
TGIF_PDF = ${TGIF_SOURCES:.obj=.pdf}
|
||||
|
||||
all: images html split-html pdf
|
||||
|
||||
# Note: tgif requires a valid x display to convert from .obj to .png.
|
||||
# If running this makefile on a remote console, the X virtual frame
|
||||
# buffer may be needed (xorg-x11-server-Xvfb) to provide a "fake"
|
||||
# display
|
||||
images:
|
||||
cd figures/; $(DIA) -t png $(DIA_SOURCES)
|
||||
cd figures/; $(DIA) -t eps $(DIA_SOURCES)
|
||||
cd figures/; $(foreach FILE,$(DIA_EPS),$(EPSTOPDF) $(FILE);)
|
||||
cd figures/; $(TGIF) -print -png $(TGIF_SOURCES)
|
||||
cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES)
|
||||
cd figures/; $(foreach FILE,$(TGIF_EPS),$(EPSTOPDF) $(FILE);)
|
||||
|
||||
html: images
|
||||
$(TEXI2HTML) ${CSS} tutorial.texi
|
||||
|
||||
split-html: images
|
||||
$(TEXI2HTML) ${CSS} ${SPLIT} tutorial.texi
|
||||
|
||||
pdf: images
|
||||
$(TEXI2PDF) tutorial.texi
|
||||
|
||||
figures-clean:
|
||||
cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF)
|
||||
cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF)
|
||||
|
||||
clean: figures-clean
|
||||
rm -rf tutorial.aux tutorial.cp tutorial.cps tutorial.fn tutorial.ky tutorial.pg tutorial.tp tutorial.vr tutorial.toc tutorial.log tutorial.pdf tutorial.html tutorial/
|
||||
@@ -0,0 +1,535 @@
|
||||
@node ns-3 Attributes
|
||||
@chapter ns-3 Attributes
|
||||
@anchor{chap:Attributes}
|
||||
|
||||
In ns-3 simulations, there are two main aspects to configuration:
|
||||
@itemize @bullet
|
||||
@item the simulation topology and how objects are connected
|
||||
@item the values used by the models instantiated in the topology
|
||||
@end itemize
|
||||
|
||||
This chapter focuses on the second item above: how the many values
|
||||
in use in ns-3 are organized, documented, and modifiable by ns-3 users.
|
||||
The ns-3 attribute system is also the underpinning of how traces
|
||||
and statistics are gathered in the simulator.
|
||||
|
||||
Before delving into details of the attribute value system,
|
||||
it will help to review some basic properties of @code{class ns3::Object}.
|
||||
|
||||
@node Object Overview
|
||||
@section Object Overview
|
||||
|
||||
ns-3 is fundamentally a C++ object-based system. By this we mean that
|
||||
new C++ classes (types) can be declared, defined, and subclassed
|
||||
as usual.
|
||||
|
||||
Many ns-3 objects inherit from the @code{ns3::Object} base class. These
|
||||
objects have some additional properties that we exploit for
|
||||
organizing the system and improving the memory management
|
||||
of our objects:
|
||||
|
||||
@itemize @bullet
|
||||
@item a "metadata" system that links the class name to a lot of
|
||||
meta-information about the object, including the base class of the subclass,
|
||||
the set of accessible constructors in the subclass, and the set of
|
||||
"attributes" of the subclass
|
||||
@item a reference counting smart pointer implementation, for memory
|
||||
management.
|
||||
@end itemize
|
||||
|
||||
ns-3 objects that use the attribute system derive from either
|
||||
@code{ns3::Object} or @code{ns3::ObjectBase}. Most ns-3 objects
|
||||
we will discuss derive from @code{ns3::Object}, but a few that
|
||||
are outside the smart pointer memory management framework derive
|
||||
from @code{ns3::ObjectBase}.
|
||||
|
||||
Let's review a couple of properties of these objects.
|
||||
|
||||
@node Smart pointers
|
||||
@subsection Smart pointers
|
||||
|
||||
As introduced above in @ref{Smart Pointers 101}, ns-3 objects
|
||||
are memory managed by a
|
||||
@uref{http://en.wikipedia.org/wiki/Smart_pointer,,reference counting smart pointer implementation}, @code{class ns3::Ptr}.
|
||||
|
||||
Smart pointers are used extensively in the ns-3 APIs, to avoid passing
|
||||
references to heap-allocated objects that may cause memory leaks.
|
||||
For most basic usage (syntax), treat a smart pointer like a regular pointer:
|
||||
@verbatim
|
||||
Ptr<WifiNetDevice> nd = ...;
|
||||
nd->CallSomeFunction ();
|
||||
// etc.
|
||||
@end verbatim
|
||||
|
||||
@node CreateObject
|
||||
@subsection CreateObject
|
||||
|
||||
As we discussed above in @ref{Object Creation},
|
||||
at the lowest-level API, objects of type @code{ns3::Object} are
|
||||
not instantiated using @code{operator new} as usual but instead by
|
||||
a templated function called @code{CreateObject()}.
|
||||
|
||||
A typical way to create such an object is as follows:
|
||||
@verbatim
|
||||
Ptr<WifiNetDevice> nd = CreateObject<WifiNetDevice> ();
|
||||
@end verbatim
|
||||
|
||||
You can think of this as being functionally equivalent to:
|
||||
@verbatim
|
||||
WifiNetDevice* nd = new WifiNetDevice ();
|
||||
@end verbatim
|
||||
|
||||
Objects that derive from @code{ns3::Object} must be allocated
|
||||
on the heap using CreateObject(). Those deriving from
|
||||
@code{ns3::ObjectBase}, such as ns-3 helper functions and packet
|
||||
headers and trailers, can be allocated on the stack.
|
||||
|
||||
In some scripts, you may not see a lot of CreateObject() calls
|
||||
in the code;
|
||||
this is because there are some helper objects in effect that
|
||||
are doing the CreateObject()s for you.
|
||||
|
||||
@node TypeId
|
||||
@subsection TypeId
|
||||
|
||||
ns-3 classes that derive from class ns3::Object can include
|
||||
a metadata class called @code{TypeId} that records meta-information
|
||||
about the class, for use in the object aggregation and component
|
||||
manager systems:
|
||||
@itemize @bullet
|
||||
@item a unique string identifying the class
|
||||
@item the base class of the subclass, within the metadata system
|
||||
@item the set of accessible constructors in the subclass
|
||||
@end itemize
|
||||
|
||||
@node Object Summary
|
||||
@subsection Object Summary
|
||||
|
||||
Putting all of these concepts together, let's look at a specific
|
||||
example: @code{class ns3::Node}.
|
||||
|
||||
The public header file node.h has a declaration that includes
|
||||
a static GetTypeId function call:
|
||||
@verbatim
|
||||
class Node : public Object
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
...
|
||||
@end verbatim
|
||||
|
||||
This is defined in the node.cc file as follows:
|
||||
@verbatim
|
||||
TypeId
|
||||
Node::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::Node")
|
||||
.SetParent<Object> ()
|
||||
return tid;
|
||||
}
|
||||
@end verbatim
|
||||
Finally, when users want to create Nodes, they call:
|
||||
@verbatim
|
||||
Ptr<Node> n = CreateObject<Node> n;
|
||||
@end verbatim
|
||||
|
||||
We next discuss how attributes (values associated with member variables
|
||||
or functions of the class) are plumbed into the above TypeId.
|
||||
|
||||
@node Attribute Overview
|
||||
@section Attribute Overview
|
||||
|
||||
The goal of the attribute system is to organize the access of
|
||||
internal member objects of a simulation. This goal arises because,
|
||||
typically in simulation, users will cut and paste/modify existing
|
||||
simulation scripts, or will use higher-level simulation constructs,
|
||||
but often will be interested in studying or tracing particular
|
||||
internal variables. For instance, use cases such as:
|
||||
@itemize @bullet
|
||||
@item "I want to trace the packets on the wireless interface only on
|
||||
the first access point"
|
||||
@item "I want to trace the value of the TCP congestion window (every
|
||||
time it changes) on a particular TCP socket"
|
||||
@item "I want a dump of all values that were used in my simulation."
|
||||
@end itemize
|
||||
|
||||
Similarly, users may want fine-grained access to internal
|
||||
variables in the simulation, or may want to broadly change the
|
||||
initial value used for a particular parameter in all subsequently
|
||||
created objects. Finally, users may wish to know what variables
|
||||
are settable and retrievable in a simulation configuration. This
|
||||
is not just for direct simulation interaction on the command line;
|
||||
consider also a (future) graphical user interface
|
||||
that would like to be able to provide a feature whereby a user
|
||||
might right-click on an node on the canvas and see a hierarchical,
|
||||
organized list of parameters that are settable on the node and its
|
||||
constituent member objects, and help text and default values for
|
||||
each parameter.
|
||||
|
||||
@node Functional overview
|
||||
@subsection Functional overview
|
||||
|
||||
We provide a way for users to access values deep in the system, without
|
||||
having to plumb accessors (pointers) through the system and walk
|
||||
pointer chains to get to them. Consider a class DropTailQueue that
|
||||
has a member variable that is an unsigned integer @code{m_maxPackets};
|
||||
this member variable controls the depth of the queue.
|
||||
|
||||
If we look at the declaration of DropTailQueue, we see the following:
|
||||
@verbatim
|
||||
class DropTailQueue : public Queue {
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
...
|
||||
|
||||
private:
|
||||
std::queue<Ptr<Packet> > m_packets;
|
||||
uint32_t m_maxPackets;
|
||||
};
|
||||
@end verbatim
|
||||
|
||||
Let's consider things that a user may want to do with the value of
|
||||
m_maxPackets:
|
||||
|
||||
@itemize @bullet
|
||||
@item Set a default value for the system, such that whenever a new
|
||||
DropTailQueue is created, this member is initialized to that default.
|
||||
@item Set or get the value on an already instantiated queue.
|
||||
@end itemize
|
||||
|
||||
The above things typically require providing Set() and Get() functions,
|
||||
and some type of global default value.
|
||||
|
||||
In the ns-3 attribute system, these value definitions and accessor
|
||||
functions are moved into the TypeId class; e.g.:
|
||||
@verbatim
|
||||
TypeId DropTailQueue::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::DropTailQueue")
|
||||
.SetParent<Queue> ()
|
||||
.AddConstructor<DropTailQueue> ()
|
||||
.AddAttribute ("MaxPackets", "The maximum number of packets accepted by this DropTailQueue.",
|
||||
Uinteger (100),
|
||||
MakeUintegerAccessor (&DropTailQueue::m_maxPackets),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
;
|
||||
|
||||
return tid;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
The AddAttribute() method is performing a number of things with this
|
||||
value:
|
||||
@itemize @bullet
|
||||
@item Binding the variable m_maxPackets to a string "MaxPackets"
|
||||
@item Providing a default value (100 packets)
|
||||
@item Providing some help text defining the value
|
||||
@item Providing a "checker" (not used in this example) that can be used to set
|
||||
bounds on the allowable range of values
|
||||
@end itemize
|
||||
|
||||
The key point is that now the value of this variable and its default
|
||||
value are accessible in the attribute namespace, which is based on
|
||||
strings such as "MaxPackets" and TypeId strings. In the next
|
||||
section, we will provide an example script that shows how users
|
||||
may manipulate these values.
|
||||
|
||||
@node Basic usage
|
||||
@subsection Basic usage
|
||||
|
||||
Let's look at how a user script might access these values.
|
||||
This is based on the script found at @code{samples/main-attribute-value.cc},
|
||||
with some details stripped out.
|
||||
@verbatim
|
||||
//
|
||||
// This is a basic example of how to use the attribute system to
|
||||
// set and get a value in the underlying system; namely, an unsigned
|
||||
// integer of the maximum number of packets in a queue
|
||||
//
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
// By default, the MaxPackets attribute has a value of 100 packets
|
||||
// (this default can be observed in the function DropTailQueue::GetTypeId)
|
||||
//
|
||||
// Here, we set it to 80 packets. We could use one of two value types:
|
||||
// a string-based value or a Uinteger value
|
||||
Config::SetDefault ("ns3::DropTailQueue::MaxPackets", String ("80"));
|
||||
// The below function call is redundant
|
||||
Config::SetDefault ("ns3::DropTailQueue::MaxPackets", Uinteger(80));
|
||||
|
||||
// Allow the user to override any of the defaults and the above
|
||||
// SetDefaults() at run-time, via command-line arguments
|
||||
CommandLine cmd;
|
||||
cmd.Parse (argc, argv);
|
||||
@end verbatim
|
||||
|
||||
The main thing to notice in the above are the two calls to
|
||||
@code{Config::SetDefault}. This is how we set the default value
|
||||
for all subsequently instantiated DropTailQueues. We illustrate
|
||||
that two types of Value classes, a String and a Uinteger class,
|
||||
can be used to assign the value to the attribute named by
|
||||
"ns3::DropTailQueue::MaxPackets".
|
||||
|
||||
Now, we will create a few objects using the low-level API; here,
|
||||
our newly created queues will not have a m_maxPackets initialized to
|
||||
100 packets but to 80 packets, because of what we did above with
|
||||
default values.
|
||||
@verbatim
|
||||
Ptr<Node> n0 = CreateObject<Node> ();
|
||||
|
||||
Ptr<PointToPointNetDevice> net0 = CreateObject<PointToPointNetDevice> ();
|
||||
n0->AddDevice (net0);
|
||||
|
||||
Ptr<Queue> q = CreateObject<DropTailQueue> ();
|
||||
net0->AddQueue(q);
|
||||
@end verbatim
|
||||
|
||||
At this point, we have created a single node (Node 0) and a
|
||||
single PointToPointNetDevice (NetDevice 0) and added a
|
||||
DropTailQueue to it.
|
||||
|
||||
Now, we can manipulate the MaxPackets value of the already
|
||||
instantiated DropTailQueue. Here are various ways to do that.
|
||||
|
||||
@subsubsection Pointer-based access
|
||||
|
||||
We assume that a smart pointer (Ptr) to a relevant network device is
|
||||
in hand; here, it is the net0 pointer.
|
||||
|
||||
One way to change the value is to access a pointer to the
|
||||
underlying queue and modify its attribute.
|
||||
|
||||
First, we observe that we can get a pointer to the (base class)
|
||||
queue via the PointToPointNetDevice attributes, where it is called
|
||||
TxQueue
|
||||
@verbatim
|
||||
Ptr<Queue> txQueue = net0->GetAttribute ("TxQueue");
|
||||
@end verbatim
|
||||
|
||||
Using the GetObject function, we can perform a safe downcast
|
||||
to a DropTailQueue, where MaxPackets is a member
|
||||
@verbatim
|
||||
Ptr<DropTailQueue> dtq = txQueue->GetObject <DropTailQueue> ();
|
||||
NS_ASSERT (dtq);
|
||||
@end verbatim
|
||||
|
||||
Next, we can get the value of an attribute on this queue
|
||||
We have introduced wrapper "Value" classes for the underlying
|
||||
data types, similar to Java wrappers around these types, since
|
||||
the attribute system stores values and not disparate types.
|
||||
Here, the attribute value is assigned to a Uinteger, and
|
||||
the Get() method on this value produces the (unwrapped) uint32_t.
|
||||
@verbatim
|
||||
Uinteger limit = dtq->GetAttribute ("MaxPackets");
|
||||
NS_LOG_INFO ("1. dtq limit: " << limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
Note that the above downcast is not really needed; we could have
|
||||
done the same using the Ptr<Queue> even though the attribute
|
||||
is a member of the subclass
|
||||
@verbatim
|
||||
limit = txQueue->GetAttribute ("MaxPackets");
|
||||
NS_LOG_INFO ("2. txQueue limit: " << limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
Now, let's set it to another value (60 packets)
|
||||
@verbatim
|
||||
txQueue->SetAttribute("MaxPackets", Uinteger (60));
|
||||
limit = txQueue->GetAttribute ("MaxPackets");
|
||||
NS_LOG_INFO ("3. txQueue limit changed: " << limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
@subsubsection Namespace-based access
|
||||
|
||||
An alternative way to get at the attribute is to use the configuration
|
||||
namespace. Here, this attribute resides on a known path in this
|
||||
namespace; this approach is useful if one doesn't have access to
|
||||
the underlying pointers and would like to configure a specific
|
||||
attribute with a single statement.
|
||||
@verbatim
|
||||
Config::Set ("/NodeList/0/DeviceList/0/TxQueue/MaxPackets", Uinteger (25));
|
||||
limit = txQueue->GetAttribute ("MaxPackets");
|
||||
NS_LOG_INFO ("4. txQueue limit changed through namespace: " <<
|
||||
limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
We could have also used wildcards to set this value for all nodes
|
||||
and all net devices (which in this simple example has the same
|
||||
effect as the previous Set())
|
||||
@verbatim
|
||||
Config::Set ("/NodeList/*/DeviceList/*/TxQueue/MaxPackets", Uinteger (15));
|
||||
limit = txQueue->GetAttribute ("MaxPackets");
|
||||
NS_LOG_INFO ("5. txQueue limit changed through wildcarded namespace: " <<
|
||||
limit.Get () << " packets");
|
||||
@end verbatim
|
||||
|
||||
@node Setting through constructors and helper classes
|
||||
@subsection Setting through constructors helper classes
|
||||
|
||||
Arbitrary combinations of attributes can be set and fetched from
|
||||
the helper and low-level APIs; either from the constructors themselves:
|
||||
@verbatim
|
||||
Ptr<Object> p = CreateObject<MyNewObject> ("n1", v1, "n2", v2, ...);
|
||||
@end verbatim
|
||||
or from the higher-level helper APIs, such as:
|
||||
@verbatim
|
||||
mobility.SetPositionAllocator ("GridPositionAllocator",
|
||||
"MinX", FpValue (-100.0),
|
||||
"MinY", FpValue (-100.0),
|
||||
"DeltaX", FpValue (5.0),
|
||||
"DeltaY", FpValue (20.0),
|
||||
"GridWidth", UintValue (20),
|
||||
"LayoutType", "RowFirst");
|
||||
@end verbatim
|
||||
|
||||
@node Value classes
|
||||
@subsection Value classes
|
||||
Readers will note the new Value classes. These can be thought of as
|
||||
an intermediate class that can be used to convert from raw types to the
|
||||
Values that are used by the system. Recall that this database is holding
|
||||
objects of many types with a single generic type. Conversions to this
|
||||
type can either be done using an intermediate class (IntValue, FpValue for
|
||||
"floating point") or via strings. Direct implicit conversion of types
|
||||
to Value is not really practical. So in the above, users have a choice
|
||||
of using strings or values:
|
||||
@verbatim
|
||||
p->Set ("cwnd", "100"); // string-based setter
|
||||
p->Set ("cwnd", IntValue(100)); // value-based setter
|
||||
@end verbatim
|
||||
|
||||
The system provides some macros that help users declare and define
|
||||
new Value subclasses for new types that they want to introduce into
|
||||
the attribute system.
|
||||
|
||||
@node Extending attributes
|
||||
@section Extending attributes
|
||||
|
||||
The ns-3 system will place a number of internal values under the
|
||||
attribute system, but undoubtedly users will want to extend this
|
||||
to pick up ones we have missed, or to add their own classes to this.
|
||||
|
||||
@subsection Adding an existing internal variable to the metadata system
|
||||
|
||||
// XXX revise me
|
||||
|
||||
Consider this variable in class TcpSocket:
|
||||
@verbatim
|
||||
uint32_t m_cWnd; // Congestion window
|
||||
@end verbatim
|
||||
|
||||
Suppose that someone working with Tcp wanted to get or set the
|
||||
value of that variable using the metadata system. If it were not
|
||||
already provided by ns-3, the user could declare the following addition
|
||||
in the metadata system (to the TypeId declaration for TcpSocket):
|
||||
@verbatim
|
||||
.AddParameter ("Congestion window",
|
||||
"Tcp congestion window (bytes)",
|
||||
MakeUIntParamSpec (&TcpSocket::m_cWnd, 1));
|
||||
|
||||
@end verbatim
|
||||
|
||||
Now, the user with a pointer to the TcpSocket can perform operations
|
||||
such as setting and getting the value, without having to add these
|
||||
functions explicitly. Furthermore, access controls can be applied, such
|
||||
as allowing the parameter to be read and not written, or bounds
|
||||
checking on the permissible values can be applied.
|
||||
|
||||
@subsection Adding a new TypeId
|
||||
|
||||
Here, we discuss the impact on a user who wants to add a new class to
|
||||
ns-3; what additional things must be done to hook it into this system.
|
||||
|
||||
We've already introduced what a TypeId definition looks like:
|
||||
@verbatim
|
||||
TypeId
|
||||
RandomWalk2dMobilityModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("RandomWalkMobilityModel")
|
||||
.SetParent<MobilityModel> ()
|
||||
.SetGroupName ("Mobility")
|
||||
.AddConstructor<RandomWalk2dMobilityModel> ()
|
||||
// followed by a number of Parameters
|
||||
.AddParameter ("bounds",
|
||||
"Bounds of the area to cruise.",
|
||||
MakeRectangleParamSpec (&RandomWalk2dMobilityModel::m_bounds, Rectangle (0.0, 0.0, 100.0, 100.0)))
|
||||
.AddParameter ("time",
|
||||
"Change current direction and speed after moving for this delay.",
|
||||
MakeTimeParamSpec (&RandomWalk2dMobilityModel::m_modeTime,
|
||||
Seconds (1.0)))
|
||||
|
||||
// etc (more parameters).
|
||||
@end verbatim
|
||||
|
||||
The declaration for this in the class declaration is one-line public
|
||||
member method:
|
||||
@verbatim
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
@end verbatim
|
||||
|
||||
@section Adding new class type to the Value system
|
||||
|
||||
From the perspective of the user who writes a new class in the system and
|
||||
wants to hook it in to the attribute system, there is mainly the matter
|
||||
of writing
|
||||
the conversions to/from strings and Values. Most of this can be
|
||||
copy/pasted with macro-ized code. For instance, consider class
|
||||
Rectangle in the @code{src/mobility/} directory:
|
||||
|
||||
One line is added to the class declaration:
|
||||
@verbatim
|
||||
/**
|
||||
* \brief a 2d rectangle
|
||||
*/
|
||||
class Rectangle
|
||||
{
|
||||
...
|
||||
|
||||
VALUE_HELPER_HEADER_1 (Rectangle);
|
||||
};
|
||||
@end verbatim
|
||||
|
||||
One templatized declaration, and two operators, are added below the
|
||||
class declaration:
|
||||
|
||||
@verbatim
|
||||
std::ostream &operator << (std::ostream &os, const Rectangle &rectangle);
|
||||
std::istream &operator >> (std::istream &is, Rectangle &rectangle);
|
||||
|
||||
VALUE_HELPER_HEADER_2 (Rectangle);
|
||||
@end verbatim
|
||||
|
||||
In the class definition, the code looks like this:
|
||||
|
||||
@verbatim
|
||||
VALUE_HELPER_CPP (Rectangle);
|
||||
|
||||
std::ostream &
|
||||
operator << (std::ostream &os, const Rectangle &rectangle)
|
||||
{
|
||||
os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax;
|
||||
return os;
|
||||
}
|
||||
std::istream &
|
||||
operator >> (std::istream &is, Rectangle &rectangle)
|
||||
{
|
||||
char c1, c2, c3;
|
||||
is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax;
|
||||
if (c1 != '|' ||
|
||||
c2 != '|' ||
|
||||
c3 != '|')
|
||||
{
|
||||
is.setstate (std::ios_base::failbit);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
These stream operators simply convert from a string representation of the
|
||||
Rectangle ("xMin|xMax|yMin|yMax") to the underlying Rectangle, and the
|
||||
modeler must specify these operators and the string syntactical representation
|
||||
of an instance of the new class.
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
@node Helper Functions
|
||||
@chapter Helper Functions
|
||||
@anchor{chap:Helpers}
|
||||
This chapter describes an intermediate API for the simulator; what we
|
||||
call the "helper API". The helper API is implemented in
|
||||
@code{src/helper/} directory; it depends on (and wraps) the low-level
|
||||
API which is implemented everywhere else in @code{src/}. The following
|
||||
figure shows this relationship.
|
||||
@center @image{figures/helpers,,,,png}
|
||||
|
||||
The use of the helper API is optional. It has two main goals:
|
||||
@itemize @bullet
|
||||
@item Provide "syntactic sugar" to wrap a number of related low-level
|
||||
API calls together, that would normally be grouped together often, into
|
||||
something that is more user-friendly.
|
||||
@item Handle configuration of larger topological units (e.g., a set
|
||||
of nodes or a set of nodes on a particular link) .
|
||||
@end itemize
|
||||
|
||||
(more to follow)
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,24 @@
|
||||
@node Logging
|
||||
@chapter Logging
|
||||
@anchor{chap:Logging}
|
||||
|
||||
This chapter is the first in a series of chapters discussing things that
|
||||
one can do to modify the input or output of existing ns-3 scripts.
|
||||
|
||||
Examples:
|
||||
@itemize @bullet
|
||||
@item Enable or disable the generation of log messages, with fine granularity
|
||||
@item Set default values for configuration values in the system
|
||||
@item Generate a report of all configuration values used during a simulation
|
||||
run (not yet implemented)
|
||||
@item Set or get values of member variables on objects already instantiated
|
||||
@item Customizing the tracing output of the script
|
||||
@item Generate statistics on (not yet implemented)
|
||||
@item Perform a large number of independent runs of the same simulation
|
||||
@end itemize
|
||||
|
||||
@node Logging Basics
|
||||
@section Logging Basics
|
||||
|
||||
@node Enabling Log Output
|
||||
@section Enabling Log Output
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,462 @@
|
||||
|
||||
@c ========================================================================
|
||||
@c Simulation Output
|
||||
@c ========================================================================
|
||||
|
||||
@node Simulation Output
|
||||
@chapter Simulation Output
|
||||
|
||||
At this point, you should be able to execute any of the built-in
|
||||
programs distributed with @command{ns-3}. Next, we will look at
|
||||
how to generate and tailor the simulation output, before turning
|
||||
to how to modify simulation scripts to do different things.
|
||||
|
||||
@node Tracing Basics
|
||||
@section Tracing Basics
|
||||
|
||||
The whole point of simulation is to generate output for further
|
||||
study, and the @command{ns-3} tracing system is a primary
|
||||
mechanism for this.
|
||||
Since @command{ns-3} is a C++ program, standard facilities for
|
||||
generating output from C++ programs apply:
|
||||
|
||||
@verbatim
|
||||
#include <iostream>
|
||||
...
|
||||
int main ()
|
||||
{
|
||||
...
|
||||
std::cout << "The value of x is " << x << std::endl;
|
||||
...
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
The goal of the @command{ns-3} tracing system is to
|
||||
provide a structured way to configure the simulator to output results
|
||||
in standard or modifiable formats.
|
||||
@itemize @bullet
|
||||
@item For basic tasks, the tracing system should allow the user to
|
||||
generate standard tracing for popular tracing sources, and to customize
|
||||
which objects generate the tracing.
|
||||
@item Intermediate users will be able to extend the tracing system to
|
||||
modify the output format generated, or to insert new tracing sources,
|
||||
without modifying the core of the simulator.
|
||||
@item Advanced users can modify the simulator core to add new
|
||||
tracing sources and sinks.
|
||||
@end itemize
|
||||
|
||||
The @command{ns-3} tracing system is fundamentally built on the
|
||||
concept of separating tracing sources from sinks.
|
||||
@enumerate
|
||||
@item Trace sources (e.g., provide access to every packet received)
|
||||
@item Trace sinks (e.g., print out the packet)
|
||||
@item A mechanism to tie together sources and sinks
|
||||
@end enumerate
|
||||
The rationale for this division is to allow users to attach new
|
||||
types of sinks to existing tracing sources, without requiring
|
||||
users to edit and recompile the core of the simulator.
|
||||
Thus, in the example above, a user could write a new tracing sink
|
||||
and attach it to an existing tracing source. What remains to
|
||||
be defined is a way for users to find these hooks (tracing sources)
|
||||
and attach sinks to them. A new tracing namespace is defined for
|
||||
this purpose.
|
||||
|
||||
We will first walk through how some pre-defined sources and sinks
|
||||
are provided and may be customized with little user effort. We
|
||||
return later in this chapter to advanced tracing configuration including
|
||||
extending the tracing namespace and creating new tracing sources.
|
||||
|
||||
@subsection ASCII tracing
|
||||
@cindex ASCII
|
||||
For Internet nodes, the ASCII trace wrapper is a wrapper around
|
||||
the @command{ns-3} low-level
|
||||
tracing system that lets you get access to underlying trace events easily.
|
||||
The output of a trace of a simulation run is an ASCII file --- thus the name.
|
||||
In the spririt of keeping things simple, you won't be able to control or
|
||||
configure the output at this stage.
|
||||
|
||||
For those familiar with @command{ns-2} output, this type of trace is
|
||||
analogous to the @command{out.tr} generated by many scripts.
|
||||
|
||||
@cindex tracing packets
|
||||
Let's just jump right in. As usual, we need to include the definitions
|
||||
related to using ASCII tracing (don't edit any files quite yet):
|
||||
|
||||
@verbatim
|
||||
#include "ns3/ascii-trace.h"
|
||||
@end verbatim
|
||||
|
||||
We then need to add the code to the script to actually enable the ASCII tracing
|
||||
code. The following code must be inserted before the call to
|
||||
@code{Simulator::Run ();}:
|
||||
|
||||
@verbatim
|
||||
AsciiTrace asciitrace ("tutorial.tr");
|
||||
asciitrace.TraceAllQueues ();
|
||||
asciitrace.TraceAllNetDeviceRx ();
|
||||
@end verbatim
|
||||
|
||||
The first line declares an object of type @code{AsciiTrace} named
|
||||
@code{asciitrace} and passes a string parameter to its constructor. This
|
||||
parameter is a file name to which all of the trace information will be written.
|
||||
The second line, @code{asciitrace.TraceAllQueues ();} asks the trace object to
|
||||
arrange that all queue operations (enqueue, dequeue, drop) on the queues
|
||||
in all of the nodes of the system be traced. On the receive side,
|
||||
@code{asciitrace.TraceAlllNetDeviceRx ()} traces packets received by
|
||||
a NetDevice. For those familiar with @command{ns-2}, these are equivalent
|
||||
to the popular trace points that log "+", "-", "d", and "r" events.
|
||||
|
||||
Try running the following program from the command line:
|
||||
@verbatim
|
||||
./waf --run tutorial-csma-echo-ascii-trace
|
||||
@end verbatim
|
||||
|
||||
@cindex tutorial.tr
|
||||
Just as you have seen previously, you will see some messages from @emph{Waf}
|
||||
and then the ``Compilation finished successfully'' message. The
|
||||
next message, @code{UDP Echo Simulation} is from the running program. When
|
||||
it ran, the program will have created a file named @code{tutorial.tr}.
|
||||
Because of the way that Waf works, the file is not created in the local
|
||||
directory, it is created at the top-level directory of the repository. So,
|
||||
change into the top level directory and take a look at the file
|
||||
@code{tutorial.tr} in your favorite editor.
|
||||
|
||||
@subsubsection Parsing Ascii Traces
|
||||
@cindex parsing ascii traces
|
||||
|
||||
This section parses in detail the structure of the ascii tracing
|
||||
output. If you find this output format self explanatory (it
|
||||
resembles tcpdump output), you may skip to the next
|
||||
section on pcap tracing.
|
||||
|
||||
@cindex trace event
|
||||
There's a lot of information there in a pretty dense form, but the first thing
|
||||
to notice is that there are a number of distinct lines in this file. It may
|
||||
be difficult to see this clearly unless you widen your windows considerably.
|
||||
Each line in the file corresponds to a @emph{trace event}. A trace event
|
||||
happens whenever specific conditions happen in the simulation. In this case
|
||||
we are tracing events on the @emph{device queue} present in every net device
|
||||
on every node in the simulation. The device queue is a queue through which
|
||||
every packet destined for a channel must pass --- it is the device
|
||||
@emph{transmit} queue. Note that each line in the trace file begins with a
|
||||
lone character (has a space after it). This character will have the following
|
||||
meaning:
|
||||
|
||||
@cindex enqueue
|
||||
@cindex dequeue
|
||||
@cindex drop
|
||||
@itemize @bullet
|
||||
@item @code{+}: An enqueue operation occurred on the device queue;
|
||||
@item @code{-}: A dequeue operation occurred on the device queue;
|
||||
@item @code{d}: A packet was dropped, typically because the queue was full.
|
||||
@end itemize
|
||||
|
||||
Let's take a more detailed view of the first line. I'll break it down into
|
||||
sections (indented for clarity) with a two digit reference number on the
|
||||
left side:
|
||||
|
||||
@verbatim
|
||||
00 +
|
||||
01 2
|
||||
02 nodeid=0
|
||||
03 device=0
|
||||
04 queue-enqueue
|
||||
05 pkt-uid=9
|
||||
06 ETHERNET
|
||||
07 length/type=0x806,
|
||||
08 source=08:00:2e:00:00:00,
|
||||
09 destination=ff:ff:ff:ff:ff:ff
|
||||
10 ARP(request
|
||||
11 source mac: 08:00:2e:00:00:00
|
||||
12 source ipv4: 10.1.1.1
|
||||
13 dest ipv4: 10.1.1.2)
|
||||
14 ETHERNET fcs=0
|
||||
@end verbatim
|
||||
|
||||
@cindex trace event
|
||||
@cindex simulation time
|
||||
The first line of this expanded trace event (reference number 00) is the
|
||||
queue operation. We have a @code{+} character, so this corresponds to an
|
||||
@emph{enqueue} operation. The second line (reference 01) is the simulation
|
||||
time expressed in seconds. You may recall that we asked the
|
||||
@code{UdpEchoClient} to start sending packets at two seconds. Here we see
|
||||
confirmation that this is, indeed, happening.
|
||||
|
||||
@cindex node number
|
||||
@cindex net device number
|
||||
@cindex smart pointer
|
||||
The next lines of the example listing (references 02 and 03) tell us that
|
||||
this trace event originated in a given node and net device. Each time a node
|
||||
is created it is given an identifying number that monotonically increases from
|
||||
zero. Therefore, @code{nodeid=0} means that the node in which the given trace
|
||||
event originated is the first node we created. In the case of our script,
|
||||
this first node is is the node pointed to by the smart pointer @code{n0}. Not
|
||||
too surpsisingly, this is also the node to which we attached the
|
||||
@code{UdpEchoClient}. The device number is local to each node, and so the
|
||||
device given by @code{device=0} is the first net device that we added to the
|
||||
node in question. In our simulation, this corresponds to the
|
||||
@code{CsmaNetDevice} we added to node zero (@code{n0}).
|
||||
|
||||
@cindex uid
|
||||
@cindex unique ID
|
||||
@cindex packet
|
||||
The next line (reference 04) is a more readable form of the operation code
|
||||
seen in the first line --- i.e., the character @code{+} means
|
||||
@code{queue-enqueue}. Reference number 05 indicates that the @emph{unique id}
|
||||
of the packet being enqueued is @code{9}. The fact that the first packet we
|
||||
see has a unique ID of 9 should indicates to you that other things have
|
||||
happened in the protocol stack before we got to this point. This will become
|
||||
clear momentarily.
|
||||
|
||||
@cindex Ethernet
|
||||
@cindex MAC address
|
||||
Reference items 06 and 14 indicate that this is an Ethernet packet with
|
||||
a zero (not computed) checksum (note the indentation to make parsing this
|
||||
trace event a little easier). Reference 08 and 09 are the source and
|
||||
destination addresses of this packet. The packet is from the MAC address we
|
||||
assigned to the node zero net device in the script, and is destined for the
|
||||
broadcast address --- this is a broadcast packet.
|
||||
|
||||
@cindex Address Resolution Protocol
|
||||
@cindex ARP
|
||||
@cindex ARP|request
|
||||
Reference items 10 through 13 make clear what is happening. This is an ARP
|
||||
(Address Resolution Protocol) request for the MAC address of the node on
|
||||
which the @code{UdpEchoServer} resides. The protocol stack can't send a UDP
|
||||
packet to be echoed until it knows (resolves) the MAC address; and this trace
|
||||
event corresponds to an ARP request being queued for transmission to the local
|
||||
network. The next line in the trace file (partially expanded),
|
||||
|
||||
@verbatim
|
||||
00 -
|
||||
01 2
|
||||
02 nodeid=0
|
||||
03 device=0
|
||||
04 queue-dequeue
|
||||
05 pkt-uid=9
|
||||
...
|
||||
@end verbatim
|
||||
|
||||
shows the (same) ARP request packet being dequeued from the device queue by
|
||||
the net device and (implicitly) being sent down the channel to the broadcast
|
||||
MAC address. We are not tracing net device reception events so we don't
|
||||
actually see all of the net devices receiving the broadcast packet. We do,
|
||||
however see the following in the third line of the trace file:
|
||||
|
||||
@verbatim
|
||||
00 +
|
||||
01 2.00207
|
||||
02 nodeid=1
|
||||
03 device=0
|
||||
04 queue-enqueue
|
||||
05 pkt-uid=10
|
||||
06 ETHERNET
|
||||
07 length/type=0x806,
|
||||
08 source=08:00:2e:00:00:01,
|
||||
09 destination=08:00:2e:00:00:00,
|
||||
10 ARP(reply
|
||||
11 source mac: 08:00:2e:00:00:01
|
||||
12 source ipv4: 10.1.1.2
|
||||
13 dest mac: 08:00:2e:00:00:00
|
||||
14 dest ipv4: 10.1.1.1)
|
||||
15 ETHERNET fcs=0
|
||||
@end verbatim
|
||||
|
||||
@cindex simulation time
|
||||
@cindex ARP|response
|
||||
Notice that this is a queue-enqueue operation (references 00 and 04) happening
|
||||
on node one (reference 02) at simulation time 2.00207 seconds (reference 01).
|
||||
Looking at the packet payload (references 10-14) we see that this is an ARP
|
||||
reply to the request sent by node one. Note that the simulation time
|
||||
(reference 01) is now 2.00207 seconds. This is direct result of the data rate
|
||||
(5 mb/s) and latency (2 ms) parameters that we passed to the
|
||||
@code{CsmaChannel} when we created it. Clearly the ARP request packet was
|
||||
sent over the channel and received approximately 2 ms later by node one. A
|
||||
corresponding ARP response packet was created and enqueued on node one's net
|
||||
device. It is this enqueue trace event that has being logged.
|
||||
|
||||
@cindex queue
|
||||
@cindex queue|transmit
|
||||
@cindex echo
|
||||
Given the current state of affairs, the next thing you may expect to see is
|
||||
this ARP request being received by node zero, but remember we are only looking
|
||||
at trace events on the device @emph{transmit} queue. The reception of the ARP
|
||||
response by node zero will not directly trigger any trace event in this case,
|
||||
but it will enable the protocol stack to continue what it was originally doing
|
||||
(trying to send an echo packet). Thus, the next line we see in the trace file
|
||||
(@code{tutorial.tr}) is the first UDP echo packet being sent to the net device.
|
||||
|
||||
@verbatim
|
||||
00 +
|
||||
01 2.00415
|
||||
02 nodeid=0
|
||||
03 device=0
|
||||
04 queue-enqueue
|
||||
05 pkt-uid=7
|
||||
06 ETHERNET
|
||||
07 length/type=0x800,
|
||||
08 source=08:00:2e:00:00:00,
|
||||
09 destination=08:00:2e:00:00:01
|
||||
10 IPV4(
|
||||
11 tos 0x0
|
||||
12 ttl 64
|
||||
13 id 0
|
||||
14 offset 0
|
||||
15 flags [none]
|
||||
16 length: 1052) 10.1.1.1 > 10.1.1.2
|
||||
17 UDP(length: 1032)
|
||||
18 49153 > 7
|
||||
19 DATA (length 1024)
|
||||
20 ETHERNET fcs=0
|
||||
@end verbatim
|
||||
|
||||
@cindex simulation time
|
||||
@cindex echo
|
||||
@cindex ARP
|
||||
@cindex ARP|request
|
||||
@cindex ARP|response
|
||||
@cindex IP
|
||||
@cindex Ipv4
|
||||
I won't go into too much detail about this packet, but I will point out a
|
||||
few key items in the trace. First, the packet was enqueued at simulation time
|
||||
of 2.00415 seconds. This time reflects the fact that the echo client
|
||||
application started at 2. seconds and there were two ARP packets transmitted
|
||||
across the network (two milliseconds + data transmission time each way). The
|
||||
packet unique identifier (reference 05) is 7. Notice that this is a lower
|
||||
number than the ARP request packet, which had a unique ID of 9. This tells
|
||||
us that the UDP packet was actually created before the ARP request packet ---
|
||||
which makes perfect sense since it was the attempt to send packet 7 that
|
||||
triggered sending the ARP request packet 9. Note that this an Ethernet
|
||||
packet (reference 06) like all other packets in this simulation, however this
|
||||
particular packet carries an IPV4 payload and therefore has an IP version 4
|
||||
header (indicated by references 10-16). This Ipv4 in turn contains a UDP
|
||||
header (references 17, 18) and finally 1024 bytes of data (reference 20).
|
||||
Clearly, this is the UDP echo packet emitted by the
|
||||
@code{UdpEchoClient Application}.
|
||||
|
||||
The next trace event is an ARP request from node one. We can infer that node
|
||||
one has received the UDP echo packet and the @code{UdpEchoServer Application}
|
||||
on that node has turned the packet around. Just as node zero needed to ARP
|
||||
for the MAC address of node one, now node one must ARP for the MAC address of
|
||||
node zero. We see the ARP request enqueued on the transmit queue of node one;
|
||||
then we see the ARP request dequeued from the tranmit queue of node one (and
|
||||
implicitly transmitted to node zero). Then we see an ARP response enqueued
|
||||
on the transmit queue of node zero; and finally the ARP response dequeued (and
|
||||
implicitly transmitted back to node one).
|
||||
|
||||
This exchange is summarized in the following trace event excerpts,
|
||||
|
||||
@verbatim
|
||||
+ 2.00786 nodeid=1 ... ARP(request ...
|
||||
- 2.00786 nodeid=1 ... ARP(request ...
|
||||
+ 2.00994 nodeid=0 ... ARP(reply ...
|
||||
- 2.00994 nodeid=0 ... ARP(reply ...
|
||||
@end verbatim
|
||||
|
||||
The final two trace events in the @code{tutorial.tr} file correspond to the
|
||||
echoed packet being enqueued for transmission on the net device for node one,
|
||||
and that packet being dequeued (and implicitly transmitted back to node zero).
|
||||
|
||||
@cindex AsciiTrace!TraceAllNetDeviceRx
|
||||
@cindex ARP!request
|
||||
If you look at the trace file (@code{tutorial.tr}) you will also see some
|
||||
entries with an @code{r} event, indicating a
|
||||
@emph{receive} trace event. Recall that the first packet sent on the network
|
||||
was a broadcast ARP request. We should then see all four nodes receive a
|
||||
copy of this request. This is the case, as the first four receive trace
|
||||
events are,
|
||||
|
||||
@verbatim
|
||||
r 2.00207 nodeid=0 device=0 dev-rx pkt-uid=9 ARP(request ...
|
||||
r 2.00207 nodeid=1 device=0 dev-rx pkt-uid=9 ARP(request ...
|
||||
r 2.00207 nodeid=2 device=0 dev-rx pkt-uid=9 ARP(request ...
|
||||
r 2.00207 nodeid=3 device=0 dev-rx pkt-uid=9 ARP(request ...
|
||||
@end verbatim
|
||||
|
||||
@cindex unique ID
|
||||
You can see that a copy of the broadcast packet with unique ID 9 was received
|
||||
by the net devices on nodes 0, 1, 2 and 3. We leave it up to you to parse the
|
||||
rest of the trace file and understand the remaining reception events.
|
||||
|
||||
@subsection PCAP Trace Wrapper
|
||||
@cindex pcap
|
||||
@cindex Wireshark
|
||||
The @command{ns-3} @emph{pcap trace wrapper} is used to create trace files in
|
||||
@code{.pcap} format. The acronym pcap (usually written in lower case) stands
|
||||
for @emph{p}acket @emph{cap}ture, and is actually an API that includes the
|
||||
definition of a @code{.pcap} file format. The most popular program that can
|
||||
read and display this format is Wireshark (formerly called Ethereal).
|
||||
However, there are many traffic trace analyzers that use this packet
|
||||
format, including X, Y, and Z. We encourage users to exploit the
|
||||
many tools available for analyzing pcap traces; below, we show how
|
||||
tcpdump and Wireshark can be used..
|
||||
|
||||
@cindex tutorial-csma-echo-ascii-trace.cc
|
||||
@cindex tutorial-csma-echo-pcap-trace.cc
|
||||
The code used to enable pcap tracing is similar to that for ASCII tracing.
|
||||
We have provided another file, @code{tutorial-csma-echo-pcap-trace.cc} that
|
||||
uses the pcap trace wrapper. We have added the code to include the pcap
|
||||
trace wrapper defintions:
|
||||
|
||||
@verbatim
|
||||
#include "ns3/pcap-trace.h"
|
||||
@end verbatim
|
||||
|
||||
And then added the following code below the AsciiTrace methods:
|
||||
|
||||
@cindex PcapTrace
|
||||
@cindex PcapTrace!TraceAllIp
|
||||
@verbatim
|
||||
PcapTrace pcaptrace ("tutorial.pcap");
|
||||
pcaptrace.TraceAllIp ();
|
||||
@end verbatim
|
||||
|
||||
The first line of the code immediately above declares an object of type
|
||||
@code{PcapTrace} named @code{pcaptrace} and passes a string parameter to its
|
||||
constructor. This object is used to hide the details of the actual tracing
|
||||
subsystem. The parameter is a base file name from which the actual trace file
|
||||
names will be built. The second line of code tells the @code{PcamTrace}
|
||||
object to trace all IP activity in all of the nodes present in the simulation.
|
||||
|
||||
@cindex interface index
|
||||
Trace files are not created until trace activity is detected. Each file name
|
||||
is composed of the base file name, followed by a @code{'-'}, a node id followed
|
||||
by a @code{'-}', and an IP interface index. You will soon see a file named
|
||||
@code{tutorial.pcap-0-1}, for example. This will be the trace file generated
|
||||
as events are detected on node zero, interface index one. N.B. Interface
|
||||
indices are different that net device indices --- interface index zero
|
||||
corresponds to the loopback interface and interface index one corresponds to
|
||||
the first net device you added to a node.
|
||||
|
||||
You may run the new program just like all of the others so far:
|
||||
|
||||
@cindex Waf
|
||||
@verbatim
|
||||
./waf --run tutorial-csma-echo-pcap-trace
|
||||
@end verbatim
|
||||
|
||||
If you look at the top level directory of your distribution, you should now
|
||||
see three log files: @code{tutorial.tr} is the ASCII trace file we have
|
||||
previously examined. @code{tutorial.pcap-0-1} and @code{tutorial.pcap-1-1}
|
||||
are the new pcap files we just generated. There will not be files
|
||||
corresponding to nodes two and three since we have not sent any IP packets to
|
||||
those nodes.
|
||||
|
||||
@subsubsection Reading output with tcpdump
|
||||
@cindex tcpdump
|
||||
|
||||
@subsubsection Reading output with Wireshark
|
||||
@cindex Wireshark
|
||||
If you are unfamilar with Wireshark, there is a web site available from which
|
||||
you can download programs and documentation: @uref{http://www.wireshark.org/}.
|
||||
|
||||
If you have Wireshark available, you can open each of the trace files and
|
||||
display the contents as if you had captured the packets using a
|
||||
@emph{packet sniffer}. Note that only IP packets are traced using this
|
||||
wrapper, so you will not see the ARP exchanges that were logged when using
|
||||
the ASCII trace wrapper. You are encouraged to take a look at the contents
|
||||
of these pcap files using your favorite pcap software (or Wireshark).
|
||||
|
||||
@node Advanced Tracing
|
||||
@section Advanced Tracing
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
@node Statistics
|
||||
@chapter Statistics
|
||||
@anchor{chap:Statistics}
|
||||
|
||||
ns-3 does not presently have support for statistics (automatically generated
|
||||
statistical output). This is planned
|
||||
for development later in 2008. If you are interested in contributing,
|
||||
please see @uref{http://www.nsnam.org/wiki/index.php/Suggested_Projects,,our suggested projects page} or contact the ns-developers
|
||||
list.
|
||||
@@ -0,0 +1,82 @@
|
||||
@node Troubleshooting
|
||||
@chapter Troubleshooting
|
||||
|
||||
This chapter posts some information about possibly common errors in building
|
||||
or running ns-3 programs.
|
||||
|
||||
Please note that the wiki (@uref{http://www.nsnam.org/wiki/index.php/Troubleshooting}) may have contributed items.
|
||||
|
||||
@node Build errors
|
||||
@section Build errors
|
||||
|
||||
@node Run-time errors
|
||||
@section Run-time errors
|
||||
|
||||
Sometimes, errors can occur with a program after a successful build. These
|
||||
are run-time errors, and can commonly occur when memory is corrupted or
|
||||
pointer values are unexpectedly null.
|
||||
|
||||
Here is an example of what might occur:
|
||||
|
||||
@verbatim
|
||||
ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point
|
||||
Entering directory `/home/tomh/ns-3-nsc/build'
|
||||
Compilation finished successfully
|
||||
Command ['/home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point'] exited with code -11
|
||||
@end verbatim
|
||||
|
||||
The error message says that the program terminated unsuccessfully, but it is
|
||||
not clear from this information what might be wrong. To examine more
|
||||
closely, try running it under the @uref{http://sources.redhat.com/gdb/,,gdb debugger}:
|
||||
|
||||
@verbatim
|
||||
ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="gdb %s"
|
||||
Entering directory `/home/tomh/ns-3-nsc/build'
|
||||
Compilation finished successfully
|
||||
GNU gdb Red Hat Linux (6.3.0.0-1.134.fc5rh)
|
||||
Copyright 2004 Free Software Foundation, Inc.
|
||||
GDB is free software, covered by the GNU General Public License, and you are
|
||||
welcome to change it and/or distribute copies of it under certain conditions.
|
||||
Type "show copying" to see the conditions.
|
||||
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
||||
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
|
||||
|
||||
(gdb) run
|
||||
Starting program: /home/tomh/ns-3-nsc/build/debug/examples/tcp-point-to-point
|
||||
Reading symbols from shared object read from target memory...done.
|
||||
Loaded system supplied DSO at 0xf5c000
|
||||
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
0x0804aa12 in main (argc=1, argv=0xbfdfefa4)
|
||||
at ../examples/tcp-point-to-point.cc:136
|
||||
136 Ptr<Socket> localSocket = socketFactory->CreateSocket ();
|
||||
(gdb) p localSocket
|
||||
$1 = {m_ptr = 0x3c5d65}
|
||||
(gdb) p socketFactory
|
||||
$2 = {m_ptr = 0x0}
|
||||
(gdb) quit
|
||||
The program is running. Exit anyway? (y or n) y
|
||||
@end verbatim
|
||||
|
||||
Note first the way the program was invoked-- pass the command to run as
|
||||
an argument to the command template "gdb %s".
|
||||
|
||||
This tells us that there was an attempt to dereference a null pointer
|
||||
socketFactory.
|
||||
|
||||
Let's look around line 136 of tcp-point-to-point, as gdb suggests:
|
||||
@verbatim
|
||||
Ptr<SocketFactory> socketFactory = n2->GetObject<SocketFactory> (Tcp::iid);
|
||||
Ptr<Socket> localSocket = socketFactory->CreateSocket ();
|
||||
localSocket->Bind ();
|
||||
@end verbatim
|
||||
|
||||
The culprit here is that the return value of GetObject is not being
|
||||
checked and may be null.
|
||||
|
||||
Sometimes you may need to use the @uref{http://valgrind.org,,valgrind memory
|
||||
checker} for more subtle errors. Again, you invoke the use of valgrind
|
||||
similarly:
|
||||
@verbatim
|
||||
ns-old:~/ns-3-nsc$ ./waf --run tcp-point-to-point --command-template="valgrind %s"
|
||||
@end verbatim
|
||||
@@ -0,0 +1,156 @@
|
||||
body {
|
||||
font-family: "Trebuchet MS", "Bitstream Vera Sans", verdana, lucida, arial, helvetica, sans-serif;
|
||||
background: white;
|
||||
color: black;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
# color: #990000;
|
||||
color: #009999;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 10pt;
|
||||
background: #e0e0e0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
font-weight: normal;
|
||||
text-decoration: underline;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#main th {
|
||||
font-size: 12pt;
|
||||
background: #b0b0b0;
|
||||
}
|
||||
|
||||
.odd {
|
||||
font-size: 12pt;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.even {
|
||||
font-size: 12pt;
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
.answer {
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.answer p {
|
||||
font-size: 12pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.answer ul {
|
||||
font-size: 12pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#container {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#feedback {
|
||||
color: #b0b0b0;
|
||||
font-size: 9pt;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#header {
|
||||
position: absolute;
|
||||
margin: 0px;
|
||||
top: 10px;
|
||||
height:96px;
|
||||
left: 175px;
|
||||
right: 10em;
|
||||
bottom: auto;
|
||||
background: white;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#middle {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#main {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
left: 175px;
|
||||
right: 100px;
|
||||
background: white;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
position: absolute;
|
||||
top: 75px;
|
||||
left: 0em;
|
||||
width: 146px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
#navbar a:link, #navbar a:visited {
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
#navbar a:hover {
|
||||
font-weight: normal;
|
||||
text-decoration: underline;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
#navbar dl {
|
||||
width: 146px;
|
||||
padding: 0;
|
||||
margin: 0 0 10px 0px;
|
||||
background: #99ffff url(images/box_bottom2.gif) no-repeat bottom left;
|
||||
}
|
||||
|
||||
#navbar dt {
|
||||
padding: 6px 10px;
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
background: #009999;
|
||||
margin: 0px;
|
||||
border-bottom: 1px solid #fff;
|
||||
color: white;
|
||||
background: #009999 url(images/box_top2.gif) no-repeat top left;
|
||||
}
|
||||
|
||||
#navbar dd {
|
||||
font-size: 100%;
|
||||
margin: 0 0 0 0px;
|
||||
padding: 6px 10px;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
dd#selected {
|
||||
background: #99ffff url(images/arrow.gif) no-repeat;
|
||||
background-position: 4px 10px;
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
@setfilename ns-3.info
|
||||
@settitle ns-3 tutorial
|
||||
@c @setchapternewpage odd
|
||||
@c %**end of header
|
||||
|
||||
@ifinfo
|
||||
Primary documentation for the @command{ns-3} project is available in
|
||||
three forms:
|
||||
@itemize @bullet
|
||||
@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator
|
||||
@item Tutorial (this document)
|
||||
@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki}
|
||||
@end itemize
|
||||
|
||||
This document is written in GNU Texinfo and is to be maintained in
|
||||
revision control on the @command{ns-3} code server. Both PDF and HTML versions
|
||||
should be available on the server. Changes to
|
||||
the document should be discussed on the ns-developers@@isi.edu mailing list.
|
||||
@end ifinfo
|
||||
|
||||
@copying
|
||||
|
||||
This is an @command{ns-3} tutorial.
|
||||
Primary documentation for the @command{ns-3} project is available in
|
||||
three forms:
|
||||
@itemize @bullet
|
||||
@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator
|
||||
@item Tutorial (this document)
|
||||
@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki}
|
||||
@end itemize
|
||||
|
||||
This document is written in GNU Texinfo and is to be maintained in
|
||||
revision control on the @command{ns-3} code server. Both PDF and HTML
|
||||
versions should be available on the server. Changes to
|
||||
the document should be discussed on the ns-developers@@isi.edu mailing list.
|
||||
|
||||
This software is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see @uref{http://www.gnu.org/licenses/}.
|
||||
@end copying
|
||||
|
||||
@titlepage
|
||||
@title ns-3 Tutorial
|
||||
@author ns-3 project
|
||||
@author feedback: ns-developers@@isi.edu
|
||||
@today{}
|
||||
|
||||
@c @page
|
||||
@vskip 0pt plus 1filll
|
||||
@insertcopying
|
||||
@end titlepage
|
||||
|
||||
@c So the toc is printed at the start.
|
||||
@anchor{Full Table of Contents}
|
||||
@contents
|
||||
|
||||
@ifnottex
|
||||
@node Top, Overview, Full Table of Contents
|
||||
@top ns-3 Tutorial (html version)
|
||||
|
||||
For a pdf version of this tutorial,
|
||||
see @uref{http://www.nsnam.org/docs/tutorial.pdf}.
|
||||
|
||||
@insertcopying
|
||||
@end ifnottex
|
||||
|
||||
@menu
|
||||
* Tutorial Goals::
|
||||
Part 1: Getting Started with ns-3
|
||||
* Overview::
|
||||
* Browsing::
|
||||
* Resources::
|
||||
* Downloading and Compiling::
|
||||
* Some-Prerequisites::
|
||||
Part 2: Reading ns-3 Programs
|
||||
* A-First-ns-3-Script::
|
||||
Part 3: Reconfiguring Existing ns-3 Scripts
|
||||
* Logging::
|
||||
* ns-3 Attributes::
|
||||
* Tracing::
|
||||
* Statistics::
|
||||
Part 4: Creating New or Revised Topologies
|
||||
* Helper Functions::
|
||||
@end menu
|
||||
|
||||
@include introduction.texi
|
||||
@include log.texi
|
||||
@include attributes.texi
|
||||
@include statistics.texi
|
||||
@include helpers.texi
|
||||
|
||||
@printindex cp
|
||||
|
||||
@bye
|
||||
@@ -0,0 +1,278 @@
|
||||
|
||||
@c ========================================================================
|
||||
@c Begin document body here
|
||||
@c ========================================================================
|
||||
|
||||
@c ========================================================================
|
||||
@c PART: Introduction
|
||||
@c ========================================================================
|
||||
@c The below chapters are under the major heading "Introduction"
|
||||
@c This is similar to the Latex \part command
|
||||
@c
|
||||
@c ========================================================================
|
||||
@c Introduction
|
||||
@c ========================================================================
|
||||
@node Introduction
|
||||
@chapter Introduction
|
||||
|
||||
@menu
|
||||
* For ns-2 Users::
|
||||
* Contributing::
|
||||
* Tutorial Organization::
|
||||
@end menu
|
||||
|
||||
The @command{ns-3} simulator is a discrete-event network simulator targeted
|
||||
primarily for research and educational use. The
|
||||
@uref{http://www.nsnam.org,,ns-3 project},
|
||||
started in 2006, is an open-source project developing ns-3.
|
||||
|
||||
Primary documentation for the @command{ns-3} project is available in four
|
||||
forms:
|
||||
@itemize @bullet
|
||||
@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}:
|
||||
Documentation of the public APIs of the simulator
|
||||
@item Tutorial (this document)
|
||||
@item @uref{http://www.nsnam.org/docs/manual.html,,Reference Manual}: Reference Manual
|
||||
@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki}
|
||||
@end itemize
|
||||
|
||||
The purpose of this tutorial is to introduce new @command{ns-3} users to the
|
||||
system in a structured way. It is sometimes difficult for new users to
|
||||
glean essential information from detailed manuals and to convert this
|
||||
information into working simulations. In this tutorial, we will build
|
||||
several example simulations, introducing and explaining key concepts and
|
||||
features as we go.
|
||||
|
||||
As the tutorial unfolds, we will introduce the full ns-3 documentation
|
||||
and provide pointers to source code for those interested in delving deeper
|
||||
into the workings of the system.
|
||||
|
||||
A few key points are worth noting at the onset:
|
||||
@itemize @bullet
|
||||
@item Ns-3 is not an extension of @uref{http://www.isi.edu/nsnam/ns,,ns-2};
|
||||
it is a new simulator. The two simulators are both written in C++ but
|
||||
@command{ns-3} is a new simulator that does not support the ns-2 APIs. Some
|
||||
models from ns-2 have already been ported from ns-2 to ns-3. The project will
|
||||
continue to maintain ns-2 while ns-3 is being built, and will study transition
|
||||
and integration mechanisms.
|
||||
@item @command{Ns-3} is open-source, and the project strives to maintain an
|
||||
open environment for researchers to contribute and share their software.
|
||||
@end itemize
|
||||
|
||||
@node For ns-2 Users
|
||||
@section For ns-2 Users
|
||||
|
||||
For those familiar with ns-2, the most visible outward change when moving to
|
||||
@command{ns-3} is the choice of scripting language. Ns-2 is typically
|
||||
scripted in Tcl and results of simulations can be visualized using the
|
||||
Network Animator @command{nam}. In @command{ns-3} there is currently no
|
||||
visualization module, and Python bindings have been developed (Tcl bindings
|
||||
have been prototyped using @uref{http://www.swig.org,,SWIG}, but are not
|
||||
currently supported). In this tutorial, we will concentrate on scripting
|
||||
directly in C++ and interpreting results via trace files.
|
||||
|
||||
But there are similarities as well (both, for example, are based on C++
|
||||
objects, and some code from ns-2 has already been ported to @command{ns-3}).
|
||||
We will try to highlight differences between ns-2 and @command{ns-3}
|
||||
as we proceed in this tutorial.
|
||||
|
||||
@node Contributing
|
||||
@section Contributing
|
||||
|
||||
@cindex contributing
|
||||
@command{Ns-3} is a research and educational simulator, by and for the
|
||||
research community. It will rely on the ongoing contributions of the
|
||||
community to develop new models, debug or maintain existing ones, and share
|
||||
results. There are a few policies that we hope will encourage people to
|
||||
contribute to @command{ns-3} like they have for ns-2:
|
||||
@itemize @bullet
|
||||
@item Open source licensing based on GNU GPLv2 compatibility;
|
||||
@item @uref{http://www.nsnam.org/wiki/index.php,,wiki};
|
||||
@item @uref{http://www.nsnam.org/wiki/index.php/Contributed_Code,,Contributed Code} page, similar to ns-2's popular
|
||||
@uref{http://nsnam.isi.edu/nsnam/index.php/Contributed_Code,,Contributed Code}
|
||||
page;
|
||||
@item @code{src/contrib} directory (we will host your contributed code);
|
||||
@item Open @uref{http://www.nsnam.org/bugzilla,,bug tracker};
|
||||
@item @command{Ns-3} developers will gladly help potential contributors to get
|
||||
started with the simulator (please contact @uref{http://www.nsnam.org/people.html,,one of us}).
|
||||
@end itemize
|
||||
|
||||
If you are an ns-3 user, please consider providing your feedback, bug fixes, or
|
||||
code to the project.
|
||||
|
||||
@node Tutorial Organization
|
||||
@section Tutorial Organization
|
||||
|
||||
The tutorial assumes that new users might initially follow a path such as the
|
||||
following:
|
||||
|
||||
@itemize @bullet
|
||||
@item Try to download and build a copy;
|
||||
@item Try to run a few sample programs;
|
||||
@item Look at simulation output, and try to adjust it.
|
||||
@end itemize
|
||||
|
||||
As a result, we have tried to organize the tutorial along the above
|
||||
broad sequences of events.
|
||||
|
||||
@c ========================================================================
|
||||
@c Resources
|
||||
@c ========================================================================
|
||||
|
||||
@node Resources
|
||||
@chapter Resources
|
||||
|
||||
@menu
|
||||
* The Web::
|
||||
* Mercurial::
|
||||
* Waf::
|
||||
* Development Environment::
|
||||
* Socket Programming::
|
||||
@end menu
|
||||
|
||||
@node The Web
|
||||
@section The Web
|
||||
|
||||
@cindex www.nsnam.org
|
||||
@cindex documentation
|
||||
@cindex architecture
|
||||
There are several important resources of which any @command{ns-3} user must be
|
||||
aware. The main web site is located at @uref{http://www.nsnam.org} and
|
||||
provides access to basic information about the ns-3 system. Detailed
|
||||
documentation is available through the main web site at
|
||||
@uref{http://www.nsnam.org/documents.html}. You can also find documents
|
||||
relating to the system architecture from this page.
|
||||
|
||||
There is a Wiki that complements the main ns-3 web site which you will find at
|
||||
@uref{http://www.nsnam.org/wiki/}. You will find user and developer FAQs
|
||||
there, as well as troubleshooting guides, third-party contributed code,
|
||||
papers, etc.
|
||||
|
||||
@cindex mercurial repository
|
||||
@cindex ns-3-dev repository
|
||||
@cindex release repository
|
||||
The source code may be found and browsed at @uref{http://code.nsnam.org/}.
|
||||
There you will find the current development tree in the repository named
|
||||
@code{ns-3-dev}. Past releases and experimental repositories of the core
|
||||
developers may also be found there.
|
||||
|
||||
@node Mercurial
|
||||
@section Mercurial
|
||||
|
||||
Complex software systems need some way to manage the organization and
|
||||
changes to the underlying code and documentation. There are many ways to
|
||||
perform this feat, and you may have heard of some of the systems that are
|
||||
currently used to do this. The Concurrent Version System (CVS) is probably
|
||||
the most well known.
|
||||
|
||||
@cindex software configuration management
|
||||
@cindex Mercurial
|
||||
The @command{ns-3} project uses Mercurial as its source code management system.
|
||||
Although you do not need to know much about Mercurial in order to complete
|
||||
this tutorial, we recommend becoming familiar with Mercurial and using it
|
||||
to access the source code. Mercurial has a web site at
|
||||
@uref{http://www.selenic.com/mercurial/},
|
||||
from which you can get binary or source releases of this Software
|
||||
Configuration Management (SCM) system. Selenic (the developer of Mercurial)
|
||||
also provides a tutorial at
|
||||
@uref{http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial/},
|
||||
and a QuickStart guide at
|
||||
@uref{http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/}.
|
||||
|
||||
You can also find vital information about using Mercurial and @command{ns-3}
|
||||
on the main @command{ns-3} web site.
|
||||
|
||||
@node Waf
|
||||
@section Waf
|
||||
|
||||
@cindex Waf
|
||||
@cindex make
|
||||
@cindex build
|
||||
Once you have source code downloaded to your local system, you will need
|
||||
to compile that source to produce usable programs. Just as in the case of
|
||||
source code management, there are many tools available to perform this
|
||||
function. Probably the most will known of these tools is @code{make}. Along
|
||||
with being the most well known, @code{make} is probably the most difficult to
|
||||
use in a very large and highly configurable system. Because of this, many
|
||||
alternatives have been developed. Recently these systems have been developed
|
||||
using the Python language.
|
||||
|
||||
The build system @code{Waf} is used on the @command{ns-3} project. It is one
|
||||
of the new generation of Python-based build systems. You will not need to
|
||||
understand any Python to build the existing ns-3 system, and will
|
||||
only have to understand a tiny and intuitively obvious subset of Python in
|
||||
order to extend the system in most cases.
|
||||
|
||||
For those interested in the gory details of Waf, the main web site can be
|
||||
found at @uref{http://freehackers.org/~tnagy/waf.html}.
|
||||
|
||||
@node Development Environment
|
||||
@section Development Environment
|
||||
|
||||
@cindex C++
|
||||
As mentioned above, scripting in ns-3 is done in C++. A working
|
||||
knowledge of C++ and object-oriented concepts is assumed in this document.
|
||||
We will take some time to review some of the more advanced concepts or
|
||||
possibly unfamiliar language features, idioms and design patterns as they
|
||||
appear. We don't want this tutorial to devolve into a C++ tutorial, though,
|
||||
so we do expect a basic command of the language. There are an almost
|
||||
unimaginable number of sources of information on C++ available on the web or
|
||||
in print.
|
||||
|
||||
If you are new to C++, you may want to find a tutorial- or cookbook-based
|
||||
book or web site and work through at least the basic features of the language
|
||||
before proceeding.
|
||||
|
||||
@cindex toolchain
|
||||
@cindex GNU
|
||||
The @command{ns-3} system uses the GNU ``toolchain'' for development. A
|
||||
software toolchain is the set of programming tools available in the given
|
||||
environment. For a quick review of what is included in the GNU toolchain see,
|
||||
@uref{http://en.wikipedia.org/wiki/GNU_toolchain}.
|
||||
|
||||
@cindex Linux
|
||||
Typically an @command{ns-3} author will work in Linux or a Linux-like
|
||||
environment. For those running under Windows, there do exist environments
|
||||
which simulate the Linux environment to various degrees. The @command{ns-3}
|
||||
project supports development in the Cygwin and the MinGW environments for
|
||||
these users. See @uref{http://www.cygwin.com/} and
|
||||
@uref{http://www.mingw.org/} for details on downloading and using these
|
||||
systems. Cygwin provides many of the popular Linux system commands.
|
||||
It can, however, sometimes be problematic due to the way it actually does its
|
||||
emulation, and sometimes interactions with other Windows software can cause
|
||||
problems.
|
||||
|
||||
@cindex Cygwin
|
||||
@cindex MinGW
|
||||
If you do use Cygwin or MinGW; and use Logitech products, we will save you
|
||||
quite a bit of heartburn right off the bat and encourage you to take a look
|
||||
at the @uref{http://www.mingw.org/MinGWiki/index.php/FAQ,,MinGW FAQ}.
|
||||
|
||||
@cindex Logitech
|
||||
Search for ``Logitech'' and read the FAQ entry, ``why does make often
|
||||
crash creating a sh.exe.stackdump file when I try to compile my source code.''
|
||||
Believe it or not, the @code{Logitech Process Monitor} insinuates itself into
|
||||
every DLL in the system when it is running. It can cause your Cygwin or
|
||||
MinGW DLLs to die in mysterious ways and often prevents debuggers from
|
||||
running. Beware of Logitech software.
|
||||
|
||||
@node Socket Programming
|
||||
@section Socket Programming
|
||||
|
||||
@cindex sockets
|
||||
We will assume a basic facility with the Berkeley Sockets API in the examples
|
||||
used in this tutorial. If you are new to sockets, we recommend reviewing the
|
||||
API and some common usage cases. For a good overview of programming TCP/IP
|
||||
sockets we recommend @uref{http://www.elsevier.com/wps/product/cws_home/680765,,Practical TCP/IP Sockets in C, Donahoo and Calvert}.
|
||||
|
||||
There is an associated web site that includes source for the examples in the
|
||||
book, which you can find at:
|
||||
@uref{http://cs.baylor.edu/~donahoo/practical/CSockets/}.
|
||||
|
||||
If you understand the first four chapters of the book (or for those who do
|
||||
not have access to a copy of the book, the echo clients and servers shown in
|
||||
the website above) you will be in good shape to understand the tutorial.
|
||||
There is a similar book on Multicast Sockets,
|
||||
@uref{http://www.elsevier.com/wps/product/cws_home/700736,,Multicast Sockets, Makofske and Almeroth}.
|
||||
that covers material you may need to understand if you look at the multicast
|
||||
examples in the distribution.
|
||||
@@ -0,0 +1,156 @@
|
||||
body {
|
||||
font-family: "Trebuchet MS", "Bitstream Vera Sans", verdana, lucida, arial, helvetica, sans-serif;
|
||||
background: white;
|
||||
color: black;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
# color: #990000;
|
||||
color: #009999;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 10pt;
|
||||
background: #e0e0e0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
font-weight: normal;
|
||||
text-decoration: underline;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#main th {
|
||||
font-size: 12pt;
|
||||
background: #b0b0b0;
|
||||
}
|
||||
|
||||
.odd {
|
||||
font-size: 12pt;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.even {
|
||||
font-size: 12pt;
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
.answer {
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.answer p {
|
||||
font-size: 12pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.answer ul {
|
||||
font-size: 12pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#container {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#feedback {
|
||||
color: #b0b0b0;
|
||||
font-size: 9pt;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#header {
|
||||
position: absolute;
|
||||
margin: 0px;
|
||||
top: 10px;
|
||||
height:96px;
|
||||
left: 175px;
|
||||
right: 10em;
|
||||
bottom: auto;
|
||||
background: white;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#middle {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#main {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
left: 175px;
|
||||
right: 100px;
|
||||
background: white;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
position: absolute;
|
||||
top: 75px;
|
||||
left: 0em;
|
||||
width: 146px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
#navbar a:link, #navbar a:visited {
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
#navbar a:hover {
|
||||
font-weight: normal;
|
||||
text-decoration: underline;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
#navbar dl {
|
||||
width: 146px;
|
||||
padding: 0;
|
||||
margin: 0 0 10px 0px;
|
||||
background: #99ffff url(images/box_bottom2.gif) no-repeat bottom left;
|
||||
}
|
||||
|
||||
#navbar dt {
|
||||
padding: 6px 10px;
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
background: #009999;
|
||||
margin: 0px;
|
||||
border-bottom: 1px solid #fff;
|
||||
color: white;
|
||||
background: #009999 url(images/box_top2.gif) no-repeat top left;
|
||||
}
|
||||
|
||||
#navbar dd {
|
||||
font-size: 100%;
|
||||
margin: 0 0 0 0px;
|
||||
padding: 6px 10px;
|
||||
color: #0047b9;
|
||||
}
|
||||
|
||||
dd#selected {
|
||||
background: #99ffff url(images/arrow.gif) no-repeat;
|
||||
background-position: 4px 10px;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
@setfilename ns-3.info
|
||||
@settitle ns-3 tutorial
|
||||
@c @setchapternewpage odd
|
||||
@c %**end of header
|
||||
|
||||
@ifinfo
|
||||
Primary documentation for the @command{ns-3} project is available in
|
||||
four forms:
|
||||
@itemize @bullet
|
||||
@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator
|
||||
@item Tutorial (this document)
|
||||
@item @uref{http://www.nsnam.org/docs/manual.html,,Reference Manual}: Reference Manual
|
||||
@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki}
|
||||
@end itemize
|
||||
|
||||
This document is written in GNU Texinfo and is to be maintained in revision
|
||||
control on the @command{ns-3} code server. Both PDF and HTML versions should
|
||||
be available on the server. Changes to the document should be discussed on
|
||||
the ns-developers@@isi.edu mailing list.
|
||||
@end ifinfo
|
||||
|
||||
@copying
|
||||
|
||||
This is an @command{ns-3} tutorial.
|
||||
Primary documentation for the @command{ns-3} project is available in
|
||||
four forms:
|
||||
@itemize @bullet
|
||||
@item @uref{http://www.nsnam.org/doxygen/index.html,,ns-3 Doxygen/Manual}: Documentation of the public APIs of the simulator
|
||||
@item Tutorial (this document)
|
||||
@item @uref{http://www.nsnam.org/docs/manual.html,,Reference Manual}: Reference Manual
|
||||
@item @uref{http://www.nsnam.org/wiki/index.php,, ns-3 wiki}
|
||||
@end itemize
|
||||
|
||||
This document is written in GNU Texinfo and is to be maintained in revision
|
||||
control on the @command{ns-3} code server. Both PDF and HTML versions should
|
||||
be available on the server. Changes to the document should be discussed on
|
||||
the ns-developers@@isi.edu mailing list.
|
||||
|
||||
This software is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see @uref{http://www.gnu.org/licenses/}.
|
||||
@end copying
|
||||
|
||||
@titlepage
|
||||
@title ns-3 Tutorial
|
||||
@author ns-3 project
|
||||
@author feedback: ns-developers@@isi.edu
|
||||
@today{}
|
||||
|
||||
@c @page
|
||||
@vskip 0pt plus 1filll
|
||||
@insertcopying
|
||||
@end titlepage
|
||||
|
||||
@c So the toc is printed at the start.
|
||||
@anchor{Full Table of Contents}
|
||||
@contents
|
||||
|
||||
@ifnottex
|
||||
@node Top, Introduction, Full Table of Contents
|
||||
@top ns-3 Tutorial (html version)
|
||||
|
||||
For a pdf version of this tutorial,
|
||||
see @uref{http://www.nsnam.org/docs/tutorial.pdf}.
|
||||
|
||||
@insertcopying
|
||||
@end ifnottex
|
||||
|
||||
@menu
|
||||
* Introduction::
|
||||
* Resources::
|
||||
* Getting Started::
|
||||
* Conceptual Overview::
|
||||
* Tweaking ns-3::
|
||||
* Building Topologies::
|
||||
@end menu
|
||||
|
||||
@include introduction.texi
|
||||
@include getting-started.texi
|
||||
@include conceptual-overview.texi
|
||||
@include tweaking.texi
|
||||
@include building-topologies.texi
|
||||
|
||||
@printindex cp
|
||||
|
||||
@bye
|
||||
Loaded 100 of 767 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user