summaryrefslogtreecommitdiff
path: root/cesar/maximus/python
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/maximus/python')
-rw-r--r--cesar/maximus/python/Makefile9
-rwxr-xr-xcesar/maximus/python/doc/fulminata_maximus_scenario_engine.odtbin0 -> 343674 bytes
-rwxr-xr-xcesar/maximus/python/doc/fulminata_maximus_scenario_engine.xmi1386
-rw-r--r--cesar/maximus/python/lib/cesar/maximus_dur.py97
-rw-r--r--cesar/maximus/python/lib/cesar/sta_cesar.py44
-rw-r--r--cesar/maximus/python/lib/fcVf/__init__.py1
-rw-r--r--cesar/maximus/python/lib/fcVf/crc24/__init__.py1
-rw-r--r--cesar/maximus/python/lib/fcVf/crc24/crc24.py84
-rw-r--r--cesar/maximus/python/lib/fcVf/crc24/crc24_algorithms.py172
-rw-r--r--cesar/maximus/python/lib/fcVf/crc24/pycrc24.py44
-rw-r--r--cesar/maximus/python/lib/fcVf/fcVfFields.py758
-rw-r--r--cesar/maximus/python/lib/framing.py45
-rw-r--r--cesar/maximus/python/lib/macFrame.py122
-rw-r--r--cesar/maximus/python/lib/mmentry/Constants.py317
-rw-r--r--cesar/maximus/python/lib/mmentry/__init__.py1
-rw-r--r--cesar/maximus/python/lib/mmentry/aes128/AES.py31
-rw-r--r--cesar/maximus/python/lib/mmentry/aes128/Python_AES.py68
-rw-r--r--cesar/maximus/python/lib/mmentry/aes128/__init__.py1
-rw-r--r--cesar/maximus/python/lib/mmentry/aes128/compat.py140
-rw-r--r--cesar/maximus/python/lib/mmentry/aes128/cryptomath.py400
-rw-r--r--cesar/maximus/python/lib/mmentry/aes128/rijndael.py392
-rw-r--r--cesar/maximus/python/lib/mmentry/bmi/__init__.py1
-rw-r--r--cesar/maximus/python/lib/mmentry/bmi/bmiBody.py21
-rw-r--r--cesar/maximus/python/lib/mmentry/bmi/bmiMethod.py482
-rw-r--r--cesar/maximus/python/lib/mmentry/encapsulation/__init__.py1
-rw-r--r--cesar/maximus/python/lib/mmentry/encapsulation/encapsulation.py250
-rw-r--r--cesar/maximus/python/lib/mmentry/fid/__init__.py1
-rw-r--r--cesar/maximus/python/lib/mmentry/fid/fidBody.py39
-rw-r--r--cesar/maximus/python/lib/mmentry/fid/fidMethod.py528
-rw-r--r--cesar/maximus/python/lib/mmentry/mmentry.py121
-rw-r--r--cesar/maximus/python/lib/mmentry/mmentryFields.py3258
-rw-r--r--cesar/maximus/python/lib/mmentry/mmentryMethod.py2089
-rw-r--r--cesar/maximus/python/lib/proto/fcall.py349
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/CHANGES.txt171
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/LICENSE.txt61
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/PKG-INFO21
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/README.txt244
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/enhancedserial.py62
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/miniterm.py165
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/scan.py27
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/setup_demo.py35
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/tcp_serial_redirect.py150
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/test.py186
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/test_advanced.py164
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/test_high_load.py67
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/wxSerialConfigDialog.py259
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/wxSerialConfigDialog.wxg262
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/wxTerminal.py332
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/examples/wxTerminal.wxg127
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/serial/__init__.py20
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/serial/serialjava.py212
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/serial/serialposix.py406
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/serial/serialutil.py366
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/serial/serialwin32.py314
-rw-r--r--cesar/maximus/python/lib/proto/pyserial/setup.py38
-rw-r--r--cesar/maximus/python/lib/proto/uspp/AUTHORS4
-rw-r--r--cesar/maximus/python/lib/proto/uspp/Copyright21
-rw-r--r--cesar/maximus/python/lib/proto/uspp/Readme190
-rw-r--r--cesar/maximus/python/lib/proto/uspp/Readme_es199
-rw-r--r--cesar/maximus/python/lib/proto/uspp/SerialPort_darwin.py326
-rw-r--r--cesar/maximus/python/lib/proto/uspp/SerialPort_linux.py329
-rw-r--r--cesar/maximus/python/lib/proto/uspp/SerialPort_win.py239
-rw-r--r--cesar/maximus/python/lib/proto/uspp/lesser.txt504
-rw-r--r--cesar/maximus/python/lib/proto/uspp/uspp.htm635
-rw-r--r--cesar/maximus/python/lib/proto/uspp/uspp.py193
-rw-r--r--cesar/maximus/python/lib/proto/uspp/uspp_es.htm629
-rw-r--r--cesar/maximus/python/lib/script.py173
-rwxr-xr-xcesar/maximus/python/lib/station/test_tx_rx.elfbin0 -> 966377 bytes
-rw-r--r--cesar/maximus/python/maximus/__init__.py16
-rw-r--r--cesar/maximus/python/maximus/channel/__init__.py7
-rw-r--r--cesar/maximus/python/maximus/channel/snr.py52
-rw-r--r--cesar/maximus/python/maximus/cli/__init__.py5
-rw-r--r--cesar/maximus/python/maximus/ethernet/__init__.py10
-rw-r--r--cesar/maximus/python/maximus/ethernet/buffer.py189
-rw-r--r--cesar/maximus/python/maximus/ethernet/create.py22
-rw-r--r--cesar/maximus/python/maximus/ethernet/eth.py109
-rw-r--r--cesar/maximus/python/maximus/ethernet/scapy.py13244
-rw-r--r--cesar/maximus/python/maximus/ethernet/sniffer.py128
-rw-r--r--cesar/maximus/python/maximus/fsm/FSM.py263
-rw-r--r--cesar/maximus/python/maximus/fsm/__init__.py7
-rw-r--r--cesar/maximus/python/maximus/macframe/__init__.py13
-rw-r--r--cesar/maximus/python/maximus/macframe/create.py10
-rw-r--r--cesar/maximus/python/maximus/macframe/fc_10.py135
-rw-r--r--cesar/maximus/python/maximus/macframe/fc_av.py173
-rw-r--r--cesar/maximus/python/maximus/macframe/macframe.py252
-rw-r--r--cesar/maximus/python/maximus/macframe/macframeheader.py80
-rw-r--r--cesar/maximus/python/maximus/macframe/macframequeue.py90
-rw-r--r--cesar/maximus/python/maximus/macframe/mpdu.py187
-rw-r--r--cesar/maximus/python/maximus/macframe/msdu.py66
-rw-r--r--cesar/maximus/python/maximus/macframe/pb.py59
-rw-r--r--cesar/maximus/python/maximus/macframe/pbheader.py95
-rw-r--r--cesar/maximus/python/maximus/mme/__init__.py10
-rw-r--r--cesar/maximus/python/maximus/mme/create.py10
-rw-r--r--cesar/maximus/python/maximus/mme/mme.py130
-rw-r--r--cesar/maximus/python/maximus/mme/mmentry.py33
-rw-r--r--cesar/maximus/python/maximus/mme/mmheader.py298
-rw-r--r--cesar/maximus/python/maximus/mme/mmtype.py20
-rw-r--r--cesar/maximus/python/maximus/result/__init__.py5
-rw-r--r--cesar/maximus/python/maximus/simu/__init__.py8
-rw-r--r--cesar/maximus/python/maximus/simu/rx.py136
-rw-r--r--cesar/maximus/python/maximus/simu/tx.py9
-rw-r--r--cesar/maximus/python/maximus/station/__init__.py8
-rw-r--r--cesar/maximus/python/maximus/station/config.py98
-rw-r--r--cesar/maximus/python/maximus/station/sta.py1052
-rw-r--r--cesar/maximus/python/maximus/utils/__init__.py10
-rw-r--r--cesar/maximus/python/maximus/utils/converter.py106
-rw-r--r--cesar/maximus/python/maximus/utils/crc.py102
-rw-r--r--cesar/maximus/python/maximus/utils/exception.py21
-rw-r--r--cesar/maximus/python/maximus/utils/format.py263
-rw-r--r--cesar/maximus/python/py/script_example.py140
-rw-r--r--cesar/maximus/python/py/test_cb.py84
-rw-r--r--cesar/maximus/python/py/test_ether.py227
-rw-r--r--cesar/maximus/python/py/test_false_alarm.py74
-rw-r--r--cesar/maximus/python/py/test_send_mpdu.py158
-rw-r--r--cesar/maximus/python/py/test_send_noise.py86
-rw-r--r--cesar/maximus/python/py/test_tx_rx.py217
-rw-r--r--cesar/maximus/python/src/interface_module.cpp745
-rwxr-xr-xcesar/maximus/python/test/startup.py29
-rw-r--r--cesar/maximus/python/test/test.txt94
-rw-r--r--cesar/maximus/python/test/test_channel.py80
-rw-r--r--cesar/maximus/python/test/test_cli.py26
-rw-r--r--cesar/maximus/python/test/test_ethernet.py489
-rw-r--r--cesar/maximus/python/test/test_fsm.py75
-rw-r--r--cesar/maximus/python/test/test_interface.py461
-rw-r--r--cesar/maximus/python/test/test_lib_cesar.py330
-rw-r--r--cesar/maximus/python/test/test_lib_proto.py376
-rw-r--r--cesar/maximus/python/test/test_macframe.py547
-rw-r--r--cesar/maximus/python/test/test_maximus.py47
-rw-r--r--cesar/maximus/python/test/test_mme.py304
-rw-r--r--cesar/maximus/python/test/test_result.py26
-rw-r--r--cesar/maximus/python/test/test_simu.py120
-rw-r--r--cesar/maximus/python/test/test_station.py268
-rw-r--r--cesar/maximus/python/test/test_utils.py107
133 files changed, 41025 insertions, 0 deletions
diff --git a/cesar/maximus/python/Makefile b/cesar/maximus/python/Makefile
new file mode 100644
index 0000000000..d8686216cb
--- /dev/null
+++ b/cesar/maximus/python/Makefile
@@ -0,0 +1,9 @@
+BASE = ../..
+
+HOST_PROGRAMS = interface.so
+
+interface.so_SOURCES = interface_module.cpp
+interface.so_MODULES = lib/python maximus lib
+interface.so_LDLIBS = -fPIC -shared
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/maximus/python/doc/fulminata_maximus_scenario_engine.odt b/cesar/maximus/python/doc/fulminata_maximus_scenario_engine.odt
new file mode 100755
index 0000000000..c1fd556c0b
--- /dev/null
+++ b/cesar/maximus/python/doc/fulminata_maximus_scenario_engine.odt
Binary files differ
diff --git a/cesar/maximus/python/doc/fulminata_maximus_scenario_engine.xmi b/cesar/maximus/python/doc/fulminata_maximus_scenario_engine.xmi
new file mode 100755
index 0000000000..8946d8348f
--- /dev/null
+++ b/cesar/maximus/python/doc/fulminata_maximus_scenario_engine.xmi
@@ -0,0 +1,1386 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XMI xmlns:UML="http://schema.omg.org/spec/UML/1.3" verified="false" timestamp="2008-02-19T16:33:55" xmi.version="1.2" >
+ <XMI.header>
+ <XMI.documentation>
+ <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter>
+ <XMI.exporterVersion>1.5.6</XMI.exporterVersion>
+ <XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
+ </XMI.documentation>
+ <XMI.metamodel xmi.name="UML" href="UML.xml" xmi.version="1.3" />
+ </XMI.header>
+ <XMI.content>
+ <UML:Model isSpecification="false" isLeaf="false" isRoot="false" xmi.id="m1" isAbstract="false" name="UML Model" >
+ <UML:Namespace.ownedElement>
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="interface" isRoot="false" isAbstract="false" name="interface" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="constructor" isRoot="false" isAbstract="false" name="constructor" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="struct" isRoot="false" isAbstract="false" name="struct" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="typedef" isRoot="false" isAbstract="false" name="typedef" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="friend" isRoot="false" isAbstract="false" name="friend" />
+ <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Logical View" isRoot="false" isAbstract="false" name="Logical View" >
+ <UML:Namespace.ownedElement>
+ <UML:Package stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Datatypes" isRoot="false" isAbstract="false" name="Datatypes" >
+ <UML:Namespace.ownedElement>
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="agtmZAmehdXM" isRoot="false" isAbstract="false" name="int" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="JcPKyEye9iP3" isRoot="false" isAbstract="false" name="char" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="txbVRO36HpfQ" isRoot="false" isAbstract="false" name="bool" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="ZJ5BrRm819Tz" isRoot="false" isAbstract="false" name="float" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="LRcU81Wzx7SM" isRoot="false" isAbstract="false" name="double" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="VVSkI78sPE3E" isRoot="false" isAbstract="false" name="short" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="dpMdwnaHDClJ" isRoot="false" isAbstract="false" name="long" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="CFI9MjVrEwaX" isRoot="false" isAbstract="false" name="unsigned int" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="1iPQuScWFz9B" isRoot="false" isAbstract="false" name="unsigned short" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="mjQxu9G6PXDl" isRoot="false" isAbstract="false" name="unsigned long" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="GgbUcB1crO0m" isRoot="false" isAbstract="false" name="string" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="ARgEDvWDshpX" isRoot="false" isAbstract="false" name="const short int" elementReference="ek5GEEjxefv1" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="mXu6MdkX4QlH" isRoot="false" isAbstract="false" name="const float" elementReference="ZJ5BrRm819Tz" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="psrQPqT9L430" isRoot="false" isAbstract="false" name="const ChannelPoint&amp;" elementReference="VsbjUz1jzxim" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="5ToJ3zPrsGFF" isRoot="false" isAbstract="false" name="ChannelPoint&amp;" elementReference="VsbjUz1jzxim" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="oL4FZe2AHfNk" isRoot="false" isAbstract="false" name="const Network_Clock_Tick" elementReference="OMC8n0NgoyNC" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="WndGhsLWd8YJ" isRoot="false" isAbstract="false" name="uint32_t*" elementReference="7rs81OTZw4E7" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="8gZ2im9FZlVF" isRoot="false" isAbstract="false" name="PhySciMsgNoise&amp;" elementReference="nNLPS46tYU5B" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="hfBiNMiT2GVk" isRoot="false" isAbstract="false" name="const uint32_t*" elementReference="7rs81OTZw4E7" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="kj4rGrwwW6er" isRoot="false" isAbstract="false" name="const PhySciMsgMpdu&amp;" elementReference="r6SeLQ0E8ets" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="WzilSttBcw0q" isRoot="false" isAbstract="false" name="const Sci_Msg_Station_Id" elementReference="iF6aeCsJls2b" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="1XretJvqfug3" isRoot="false" isAbstract="false" name="const unsigned int" elementReference="CFI9MjVrEwaX" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="HSbuMHwp53nG" isRoot="false" isAbstract="false" name="const uint8_t*" elementReference="eNNzwM7vtyZm" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="PfzwSs1KcVMd" isRoot="false" isAbstract="false" name="const Channel_Settings_Key&amp;" elementReference="aXMfZ9tQ8GTx" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="PVMPlwqpaaYi" isRoot="false" isAbstract="false" name="std::map&lt; const Channel_Settings_Key, ChannelSettings *, ltkey >" elementReference="qYY4ISujM3Ed" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="tq6FaofPTzwd" isRoot="false" isAbstract="false" name="StationsList*" elementReference="0IENWuVgMRRQ" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="3YkVVg8j3o2Y" isRoot="false" isAbstract="false" name="IPhy*" elementReference="5VCzTkjjCKbZ" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="rxKsjMRYfTiU" isRoot="false" isAbstract="false" name="ISystem*" elementReference="P5iAKaTM6Drb" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="X118ilRkx2cY" isRoot="false" isAbstract="false" name="const unsigned short int" elementReference="SRA7JvZo6AuO" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="zypnSFDYKlG8" isRoot="false" isAbstract="false" name="const Channel_Mod" elementReference="kbTW3DFGwneP" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="fLpWgryb0030" isRoot="false" isAbstract="false" name="const unsigned char*" elementReference="eniEjhTPROwl" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="b4ob1ibWBqLq" isRoot="false" isAbstract="false" name="PhySciMsgMpdu&amp;" elementReference="r6SeLQ0E8ets" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="NBTpmTxZCmcb" isRoot="false" isAbstract="false" name="const bool" elementReference="txbVRO36HpfQ" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="LlOVV04Zpapx" isRoot="false" isAbstract="false" name="std::vector&lt; ChannelSettings * >&amp;" elementReference="AlwnfvQ24tqq" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="su73E4iG7Y8j" isRoot="false" isAbstract="false" name="const unsigned long" elementReference="mjQxu9G6PXDl" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="41M2qczWxT6z" isRoot="false" isAbstract="false" name="uint8_t*" elementReference="eNNzwM7vtyZm" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="m2IzC9ii2UsR" isRoot="false" isAbstract="false" name="const double" elementReference="LRcU81Wzx7SM" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="448sjDF59poj" isRoot="false" isAbstract="false" name="const ChannelPoint" elementReference="VsbjUz1jzxim" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="BVdJY7XV1Crz" isRoot="false" isAbstract="false" name="unsigned int&amp;" elementReference="CFI9MjVrEwaX" />
+ </UML:Namespace.ownedElement>
+ </UML:Package>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ka695HsLyRqa" isRoot="false" isAbstract="false" name="Maximus simulator" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="rGkvr2wbb0ig" isRoot="false" isAbstract="false" name="station_id=1" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ACuye0MTG4P7" isRoot="false" isAbstract="false" name="station_id=2" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="t1tc2bTZdTo7" isRoot="false" isAbstract="false" name="SCI server" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="EPI1UgANf3xg" isRoot="false" isAbstract="false" name="PHY processor" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="xbRaG9lhs3GA" isRoot="false" isAbstract="false" name="SCI msg" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="y0Zndhh8NjGq" isRoot="false" isAbstract="false" name="PHY SCI msg" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ouQgLFbCZBH6" isRoot="false" isAbstract="false" name="USER" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="R2g1PPyRrFdJ" isRoot="false" isAbstract="false" name="bool [PHY_CARRIER_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="pKHo6OTH6XRU" isRoot="false" isAbstract="false" name="stationsList" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="MjbCnbmzupQK" isRoot="false" isAbstract="false" name="bool [PHY_CARRIER_MAX_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="iF6aeCsJls2b" isRoot="false" isAbstract="false" name="Sci_Msg_Station_Id" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="IVIVFrTsSA9W" isRoot="false" isAbstract="false" name="unsigned char [PHY_CARRIER_MAX_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="OTUqbbMS8cB5" isRoot="false" isAbstract="false" name="float [PHY_CARRIER_MAX_NB][interval_nb]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Y2z0vH5PWhVj" isRoot="false" isAbstract="false" name="unsigned char [TONEMAP_INDEX_NB][PHY_CARRIER_MAX_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="NNrPbFIBbTWJ" isRoot="false" isAbstract="false" name="float [interval_nb][PHY_CARRIER_MAX_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="OMC8n0NgoyNC" isRoot="false" isAbstract="false" name="Network_Clock_Tick" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="QCc0kys9xMnl" isRoot="false" isAbstract="false" name="const float[interval_nb][PHY_CARRIER_MAX_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="pnRk9DVlgulU" isRoot="false" isAbstract="false" name="const unsigned char [PHY_CARRIER_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="0ZbYQWqDJFyR" isRoot="false" isAbstract="false" name="const unsigned char [PHY_CARRIER_MAX_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="SRA7JvZo6AuO" isRoot="false" isAbstract="false" name="unsigned short int" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="71EBB6ZerqDE" isRoot="false" isAbstract="false" name="Phy_Tonemap_Index" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ryY5K4jdy734" isRoot="false" isAbstract="false" name="unsigned char *" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="5hM3oO8IvMZa" isRoot="false" isAbstract="false" name="Phy_Header &amp;" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="yBbPCZ8HGSK2" isRoot="false" isAbstract="false" name="uint8_t [PHY_SYMBOL_MAX_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="TwO4O4jLDIiP" isRoot="false" isAbstract="false" name="uint16_t [PHY_CARRIER_MAX_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="p0EIenqzKrdV" isRoot="false" isAbstract="false" name="Point" >
+ <UML:Classifier.feature>
+ <UML:Attribute isSpecification="false" visibility="public" xmi.id="ihYvkGnalcj8" type="agtmZAmehdXM" name="I" />
+ <UML:Attribute isSpecification="false" visibility="public" xmi.id="DcQ21IYgvf4A" type="agtmZAmehdXM" name="Q" />
+ <UML:Attribute isSpecification="false" visibility="public" xmi.id="0PpuG29IN9r4" type="CFI9MjVrEwaX" name="C" />
+ <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="lRK3GxXGwC31" isRoot="false" isAbstract="false" isQuery="false" name="code" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="mXxquaFcgKTK" value="" type="eniEjhTPROwl" name="modulation" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="tGjpAvxFMVQv" isRoot="false" isAbstract="false" isQuery="false" name="decode" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="fsUnMzU0oJzm" value="" type="eniEjhTPROwl" name="modulation" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="2UAE6pa80TlD" isRoot="false" isAbstract="false" isQuery="false" name="setC" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="08ssluxBHCfG" value="" type="CFI9MjVrEwaX" name="N" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="VGvoUjjCRsDk" value="" type="ryY5K4jdy734" name="mpdu_payload" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="OgKLO7M3nXAL" value="" type="agtmZAmehdXM" name="mpdu_index" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="iRfrv7uIeAaZ" isRoot="false" isAbstract="false" isQuery="false" name="setIQ" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="VAMLmupGxElF" value="" type="agtmZAmehdXM" name="I" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="uCytgOJgVmGl" value="" type="agtmZAmehdXM" name="Q" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="eniEjhTPROwl" isRoot="false" isAbstract="false" name="unsigned char" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="zwpATNw5hYwj" isRoot="false" isAbstract="false" name="PhyProcessor" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="J5I5GN6BUVNH" isRoot="false" isAbstract="false" name="PhySciMsg &amp;" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="CvLZ2CQ63P41" isRoot="false" isAbstract="false" name="station_id=3" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="IW1PTWwAuJXf" isRoot="false" isAbstract="false" name="unsigned int [MAXIMUS_PHY_MOD_NB]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="ek5GEEjxefv1" isRoot="false" isAbstract="false" name="short int" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="7rs81OTZw4E7" isRoot="false" isAbstract="false" name="uint32_t" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="eNNzwM7vtyZm" isRoot="false" isAbstract="false" name="uint8_t" />
+ <UML:Package isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="6elj96McODtx" isRoot="false" isAbstract="false" name="std" >
+ <UML:Namespace.ownedElement>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="6elj96McODtx" xmi.id="qYY4ISujM3Ed" isRoot="false" isAbstract="false" name="map" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="6elj96McODtx" xmi.id="AlwnfvQ24tqq" isRoot="false" isAbstract="false" name="vector" />
+ </UML:Namespace.ownedElement>
+ </UML:Package>
+ <UML:Generalization isSpecification="false" child="FA5tCgQO5jOX" visibility="public" namespace="Logical View" xmi.id="guI259xtgWxy" parent="MJNkMwYhFv8H" discriminator="" name="" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="0IENWuVgMRRQ" isRoot="false" isAbstract="false" name="StationsList" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="P5iAKaTM6Drb" isRoot="false" isAbstract="false" name="ISystem" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="kbTW3DFGwneP" isRoot="false" isAbstract="false" name="Channel_Mod" />
+ <UML:Generalization isSpecification="false" child="FA5tCgQO5jOX" visibility="public" namespace="Logical View" xmi.id="sOkJkhMy5511" parent="MJNkMwYhFv8H" discriminator="" name="" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="MMOOLBCfmrGJ" isRoot="false" isAbstract="false" name="uint8_t [(PHY_CARRIER_MAX_NB+1)/2]" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="5VCzTkjjCKbZ" isRoot="false" isAbstract="false" name="IPhy" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="nNLPS46tYU5B" isRoot="false" isAbstract="false" name="PhySciMsgNoise" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="r6SeLQ0E8ets" isRoot="false" isAbstract="false" name="PhySciMsgMpdu" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="aXMfZ9tQ8GTx" isRoot="false" isAbstract="false" name="Channel_Settings_Key" >
+ <UML:Classifier.feature>
+ <UML:Attribute isSpecification="false" visibility="public" xmi.id="FsOabmphHzei" type="iF6aeCsJls2b" name="tx_station_id" />
+ <UML:Attribute isSpecification="false" visibility="public" xmi.id="jNPug1TGWnt5" type="iF6aeCsJls2b" name="rx_station_id" />
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="umW20xxGpJoP" isRoot="false" isAbstract="false" name="ltkey" >
+ <UML:Classifier.feature>
+ <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="3d6Ick1K5QEl" isRoot="false" isAbstract="false" isQuery="false" name="operator ( )" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="wEoKDxqvdkhA" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="TIrIZffdGlvq" value="" type="PfzwSs1KcVMd" name="key1" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="TuAXJMGi1GcR" value="" type="PfzwSs1KcVMd" name="key2" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="zSo720DHUtK4" isRoot="false" isAbstract="false" name="ChannelSettingsList" />
+ <UML:Class comment="class ChannelComputer" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="FA5tCgQO5jOX" isRoot="false" isAbstract="false" name="ChannelComputer" >
+ <UML:GeneralizableElement.generalization>
+ <UML:Generalization xmi.idref="guI259xtgWxy" />
+ <UML:Generalization xmi.idref="sOkJkhMy5511" />
+ <UML:Generalization xmi.idref="KY1cn4F7HHaL" />
+ </UML:GeneralizableElement.generalization>
+ <UML:Classifier.feature>
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="vLNKsMwHnQ5O" type="zSo720DHUtK4" name="mListOfChannelSettings" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="uHZmB3x8YrWn" type="SRA7JvZo6AuO" name="mNumberOfCopiesArray" ownerScope="classifier" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="EPgLV4JWKVtq" type="tq6FaofPTzwd" name="mpListOfStations" />
+ <UML:Attribute comment="// private attributes//// for random" isSpecification="false" visibility="private" xmi.id="iNWc4oZxCl7B" type="IWPuXt3VypIz" name="mEngine" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="GQR4rnp7JCzr" type="ZJ5BrRm819Tz" name="mPowerScaleArray" ownerScope="classifier" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="GewSP3dgS2iJ" type="41M2qczWxT6z" name="mpTonemask" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="pXR9jOynPIoD" type="CFI9MjVrEwaX" name="mBeaconPeriod" />
+ <UML:Operation stereotype="constructor" comment="// Constructors/Destructors// /**
+Constructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="PNXlmw9fnFuL" isRoot="false" isAbstract="false" isQuery="false" name="ChannelComputer" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="rL49qwyEJTx3" value="" type="3YkVVg8j3o2Y" name="p_phy" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="Neig7djUiPf1" value="" type="rxKsjMRYfTiU" name="p_system" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Empty Destructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="y8L4KAg9702o" isRoot="false" isAbstract="false" isQuery="false" name="~ ChannelComputer" />
+ <UML:Operation comment="// public methods// /**
+Compute PB measurement and NOISE.
+@param pb_measurement_array the PB measurement to fill in (for all PBs composing the MPDU)
+@param noise the PHY SCI message NOISE to fill in
+@param pb_header_array the PB header of each PB composing the MPDU
+@param mpdu a PHY SCI message MPDU that contains the complete received MPDU payload
+@param tx_station_id the ID of the transmitting station
+@param rx_station_id the ID of the destination station
+@param current_tick the current Network Clock tick
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="LRN0s3UGfAwm" isRoot="false" isAbstract="false" isQuery="false" name="addPerturbation" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="zd95SlqOdqdd" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="meGU1tTz0m2I" value="" type="WndGhsLWd8YJ" name="pb_measurement_array" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="wiR3gRq1sB2l" value="" type="8gZ2im9FZlVF" name="noise" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="EU1tfvdRXrtX" value="" type="hfBiNMiT2GVk" name="pb_header_array" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="lLWj7Y14EQ5v" value="" type="kj4rGrwwW6er" name="mpdu" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="svwi6wRIRQ94" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="MmVreMONht4n" value="" type="WzilSttBcw0q" name="rx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="P5reTuXLoR2s" value="" type="oL4FZe2AHfNk" name="current_tick" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Add Channel Settings to the list.
+Called when a station is created => create its associated Channel Settings.
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="MTBnuIpE5I5h" isRoot="false" isAbstract="false" isQuery="false" name="addChannelSettings" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="zR12RM2LZqgm" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="eS2KL67i9wMc" value="" type="WzilSttBcw0q" name="created_station_id" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Called when the PHY processor receives a preamble.
+@param current_tick the current Network Clock tick
+@param tx_station_id the ID of the transmitting station
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="qrweJyXfPgQH" isRoot="false" isAbstract="false" isQuery="false" name="receivePre" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="nUhRCPZC2hFS" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="yDV1VZg7ziRI" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="mY0vULWJCSxT" value="" type="oL4FZe2AHfNk" name="current_tick" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Called when the PHY processor receives a frame control.
+@param current_tick the current Network Clock tick
+@param tx_station_id the ID of the transmitting station
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="OS6l8U35hW6C" isRoot="false" isAbstract="false" isQuery="false" name="receiveFc" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="S5r4uSfttewJ" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="3nK2TjIGGJ9i" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="ef1o7xGTPMFW" value="" type="oL4FZe2AHfNk" name="current_tick" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="// private methods// /**
+Initializes the Channel Computer class attributes." isSpecification="false" isLeaf="false" visibility="private" xmi.id="jRbAQQ47XE3x" isRoot="false" isAbstract="false" isQuery="false" name="initAttributes" />
+ <UML:Operation comment="Update the list of Channel Settings.
+Called when channel perturbation has to be added.
+Check if stations have been removed => remove their associated Channel Settings." isSpecification="false" isLeaf="false" visibility="private" xmi.id="qQZrSJeClEK9" isRoot="false" isAbstract="false" isQuery="false" name="updateListOfChannelSettings" />
+ <UML:Operation comment="// public methods// /**
+Duplicate the MPDU payload.
+@param mpdu a PHY SCI message MPDU that contains the complete received MPDU payload
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="OZe7W5VrVgaA" isRoot="false" isAbstract="false" isQuery="false" name="duplicateMpduPayload" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="1weamIKXm0wx" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="eXkNB8JdLiXJ" value="" type="b4ob1ibWBqLq" name="mpdu" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Find Channel Settings.
+@param tx_station_id the ID of the transmitting station
+@param rx_station_id the ID of the destination station
+@return a list of Channel Settings" isSpecification="false" isLeaf="false" visibility="public" xmi.id="09RFjqmd0dax" isRoot="false" isAbstract="false" isQuery="false" name="findChannelSettings" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="PU9PBOsdRjfL" type="LlOVV04Zpapx" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="T1b73JO0VdWP" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="MN7FXFtWPJl8" value="" type="WzilSttBcw0q" name="rx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="7Vk78K2bMeiN" value="" type="NBTpmTxZCmcb" name="both_directions" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="// public attribute accessor methods// // private attribute accessor methods// /**
+Sets the tonemask.
+@param p_tonemask the new value of mpTonemask
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="fYXdFW0u7v45" isRoot="false" isAbstract="false" isQuery="false" name="setTonemask" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="9KF3z9Ky5yWr" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="TmjfeN9KMrw5" value="" type="HSbuMHwp53nG" name="p_tonemask" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the tonemap of the current transmission.
+@return bool
+@param tx_station_id the ID of the transmitting station
+@param length the tonemap length in octets
+@param p_tonemap the tonemap" isSpecification="false" isLeaf="false" visibility="public" xmi.id="BALxxO2awYCA" isRoot="false" isAbstract="false" isQuery="false" name="setTonemap" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="FqMzqJwDn3by" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="2C4956EYqxBS" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="ILncAjhMt1Hp" value="" type="su73E4iG7Y8j" name="length" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="PJPKpbUslW1r" value="" type="fLpWgryb0030" name="p_tonemap" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the beacon period in ticks 25 MHz.
+@return bool
+@param frequency the power-line frequency" isSpecification="false" isLeaf="false" visibility="public" xmi.id="dGNRBZuSsh40" isRoot="false" isAbstract="false" isQuery="false" name="setBeaconPeriod" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="RTZrAFCJXPKU" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="OkMGld58vSSk" value="" type="mXu6MdkX4QlH" name="frequency" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets a tonemask value.
+@param carrier_index
+@return a boolean value indicating if the requested carrier is enabled or not" isSpecification="false" isLeaf="false" visibility="private" xmi.id="XLTP0YPPGkf1" isRoot="false" isAbstract="false" isQuery="false" name="getTonemask" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="YeSdbwSqlppZ" type="NBTpmTxZCmcb" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="Li9EAazAUZwt" value="" type="X118ilRkx2cY" name="carrier_index" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the beacon period in ticks 25 MHz.
+@return mBeaconPeriod" isSpecification="false" isLeaf="false" visibility="private" xmi.id="2s4IahHvPPAX" isRoot="false" isAbstract="false" isQuery="false" name="getBeaconPeriod" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="6mnrpOpFpM6x" type="1XretJvqfug3" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="// protected methods// All following protected methods could be declared as private methods,// but they are declared as protected methods to be unitarly tested.///**
+Gets the sigma factor.
+@param modulation the tonemap modulation
+@param snr_in_db the SNR value in dB
+@return the sigma factor" isSpecification="false" isLeaf="false" visibility="protected" xmi.id="z7iRgeJqCCrj" isRoot="false" isAbstract="false" isQuery="false" name="getSigma" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="bGG7gbbED2qo" type="m2IzC9ii2UsR" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="VuoAPHpR7tih" value="" type="zypnSFDYKlG8" name="modulation" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="YzaxOiULnAlS" value="" type="mXu6MdkX4QlH" name="snr_in_db" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the PowerScale.
+@param modulation the tonemap modulation
+@return 1 / (PowerScale^2)" isSpecification="false" isLeaf="false" visibility="protected" xmi.id="jfqqWYV4W41s" isRoot="false" isAbstract="false" isQuery="false" name="getPowerScale" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="yGeh3UH7E2y1" type="mXu6MdkX4QlH" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="mTCaex2QzINB" value="" type="zypnSFDYKlG8" name="modulation" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the linear SNR.
+@param snr_in_db the SNR value in dB
+@return the linear SNR value" isSpecification="false" isLeaf="false" visibility="protected" xmi.id="P3rRYhqHMh6s" isRoot="false" isAbstract="false" isQuery="false" name="getLinearSnr" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="OnED8IAhZOoD" type="m2IzC9ii2UsR" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="DbwjfvcQPoy1" value="" type="mXu6MdkX4QlH" name="snr_in_db" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Add noise.
+@param point the original point coordinates
+@param sigma the sigma factor
+@return the noise point coordinates" isSpecification="false" isLeaf="false" visibility="protected" xmi.id="jyRgGnpfqf5M" isRoot="false" isAbstract="false" isQuery="false" name="addNoise" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="xOPBQDzMUe4V" type="448sjDF59poj" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="MvcjciboHWXv" value="" type="psrQPqT9L430" name="point" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="R7LqtHpaFHGV" value="" type="m2IzC9ii2UsR" name="sigma" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Compute the BER.
+@param codeA / codeB the 2 codes to compare
+@return the BER" isSpecification="false" isLeaf="false" visibility="protected" xmi.id="XOXms3hJA084" isRoot="false" isAbstract="false" isQuery="false" name="computeBer" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="6LdINbJlNWwV" type="X118ilRkx2cY" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="HxcWCtzEv87e" value="" type="X118ilRkx2cY" name="codeA" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="LKjS9WAeshOk" value="" type="X118ilRkx2cY" name="codeB" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Compute the noise.
+@param pointA / pointB the 2 points coordinates
+@return the (distance)^2 between the 2 points" isSpecification="false" isLeaf="false" visibility="protected" xmi.id="k41t27vK3XoF" isRoot="false" isAbstract="false" isQuery="false" name="computeNoise" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="o6CNS1YQPybn" type="1XretJvqfug3" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="OmSJsXxBrfey" value="" type="psrQPqT9L430" name="pointA" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="9oazTyhE0i53" value="" type="psrQPqT9L430" name="pointB" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Compute the FER.
+@param ber the BER of the current PB
+@param n the average number of bits coded per carrier on the current PB
+@param modulation the tonemap modulation
+@return the FER" isSpecification="false" isLeaf="false" visibility="protected" xmi.id="o0LrX74wtWDl" isRoot="false" isAbstract="false" isQuery="false" name="computeFer" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="Ba9dCD9GWmYt" type="mXu6MdkX4QlH" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="39xsoZovNOuo" value="" type="X118ilRkx2cY" name="ber" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="Lb2LH5O55hub" value="" type="1XretJvqfug3" name="n" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="pzViTiSVrNNd" value="" type="zypnSFDYKlG8" name="modulation" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Compute the CRC error.
+@param fer the FER of the current PB
+@return the CRC error" isSpecification="false" isLeaf="false" visibility="protected" xmi.id="wAYHYS5t16DH" isRoot="false" isAbstract="false" isQuery="false" name="computeCrcError" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="NqckMYF8cQU3" type="NBTpmTxZCmcb" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="BZMFHFq6ELmf" value="" type="mXu6MdkX4QlH" name="fer" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class comment="class IChannel" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="MJNkMwYhFv8H" isRoot="false" isAbstract="false" name="IChannel" >
+ <UML:Classifier.feature>
+ <UML:Operation stereotype="constructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="11oV4ziv3AYN" isRoot="false" isAbstract="false" isQuery="false" name="IChannel" />
+ <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="YYbhCSZWluH5" isRoot="false" isAbstract="false" isQuery="false" name="~ IChannel" />
+ <UML:Operation comment="// public methods// /**
+Compute PB measurement and NOISE.
+@param pb_measurement_array the PB measurement to fill in
+@param noise the PHY SCI message NOISE to fill in
+@param pb_header_array the PB header of each PB composing the MPDU
+@param mpdu a PHY SCI message MPDU that contains the complete received MPDU payload
+@param tx_station_id the ID of the transmitting station
+@param rx_station_id the ID of the destination station
+@param current_tick the current Network Clock tick
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="qnn4itLhu9Bz" isRoot="false" isAbstract="true" isQuery="false" name="addPerturbation" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="R2Toy4bAcinn" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="1t1u1Cr63jC2" value="" type="WndGhsLWd8YJ" name="pb_measurement_array" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="bojFxHYw8Xo7" value="" type="8gZ2im9FZlVF" name="noise" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="2dxZMQmxFVCA" value="" type="hfBiNMiT2GVk" name="pb_header_array" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="SNKUdoCdP8Cl" value="" type="kj4rGrwwW6er" name="mpdu" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="nwmJ2RBUmTwN" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="F70eDCPj96Tc" value="" type="WzilSttBcw0q" name="rx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="zMlZIlP3fCNi" value="" type="oL4FZe2AHfNk" name="current_tick" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Add Channel Settings to the list.
+Called when a station is created => create its associated Channel Settings.
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="bWALx5iDCipN" isRoot="false" isAbstract="true" isQuery="false" name="addChannelSettings" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="wu3SgaK4Oumi" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="uF62LZeIuPrA" value="" type="WzilSttBcw0q" name="created_station_id" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Called when the PHY processor receives a preamble.
+@param tx_station_id the ID of the transmitting station
+@param current_tick the current Network Clock tick
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="AGEpQZVz3eK0" isRoot="false" isAbstract="true" isQuery="false" name="receivePre" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="R0q1QK4pLXdJ" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="j0Bti1GbEMdX" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="uFpmceuks6XJ" value="" type="oL4FZe2AHfNk" name="current_tick" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Called when the PHY processor receives a frame control.
+@param tx_station_id the ID of the transmitting station
+@param current_tick the current Network Clock tick
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="d3GgfZfOZoHG" isRoot="false" isAbstract="true" isQuery="false" name="receiveFc" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="ZCTAuFxo9yFo" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="pVp1pSYhfLTH" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="zM1sQY94ZPiE" value="" type="oL4FZe2AHfNk" name="current_tick" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="// public methods// /**
+Duplicate the MPDU payload.
+@param mpdu a PHY SCI message MPDU that contains the complete received MPDU payload
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="PujNU9MyUc3R" isRoot="false" isAbstract="true" isQuery="false" name="duplicateMpduPayload" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="WXquRccqaRs0" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="xX2WY1uSiHwr" value="" type="b4ob1ibWBqLq" name="mpdu" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Find Channel Settings.
+@param tx_station_id the ID of the transmitting station
+@param rx_station_id the ID of the destination station
+@return a list of Channel Settings" isSpecification="false" isLeaf="false" visibility="public" xmi.id="hYiS0RDqSc09" isRoot="false" isAbstract="true" isQuery="false" name="findChannelSettings" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="jwn4SQO1apBT" type="LlOVV04Zpapx" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="nlp4OJFwDJNs" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="0gvOr8GYew0f" value="" type="WzilSttBcw0q" name="rx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="3rVG8q99X2VO" value="" type="NBTpmTxZCmcb" name="both_directions" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the tonemask.
+@param p_tonemask the new value of mpTonemask
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="qCYOB46xZJIN" isRoot="false" isAbstract="true" isQuery="false" name="setTonemask" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="26HA5Uyb1mUR" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="ThYihpYABMxg" value="" type="HSbuMHwp53nG" name="p_tonemask" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the tonemap of the current transmission.
+@return bool
+@param tx_station_id the ID of the transmitting station
+@param length the tonemap length in octets
+@param p_tonemap the tonemap" isSpecification="false" isLeaf="false" visibility="public" xmi.id="34qsc33QFZoO" isRoot="false" isAbstract="true" isQuery="false" name="setTonemap" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="M4HxV9vF4jHW" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="evLBEcYfH4Oz" value="" type="WzilSttBcw0q" name="tx_station_id" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="bA9ohvCLoWU0" value="" type="su73E4iG7Y8j" name="length" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="83gP52MxwT18" value="" type="fLpWgryb0030" name="p_tonemap" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the beacon period in ticks 25 MHz.
+@return bool
+@param frequency the power-line frequency" isSpecification="false" isLeaf="false" visibility="public" xmi.id="WhMdFTMpdTdI" isRoot="false" isAbstract="true" isQuery="false" name="setBeaconPeriod" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="7dXiTh9TnQdq" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="MoeBK8BS9rpF" value="" type="mXu6MdkX4QlH" name="frequency" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the beacon period in ticks 25 MHz.
+@return mBeaconPeriod" isSpecification="false" isLeaf="false" visibility="public" xmi.id="tCCndBu9sGk6" isRoot="false" isAbstract="true" isQuery="false" name="getBeaconPeriod" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="tZQuLuLiybdS" type="1XretJvqfug3" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Generalization isSpecification="false" child="FA5tCgQO5jOX" visibility="public" namespace="Logical View" xmi.id="KY1cn4F7HHaL" parent="MJNkMwYhFv8H" discriminator="" name="" />
+ <UML:Package isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="uPECzXJFnTOn" isRoot="false" isAbstract="false" name="boost" >
+ <UML:Namespace.ownedElement>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="uPECzXJFnTOn" xmi.id="IWPuXt3VypIz" isRoot="false" isAbstract="false" name="mt19937" />
+ </UML:Namespace.ownedElement>
+ </UML:Package>
+ <UML:Class comment="ChannelPoint.h - Copyright buret
+Here you can write a license for your code, some comments or any other
+information you want to have in your generated code. To to this simply
+configure the &quot;headings&quot; directory in uml to point to a directory
+where you have your heading files.
+or you can just replace the contents of this file with your own.
+If you want to do this, this file is located at
+/usr/share/apps/umbrello/headings/heading.h
+-->Code Generators searches for heading files based on the file extension
+i.e. it will look for a file name ending in &quot;.h&quot; to include in C++ header
+files, and for a file name ending in &quot;.java&quot; to include in all generated
+java code.
+If you name the file &quot;heading.&lt;extension>&quot;, Code Generator will always
+choose this file even if there are other files with the same extension in the
+directory. If you name the file something else, it must be the only one with that
+extension in the directory to guarantee that Code Generator will choose it.
+you can use variables in your heading files which are replaced at generation
+time. possible variables are : author, date, time, filename and filepath.
+just write %variable_name%
+This file was generated on %date% at %time%
+The original location of this file is /home/buret/eclipse/maximus/channel/inc/ChannelPoint.h
+//**
+class ChannelPoint" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="VsbjUz1jzxim" isRoot="false" isAbstract="false" name="ChannelPoint" >
+ <UML:Classifier.feature>
+ <UML:Attribute comment="// public attributes// // abscissa" isSpecification="false" visibility="public" xmi.id="hRU6f1aVcHyc" type="ZJ5BrRm819Tz" name="I" />
+ <UML:Attribute comment="// ordinate" isSpecification="false" visibility="public" xmi.id="IhZENLi13oFI" type="ZJ5BrRm819Tz" name="Q" />
+ <UML:Operation stereotype="constructor" comment="// Constructors/Destructors// /**
+Empty Constructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="0zDce8bMX5QB" isRoot="false" isAbstract="false" isQuery="false" name="ChannelPoint" />
+ <UML:Operation comment="Empty Destructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="kVbwfpKRKEVh" isRoot="false" isAbstract="false" isQuery="false" name="~ ChannelPoint" />
+ <UML:Operation comment="// public methods// /**
+Operator =
+@param channel_point
+@return ChannelPoint &amp;" isSpecification="false" isLeaf="false" visibility="public" xmi.id="rGEtgzA0EaD8" isRoot="false" isAbstract="false" isQuery="false" name="operator =" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="kYfoHwINao51" type="5ToJ3zPrsGFF" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="tNQDbtuR98Ko" value="" type="psrQPqT9L430" name="channel_point" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Operator ==
+@param channel_point
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="5iOQmRPfmnrL" isRoot="false" isAbstract="false" isQuery="false" name="operator ==" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="VCUGc67TdVOx" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="glmqs7cxaQFb" value="" type="psrQPqT9L430" name="channel_point" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Checks Channel Point values ranges,
+i.e. checks I and Q coordinates validity.
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="OeSEtgTyOpM9" isRoot="false" isAbstract="false" isQuery="false" name="checkValidity" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="PhdLIGl1oQp4" type="txbVRO36HpfQ" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation stereotype="constructor" comment="Constructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="Vo4VsHm3o6I5" isRoot="false" isAbstract="false" isQuery="false" name="ChannelPoint" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="L6BXRyDTALMi" value="" type="ZJ5BrRm819Tz" name="i" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="pqBVtugPikua" value="" type="mXu6MdkX4QlH" name="q" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class comment="ChannelMapping.h - Copyright buret
+Here you can write a license for your code, some comments or any other
+information you want to have in your generated code. To to this simply
+configure the &quot;headings&quot; directory in uml to point to a directory
+where you have your heading files.
+or you can just replace the contents of this file with your own.
+If you want to do this, this file is located at
+/usr/share/apps/umbrello/headings/heading.h
+-->Code Generators searches for heading files based on the file extension
+i.e. it will look for a file name ending in &quot;.h&quot; to include in C++ header
+files, and for a file name ending in &quot;.java&quot; to include in all generated
+java code.
+If you name the file &quot;heading.&lt;extension>&quot;, Code Generator will always
+choose this file even if there are other files with the same extension in the
+directory. If you name the file something else, it must be the only one with that
+extension in the directory to guarantee that Code Generator will choose it.
+you can use variables in your heading files which are replaced at generation
+time. possible variables are : author, date, time, filename and filepath.
+just write %variable_name%
+This file was generated on %date% at %time%
+The original location of this file is /home/buret/eclipse/maximus/channel/inc/ChannelMapping.h
+//**
+class ChannelMapping" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="HjupUSYowhI4" isRoot="false" isAbstract="false" name="ChannelMapping" >
+ <UML:Classifier.feature>
+ <UML:Attribute comment="// private attributes//" isSpecification="false" visibility="private" xmi.id="ZSwkq19bojv2" type="VsbjUz1jzxim" name="mPoint" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="Ge7RT8Ckq5ZI" type="SRA7JvZo6AuO" name="mCode" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="V57RkPTHrQ2f" type="SRA7JvZo6AuO" name="mNbOfBitsArray" ownerScope="classifier" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="P9GDsAF7oLYH" type="ek5GEEjxefv1" name="mMappingArray" ownerScope="classifier" />
+ <UML:Operation stereotype="constructor" comment="// Constructors/Destructors// /**
+Empty Constructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="4DctbcZ0lnEe" isRoot="false" isAbstract="false" isQuery="false" name="ChannelMapping" />
+ <UML:Operation stereotype="constructor" comment="Constructors" isSpecification="false" isLeaf="false" visibility="public" xmi.id="xRjlmH0Ez1Tl" isRoot="false" isAbstract="false" isQuery="false" name="ChannelMapping" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="e9XQwl2sCldx" value="" type="X118ilRkx2cY" name="code" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation stereotype="constructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="0eBxdci9ekFK" isRoot="false" isAbstract="false" isQuery="false" name="ChannelMapping" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="Th3OhfxLoUji" value="" type="psrQPqT9L430" name="point" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Empty Destructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="DjaPUCMSoVQR" isRoot="false" isAbstract="false" isQuery="false" name="~ ChannelMapping" />
+ <UML:Operation comment="// public methods// /**
+Computes the code from the already set I and Q coordinates.
+@param modulation the used modulation
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="66Ykoo2IT5gA" isRoot="false" isAbstract="false" isQuery="false" name="computeCode" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="L6RvuUwPgOdG" type="X118ilRkx2cY" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="XIQ0O586ecbi" value="" type="zypnSFDYKlG8" name="modulation" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Computes the I and Q coordinates from an already set code.
+@param modulation the used modulation
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="nowhba6bZwOz" isRoot="false" isAbstract="false" isQuery="false" name="computePoint" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="Sik6D63angu6" type="psrQPqT9L430" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="9ZXTLlcs30rP" value="" type="zypnSFDYKlG8" name="modulation" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the code.
+@param code the new value of mCode
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="jtReTM98izcO" isRoot="false" isAbstract="false" isQuery="false" name="setCode" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="uf7g4ukP09Ks" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="qbzoZ0nxSxIq" value="" type="X118ilRkx2cY" name="code" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the code.
+@return mCode" isSpecification="false" isLeaf="false" visibility="public" xmi.id="huvhfiqMaF13" isRoot="false" isAbstract="false" isQuery="false" name="getCode" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="bEHHatW3bG9p" type="SRA7JvZo6AuO" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the coordinates.
+@param point the new value of mPoint
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="c8CI5oguNdiw" isRoot="false" isAbstract="false" isQuery="false" name="setPoint" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="KAP7qHBixGOz" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="dTt5RCv64oni" value="" type="psrQPqT9L430" name="point" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the Channel Point.
+@return mPoint" isSpecification="false" isLeaf="false" visibility="public" xmi.id="Uc44r38RCKjF" isRoot="false" isAbstract="false" isQuery="false" name="getPoint" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="B7O9Gg2suH7S" type="5ToJ3zPrsGFF" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the I coordinate.
+@return mPoint.I" isSpecification="false" isLeaf="false" visibility="public" xmi.id="I0RSI9iPWrpV" isRoot="false" isAbstract="false" isQuery="false" name="getI" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="AbVmpcZ9mwHa" type="mXu6MdkX4QlH" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the Q coordinate.
+@param q mPoint.Q
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="fD4zThhtEUMY" isRoot="false" isAbstract="false" isQuery="false" name="setQ" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="EQI9hh8soWz2" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="5YMFnEF4FhWX" value="" type="mXu6MdkX4QlH" name="q" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the Q coordinate.
+@return mPoint.Q" isSpecification="false" isLeaf="false" visibility="public" xmi.id="qEuK4jnjvsgO" isRoot="false" isAbstract="false" isQuery="false" name="getQ" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="Azs2F0UPZ09P" type="mXu6MdkX4QlH" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Retrieve the integer (except for QAM8) I and Q coordinates from the already set I and Q coordinates.
+@param modulation the used modulation
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="o3dYjumm81LP" isRoot="false" isAbstract="false" isQuery="false" name="retrievePoint" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="cgYNdnxrEGyv" type="448sjDF59poj" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="8HAG5wPTP3yk" value="" type="zypnSFDYKlG8" name="modulation" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="// public attribute accessor methods// // private attribute accessor methods// /**
+Sets the code.
+@param modulation the used modulation
+@param mpdu_payload_length the length of the MPDU payload
+@param p_mpdu_payload pointer to the MPDU payload
+@param mpdu_index indicates the current index of the MPDU payload (in bits)
+@return bool (and update mpdu_index)" isSpecification="false" isLeaf="false" visibility="public" xmi.id="rCiZ34ts7WOo" isRoot="false" isAbstract="false" isQuery="false" name="setCode" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="v6ljakjkicmx" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="Q9aXAtuGA3WD" value="" type="zypnSFDYKlG8" name="modulation" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="zwhMxd6npmKq" value="" type="su73E4iG7Y8j" name="mpdu_payload_length" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="qDgvh5j5EHcM" value="" type="fLpWgryb0030" name="p_mpdu_payload" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="pvkef4STH9Ow" value="" type="BVdJY7XV1Crz" name="mpdu_index" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the I coordinate.
+@param i the new value of mPoint.I
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="no29iM1Z9CGC" isRoot="false" isAbstract="false" isQuery="false" name="setI" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="aEK9EUYpA5Al" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="KSVqaKu0ZipJ" value="" type="mXu6MdkX4QlH" name="i" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class comment="ChannelSettings.h - Copyright buret
+Here you can write a license for your code, some comments or any other
+information you want to have in your generated code. To to this simply
+configure the &quot;headings&quot; directory in uml to point to a directory
+where you have your heading files.
+or you can just replace the contents of this file with your own.
+If you want to do this, this file is located at
+/usr/share/apps/umbrello/headings/heading.h
+-->Code Generators searches for heading files based on the file extension
+i.e. it will look for a file name ending in &quot;.h&quot; to include in C++ header
+files, and for a file name ending in &quot;.java&quot; to include in all generated
+java code.
+If you name the file &quot;heading.&lt;extension>&quot;, Code Generator will always
+choose this file even if there are other files with the same extension in the
+directory. If you name the file something else, it must be the only one with that
+extension in the directory to guarantee that Code Generator will choose it.
+you can use variables in your heading files which are replaced at generation
+time. possible variables are : author, date, time, filename and filepath.
+just write %variable_name%
+This file was generated on %date% at %time%
+The original location of this file is /home/buret/eclipse/maximus/channel/inc/ChannelSettings.h
+//**
+class ChannelSettings" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="PGF0sP6Kgb0l" isRoot="false" isAbstract="false" name="ChannelSettings" >
+ <UML:Classifier.feature>
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="YzQ8Jmmx2Rx1" initialValue="0" type="OMC8n0NgoyNC" name="mPreDetectionDate" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="C8LZTmT1jr71" initialValue="0" type="OMC8n0NgoyNC" name="mFcReceptionDate" />
+ <UML:Attribute comment="// private attributes//" isSpecification="false" visibility="private" xmi.id="ECT43sTE9tu7" type="txbVRO36HpfQ" name="mIsConfigured" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="8uij0qPBhzDF" type="ZJ5BrRm819Tz" name="mSnrArray" />
+ <UML:Attribute isSpecification="false" visibility="private" xmi.id="dsqJeeDqqfut" type="kbTW3DFGwneP" name="mTonemapArray" />
+ <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="N1iX9W91mjbs" isRoot="false" isAbstract="false" isQuery="false" name="setSnr" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="eTOzncRBd8im" value="" type="QCc0kys9xMnl" name="snr" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation stereotype="constructor" comment="// Constructors/Destructors// /**
+Empty Constructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="cnVd2iEDTGap" isRoot="false" isAbstract="false" isQuery="false" name="ChannelSettings" />
+ <UML:Operation comment="Empty Destructor" isSpecification="false" isLeaf="false" visibility="public" xmi.id="dccFV5HKv9Wt" isRoot="false" isAbstract="false" isQuery="false" name="~ ChannelSettings" />
+ <UML:Operation comment="// public methods// // public attribute accessor methods// // private attribute accessor methods// /**
+Sets the PRE detection date.
+@param date tick at which the preamble has been received
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="CRgGs5fVq86t" isRoot="false" isAbstract="false" isQuery="false" name="setPreDetectionDate" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="s7c6LY1GemxC" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="d5bmZVy09CqC" value="" type="oL4FZe2AHfNk" name="date" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the FC reception date.
+@param date tick at which the frame control has been received
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="rJ3xOwjhyyGc" isRoot="false" isAbstract="false" isQuery="false" name="setFcReceptionDate" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="VhwBJg8tvS27" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="1OremcKPfw9E" value="" type="oL4FZe2AHfNk" name="date" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="// private methods// /**
+Initializes the Channel Settings class attributes." isSpecification="false" isLeaf="false" visibility="private" xmi.id="P5CYI2l7Km5i" isRoot="false" isAbstract="false" isQuery="false" name="initAttributes" />
+ <UML:Operation comment="Gets the PRE detection date.
+@return mPreDetectionDate tick at which the preamble has been received" isSpecification="false" isLeaf="false" visibility="private" xmi.id="goPeldGm16Ol" isRoot="false" isAbstract="false" isQuery="false" name="getPreDetectionDate" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="uZu5e4qWCRdV" type="oL4FZe2AHfNk" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the FC reception date.
+@return mFcReceptionDate tick at which the frame control has been received" isSpecification="false" isLeaf="false" visibility="private" xmi.id="iiALeHZ1Njaf" isRoot="false" isAbstract="false" isQuery="false" name="getFcReceptionDate" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="zcmcNjoqQj1h" type="oL4FZe2AHfNk" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="// public methods// /**
+Gets the first symbol start date (in ticks).
+@return tick at which the first symbol has started" isSpecification="false" isLeaf="false" visibility="public" xmi.id="dWaTBSKgoPJ3" isRoot="false" isAbstract="false" isQuery="false" name="getFirstSymbolStartDate" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="N9aGZbOUAGXm" type="oL4FZe2AHfNk" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the tonemap modulation.
+@param carrier the current carrier number
+@return the tonemap modulation" isSpecification="false" isLeaf="false" visibility="public" xmi.id="M3QGTU7iw8dM" isRoot="false" isAbstract="false" isQuery="false" name="getModulation" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="LLIVmt0kUkKp" type="zypnSFDYKlG8" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="MmOSniAOCkrL" value="" type="1XretJvqfug3" name="carrier" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the SNR in dB.
+@param interval the current interval number
+@param carrier the current carrier number
+@return the SNR in dB" isSpecification="false" isLeaf="false" visibility="public" xmi.id="AB0zYJ2vLR9m" isRoot="false" isAbstract="false" isQuery="false" name="getSnr" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="U6fsnga9n8PM" type="mXu6MdkX4QlH" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="tEUpM8CisaAg" value="" type="oL4FZe2AHfNk" name="beacon_period" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="GI4R2umB3mAc" value="" type="oL4FZe2AHfNk" name="symbol_start_date" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="4AXPZg9TueIH" value="" type="1XretJvqfug3" name="carrier" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="// public attribute accessor methods// // private attribute accessor methods// /**
+Gets if the channel has been configured.
+@return mIsConfigured" isSpecification="false" isLeaf="false" visibility="public" xmi.id="kSxc26GHOJiP" isRoot="false" isAbstract="false" isQuery="false" name="isConfigured" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="hlqp2LbLhsoR" type="NBTpmTxZCmcb" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the SNR.
+@param snr_value SNR value in dB
+@return bool" isSpecification="false" isLeaf="false" visibility="public" xmi.id="BSaEFiqHsNgS" isRoot="false" isAbstract="false" isQuery="false" name="setSnr" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="joBDZT01YfrL" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="3pvwRBD9e8ke" value="" type="mXu6MdkX4QlH" name="snr_value" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets the tonemap of the current transmission.
+@return bool
+@param tonemap_array the new value of mTonemapArray" isSpecification="false" isLeaf="false" visibility="public" xmi.id="dzYH8IvKHpvW" isRoot="false" isAbstract="false" isQuery="false" name="setTonemap" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="JPU6YuRFdF5f" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="OvxQVcfl5Duw" value="" type="zypnSFDYKlG8" name="tonemap_array[]" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Sets if the channel is configured.
+@param is_configured the new value of mIsConfigured
+@return bool" isSpecification="false" isLeaf="false" visibility="private" xmi.id="w6NMjCexlRoY" isRoot="false" isAbstract="false" isQuery="false" name="setIsConfigured" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="beyIWmjGbtR8" type="txbVRO36HpfQ" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="0MvEx1tWQRx1" value="" type="NBTpmTxZCmcb" name="is_configured" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Gets the time interval.
+@param symbol_start_date the current symbol start date in ticks
+@return the interval number" isSpecification="false" isLeaf="false" visibility="private" xmi.id="Z1yyRvzefObL" isRoot="false" isAbstract="false" isQuery="false" name="getInterval" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="KS7s5wEPMgTu" type="1XretJvqfug3" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="4QwoboIxLg3I" value="" type="oL4FZe2AHfNk" name="beacon_period" />
+ <UML:Parameter isSpecification="false" visibility="private" xmi.id="rgELEMnmNlko" value="" type="oL4FZe2AHfNk" name="symbol_start_date" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ </UML:Namespace.ownedElement>
+ <XMI.extension xmi.extender="umbrello" >
+ <diagrams>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="894" snapy="10" showatts="1" xmi.id="gixkluDaZdUp" documentation="" type="1" showops="1" showpackage="1" name="class diagram channel computer" localid="" showstereotype="1" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="912" >
+ <widgets>
+ <classwidget usesdiagramfillcolor="0" width="314" showattsigs="601" x="125" fillcolor="#ffffc0" y="350" showopsigs="600" linewidth="none" height="558" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="FA5tCgQO5jOX" showoperations="1" showpackage="1" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+ <classwidget usesdiagramfillcolor="0" width="182" showattsigs="601" x="184" fillcolor="#ffffc0" y="27" showopsigs="600" linewidth="none" height="261" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="MJNkMwYhFv8H" showoperations="1" showpackage="1" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,50,1,0,0,0,0" linecolor="#ff0000" />
+ </widgets>
+ <messages/>
+ <associations>
+ <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="MJNkMwYhFv8H" widgetaid="FA5tCgQO5jOX" xmi.id="guI259xtgWxy" linecolor="none" >
+ <linepath>
+ <startpoint startx="218" starty="350" />
+ <endpoint endx="218" endy="288" />
+ </linepath>
+ </assocwidget>
+ </associations>
+ </diagram>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="910" snapy="10" showatts="1" xmi.id="qdI3cPCM6cK0" documentation="" type="3" showops="1" showpackage="1" name="sequence diagram global" localid="7JggHOMZzMnz" showstereotype="1" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="824" >
+ <widgets>
+ <objectwidget usesdiagramfillcolor="0" width="143" x="337" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="ka695HsLyRqa" decon="0" localid="apCSEDC2oS6O" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="111" x="73" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="rGkvr2wbb0ig" decon="0" localid="Ia2G2qocfz2t" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="103" x="696" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="ACuye0MTG4P7" decon="0" localid="7JggHOMZzMnz" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <notewidget usesdiagramfillcolor="1" width="188" x="209" fillcolor="none" y="575" linewidth="none" height="50" usefillcolor="1" isinstance="0" xmi.id="IStaETkdi0j5" showstereotype="1" text="pb_measurement is empty" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="188" x="530" fillcolor="none" y="576" linewidth="none" height="50" usefillcolor="1" isinstance="0" xmi.id="srWZhXyIrLIM" showstereotype="1" text="pb_measurement is filled in" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="233" x="425" fillcolor="none" y="146" linewidth="none" height="71" usefillcolor="1" isinstance="0" xmi.id="tM9tcbkDpExS" showstereotype="1" text="Tonemask is described on 1155 carriers. It is sent once at program start." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="300" x="425" fillcolor="none" y="430" linewidth="none" height="97" usefillcolor="1" isinstance="0" xmi.id="NCpDY8ZPSiH5" showstereotype="1" text="Tonemap is described on 1155 carriers. It is sent before each TX using the TM.
+For TX in ROBO mode, Maximus should know which modulation to applied." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="191" x="532" fillcolor="none" y="671" linewidth="none" height="50" usefillcolor="1" isinstance="0" xmi.id="vgNaXDp4Y1sl" showstereotype="1" text="with time noise and frequency noise" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </widgets>
+ <messages>
+ <messagewidget usesdiagramfillcolor="1" width="278" x="129" fillcolor="none" y="173" operation="phy msg (TONEMASK)" linewidth="none" widgetbid="apCSEDC2oS6O" height="8" usefillcolor="1" seqnum="1" textid="Z3so7HtCYasq" widgetaid="Ia2G2qocfz2t" isinstance="0" xmi.id="AcZqbchlobhR" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="165" x="147" fillcolor="none" y="151" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="Z3so7HtCYasq" text="1: phy msg (TONEMASK)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="278" x="129" fillcolor="none" y="274" operation="phy msg (PREAMBLE)" linewidth="none" widgetbid="apCSEDC2oS6O" height="8" usefillcolor="1" seqnum="2" textid="D5opmFOp8CuN" widgetaid="Ia2G2qocfz2t" isinstance="0" xmi.id="DPvXBuinSYM2" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="161" x="186" fillcolor="none" y="252" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="D5opmFOp8CuN" showstereotype="1" text="2: phy msg (PREAMBLE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="337" x="409" fillcolor="none" y="307" operation="phy msg (PREAMBLE)" linewidth="none" widgetbid="7JggHOMZzMnz" height="8" usefillcolor="1" seqnum="2.1" textid="QS5qyPsBUhyG" widgetaid="apCSEDC2oS6O" isinstance="0" xmi.id="67uezkcC7YkI" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="173" x="414" fillcolor="none" y="285" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="QS5qyPsBUhyG" showstereotype="1" text="2.1: phy msg (PREAMBLE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="278" x="129" fillcolor="none" y="355" operation="phy msg (FC_AV_ONLY_MODE)" linewidth="none" widgetbid="apCSEDC2oS6O" height="8" usefillcolor="1" seqnum="3" textid="Oj3B4SmNHDpb" widgetaid="Ia2G2qocfz2t" isinstance="0" xmi.id="JXLvabAdZ2of" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="221" x="147" fillcolor="none" y="333" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="Oj3B4SmNHDpb" showstereotype="1" text="3: phy msg (FC_AV_ONLY_MODE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="337" x="409" fillcolor="none" y="396" operation="phy msg (FC_AV_ONLY_MODE)" linewidth="none" widgetbid="7JggHOMZzMnz" height="8" usefillcolor="1" seqnum="3.1" textid="JPNrQBWmuXvy" widgetaid="apCSEDC2oS6O" isinstance="0" xmi.id="ME7N0gMKEiFm" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="233" x="414" fillcolor="none" y="374" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="JPNrQBWmuXvy" showstereotype="1" text="3.1: phy msg (FC_AV_ONLY_MODE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="278" x="129" fillcolor="none" y="563" operation="phy msg (MPDU_PAYLOAD)" linewidth="none" widgetbid="apCSEDC2oS6O" height="8" usefillcolor="1" seqnum="5" textid="e9HR1oM0j2Jy" widgetaid="Ia2G2qocfz2t" isinstance="0" xmi.id="MdygpgtayGxn" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="199" x="147" fillcolor="none" y="541" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="e9HR1oM0j2Jy" text="5: phy msg (MPDU_PAYLOAD)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="337" x="409" fillcolor="none" y="563" operation="phy msg (MPDU_PAYLOAD)" linewidth="none" widgetbid="7JggHOMZzMnz" height="8" usefillcolor="1" seqnum="5.1" textid="LbiJre4UlLvm" widgetaid="apCSEDC2oS6O" isinstance="0" xmi.id="vOm8kjk4Lgi8" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="211" x="414" fillcolor="none" y="541" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="LbiJre4UlLvm" text="5.1: phy msg (MPDU_PAYLOAD)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="337" x="409" fillcolor="none" y="657" operation="phy msg (NOISE)" linewidth="none" widgetbid="7JggHOMZzMnz" height="8" usefillcolor="1" seqnum="5.2" textid="JyEcfwiyVPFL" widgetaid="apCSEDC2oS6O" isinstance="0" xmi.id="7FkqF2p8QbGA" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="145" x="461" fillcolor="none" y="635" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="JyEcfwiyVPFL" text="5.2: phy msg (NOISE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="278" x="129" fillcolor="none" y="475" operation="phy msg (TONEMAP)" linewidth="none" widgetbid="apCSEDC2oS6O" height="8" usefillcolor="1" seqnum="4" textid="LOJl0YuHU6t9" widgetaid="Ia2G2qocfz2t" isinstance="0" xmi.id="3JpoeiYlxJbB" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="156" x="134" fillcolor="none" y="453" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="LOJl0YuHU6t9" text="4: phy msg (TONEMAP)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ </messages>
+ <associations/>
+ </diagram>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1458" snapy="10" showatts="1" xmi.id="X42GTN9PoAyH" documentation="" type="3" showops="1" showpackage="1" name="sequence diagram maximus" localid="iG3Nps5Lu2Mn" showstereotype="1" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="1641" >
+ <widgets>
+ <objectwidget usesdiagramfillcolor="0" width="111" x="19" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="rGkvr2wbb0ig" decon="0" localid="3DAVyBoln7OB" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="87" x="213" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="t1tc2bTZdTo7" decon="0" localid="pvUd5Su7d2cZ" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="114" x="554" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="EPI1UgANf3xg" decon="0" localid="dODGr1LexpH0" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="142" x="699" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="FA5tCgQO5jOX" decon="0" localid="NYu3arhDDuR4" multipleinstance="0" drawasactor="0" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="103" x="1139" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="ACuye0MTG4P7" decon="0" localid="unhpayno6tfH" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="104" x="387" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="y0Zndhh8NjGq" decon="0" localid="niFReFLgyuZm" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="57" x="1271" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="ouQgLFbCZBH6" decon="0" localid="asRxXJUOaOs0" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <notewidget usesdiagramfillcolor="1" width="234" x="582" fillcolor="none" y="344" linewidth="none" height="71" usefillcolor="1" isinstance="0" xmi.id="h94z0oip6zcC" showstereotype="1" text="if already set by another station, return an error if a different tonemask is received" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <objectwidget usesdiagramfillcolor="0" width="127" x="916" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="PGF0sP6Kgb0l" decon="0" localid="iG3Nps5Lu2Mn" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <notewidget usesdiagramfillcolor="1" width="233" x="45" fillcolor="none" y="138" linewidth="none" height="71" usefillcolor="1" isinstance="0" xmi.id="XNhoyoP1qY7e" showstereotype="1" text="Tonemask is described on 1155 carriers. It is sent once at program start." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="300" x="20" fillcolor="none" y="939" linewidth="none" height="97" usefillcolor="1" isinstance="0" xmi.id="hqoOxdLglCpc" showstereotype="1" text="Tonemap is described on 1155 carriers. It is sent before each TX using the TM.
+For TX in ROBO mode, Maximus should know which modulation to applied." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </widgets>
+ <messages>
+ <messagewidget usesdiagramfillcolor="1" width="180" x="75" fillcolor="none" y="238" operation="PHY msg (TONEMASK)" linewidth="none" widgetbid="pvUd5Su7d2cZ" height="8" usefillcolor="1" seqnum="1" textid="qsL3mm5gXkV8" widgetaid="3DAVyBoln7OB" isinstance="0" xmi.id="X5fao37AazDA" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="167" x="84" fillcolor="none" y="216" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="qsL3mm5gXkV8" text="1: PHY msg (TONEMASK)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="180" x="75" fillcolor="none" y="399" operation="PHY msg (PREAMBLE)" linewidth="none" widgetbid="pvUd5Su7d2cZ" height="8" usefillcolor="1" seqnum="2" textid="V0qCm3Vi3FWN" widgetaid="3DAVyBoln7OB" isinstance="0" xmi.id="rrJ9iTwEnK49" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="163" x="80" fillcolor="none" y="377" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="V0qCm3Vi3FWN" text="2: PHY msg (PREAMBLE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="180" x="75" fillcolor="none" y="1066" operation="PHY msg (TONEMAP)" linewidth="none" widgetbid="pvUd5Su7d2cZ" height="8" usefillcolor="1" seqnum="4" textid="ftRXfy3geebu" widgetaid="3DAVyBoln7OB" isinstance="0" xmi.id="L3omNKIOraEr" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="163" x="88" fillcolor="none" y="1044" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="ftRXfy3geebu" text="4: PHY msg (TONEMAP)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="181" x="257" fillcolor="none" y="265" operation="dispatch msg ()" linewidth="none" widgetbid="niFReFLgyuZm" height="8" usefillcolor="1" seqnum="1.1" textid="vCCIjlQ6bD0S" widgetaid="pvUd5Su7d2cZ" isinstance="0" xmi.id="b208fWbLMhyw" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="136" x="298" fillcolor="none" y="243" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="vCCIjlQ6bD0S" text="1.1: dispatch msg ()" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="181" x="257" fillcolor="none" y="440" operation="dispatch msg ()" linewidth="none" widgetbid="niFReFLgyuZm" height="8" usefillcolor="1" seqnum="2.1" textid="XFjtxfoqsy9Z" widgetaid="pvUd5Su7d2cZ" isinstance="0" xmi.id="aTS6yi3Xk1eQ" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="136" x="294" fillcolor="none" y="418" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="XFjtxfoqsy9Z" showstereotype="1" text="2.1: dispatch msg ()" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="181" x="257" fillcolor="none" y="678" operation="dispatch msg()" linewidth="none" widgetbid="niFReFLgyuZm" height="8" usefillcolor="1" seqnum="3.1" textid="qUaZVCx0SgsN" widgetaid="pvUd5Su7d2cZ" isinstance="0" xmi.id="jZfIndiL78R3" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="132" x="262" fillcolor="none" y="656" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="qUaZVCx0SgsN" text="3.1: dispatch msg()" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="170" x="440" fillcolor="none" y="302" operation="receive tonemask (PHY SCI msg)" linewidth="none" widgetbid="dODGr1LexpH0" height="8" usefillcolor="1" seqnum="1.2" textid="2Iy7RQAFsjoO" widgetaid="niFReFLgyuZm" isinstance="0" xmi.id="MgDCcKlJsPcd" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="250" x="445" fillcolor="none" y="280" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="2Iy7RQAFsjoO" text="1.2: receive tonemask (PHY SCI msg)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="170" x="440" fillcolor="none" y="464" operation="receive preamble (PHY SCI msg)" linewidth="none" widgetbid="dODGr1LexpH0" height="8" usefillcolor="1" seqnum="2.2" textid="Cho46Of7eeE3" widgetaid="niFReFLgyuZm" isinstance="0" xmi.id="vjMLQEgkuswU" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="244" x="445" fillcolor="none" y="442" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="Cho46Of7eeE3" text="2.2: receive preamble (PHY SCI msg)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="170" x="440" fillcolor="none" y="1140" operation="receive tonemap (PHY SCI msg)" linewidth="none" widgetbid="dODGr1LexpH0" height="8" usefillcolor="1" seqnum="4.2" textid="bMkg1Os4QFLK" widgetaid="niFReFLgyuZm" isinstance="0" xmi.id="DtzvmrpE2W04" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="243" x="445" fillcolor="none" y="1118" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="bMkg1Os4QFLK" text="4.2: receive tonemap (PHY SCI msg)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="353" x="257" fillcolor="none" y="534" operation="send msg (PHY SCI msg)" linewidth="none" widgetbid="pvUd5Su7d2cZ" height="8" usefillcolor="1" seqnum="2.5" textid="5zkAU00p74Ai" widgetaid="dODGr1LexpH0" isinstance="0" xmi.id="VhUvuoGCBrRN" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="195" x="281" fillcolor="none" y="512" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="5zkAU00p74Ai" text="2.5: send msg (PHY SCI msg)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="932" x="257" fillcolor="none" y="579" operation="PHY msg (PREAMBLE)" linewidth="none" widgetbid="unhpayno6tfH" height="8" usefillcolor="1" seqnum="2.6" textid="JSR9XTHDZt45" widgetaid="pvUd5Su7d2cZ" isinstance="0" xmi.id="HCOTNDukIrSR" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="175" x="267" fillcolor="none" y="557" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="JSR9XTHDZt45" showstereotype="1" text="2.6: PHY msg (PREAMBLE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="180" x="75" fillcolor="none" y="646" operation="PHY msg (FC_AV_ONLY_MODE)" linewidth="none" widgetbid="pvUd5Su7d2cZ" height="8" usefillcolor="1" seqnum="3" textid="Zhw6ADKj5Mog" widgetaid="3DAVyBoln7OB" isinstance="0" xmi.id="cNozaghrV7Ip" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="223" x="80" fillcolor="none" y="624" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="Zhw6ADKj5Mog" showstereotype="1" text="3: PHY msg (FC_AV_ONLY_MODE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="181" x="257" fillcolor="none" y="1106" operation="dispatch msg ()" linewidth="none" widgetbid="niFReFLgyuZm" height="8" usefillcolor="1" seqnum="4.1" textid="w2PIwyZ3QrjY" widgetaid="pvUd5Su7d2cZ" isinstance="0" xmi.id="wVhd8YYauIE1" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="136" x="262" fillcolor="none" y="1084" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="w2PIwyZ3QrjY" text="4.1: dispatch msg ()" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="170" x="440" fillcolor="none" y="708" operation="receive FC (PHY SCI msg)" linewidth="none" widgetbid="dODGr1LexpH0" height="8" usefillcolor="1" seqnum="3.2" textid="t41nKGpFICXC" widgetaid="niFReFLgyuZm" isinstance="0" xmi.id="t8guysgvLNWT" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="198" x="445" fillcolor="none" y="686" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="t41nKGpFICXC" showstereotype="1" text="3.2: receive FC (PHY SCI msg)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="353" x="257" fillcolor="none" y="807" operation="send msg (PHY SCI msg)" linewidth="none" widgetbid="pvUd5Su7d2cZ" height="8" usefillcolor="1" seqnum="3.5" textid="H8EMrtQSCMPt" widgetaid="dODGr1LexpH0" isinstance="0" xmi.id="gA4wMZ8UbL3U" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="195" x="281" fillcolor="none" y="785" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="H8EMrtQSCMPt" text="3.5: send msg (PHY SCI msg)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="932" x="257" fillcolor="none" y="854" operation="PHY msg (FC_AV_ONLY_MODE)" linewidth="none" widgetbid="unhpayno6tfH" height="8" usefillcolor="1" seqnum="3.6" textid="dwoCHpgWvvtm" widgetaid="pvUd5Su7d2cZ" isinstance="0" xmi.id="noTHEo4uz6oJ" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="235" x="268" fillcolor="none" y="832" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="dwoCHpgWvvtm" showstereotype="1" text="3.6: PHY msg (FC_AV_ONLY_MODE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="180" x="75" fillcolor="none" y="1254" operation="PHY msg (MPDU_PAYLOAD)" linewidth="none" widgetbid="pvUd5Su7d2cZ" height="8" usefillcolor="1" seqnum="5" textid="8ZTvFzq8qat5" widgetaid="3DAVyBoln7OB" isinstance="0" xmi.id="Jcc5gU2lIMMC" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="201" x="80" fillcolor="none" y="1232" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="8ZTvFzq8qat5" showstereotype="1" text="5: PHY msg (MPDU_PAYLOAD)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="181" x="257" fillcolor="none" y="1288" operation="dispatch msg ()" linewidth="none" widgetbid="niFReFLgyuZm" height="8" usefillcolor="1" seqnum="5.1" textid="m532RPEXyfSC" widgetaid="pvUd5Su7d2cZ" isinstance="0" xmi.id="mshMg3kzdK2I" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="136" x="262" fillcolor="none" y="1266" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="m532RPEXyfSC" text="5.1: dispatch msg ()" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="170" x="440" fillcolor="none" y="1322" operation="receive MPDU (PHY SCI msg)" linewidth="none" widgetbid="dODGr1LexpH0" height="8" usefillcolor="1" seqnum="5.2" textid="Fhet2hBmkEp9" widgetaid="niFReFLgyuZm" isinstance="0" xmi.id="fIITsBZc1Ezh" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="221" x="445" fillcolor="none" y="1300" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="Fhet2hBmkEp9" text="5.2: receive MPDU (PHY SCI msg)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="353" x="257" fillcolor="none" y="1453" operation="send msg (PHY SCI msg)" linewidth="none" widgetbid="pvUd5Su7d2cZ" height="8" usefillcolor="1" seqnum="5.4" textid="o7lnxzqaHK2w" widgetaid="dODGr1LexpH0" isinstance="0" xmi.id="c6xYdiuSYlEe" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="195" x="262" fillcolor="none" y="1431" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="o7lnxzqaHK2w" text="5.4: send msg (PHY SCI msg)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="932" x="257" fillcolor="none" y="1511" operation="PHY msg (MPDU_PAYLOAD)" linewidth="none" widgetbid="unhpayno6tfH" height="8" usefillcolor="1" seqnum="5.5" textid="hjoGU2uH7d22" widgetaid="pvUd5Su7d2cZ" isinstance="0" xmi.id="LOpngd6Ij1oM" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="213" x="262" fillcolor="none" y="1489" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="hjoGU2uH7d22" text="5.5: PHY msg (MPDU_PAYLOAD)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="353" x="257" fillcolor="none" y="1566" operation="send msg (PHY SCI msg)" linewidth="none" widgetbid="pvUd5Su7d2cZ" height="8" usefillcolor="1" seqnum="5.6" textid="QWcGEsXpz2YD" widgetaid="dODGr1LexpH0" isinstance="0" xmi.id="Pf6r4QIR7pB6" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="203" x="262" fillcolor="none" y="1544" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="QWcGEsXpz2YD" text="5.6: send msg (PHY SCI msg)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="932" x="257" fillcolor="none" y="1609" operation="PHY msg (NOISE)" linewidth="none" widgetbid="unhpayno6tfH" height="8" usefillcolor="1" seqnum="5.7" textid="mdfrSqxrKZ5Y" widgetaid="pvUd5Su7d2cZ" isinstance="0" xmi.id="GRMb9VGWBMND" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="155" x="262" fillcolor="none" y="1587" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="mdfrSqxrKZ5Y" text="5.7: PHY msg (NOISE)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="157" x="612" fillcolor="none" y="1171" operation="BALxxO2awYCA" linewidth="none" widgetbid="NYu3arhDDuR4" height="8" usefillcolor="1" seqnum="4.3" textid="FsdpD1lAYuX2" widgetaid="dODGr1LexpH0" isinstance="0" xmi.id="6tGl6PP1piEa" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="837" x="617" fillcolor="none" y="1149" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="FsdpD1lAYuX2" text="4.3: setTonemap(tx_station_id : const Sci_Msg_Station_Id, length : const unsigned long, p_tonemap : const unsigned char*) : bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="157" x="612" fillcolor="none" y="332" operation="fYXdFW0u7v45" linewidth="none" widgetbid="NYu3arhDDuR4" height="8" usefillcolor="1" seqnum="1.3" textid="oyH4FIsmjMnd" widgetaid="dODGr1LexpH0" isinstance="0" xmi.id="0ea9mnvPOz8D" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="352" x="617" fillcolor="none" y="310" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="oyH4FIsmjMnd" text="1.3: setTonemask(p_tonemask : const uint8_t*) : bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="157" x="612" fillcolor="none" y="494" operation="qrweJyXfPgQH" linewidth="none" widgetbid="NYu3arhDDuR4" height="8" usefillcolor="1" seqnum="2.3" textid="FmRal8d0mKsL" widgetaid="dODGr1LexpH0" isinstance="0" xmi.id="q7x8JGpaGYcr" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="665" x="617" fillcolor="none" y="472" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="FmRal8d0mKsL" showstereotype="1" text="2.3: receivePre(tx_station_id : const Sci_Msg_Station_Id, current_tick : const Network_Clock_Tick) : bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="157" x="612" fillcolor="none" y="745" operation="OS6l8U35hW6C" linewidth="none" widgetbid="NYu3arhDDuR4" height="8" usefillcolor="1" seqnum="3.3" textid="9WbSBVHWt1w6" widgetaid="dODGr1LexpH0" isinstance="0" xmi.id="VgNj3rHVA6es" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="658" x="617" fillcolor="none" y="723" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="9WbSBVHWt1w6" showstereotype="1" text="3.3: receiveFc(tx_station_id : const Sci_Msg_Station_Id, current_tick : const Network_Clock_Tick) : bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="207" x="771" fillcolor="none" y="785" operation="rJ3xOwjhyyGc" linewidth="none" widgetbid="iG3Nps5Lu2Mn" height="8" usefillcolor="1" seqnum="3.4" textid="fEktuJp4hoN5" widgetaid="NYu3arhDDuR4" isinstance="0" xmi.id="C9q4zpJcLPes" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="417" x="776" fillcolor="none" y="763" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="fEktuJp4hoN5" showstereotype="1" text="3.4: setFcReceptionDate(date : const Network_Clock_Tick) : bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="207" x="771" fillcolor="none" y="515" operation="CRgGs5fVq86t" linewidth="none" widgetbid="iG3Nps5Lu2Mn" height="8" usefillcolor="1" seqnum="2.4" textid="hzPrvJoRRWSV" widgetaid="NYu3arhDDuR4" isinstance="0" xmi.id="m59xDlN772zf" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="423" x="776" fillcolor="none" y="493" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="hzPrvJoRRWSV" showstereotype="1" text="2.4: setPreDetectionDate(date : const Network_Clock_Tick) : bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="318" x="980" fillcolor="none" y="162" operation="N1iX9W91mjbs" linewidth="none" widgetbid="iG3Nps5Lu2Mn" height="8" usefillcolor="1" seqnum="0" textid="69FbMxXh4qus" widgetaid="asRxXJUOaOs0" isinstance="0" xmi.id="o91EgffKrvqF" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="423" x="985" fillcolor="none" y="140" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="69FbMxXh4qus" text="0: setSnr(snr : const float[interval_nb][PHY_CARRIER_MAX_NB])" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="157" x="612" fillcolor="none" y="1362" operation="addPerturbation()" linewidth="none" widgetbid="NYu3arhDDuR4" height="8" usefillcolor="1" seqnum="5.3" textid="ZwsIbgkqlGwo" widgetaid="dODGr1LexpH0" isinstance="0" xmi.id="mkSrDPCjpToZ" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="149" x="617" fillcolor="none" y="1340" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="ZwsIbgkqlGwo" showstereotype="1" text="5.3: addPerturbation()" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="207" x="771" fillcolor="none" y="1209" operation="dzYH8IvKHpvW" linewidth="none" widgetbid="iG3Nps5Lu2Mn" height="8" usefillcolor="1" seqnum="" textid="brWHhG3EgPgP" widgetaid="NYu3arhDDuR4" isinstance="0" xmi.id="VBUTLWqLNO3T" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="390" x="776" fillcolor="none" y="1187" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="brWHhG3EgPgP" showstereotype="1" text=": setTonemap(tonemap_array[] : const Channel_Mod) : bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ </messages>
+ <associations/>
+ </diagram>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1882" snapy="10" showatts="1" xmi.id="wHQW0owEmBOE" documentation="" type="3" showops="1" showpackage="1" name="sequence diagram channel" localid="g4uHNUZyzX5B" showstereotype="1" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="1271" >
+ <widgets>
+ <objectwidget usesdiagramfillcolor="0" width="114" x="25" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="EPI1UgANf3xg" decon="0" localid="JSGw5HTuusup" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="138" x="251" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="FA5tCgQO5jOX" decon="0" localid="u4Vw6zChn0FB" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="127" x="544" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="PGF0sP6Kgb0l" decon="0" localid="VcHEp6yBGZmE" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <notewidget usesdiagramfillcolor="1" width="167" x="1063" fillcolor="none" y="847" linewidth="none" height="50" usefillcolor="1" isinstance="0" xmi.id="HOSEWhecreBb" showstereotype="1" text="for P2 coordinates" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="151" x="961" fillcolor="none" y="763" linewidth="none" height="76" usefillcolor="1" isinstance="0" xmi.id="fokHPWTHSe6Q" showstereotype="1" text="get the P0 coordinates from the code C0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="165" x="1386" fillcolor="none" y="871" linewidth="none" height="77" usefillcolor="1" isinstance="0" xmi.id="4xzip5SwM7Ck" showstereotype="1" text="get the code C2 from the P2 coordinates" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="275" x="28" fillcolor="none" y="308" linewidth="none" height="60" usefillcolor="1" isinstance="0" xmi.id="r571dUJXBSUA" showstereotype="1" text="Do actions 1 to 13 for each carrier of each symbol" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="135" x="172" fillcolor="none" y="1153" linewidth="none" height="81" usefillcolor="1" isinstance="0" xmi.id="L6D0iIcPJ49O" showstereotype="1" text="Do actions 14 and 15 at the end of each PB" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <objectwidget usesdiagramfillcolor="0" width="192" x="855" fillcolor="#ffffc0" y="48" instancename="mapping0" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="HjupUSYowhI4" decon="0" localid="a8y22aDmxi4S" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="192" x="1139" fillcolor="#ffffc0" y="48" instancename="mapping1" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="HjupUSYowhI4" decon="0" localid="PNVizgbJacYd" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="192" x="1467" fillcolor="#ffffc0" y="48" instancename="mapping2" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="HjupUSYowhI4" decon="0" localid="ui3PEJBmn8rj" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ </widgets>
+ <messages>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="321" fillcolor="none" y="687" operation="z7iRgeJqCCrj" linewidth="none" widgetbid="u4Vw6zChn0FB" height="32" usefillcolor="1" seqnum="6" textid="uYaEkn1fsPxQ" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="9QRr8oHrIyOQ" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="547" x="326" fillcolor="none" y="665" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="uYaEkn1fsPxQ" showstereotype="1" text="6: getSigma(modulation : const Channel_Mod, snr_in_db : const float) : const double" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="285" x="321" fillcolor="none" y="578" operation="M3QGTU7iw8dM" linewidth="none" widgetbid="VcHEp6yBGZmE" height="8" usefillcolor="1" seqnum="4" textid="fJs8zIVwsUpx" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="jRTpUCUaTrp5" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="518" x="326" fillcolor="none" y="556" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="fJs8zIVwsUpx" text="4: getModulation(carrier : const unsigned int) : const Channel_Mod" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="321" fillcolor="none" y="506" operation="P3rRYhqHMh6s" linewidth="none" widgetbid="u4Vw6zChn0FB" height="32" usefillcolor="1" seqnum="3" textid="4S9x0L8wK3Te" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="muSfiL1vGzl3" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="350" x="326" fillcolor="none" y="484" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="4S9x0L8wK3Te" showstereotype="1" text="3: getLinearSnr(snr_in_db : const float) : const double" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="321" fillcolor="none" y="627" operation="jfqqWYV4W41s" linewidth="none" widgetbid="u4Vw6zChn0FB" height="32" usefillcolor="1" seqnum="5" textid="WtHx3BbQh5q4" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="IrO6a4kn04VS" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="416" x="326" fillcolor="none" y="605" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="WtHx3BbQh5q4" showstereotype="1" text="5: getPowerScale(modulation : const Channel_Mod) : const float" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="321" fillcolor="none" y="182" operation="09RFjqmd0dax" linewidth="none" widgetbid="u4Vw6zChn0FB" height="32" usefillcolor="1" seqnum="0.1" textid="jq17ZjwGkSkg" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="HOn0jC4IxHwb" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="1113" x="326" fillcolor="none" y="160" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="jq17ZjwGkSkg" text="0.1: findChannelSettings(tx_station_id : const Sci_Msg_Station_Id, rx_station_id : const Sci_Msg_Station_Id, both_directions : const bool) : std::vector&lt; ChannelSettings * >&amp;" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="236" x="83" fillcolor="none" y="130" operation="LRN0s3UGfAwm" linewidth="none" widgetbid="u4Vw6zChn0FB" height="8" usefillcolor="1" seqnum="0" textid="yJ8aftxYwuoW" widgetaid="JSGw5HTuusup" isinstance="0" xmi.id="vYaZ8E857Uzs" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="1790" x="88" fillcolor="none" y="108" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="yJ8aftxYwuoW" text="0: addPerturbation(pb_measurement_array : uint32_t*, noise : PhySciMsgNoise&amp;, pb_header_array : const uint32_t*, mpdu : const PhySciMsgMpdu&amp;, tx_station_id : const Sci_Msg_Station_Id, rx_station_id : const Sci_Msg_Station_Id, current_tick : const Network_Clock_Tick) : bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="285" x="321" fillcolor="none" y="247" operation="dWaTBSKgoPJ3" linewidth="none" widgetbid="VcHEp6yBGZmE" height="8" usefillcolor="1" seqnum="0.2" textid="GZIM315LGZEW" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="7Gbh73pmyjD4" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="380" x="326" fillcolor="none" y="225" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="GZIM315LGZEW" showstereotype="1" text="0.2: getFirstSymbolStartDate() : const Network_Clock_Tick" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="629" x="321" fillcolor="none" y="758" operation="rCiZ34ts7WOo" linewidth="none" widgetbid="a8y22aDmxi4S" height="8" usefillcolor="1" seqnum="7" textid="mpdOyViWiQTz" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="NPrLTDPM1My6" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="1076" x="326" fillcolor="none" y="736" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="mpdOyViWiQTz" showstereotype="1" text="7: setCode(modulation : const Channel_Mod, mpdu_payload_length : const unsigned long, p_mpdu_payload : const unsigned char*, mpdu_index : unsigned int&amp;) : bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="629" x="321" fillcolor="none" y="802" operation="nowhba6bZwOz" linewidth="none" widgetbid="a8y22aDmxi4S" height="8" usefillcolor="1" seqnum="8" textid="NZDmZTbnQy08" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="9YVTK9l70IqV" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="478" x="326" fillcolor="none" y="780" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="NZDmZTbnQy08" text="8: computePoint(modulation : const Channel_Mod) : const ChannelPoint&amp;" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="321" fillcolor="none" y="844" operation="jyRgGnpfqf5M" linewidth="none" widgetbid="u4Vw6zChn0FB" height="32" usefillcolor="1" seqnum="9" textid="X8sw5uavM44a" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="u7dxbPK1G8Yu" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="548" x="326" fillcolor="none" y="822" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="X8sw5uavM44a" text="9: addNoise(point : const ChannelPoint&amp;, sigma : const double) : const ChannelPoint" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="913" x="321" fillcolor="none" y="899" operation="o3dYjumm81LP" linewidth="none" widgetbid="PNVizgbJacYd" height="8" usefillcolor="1" seqnum="10" textid="TviPGPMNGWmm" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="AboEaCBFVTRe" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="467" x="326" fillcolor="none" y="877" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="TviPGPMNGWmm" text="10: retrievePoint(modulation : const Channel_Mod) : const ChannelPoint" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="1241" x="321" fillcolor="none" y="952" operation="66Ykoo2IT5gA" linewidth="none" widgetbid="ui3PEJBmn8rj" height="8" usefillcolor="1" seqnum="11" textid="nuZRxZVATbii" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="BEczhLNQKErc" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="507" x="326" fillcolor="none" y="930" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="nuZRxZVATbii" showstereotype="1" text="11: computeCode(modulation : const Channel_Mod) : const unsigned short int" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="321" fillcolor="none" y="999" operation="XOXms3hJA084" linewidth="none" widgetbid="u4Vw6zChn0FB" height="32" usefillcolor="1" seqnum="12" textid="g4GGNIBXMiNb" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="ltqm7OE0pjjp" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="707" x="326" fillcolor="none" y="977" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="g4GGNIBXMiNb" showstereotype="1" text="12: computeBer(codeA : const unsigned short int, codeB : const unsigned short int) : const unsigned short int" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="321" fillcolor="none" y="1155" operation="o0LrX74wtWDl" linewidth="none" widgetbid="u4Vw6zChn0FB" height="32" usefillcolor="1" seqnum="14" textid="NQHoDpzJblzE" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="p9IvJtNiyBIa" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="747" x="326" fillcolor="none" y="1133" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="NQHoDpzJblzE" text="14: computeFer(ber : const unsigned short int, n : const unsigned int, modulation : const Channel_Mod) : const float" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="321" fillcolor="none" y="1215" operation="wAYHYS5t16DH" linewidth="none" widgetbid="u4Vw6zChn0FB" height="32" usefillcolor="1" seqnum="15" textid="5fcFCtaBtUj2" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="QtHPrgMs3A6u" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="325" x="326" fillcolor="none" y="1193" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="5fcFCtaBtUj2" showstereotype="1" text="15: computeCrcError(fer : const float) : const bool" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="321" fillcolor="none" y="1070" operation="k41t27vK3XoF" linewidth="none" widgetbid="u4Vw6zChn0FB" height="32" usefillcolor="1" seqnum="13" textid="RzzRQLxjTpPs" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="pe8kGhrJKg63" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="646" x="326" fillcolor="none" y="1048" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="RzzRQLxjTpPs" text="13: computeNoise(pointA : const ChannelPoint&amp;, pointB : const ChannelPoint&amp;) : const unsigned int" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="285" x="321" fillcolor="none" y="393" operation="AB0zYJ2vLR9m" linewidth="none" widgetbid="VcHEp6yBGZmE" height="8" usefillcolor="1" seqnum="1" textid="tYOTbc6noQuY" widgetaid="u4Vw6zChn0FB" isinstance="0" xmi.id="ncXBJkvSItqN" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="905" x="326" fillcolor="none" y="371" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="tYOTbc6noQuY" text="1: getSnr(beacon_period : const Network_Clock_Tick, symbol_start_date : const Network_Clock_Tick, carrier : const unsigned int) : const float" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="608" fillcolor="none" y="437" operation="Z1yyRvzefObL" linewidth="none" widgetbid="VcHEp6yBGZmE" height="32" usefillcolor="1" seqnum="2" textid="KgciLhLFiQt2" widgetaid="VcHEp6yBGZmE" isinstance="0" xmi.id="kPRSVvRUyNkh" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="802" x="613" fillcolor="none" y="415" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="KgciLhLFiQt2" showstereotype="1" text="2: getInterval(beacon_period : const Network_Clock_Tick, symbol_start_date : const Network_Clock_Tick) : const unsigned int" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ </messages>
+ <associations/>
+ </diagram>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1340" snapy="10" showatts="1" xmi.id="NdBn9ALHuRov" documentation="" type="3" showops="1" showpackage="1" name="sequence diagram phy" localid="vTN4WfHZyzzP" showstereotype="1" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="808" >
+ <widgets>
+ <objectwidget usesdiagramfillcolor="0" width="145" x="742" fillcolor="#ffffc0" y="48" instancename="sta_Rx" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="ACuye0MTG4P7" decon="0" localid="TEq0CDwjmGJP" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="152" x="73" fillcolor="#ffffc0" y="48" instancename="sta_Tx" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="rGkvr2wbb0ig" decon="0" localid="wsGISdwu93Fw" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="143" x="422" fillcolor="#ffffc0" y="48" instancename="" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="ka695HsLyRqa" decon="0" localid="UzpajIea0XQC" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <objectwidget usesdiagramfillcolor="0" width="123" x="999" fillcolor="#ffffc0" y="48" instancename="sta" linewidth="none" height="28" usefillcolor="1" isinstance="0" xmi.id="CvLZ2CQ63P41" decon="0" localid="vTN4WfHZyzzP" multipleinstance="0" drawasactor="0" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,0,50,0,1,0,0,0" linecolor="#ff0000" />
+ <notewidget usesdiagramfillcolor="1" width="288" x="725" fillcolor="none" y="375" linewidth="none" height="77" usefillcolor="1" isinstance="0" xmi.id="vaLJXLQEXaTQ" showstereotype="1" text="sta_Rx informs Maximus that it is waiting for a phy msg MPDU PAYLOAD with station_id=1 and tx_id=n." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ <notewidget usesdiagramfillcolor="1" width="254" x="945" fillcolor="none" y="596" linewidth="none" height="76" usefillcolor="1" isinstance="0" xmi.id="xI2mvXuq5XQ1" showstereotype="1" text="Maximus does not forward the message to this station because the station did not request it." usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </widgets>
+ <messages>
+ <messagewidget usesdiagramfillcolor="1" width="342" x="150" fillcolor="none" y="157" operation="phy msg PREAMBLE (station_id=1, tx_id=n)" linewidth="none" widgetbid="UzpajIea0XQC" height="8" usefillcolor="1" seqnum="1" textid="bOloW713jQsW" widgetaid="wsGISdwu93Fw" isinstance="0" xmi.id="Mv0zqKRZhUnv" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="308" x="155" fillcolor="none" y="135" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="bOloW713jQsW" showstereotype="1" text="1: phy msg PREAMBLE (station_id=1, tx_id=n)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="342" x="150" fillcolor="none" y="272" operation="phy msg FC (station_id=1, tx_id=n)" linewidth="none" widgetbid="UzpajIea0XQC" height="8" usefillcolor="1" seqnum="2" textid="9Lu6jLuuqk9N" widgetaid="wsGISdwu93Fw" isinstance="0" xmi.id="fQ14khLUfnNq" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="251" x="155" fillcolor="none" y="250" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="9Lu6jLuuqk9N" text="2: phy msg FC (station_id=1, tx_id=n)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="342" x="150" fillcolor="none" y="620" operation="phy msg MPDU PAYLOAD (station_id=1, tx_id=n)" linewidth="none" widgetbid="UzpajIea0XQC" height="8" usefillcolor="1" seqnum="3" textid="knYyVvmnygjd" widgetaid="wsGISdwu93Fw" isinstance="0" xmi.id="2ezxScrI455n" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="338" x="155" fillcolor="none" y="598" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="knYyVvmnygjd" showstereotype="1" text="3: phy msg MPDU PAYLOAD (station_id=1, tx_id=n)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="319" x="494" fillcolor="none" y="158" operation="phy msg PREAMBLE (station_id=1, tx_id=n)" linewidth="none" widgetbid="TEq0CDwjmGJP" height="8" usefillcolor="1" seqnum="1.1" textid="Vp1SBTakUluB" widgetaid="UzpajIea0XQC" isinstance="0" xmi.id="jNrUtdvesECz" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="315" x="499" fillcolor="none" y="136" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="Vp1SBTakUluB" showstereotype="1" text="1.1: phy msg PREAMBLE (station_id=1, tx_id=n)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="565" x="494" fillcolor="none" y="206" operation="phy msg PREAMBLE (station_id=1, tx_id=n)" linewidth="none" widgetbid="vTN4WfHZyzzP" height="8" usefillcolor="1" seqnum="1.2" textid="RXJBTM0Jf1co" widgetaid="UzpajIea0XQC" isinstance="0" xmi.id="WJhwQHceMTqC" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="315" x="499" fillcolor="none" y="184" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="RXJBTM0Jf1co" showstereotype="1" text="1.2: phy msg PREAMBLE (station_id=1, tx_id=n)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="319" x="494" fillcolor="none" y="269" operation="phy msg FC (station_id=1, tx_id=n)" linewidth="none" widgetbid="TEq0CDwjmGJP" height="8" usefillcolor="1" seqnum="2.1" textid="OLVTLWolFCsg" widgetaid="UzpajIea0XQC" isinstance="0" xmi.id="Q6PapcRWPuEz" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="263" x="499" fillcolor="none" y="247" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="OLVTLWolFCsg" showstereotype="1" text="2.1: phy msg FC (station_id=1, tx_id=n)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="565" x="494" fillcolor="none" y="507" operation="phy msg FC (station_id=1, tx_id=n)" linewidth="none" widgetbid="vTN4WfHZyzzP" height="8" usefillcolor="1" seqnum="2.2" textid="EBWXiv4NpPQR" widgetaid="UzpajIea0XQC" isinstance="0" xmi.id="OBh7pccOhqSd" sequencemessagetype="1001" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="263" x="499" fillcolor="none" y="485" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="EBWXiv4NpPQR" showstereotype="1" text="2.2: phy msg FC (station_id=1, tx_id=n)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="815" fillcolor="none" y="298" operation="phy_rx_prepare (short_ppdu=false)" linewidth="none" widgetbid="TEq0CDwjmGJP" height="32" usefillcolor="1" seqnum="2.1.1" textid="w3lqVE3FVdpA" widgetaid="TEq0CDwjmGJP" isinstance="0" xmi.id="YGIWHyaOQQR1" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="274" x="820" fillcolor="none" y="276" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="w3lqVE3FVdpA" showstereotype="1" text="2.1.1: phy_rx_prepare (short_ppdu=false)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="1061" fillcolor="none" y="537" operation="phy_rx_prepare (short_ppdu=true)" linewidth="none" widgetbid="vTN4WfHZyzzP" height="32" usefillcolor="1" seqnum="2.2.1" textid="37M4PIbBIbTx" widgetaid="vTN4WfHZyzzP" isinstance="0" xmi.id="YWBfB4JOZN86" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="270" x="1066" fillcolor="none" y="515" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="37M4PIbBIbTx" showstereotype="1" text="2.2.1: phy_rx_prepare (short_ppdu=true)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="319" x="494" fillcolor="none" y="354" operation="phy msg RX (station_id=2, tx_id=n, src_station_id=1)" linewidth="none" widgetbid="UzpajIea0XQC" height="8" usefillcolor="1" seqnum="2.1.2" textid="Q9fmWfwVXIRK" widgetaid="TEq0CDwjmGJP" isinstance="0" xmi.id="6pUz2zEfdQkC" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="390" x="499" fillcolor="none" y="332" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="Q9fmWfwVXIRK" text="2.1.2: phy msg RX (station_id=2, tx_id=n, src_station_id=1)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="319" x="494" fillcolor="none" y="630" operation="phy msg MPDU PAYLOAD (station_id=1, tx_id=n)" linewidth="none" widgetbid="TEq0CDwjmGJP" height="8" usefillcolor="1" seqnum="3.1" textid="BygjONyynXM1" widgetaid="UzpajIea0XQC" isinstance="0" xmi.id="uRpeGm54E613" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="350" x="499" fillcolor="none" y="608" linewidth="none" posttext="" role="704" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="BygjONyynXM1" showstereotype="1" text="3.1: phy msg MPDU PAYLOAD (station_id=1, tx_id=n)" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ <messagewidget usesdiagramfillcolor="1" width="48" x="150" fillcolor="none" y="664" operation="tx_id++" linewidth="none" widgetbid="wsGISdwu93Fw" height="32" usefillcolor="1" seqnum="4" textid="dA4iPXnEjCVb" widgetaid="wsGISdwu93Fw" isinstance="0" xmi.id="3DGqw8zT8FYD" sequencemessagetype="1001" showstereotype="1" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" >
+ <floatingtext usesdiagramfillcolor="1" width="76" x="155" fillcolor="none" y="642" linewidth="none" posttext="" role="705" height="22" usefillcolor="1" pretext="" isinstance="0" xmi.id="dA4iPXnEjCVb" showstereotype="1" text="4: tx_id++" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </messagewidget>
+ </messages>
+ <associations/>
+ </diagram>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="1100" snapy="10" showatts="1" xmi.id="ZpAs8xwGrNaW" documentation="" type="1" showops="1" showpackage="1" name="class diagram channel settings" localid="" showstereotype="1" showscope="1" snapcsgrid="0" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="1107" >
+ <widgets>
+ <classwidget usesdiagramfillcolor="0" width="908" showattsigs="601" x="72" fillcolor="#ffffc0" y="42" showopsigs="601" linewidth="none" height="396" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="PGF0sP6Kgb0l" showoperations="1" showpackage="1" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+ <classwidget usesdiagramfillcolor="0" width="449" showattsigs="601" x="199" fillcolor="#ffffc0" y="941" showopsigs="601" linewidth="none" height="162" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="VsbjUz1jzxim" showoperations="1" showpackage="1" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+ <classwidget usesdiagramfillcolor="0" width="1079" showattsigs="601" x="17" fillcolor="#ffffc0" y="486" showopsigs="601" linewidth="none" height="378" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="HjupUSYowhI4" showoperations="1" showpackage="1" showscope="1" showstereotype="1" usesdiagramusefillcolor="0" font="Sans Serif,10,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+ </widgets>
+ <messages/>
+ <associations>
+ <assocwidget totalcounta="2" indexa="1" visibilityB="200" totalcountb="2" indexb="1" linewidth="none" widgetbid="VsbjUz1jzxim" widgetaid="HjupUSYowhI4" xmi.id="ZSwkq19bojv2" type="510" changeabilityA="900" changeabilityB="900" linecolor="none" visibilityA="200" >
+ <linepath>
+ <startpoint startx="221" starty="864" />
+ <endpoint endx="221" endy="941" />
+ </linepath>
+ <floatingtext usesdiagramfillcolor="1" width="64" x="161" fillcolor="none" y="917" linewidth="none" posttext="" role="710" height="22" usefillcolor="1" pretext="+" isinstance="0" xmi.id="RACYAu1DgR4Z" showstereotype="1" text="mPoint" usesdiagramusefillcolor="1" font="Sans Serif,10,-1,0,50,0,0,0,0,0" linecolor="none" />
+ </assocwidget>
+ </associations>
+ </diagram>
+ </diagrams>
+ </XMI.extension>
+ </UML:Model>
+ <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Use Case View" isRoot="false" isAbstract="false" name="Use Case View" >
+ <UML:Namespace.ownedElement/>
+ </UML:Model>
+ <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Component View" isRoot="false" isAbstract="false" name="Component View" >
+ <UML:Namespace.ownedElement/>
+ </UML:Model>
+ <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Deployment View" isRoot="false" isAbstract="false" name="Deployment View" >
+ <UML:Namespace.ownedElement/>
+ </UML:Model>
+ <UML:Model stereotype="folder" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Entity Relationship Model" isRoot="false" isAbstract="false" name="Entity Relationship Model" >
+ <UML:Namespace.ownedElement/>
+ </UML:Model>
+ </UML:Namespace.ownedElement>
+ </UML:Model>
+ </XMI.content>
+ <XMI.extensions xmi.extender="umbrello" >
+ <docsettings viewid="NdBn9ALHuRov" documentation="" uniqueid="KS7s5wEPMgTu" />
+ <listview>
+ <listitem open="1" type="800" label="Views" >
+ <listitem open="1" type="801" id="Logical View" >
+ <listitem open="0" type="813" id="FA5tCgQO5jOX" >
+ <listitem open="0" type="814" id="vLNKsMwHnQ5O" />
+ <listitem open="0" type="814" id="uHZmB3x8YrWn" />
+ <listitem open="0" type="814" id="EPgLV4JWKVtq" />
+ <listitem open="0" type="814" id="iNWc4oZxCl7B" />
+ <listitem open="0" type="814" id="GQR4rnp7JCzr" />
+ <listitem open="0" type="814" id="GewSP3dgS2iJ" />
+ <listitem open="0" type="814" id="pXR9jOynPIoD" />
+ <listitem open="0" type="815" id="PNXlmw9fnFuL" />
+ <listitem open="0" type="815" id="y8L4KAg9702o" />
+ <listitem open="0" type="815" id="LRN0s3UGfAwm" />
+ <listitem open="0" type="815" id="MTBnuIpE5I5h" />
+ <listitem open="0" type="815" id="qrweJyXfPgQH" />
+ <listitem open="0" type="815" id="OS6l8U35hW6C" />
+ <listitem open="0" type="815" id="jRbAQQ47XE3x" />
+ <listitem open="0" type="815" id="qQZrSJeClEK9" />
+ <listitem open="0" type="815" id="OZe7W5VrVgaA" />
+ <listitem open="0" type="815" id="09RFjqmd0dax" />
+ <listitem open="0" type="815" id="fYXdFW0u7v45" />
+ <listitem open="0" type="815" id="BALxxO2awYCA" />
+ <listitem open="0" type="815" id="dGNRBZuSsh40" />
+ <listitem open="0" type="815" id="XLTP0YPPGkf1" />
+ <listitem open="0" type="815" id="2s4IahHvPPAX" />
+ <listitem open="0" type="815" id="z7iRgeJqCCrj" />
+ <listitem open="0" type="815" id="jfqqWYV4W41s" />
+ <listitem open="0" type="815" id="P3rRYhqHMh6s" />
+ <listitem open="0" type="815" id="jyRgGnpfqf5M" />
+ <listitem open="0" type="815" id="XOXms3hJA084" />
+ <listitem open="0" type="815" id="k41t27vK3XoF" />
+ <listitem open="0" type="815" id="o0LrX74wtWDl" />
+ <listitem open="0" type="815" id="wAYHYS5t16DH" />
+ </listitem>
+ <listitem open="0" type="813" id="HjupUSYowhI4" >
+ <listitem open="0" type="814" id="ZSwkq19bojv2" />
+ <listitem open="0" type="814" id="Ge7RT8Ckq5ZI" />
+ <listitem open="0" type="814" id="V57RkPTHrQ2f" />
+ <listitem open="0" type="814" id="P9GDsAF7oLYH" />
+ <listitem open="0" type="815" id="4DctbcZ0lnEe" />
+ <listitem open="0" type="815" id="xRjlmH0Ez1Tl" />
+ <listitem open="0" type="815" id="0eBxdci9ekFK" />
+ <listitem open="0" type="815" id="DjaPUCMSoVQR" />
+ <listitem open="0" type="815" id="66Ykoo2IT5gA" />
+ <listitem open="0" type="815" id="nowhba6bZwOz" />
+ <listitem open="0" type="815" id="jtReTM98izcO" />
+ <listitem open="0" type="815" id="huvhfiqMaF13" />
+ <listitem open="0" type="815" id="c8CI5oguNdiw" />
+ <listitem open="0" type="815" id="Uc44r38RCKjF" />
+ <listitem open="0" type="815" id="I0RSI9iPWrpV" />
+ <listitem open="0" type="815" id="fD4zThhtEUMY" />
+ <listitem open="0" type="815" id="qEuK4jnjvsgO" />
+ <listitem open="0" type="815" id="o3dYjumm81LP" />
+ <listitem open="0" type="815" id="rCiZ34ts7WOo" />
+ <listitem open="0" type="815" id="no29iM1Z9CGC" />
+ </listitem>
+ <listitem open="0" type="813" id="VsbjUz1jzxim" >
+ <listitem open="0" type="814" id="hRU6f1aVcHyc" />
+ <listitem open="0" type="814" id="IhZENLi13oFI" />
+ <listitem open="0" type="815" id="0zDce8bMX5QB" />
+ <listitem open="0" type="815" id="kVbwfpKRKEVh" />
+ <listitem open="0" type="815" id="rGEtgzA0EaD8" />
+ <listitem open="0" type="815" id="5iOQmRPfmnrL" />
+ <listitem open="0" type="815" id="OeSEtgTyOpM9" />
+ <listitem open="0" type="815" id="Vo4VsHm3o6I5" />
+ </listitem>
+ <listitem open="0" type="813" id="PGF0sP6Kgb0l" >
+ <listitem open="0" type="814" id="YzQ8Jmmx2Rx1" />
+ <listitem open="0" type="814" id="C8LZTmT1jr71" />
+ <listitem open="0" type="814" id="ECT43sTE9tu7" />
+ <listitem open="0" type="814" id="8uij0qPBhzDF" />
+ <listitem open="0" type="814" id="dsqJeeDqqfut" />
+ <listitem open="0" type="815" id="N1iX9W91mjbs" />
+ <listitem open="0" type="815" id="cnVd2iEDTGap" />
+ <listitem open="0" type="815" id="dccFV5HKv9Wt" />
+ <listitem open="0" type="815" id="CRgGs5fVq86t" />
+ <listitem open="0" type="815" id="rJ3xOwjhyyGc" />
+ <listitem open="0" type="815" id="P5CYI2l7Km5i" />
+ <listitem open="0" type="815" id="goPeldGm16Ol" />
+ <listitem open="0" type="815" id="iiALeHZ1Njaf" />
+ <listitem open="0" type="815" id="dWaTBSKgoPJ3" />
+ <listitem open="0" type="815" id="M3QGTU7iw8dM" />
+ <listitem open="0" type="815" id="AB0zYJ2vLR9m" />
+ <listitem open="0" type="815" id="kSxc26GHOJiP" />
+ <listitem open="0" type="815" id="BSaEFiqHsNgS" />
+ <listitem open="0" type="815" id="dzYH8IvKHpvW" />
+ <listitem open="0" type="815" id="w6NMjCexlRoY" />
+ <listitem open="0" type="815" id="Z1yyRvzefObL" />
+ </listitem>
+ <listitem open="1" type="813" id="zSo720DHUtK4" />
+ <listitem open="0" type="813" id="kbTW3DFGwneP" />
+ <listitem open="0" type="813" id="aXMfZ9tQ8GTx" >
+ <listitem open="0" type="814" id="FsOabmphHzei" />
+ <listitem open="0" type="814" id="jNPug1TGWnt5" />
+ </listitem>
+ <listitem open="0" type="813" id="MJNkMwYhFv8H" >
+ <listitem open="0" type="815" id="11oV4ziv3AYN" />
+ <listitem open="0" type="815" id="YYbhCSZWluH5" />
+ <listitem open="0" type="815" id="qnn4itLhu9Bz" />
+ <listitem open="0" type="815" id="bWALx5iDCipN" />
+ <listitem open="0" type="815" id="AGEpQZVz3eK0" />
+ <listitem open="0" type="815" id="d3GgfZfOZoHG" />
+ <listitem open="0" type="815" id="PujNU9MyUc3R" />
+ <listitem open="0" type="815" id="hYiS0RDqSc09" />
+ <listitem open="0" type="815" id="qCYOB46xZJIN" />
+ <listitem open="0" type="815" id="34qsc33QFZoO" />
+ <listitem open="0" type="815" id="WhMdFTMpdTdI" />
+ <listitem open="0" type="815" id="tCCndBu9sGk6" />
+ </listitem>
+ <listitem open="0" type="813" id="5VCzTkjjCKbZ" />
+ <listitem open="0" type="813" id="P5iAKaTM6Drb" />
+ <listitem open="1" type="813" id="ka695HsLyRqa" />
+ <listitem open="1" type="813" id="OMC8n0NgoyNC" />
+ <listitem open="1" type="813" id="y0Zndhh8NjGq" />
+ <listitem open="1" type="813" id="EPI1UgANf3xg" />
+ <listitem open="1" type="813" id="zwpATNw5hYwj" />
+ <listitem open="1" type="813" id="J5I5GN6BUVNH" />
+ <listitem open="0" type="813" id="r6SeLQ0E8ets" />
+ <listitem open="0" type="813" id="nNLPS46tYU5B" />
+ <listitem open="1" type="813" id="5hM3oO8IvMZa" />
+ <listitem open="1" type="813" id="71EBB6ZerqDE" />
+ <listitem open="0" type="813" id="p0EIenqzKrdV" >
+ <listitem open="0" type="814" id="ihYvkGnalcj8" />
+ <listitem open="0" type="814" id="DcQ21IYgvf4A" />
+ <listitem open="0" type="814" id="0PpuG29IN9r4" />
+ <listitem open="0" type="815" id="lRK3GxXGwC31" />
+ <listitem open="0" type="815" id="tGjpAvxFMVQv" />
+ <listitem open="0" type="815" id="2UAE6pa80TlD" />
+ <listitem open="0" type="815" id="iRfrv7uIeAaZ" />
+ </listitem>
+ <listitem open="1" type="813" id="xbRaG9lhs3GA" />
+ <listitem open="1" type="813" id="t1tc2bTZdTo7" />
+ <listitem open="1" type="813" id="iF6aeCsJls2b" />
+ <listitem open="0" type="813" id="0IENWuVgMRRQ" />
+ <listitem open="1" type="813" id="ouQgLFbCZBH6" />
+ <listitem open="1" type="813" id="MjbCnbmzupQK" />
+ <listitem open="1" type="813" id="R2g1PPyRrFdJ" />
+ <listitem open="1" type="813" id="QCc0kys9xMnl" />
+ <listitem open="1" type="813" id="0ZbYQWqDJFyR" />
+ <listitem open="1" type="813" id="pnRk9DVlgulU" />
+ <listitem open="1" type="813" id="OTUqbbMS8cB5" />
+ <listitem open="1" type="813" id="NNrPbFIBbTWJ" />
+ <listitem open="0" type="813" id="umW20xxGpJoP" >
+ <listitem open="0" type="815" id="3d6Ick1K5QEl" />
+ </listitem>
+ <listitem open="0" type="813" id="ek5GEEjxefv1" />
+ <listitem open="1" type="813" id="rGkvr2wbb0ig" />
+ <listitem open="1" type="813" id="ACuye0MTG4P7" />
+ <listitem open="1" type="813" id="CvLZ2CQ63P41" />
+ <listitem open="1" type="813" id="pKHo6OTH6XRU" />
+ <listitem open="1" type="813" id="TwO4O4jLDIiP" />
+ <listitem open="0" type="813" id="7rs81OTZw4E7" />
+ <listitem open="0" type="813" id="eNNzwM7vtyZm" />
+ <listitem open="1" type="813" id="MMOOLBCfmrGJ" />
+ <listitem open="1" type="813" id="yBbPCZ8HGSK2" />
+ <listitem open="1" type="813" id="eniEjhTPROwl" />
+ <listitem open="1" type="813" id="ryY5K4jdy734" />
+ <listitem open="1" type="813" id="IVIVFrTsSA9W" />
+ <listitem open="1" type="813" id="Y2z0vH5PWhVj" />
+ <listitem open="1" type="813" id="IW1PTWwAuJXf" />
+ <listitem open="1" type="813" id="SRA7JvZo6AuO" />
+ <listitem open="0" type="818" id="uPECzXJFnTOn" >
+ <listitem open="0" type="813" id="IWPuXt3VypIz" />
+ </listitem>
+ <listitem open="0" type="818" id="6elj96McODtx" >
+ <listitem open="0" type="813" id="qYY4ISujM3Ed" />
+ <listitem open="0" type="813" id="AlwnfvQ24tqq" />
+ </listitem>
+ <listitem open="0" type="830" id="Datatypes" >
+ <listitem open="0" type="829" id="5ToJ3zPrsGFF" />
+ <listitem open="0" type="829" id="3YkVVg8j3o2Y" />
+ <listitem open="0" type="829" id="rxKsjMRYfTiU" />
+ <listitem open="0" type="829" id="b4ob1ibWBqLq" />
+ <listitem open="0" type="829" id="8gZ2im9FZlVF" />
+ <listitem open="0" type="829" id="tq6FaofPTzwd" />
+ <listitem open="1" type="829" id="txbVRO36HpfQ" />
+ <listitem open="1" type="829" id="JcPKyEye9iP3" />
+ <listitem open="0" type="829" id="448sjDF59poj" />
+ <listitem open="0" type="829" id="psrQPqT9L430" />
+ <listitem open="0" type="829" id="zypnSFDYKlG8" />
+ <listitem open="0" type="829" id="PfzwSs1KcVMd" />
+ <listitem open="0" type="829" id="oL4FZe2AHfNk" />
+ <listitem open="0" type="829" id="kj4rGrwwW6er" />
+ <listitem open="0" type="829" id="WzilSttBcw0q" />
+ <listitem open="0" type="829" id="NBTpmTxZCmcb" />
+ <listitem open="0" type="829" id="m2IzC9ii2UsR" />
+ <listitem open="0" type="829" id="mXu6MdkX4QlH" />
+ <listitem open="0" type="829" id="ARgEDvWDshpX" />
+ <listitem open="0" type="829" id="hfBiNMiT2GVk" />
+ <listitem open="0" type="829" id="HSbuMHwp53nG" />
+ <listitem open="0" type="829" id="fLpWgryb0030" />
+ <listitem open="0" type="829" id="1XretJvqfug3" />
+ <listitem open="0" type="829" id="su73E4iG7Y8j" />
+ <listitem open="0" type="829" id="X118ilRkx2cY" />
+ <listitem open="1" type="829" id="LRcU81Wzx7SM" />
+ <listitem open="1" type="829" id="ZJ5BrRm819Tz" />
+ <listitem open="1" type="829" id="agtmZAmehdXM" />
+ <listitem open="1" type="829" id="dpMdwnaHDClJ" />
+ <listitem open="1" type="829" id="VVSkI78sPE3E" />
+ <listitem open="0" type="829" id="PVMPlwqpaaYi" />
+ <listitem open="0" type="829" id="LlOVV04Zpapx" />
+ <listitem open="1" type="829" id="GgbUcB1crO0m" />
+ <listitem open="0" type="829" id="WndGhsLWd8YJ" />
+ <listitem open="0" type="829" id="41M2qczWxT6z" />
+ <listitem open="1" type="829" id="CFI9MjVrEwaX" />
+ <listitem open="0" type="829" id="BVdJY7XV1Crz" />
+ <listitem open="1" type="829" id="mjQxu9G6PXDl" />
+ <listitem open="1" type="829" id="1iPQuScWFz9B" />
+ </listitem>
+ </listitem>
+ <listitem open="1" type="802" id="Use Case View" />
+ <listitem open="1" type="821" id="Component View" />
+ <listitem open="1" type="827" id="Deployment View" />
+ <listitem open="1" type="836" id="Entity Relationship Model" />
+ </listitem>
+ </listview>
+ <codegeneration>
+ <codegenerator language="C++" />
+ </codegeneration>
+ </XMI.extensions>
+</XMI>
diff --git a/cesar/maximus/python/lib/cesar/maximus_dur.py b/cesar/maximus/python/lib/cesar/maximus_dur.py
new file mode 100644
index 0000000000..1c5e08232c
--- /dev/null
+++ b/cesar/maximus/python/lib/cesar/maximus_dur.py
@@ -0,0 +1,97 @@
+#! usr/bin/env python
+
+#print __name__
+
+from interface import *
+from maximus.station.sta import PHY_CARRIER_NB
+
+def maximus_dur_carrier_nb(maximus, station, tonemask):
+ """Counts the number of used carriers.
+ maximus - the Maximus object, already initialized
+ station - the destination station (note: you can use the method "get()" of the STA class)
+ tonemask - must be a bits field (note: you can use the method "get_tonemask()" of the STA class)
+ Returns number of carriers.
+ """
+ # Create and send a function call to call the following Maximus duration function:
+ # "uint maximus_dur_carrier_nb (const u8 *tonemask);"
+ rsp = maximus.create_fcall("maximus_dur_carrier_nb")\
+ .add_param("tonemask", tonemask)\
+ .send(station)
+ return rsp.bind_param_ulong("carrier_nb")
+
+def maximus_dur_bits_per_symbol(maximus, station, mod, tonemask, tonemap, carrier_nb):
+ """Computes the number of bits per OFDM symbol.
+ maximus - the Maximus object, already initialized
+ station - the destination station (note: you can use the method "get()" of the STA class)
+ mod - PHY modulation
+ tonemask - must be a bits field (note: you can use the method "get_tonemask()" of the STA class)
+ tonemap - must be a bits field or None for ROBO modes
+ carrier_nb - number of carriers for this tonemap
+ Returns the number of bits per OFDM symbol.
+ """
+ # Create and send a function call to call the following Maximus duration function:
+ # "uint maximus_dur_bits_per_symbol (phy_mod_t mod, const u8 *tonemask, const blk_t *tonemap, uint carrier_nb);"
+ if tonemap is None:
+ tonemap = ((PHY_CARRIER_NB + 1) / 2) * '\0'
+ rsp = maximus.create_fcall("maximus_dur_bits_per_symbol")\
+ .add_param_ulong("mod", mod)\
+ .add_param("tonemask", tonemask)\
+ .add_param("tonemap", tonemap)\
+ .add_param_ulong("carrier_nb", carrier_nb)\
+ .send(station)
+ return rsp.bind_param_ulong("bits_per_symbol")
+
+def maximus_dur_symbol_nb(maximus, station, fecrate, pb_size, bits_per_symbol, pb_nb):
+ """Computes the number of symbols for a given number of PB.
+ maximus - the Maximus object, already initialized
+ station - the destination station (note: you can use the method "get()" of the STA class)
+ fecrate - FEC encoding rate
+ pb_size - PB size
+ bits_per_symbol - number of bits per symbol
+ pb_nb - PB number
+ Returns the number of used symbols.
+ """
+ # Create and send a function call to call the following Maximus duration function:
+ # "uint maximus_dur_symbol_nb (phy_fecrate_t fecrate, phy_pb_size_t pb_size, uint bits_per_symbol, uint pb_nb);"
+ rsp = maximus.create_fcall("maximus_dur_symbol_nb")\
+ .add_param_ulong("fecrate", fecrate)\
+ .add_param_ulong("pb_size", pb_size)\
+ .add_param_ulong("bits_per_symbol", bits_per_symbol)\
+ .add_param_ulong("pb_nb", pb_nb)\
+ .send(station)
+ return rsp.bind_param_ulong("symbol_nb")
+
+def maximus_dur_data_tck(maximus, station, gil, symbol_nb):
+ """Computes the duration of the data part of a frame for a given number of symbols.
+ maximus - the Maximus object, already initialized
+ station - the destination station (note: you can use the method "get()" of the STA class)
+ gil - guard interval for third symbol and following symbols
+ symbol_nb - number of OFDM symbols
+ Returns the duration in ticks.
+ """
+ # Create and send a function call to call the following Maximus duration function:
+ # "uint maximus_dur_data_tck (phy_gil_t gil, uint symbol_nb);"
+ rsp = maximus.create_fcall("maximus_dur_data_tck")\
+ .add_param_ulong("gil", gil)\
+ .add_param_ulong("symbol_nb", symbol_nb)\
+ .send(station)
+ return rsp.bind_param_ulong("data_tck")
+
+def maximus_dur(maximus, station, tonemask, mod, tonemap, fecrate, pb_size, pb_nb, gil):
+ """Computes the duration of the data part of a frame.
+ maximus - the Maximus object, already initialized
+ station - the destination station (note: you can use the method "get()" of the STA class)
+ tonemask - must be a bits field (note: you can use the method "get_tonemask()" of the STA class)
+ mod - PHY modulation
+ tonemap - must be a bits field or None for ROBO modes
+ fecrate - FEC encoding rate
+ pb_size - PB size
+ pb_nb - PB number
+ gil - guard interval for third symbol and following symbols
+ Returns the duration in ticks.
+ """
+ return maximus_dur_data_tck(maximus, station, gil,\
+ maximus_dur_symbol_nb(maximus, station, fecrate, pb_size,\
+ maximus_dur_bits_per_symbol(maximus, station, mod, tonemask, tonemap,\
+ maximus_dur_carrier_nb(maximus, station, tonemask)),\
+ pb_nb))
diff --git a/cesar/maximus/python/lib/cesar/sta_cesar.py b/cesar/maximus/python/lib/cesar/sta_cesar.py
new file mode 100644
index 0000000000..bf02b23e4e
--- /dev/null
+++ b/cesar/maximus/python/lib/cesar/sta_cesar.py
@@ -0,0 +1,44 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.station import *
+from string import *
+
+# Find constant defining the additional number of MME buffers to allocate into the station
+base = '../../../../'
+header = 'interface/interface.h'
+define = 'INTERFACE_BUFFER_LIST_NUM_SLOTS'
+f = open(__file__[:__file__.find(".py") - len(__name__)] + base + header, 'r') # or ".pyc"
+s = f.read()
+f.close()
+begin = s.find(define) + len(define)
+while s[begin] == " " or s[begin] == "\t":
+ begin += 1
+end = begin
+while s[end] in digits: # digits is the string '0123456789'
+ end += 1
+INTERFACE_BUFFER_LIST_NUM_SLOTS = int(s[begin:end])
+
+def STACesar(maximus,\
+ executable = None,\
+ debug = False,\
+ name = None,\
+ data_buffer_nb=0,\
+ mme_buffer_nb=1,\
+ interface_buffer_nb=0,\
+ config_mode = 'MME',\
+ config = Config()):
+ """This function creates a STA object with the given arguments,
+ with an additional number of MME buffers to allocate into the station,
+ and returns the created STA object.
+ """
+ return STA(maximus,\
+ executable = executable,\
+ debug = debug,\
+ name = name,\
+ data_buffer_nb=data_buffer_nb,\
+ mme_buffer_nb=mme_buffer_nb,\
+ interface_buffer_nb=INTERFACE_BUFFER_LIST_NUM_SLOTS,\
+ config_mode = config_mode,\
+ config = config)
diff --git a/cesar/maximus/python/lib/fcVf/__init__.py b/cesar/maximus/python/lib/fcVf/__init__.py
new file mode 100644
index 0000000000..ae0fc2de39
--- /dev/null
+++ b/cesar/maximus/python/lib/fcVf/__init__.py
@@ -0,0 +1 @@
+from fcVfFields import *
diff --git a/cesar/maximus/python/lib/fcVf/crc24/__init__.py b/cesar/maximus/python/lib/fcVf/crc24/__init__.py
new file mode 100644
index 0000000000..96bcf63b8d
--- /dev/null
+++ b/cesar/maximus/python/lib/fcVf/crc24/__init__.py
@@ -0,0 +1 @@
+from pycrc24 import *
diff --git a/cesar/maximus/python/lib/fcVf/crc24/crc24.py b/cesar/maximus/python/lib/fcVf/crc24/crc24.py
new file mode 100644
index 0000000000..3f453d6271
--- /dev/null
+++ b/cesar/maximus/python/lib/fcVf/crc24/crc24.py
@@ -0,0 +1,84 @@
+# -*- coding: Latin-1 -*-
+
+
+# Class Options
+###############################################################################
+class Options(object):
+ """
+ The options parsing and validationg class
+ """
+
+ """
+ Bitmap of the algorithms
+ """
+ Algo_None = 0x00
+ Algo_Bit_by_Bit = 0x01
+ Algo_Bit_by_Bit_Fast = 0x02
+ Algo_Table_Driven = 0x04
+
+ # Class constructor
+ ###############################################################################
+ def __init__(self, version):
+ self.ProgramName = "pycrc"
+ self.Version = version
+ self.VersionStr = "%s v%s" % (self.ProgramName, self.Version)
+ self.WebAddress = "http://www.tty1.net/pycrc/"
+ self.Width = None
+ self.Poly = None
+ self.ReflectIn = None
+ self.XorIn = None
+ self.ReflectOut = None
+ self.XorOut = None
+ self.TableIdxWidth = 8
+ self.TableWidth = 1 << self.TableIdxWidth
+ self.Verbose = False
+ self.CheckString = "123456789"
+
+ self.Algorithm = self.Algo_None
+ self.SymbolPrefix = "crc_"
+ self.OutputFile = None
+ self.Action = "check_string"
+ self.CStd = None
+
+
+ #CRC24 :
+ self.Width=24
+ self.Poly=0x864cfbL
+ self.ReflectIn=False
+ self.XorIn=0xb704ceL
+ self.ReflectOut=False
+ self.XorOut=0x0L
+ self.parse()
+
+
+ # function parse
+ ###############################################################################
+ def parse(self):
+ """
+ Parses and validates the options given as arguments
+ """
+ if self.Width != None:
+ if self.Width <= 0:
+ sys.stderr.write("Error: Width must be strictly positive\n")
+ sys.exit(1)
+ self.MSB_Mask = 0x1 << (self.Width - 1)
+ self.Mask = ((self.MSB_Mask - 1) << 1) | 1
+ if self.Poly != None:
+ self.Poly = self.Poly & self.Mask
+ if self.XorIn != None:
+ self.XorIn = self.XorIn & self.Mask
+ if self.XorOut != None:
+ self.XorOut = self.XorOut & self.Mask
+ else:
+ self.MSB_Mask = None
+ self.Mask = None
+
+ if self.Width == None or \
+ self.Poly == None or \
+ self.ReflectIn == None or \
+ self.XorIn == None or \
+ self.ReflectOut == None or \
+ self.XorOut == None:
+ self.UndefinedCrcParameters = True
+ else:
+ self.UndefinedCrcParameters = False
diff --git a/cesar/maximus/python/lib/fcVf/crc24/crc24_algorithms.py b/cesar/maximus/python/lib/fcVf/crc24/crc24_algorithms.py
new file mode 100644
index 0000000000..9158758dd4
--- /dev/null
+++ b/cesar/maximus/python/lib/fcVf/crc24/crc24_algorithms.py
@@ -0,0 +1,172 @@
+# -*- coding: Latin-1 -*-
+
+# Class Crc
+###############################################################################
+class Crc(object):
+ """
+ A base class for CRC routines.
+ """
+
+ # constructor
+ ###############################################################################
+ def __init__(self, opt):
+ """The Crc constructor.
+
+ The opt parameter is an object containing the following members:
+ Width
+ Poly
+ ReflectIn
+ XorIn
+ ReflectOut
+ XorOut
+ """
+ self.Width = opt.Width
+ self.Poly = opt.Poly
+ self.ReflectIn = opt.ReflectIn
+ self.XorIn = opt.XorIn
+ self.ReflectOut = opt.ReflectOut
+ self.XorOut = opt.XorOut
+
+ self.MSB_Mask = 0x1 << (opt.Width - 1)
+ self.Mask = ((opt.MSB_Mask - 1) << 1) | 1
+ if opt.TableIdxWidth != None:
+ self.TableIdxWidth = opt.TableIdxWidth
+ self.TableWidth = 1 << opt.TableIdxWidth
+ else:
+ self.TableIdxWidth = 8
+ self.TableWidth = 1 << self.TableIdxWidth
+
+ # function reflect
+ ###############################################################################
+ def reflect(self, data, width):
+ """
+ reflects a data word, i.e. reverts the bit order
+ """
+ x = 0
+ for i in range(width):
+ x = x | (((data >> (width - i -1)) & 1) << i)
+ return x
+
+ # function handle_bit
+ ###############################################################################
+ def __handle_bit(self, register, new_bit):
+ """
+ This function is part of the bit_by_bit algorithm.
+ It function takes one bit from the augmented message as argument and returns the new crc value
+ """
+ register_msb = register & self.MSB_Mask
+ register = (register << 1) & self.Mask
+ if new_bit != 0:
+ register = register | 1
+ if register_msb != 0:
+ register = register ^ self.Poly
+ return register & self.Mask
+
+ # function bit_by_bit
+ ###############################################################################
+ def bit_by_bit(self, str):
+ """
+ Classic simple and slow CRC implementation.
+ This function iterates bit by bit over the augmented input message and returns the calculated CRC value at the end
+ """
+ register = self.XorIn
+ for j in range(self.Width):
+ bit = register & 1
+ if bit != 0:
+ register = ((register ^ self.Poly) >> 1) | self.MSB_Mask
+ else:
+ register = register >> 1
+ register &= self.Mask
+
+ for i in range(len(str)):
+ octet = ord(str[i])
+ if self.ReflectIn:
+ octet = self.reflect(octet, 8)
+ for j in range(8):
+ new_bit = octet & (0x80 >> j)
+ register = self.__handle_bit(register, new_bit)
+ for j in range(self.Width):
+ register = self.__handle_bit(register, 0)
+
+ if self.ReflectOut:
+ register = self.reflect(register, self.Width)
+ register = register ^ self.XorOut
+ return register
+
+ # function bit_by_bit_fast
+ ###############################################################################
+ def bit_by_bit_fast(self, str):
+ """
+ This is a slightly modified version of the bit_by_bit algorithm: it does not need to loop over the augmented bit,
+ i.e. the Width 0-bits wich are appended to the input message in the bit_by_bit algorithm.
+ """
+ register = self.XorIn
+
+ for i in range(len(str)):
+ octet = ord(str[i])
+ if self.ReflectIn:
+ octet = self.reflect(octet, 8)
+ for j in range(8):
+ bit = register & self.MSB_Mask
+ register <<= 1
+ if octet & (0x80 >> j):
+ bit ^= self.MSB_Mask
+ if bit:
+ register ^= self.Poly
+ register &= self.Mask
+ if self.ReflectOut:
+ register = self.reflect(register, self.Width)
+ register = register ^ self.XorOut
+ return register
+
+ # function gen_table
+ ###############################################################################
+ def gen_table(self):
+ """
+ This function generates the CRC table used for the table_driven CRC algorithm.
+ The Python version cannot handle tables of a different size rather than 8.
+ See the generated C code for tables with different sizes instead.
+ """
+ tbl = {}
+ for i in range(1 << self.TableIdxWidth):
+ register = i
+ if self.ReflectIn:
+ register = self.reflect(register, self.TableIdxWidth)
+ register = register << (self.Width - self.TableIdxWidth)
+ for j in range(self.TableIdxWidth):
+ if register & self.MSB_Mask != 0:
+ register = (register << 1) ^ self.Poly
+ else:
+ register = (register << 1)
+ if self.ReflectIn:
+ register = self.reflect(register, self.Width)
+ tbl[i] = register & self.Mask
+ return tbl
+
+ # function table_driven
+ ###############################################################################
+ def table_driven(self, str):
+ """
+ The Standard table_driven CRC algorithm.
+ """
+ tbl = self.gen_table()
+
+ if not self.ReflectIn:
+ register = self.XorIn
+ for i in range(len(str)):
+ octet = ord(str[i])
+ tblidx = ((register >> (self.Width - 8)) ^ octet) & 0xff
+ register = ((register << 8) ^ tbl[tblidx]) & self.Mask
+ else:
+ register = self.reflect(self.XorIn, self.Width)
+ for i in range(len(str)):
+ octet = ord(str[i])
+ tblidx = (register ^ octet) & 0xff
+ register = ((register >> 8) ^ tbl[tblidx]) & self.Mask
+ register = self.reflect(register, self.Width)
+
+ if self.ReflectOut:
+ register = self.reflect(register, self.Width)
+ register = register ^ self.XorOut
+ return register
+
diff --git a/cesar/maximus/python/lib/fcVf/crc24/pycrc24.py b/cesar/maximus/python/lib/fcVf/crc24/pycrc24.py
new file mode 100644
index 0000000000..2f8f4df7fc
--- /dev/null
+++ b/cesar/maximus/python/lib/fcVf/crc24/pycrc24.py
@@ -0,0 +1,44 @@
+# -*- coding: Latin-1 -*-
+
+from crc24 import Options
+from crc24_algorithms import Crc
+
+
+# function check_string
+###############################################################################
+def check_string(myString):
+
+
+ opt=Options("0.6.4")
+ opt.CheckString=myString
+ """
+ Returns the calculated CRC sum of a string
+ """
+ if opt.UndefinedCrcParameters:
+ sys.stderr.write("Error: undefined parameters\n")
+ sys.exit(1)
+ if opt.Algorithm == 0:
+ opt.Algorithm = opt.Algo_Bit_by_Bit | opt.Algo_Bit_by_Bit_Fast | opt.Algo_Table_Driven
+
+ alg = Crc(opt)
+ crc = this_crc = None
+ if opt.Algorithm & opt.Algo_Bit_by_Bit:
+ this_crc = alg.bit_by_bit(opt.CheckString)
+ if crc != None and this_crc != crc:
+ sys.stderr.write("Error: different checksums: 0x%x, 0x%x\n" % (this_crc, crc))
+ sys.exit(1)
+ crc = this_crc
+ if opt.Algorithm & opt.Algo_Bit_by_Bit_Fast:
+ this_crc = alg.bit_by_bit_fast(opt.CheckString)
+ if crc != None and this_crc != crc:
+ sys.stderr.write("Error: different checksums: 0x%x, 0x%x\n" % (this_crc, crc))
+ sys.exit(1)
+ crc = this_crc
+ if opt.Algorithm & opt.Algo_Table_Driven:
+ opt.TableIdxWidth = 8 # FIXME cowardly refusing to use less bits for the table
+ this_crc = alg.table_driven(opt.CheckString)
+ if crc != None and this_crc != crc:
+ sys.stderr.write("Error: different checksums: 0x%x, 0x%x\n" % (this_crc, crc))
+ sys.exit(1)
+ crc = this_crc
+ return crc
diff --git a/cesar/maximus/python/lib/fcVf/fcVfFields.py b/cesar/maximus/python/lib/fcVf/fcVfFields.py
new file mode 100644
index 0000000000..8adefcba91
--- /dev/null
+++ b/cesar/maximus/python/lib/fcVf/fcVfFields.py
@@ -0,0 +1,758 @@
+# -*- coding:Utf-8 -*-
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+#from maximus import *
+from maximus import FC_AV, MACFrameHeader, MACFrame
+
+#print "Create Frame Control"
+myFC_AV = FC_AV()
+#print "Create MAC Frame Header"
+myMacFrameHeader = MACFrameHeader()
+myMacFrame = MACFrame()
+
+#Frame Control Variant Fields
+
+from struct import *
+
+from math import *
+from random import randrange #random library is used : randrange(),
+from Constants import *
+
+from crc24 import *
+
+
+#FcVfFields lists all fields existing in every Frame Control Variant Fields
+class FcVfFields():
+
+ #Network Encryption Key
+ nek = randrange(0,pow(2,128)-1,1) #Random by default
+ nekField = pack('QQ',nek%pow_2_64,nek/pow_2_64)
+ def createNek(self, myNek=None, myRandomNek=False):
+ if myNek!=None:
+ self.nek = myNek
+ elif myRandomNek==True:
+ self.nek = randrange(0,pow(2,128)-1,1)
+ self.nekField = pack('QQ',self.nek%pow_2_64,self.nek/pow_2_64)
+ print "nek = "+hex(self.nek)
+
+ #Beacon Time Stamp
+ bts = randrange(0,pow(2,32),1) #Random by default
+ btsField = pack('I',bts)
+ def createBts(self, myBts=None):
+ if myBts!=None:
+ self.bts = myBts
+ self.btsField = pack('I',self.bts)
+ print "bts = "+hex(self.bts)
+
+ #Beacon Time Offset
+ bto_0 = randrange(-pow(2,15)+1,pow(2,15)-1,1) #Random by default
+ bto_0Field = pack('h',bto_0)
+ def createBto_0(self, myBto_0=None):
+ if myBto_0!=None:
+ self.bto_0 = myBto_0
+ self.bto_0Field = pack('h',self.bto_0)
+ print "bto_0 = "+hex(self.bto_0)
+
+ #Beacon Time Offset
+ bto_1 = randrange(-pow(2,15)+1,pow(2,15)-1,1) #Random by default
+ bto_1Field = pack('h',bto_1)
+ def createBto_1(self, myBto_1=None):
+ if myBto_1!=None:
+ self.bto_1 = myBto_1
+ self.bto_1Field = pack('h',self.bto_1)
+ print "bto_1 = "+hex(self.bto_1)
+
+ #Beacon Time Offset
+ bto_2 = randrange(-pow(2,15)+1,pow(2,15)-1,1) #Random by default
+ bto_2Field = pack('h',bto_2)
+ def createBto_2(self, myBto_2=None):
+ if myBto_2!=None:
+ self.bto_2 = myBto_2
+ self.bto_2Field = pack('h',self.bto_2)
+ print "bto_2 = "+hex(self.bto_2)
+
+ #Beacon Time Offset
+ bto_3 = randrange(-pow(2,15)+1,pow(2,15)-1,1) #Random by default
+ bto_3Field = pack('h',bto_3)
+ def createBto_3(self, myBto_3=None):
+ if myBto_3!=None:
+ self.bto_3 = myBto_3
+ self.bto_3Field = pack('h',self.bto_3)
+ print "bto_3 = "+hex(self.bto_3)
+
+ #STEI
+ stei = 0
+ steiField = pack('B',stei)
+ def createStei(self, myStei=None):
+ if myStei!=None:
+ self.stei=myStei
+ self.steiField = pack('B',self.stei)
+ print "stei = "+hex(self.stei)
+
+ #DTEI
+ dtei = 0
+ dteiField = pack('B',dtei)
+ def createDtei(self, myDtei=None):
+ if myDtei!=None:
+ self.dtei=myDtei
+ self.dteiField = pack('B',self.dtei)
+ print "dtei = "+hex(self.dtei)
+
+ #LID
+ lid = 0
+ lidField = pack('B',lid)
+ def createLid(self, myLid=None):
+ if myLid!=None:
+ self.lid=myLid
+ self.lidField = pack('B',self.lid)
+ print "lid = "+hex(self.lid)
+
+ cfs = 0 #Contesion Free Session #CSMA Allocation by default
+ bdf = 0 #Beacon detect Flag #Not Heard by default
+ hp10df = 0 #Home Plug 1.0.1 Detect Flag #Not detected by default
+ hp11df = 0 #Home Plug 1.1 Detect Flag #Not detected by default
+ eks = 0 #Encryption Key Select #0 by default
+ cfsBdfHp10dfHp11dfEks = int(cfs + bdf*pow(2,1) + hp10df*pow(2,2) + hp11df*pow(2,3) + eks*pow(2,4))
+ cfsBdfHp10dfHp11dfEksField = pack('B',cfsBdfHp10dfHp11dfEks)
+ def createCfsBdfHp10dfHp11dfEks(self, myCfs=None, myBdf=None, myHp10df=None, myHp11df=None, myEks=None, myCfsBdfHp10dfHp11dfEks=None):
+ if myCfs!=None or myBdf!=None or myHp10df!=None or myHp11df!=None or myEks!=None:
+ if myCfs!=None:
+ self.cfs=myCfs
+ if myBdf!=None:
+ self.bdf=myBdf
+ if myHp10df!=None:
+ self.hp10df=myHp10df
+ if myHp11df!=None:
+ self.hp11df=myHp11df
+ if myEks!=None:
+ self.eks=myEks
+ self.cfsBdfHp10dfHp11dfEks = int(self.cfs + self.bdf*pow(2,1) + self.hp10df*pow(2,2) + self.hp11df*pow(2,3) + self.eks*pow(2,4))
+ if myCfsBdfHp10dfHp11dfEks!=None:
+ self.cfsBdfHp10dfHp11dfEks = myCfsBdfHp10dfHp11dfEks
+ print "cfsBdfHp10dfHp11dfEks = "+hex(self.cfsBdfHp10dfHp11dfEks)
+ else:
+ print "cfs = "+hex(self.cfs)
+ print "bdf = "+hex(self.bdf)
+ print "hp10df = "+hex(self.hp10df)
+ print "hp11df = "+hex(self.hp11df)
+ print "eks = "+hex(self.eks)
+ self.cfsBdfHp10dfHp11dfEksField = pack('B',self.cfsBdfHp10dfHp11dfEks)
+
+ #Pending PHY Blocks
+ intPpb = 0
+ if intPpb >= 16:
+ ppbExponent = max(0,int(log(max(2,intPpb),2))-3)
+ ppbMantissa = max(0,int(16*(intPpb/pow(2,ppbExponent+3)-1)))
+ else:
+ ppbExponent = 0
+ ppbMantissa = intPpb
+ ppb = int(ppbExponent + ppbMantissa*pow(2,4))
+ ppbField = pack('B',ppb)
+ def createPpb(self, myIntPpb=None, myPpb=None):
+ if myIntPpb!=None:
+ self.intPpb=myIntPpb
+ if self.intPpb >= 16:
+ self.ppbExponent = max(0,int(log(max(2,self.intPpb),2))-3)
+ self.ppbMantissa = max(0,int(16*(self.intPpb/pow(2,self.ppbExponent+3)-1)))
+ else:
+ self.ppbExponent = 0
+ self.ppbMantissa = self.intPpb
+ self.ppb = int(self.ppbExponent + self.ppbMantissa*pow(2,4))
+ elif myPpb!=None:
+ self.ppb=myPpb
+ self.ppbField = pack('B',self.ppb)
+ print "ppb = "+hex(self.ppb)
+
+ #Bit Loading Estimation
+ intBle = 0
+ bleExponent = max(0,int(log(max(2,intBle),2))-1)
+ bleMantissa = max(0,int(32*(intBle/pow(2,bleExponent+1)-1)))
+ ble = int(bleExponent + bleMantissa*pow(2,3))
+ bleField = pack('B',ble)
+ def createBle(self, myIntBle=None, myBle=None):
+ if myIntBle!=None:
+ self.intBle=myIntBle
+ self.bleExponent = max(0,int(log(max(2,self.intBle),2))-1)
+ self.bleMantissa = max(0,int(32*(self.intBle/pow(2,self.bleExponent+1)-1)))
+ self.ble = int(self.bleExponent + self.bleMantissa*pow(2,3))
+ if myBle!=None:
+ self.ble=myBle
+ self.bleField = pack('B',self.ble)
+ print "ble = "+hex(self.ble)
+
+ pbSz = 0 #PHY Block Size #520 octets by default
+ numSym = 1 #Number of symbol #1 by default
+ tmi_AV = 0 #Home Plug AV Tone Map Index #ROBO by default
+ pbSzNumSymTmi_AV = int(pbSz + numSym*pow(2,1) + tmi_AV*pow(2,3))
+ pbSzNumSymTmi_AVField = pack('B',pbSzNumSymTmi_AV)
+ def createPbSzNumSymTmi_AV(self, myPbSz=None, myNumSym=None, myTmi_AV=None, myPbSzNumSymTmi_AV=None):
+ if myPbSz!=None or myNumSym!=None or myTmi_AV!=None:
+ if myPbSz!=None:
+ self.pbSz=myPbSz
+ if myNumSym!=None:
+ self.numSym=myNumSym
+ if myTmi_AV!=None:
+ self.tmi_AV=myTmi_AV
+ self.pbSzNumSymTmi_AV = int(self.pbSz + self.numSym*pow(2,1) + self.tmi_AV*pow(2,3))
+ if myPbSzNumSymTmi_AV!=None:
+ self.pbSzNumSymTmi_AV = myPbSzNumSymTmi_AV
+ print "pbSzNumSymTmi_AV = "+hex(self.pbSzNumSymTmi_AV)
+ else:
+ print "pbSz = "+hex(self.pbSz)
+ print "numSym = "+hex(self.numSym)
+ print "tmi_AV = "+hex(self.tmi_AV)
+ self.pbSzNumSymTmi_AVField = pack('B',self.pbSzNumSymTmi_AV)
+
+ fl_AV = 0x3E #Home Plug AV Frame Length #79.36 µs by default
+ mpduCnt = 0 #MPDU Count #not a burst or last by default
+ burstCnt = 0 #Burst Count #0 by default
+ fl_AVMpduCntBurstCnt = int(fl_AV + mpduCnt*pow(2,12) + burstCnt*pow(2,14))
+ fl_AVMpduCntBurstCntField = pack('H',fl_AVMpduCntBurstCnt)
+ def createFl_AVMpduCntBurstCnt(self, myFl_AV=None, myMpduCnt=None, myBurstCnt=None, myFl_AVMpduCntBurstCnt=None):
+ if myFl_AV!=None or myMpduCnt!=None or myBurstCnt!=None:
+ if myFl_AV!=None:
+ self.fl_AV=myFl_AV
+ if myMpduCnt!=None:
+ self.mpduCnt=myMpduCnt
+ if myBurstCnt!=None:
+ self.burstCnt=myBurstCnt
+ self.fl_AVMpduCntBurstCnt = int(self.fl_AV + self.mpduCnt*pow(2,12) + self.burstCnt*pow(2,14))
+ if myFl_AVMpduCntBurstCnt!=None:
+ self.fl_AVMpduCntBurstCnt = myFl_AVMpduCntBurstCnt
+ print "fl_AVMpduCntBurstCnt = "+hex(self.fl_AVMpduCntBurstCnt)
+ else:
+ print "fl_AV = "+hex(self.fl_AV)
+ print "mpduCnt = "+hex(self.mpduCnt)
+ print "burstCnt = "+hex(self.burstCnt)
+ self.fl_AVMpduCntBurstCntField = pack('H',self.fl_AVMpduCntBurstCnt)
+
+ bbf = 0 #Bidirectional Burst Flag #Terminated after this MPDU by default
+ mrtfl = 0 #Max Reverse Transmission FL #163.84 µs by default
+ dcppcf = 0 #Different CP PHY Clock Flag #Not different by default
+ mcf = 0 #Multicast Flag #Unicast by default
+ mnbf = 0 #MultiNetwork Broadcast Flag #0 by default
+ bbfMrtflDcppcfMcfMnbf = int(bbf + mrtfl*pow(2,1) + dcppcf*pow(2,5) + mcf*pow(2,6) + mnbf*pow(2,7))
+ bbfMrtflDcppcfMcfMnbfField = pack('B',bbfMrtflDcppcfMcfMnbf)
+ def createBbfMrtflDcppcfMcfMnbf(self, myBbf=None, myMrtfl=None, myDcppcf=None, myMcf=None, myMnbf=None, myBbfMrtflDcppcfMcfMnbf=None):
+ if myBbf!=None or myMrtfl!=None or myDcppcf!=None or myMcf!=None or myMnbf!=None:
+ if myBbf!=None:
+ self.bbf=myBbf
+ if myMrtfl!=None:
+ self.mrtfl=myMrtfl
+ if myDcppcf!=None:
+ self.dcppcf=myDcppcf
+ if myMcf!=None:
+ self.mcf=myMcf
+ if myMnbf!=None:
+ self.mnbf=myMnbf
+ self.bbfMrtflDcppcfMcfMnbf = int(self.bbf + self.mrtfl*pow(2,1) + self.dcppcf*pow(2,5) + self.mcf*pow(2,6) + self.mnbf*pow(2,7))
+ if myBbfMrtflDcppcfMcfMnbf!=None:
+ self.bbfMrtflDcppcfMcfMnbf = myBbfMrtflDcppcfMcfMnbf
+ print "bbfMrtflDcppcfMcfMnbf = "+hex(self.bbfMrtflDcppcfMcfMnbf)
+ else:
+ print "bbf = "+hex(self.bbf)
+ print "mrtfl = "+hex(self.mrtfl)
+ print "dcppcf = "+hex(self.dcppcf)
+ print "mcf = "+hex(self.mcf)
+ print "mnbf = "+hex(self.mnbf)
+ self.bbfMrtflDcppcfMcfMnbfField = pack('B',self.bbfMrtflDcppcfMcfMnbf)
+
+ rsr = 0 #Request SACK retransmission #Not requested by default
+ clst = 0 #Convergence Layer SAP Type #Ethernet II by default
+ mfsCmdMgmt = 4 #Management MFS Command #NOP by default
+ mfsCmdData = 4 #Data MFS Command #NOP by default
+ rsrClstMfsCmdMgmtMfsCmdData = int(rsr + clst*pow(2,1) + mfsCmdMgmt*pow(2,2) + mfsCmdData*pow(2,5))
+ rsrClstMfsCmdMgmtMfsCmdDataField = pack('B',rsrClstMfsCmdMgmtMfsCmdData)
+ def createRsrClstMfsCmdMgmtMfsCmdData(self, myRsr=None, myClst=None, myMfsCmdMgmt=None, myMfsCmdData=None, myRsrClstMfsCmdMgmtMfsCmdData=None):
+ if myRsr!=None or myClst!=None or myMfsCmdMgmt!=None or myMfsCmdData!=None:
+ if myRsr!=None:
+ self.rsr=myRsr
+ if myClst!=None:
+ self.clst=myClst
+ if myMfsCmdMgmt!=None:
+ self.mfsCmdMgmt=myMfsCmdMgmt
+ if myMfsCmdData!=None:
+ self.mfsCmdData=myMfsCmdData
+ self.rsrClstMfsCmdMgmtMfsCmdData = int(self.rsr + self.clst*pow(2,1) + self.mfsCmdMgmt*pow(2,2) + self.mfsCmdData*pow(2,5))
+ if myRsrClstMfsCmdMgmtMfsCmdData!=None:
+ self.rsrClstMfsCmdMgmtMfsCmdData = myRsrClstMfsCmdMgmtMfsCmdData
+ print "rsrClstMfsCmdMgmtMfsCmdData = "+hex(self.rsrClstMfsCmdMgmtMfsCmdData)
+ else:
+ print "rsr = "+hex(self.rsr)
+ print "clst = "+hex(self.clst)
+ print "mfsCmdMgmt = "+hex(self.mfsCmdMgmt)
+ print "mfsCmdData = "+hex(self.mfsCmdData)
+ self.rsrClstMfsCmdMgmtMfsCmdDataField = pack('B',self.rsrClstMfsCmdMgmtMfsCmdData)
+
+ mfsRspMgmt = 0 #Management MFS Response #ACK by default
+ mfsRspData = 1 #Data MFS Response #ACK by default
+ bm_SACKI = 0 #Bit Map SACK Info #All Succesfully Received by default
+ mfsRspMgmtMfsRspDataBm_SACKI = int(mfsRspMgmt + mfsRspData*pow(2,2) + bm_SACKI*pow(2,4))
+ mfsRspMgmtMfsRspDataBm_SACKIField = pack('B',mfsRspMgmtMfsRspDataBm_SACKI)
+ def createMfsRspMgmtMfsRspDataBm_SACKI(self, myMfsRspMgmt=None, myMfsRspData=None, myBm_SACKI=None, myMfsRspMgmtMfsRspDataBm_SACKI=None):
+ if myMfsRspMgmt!=None or myMfsRspData!=None or myBm_SACKI!=None:
+ if myMfsRspMgmt!=None:
+ self.mfsRspMgmt=myMfsRspMgmt
+ if myMfsRspData!=None:
+ self.mfsRspData=myMfsRspData
+ if myBm_SACKI!=None:
+ self.bm_SACKI=myBm_SACKI
+ self.mfsRspMgmtMfsRspDataBm_SACKI = int(self.mfsRspMgmt + self.mfsRspData*pow(2,2) + self.bm_SACKI*pow(2,4))
+ if myMfsRspMgmtMfsRspDataBm_SACKI!=None:
+ self.mfsRspMgmtMfsRspDataBm_SACKI = myMfsRspMgmtMfsRspDataBm_SACKI
+ print "mfsRspMgmtMfsRspDataBm_SACKI = "+hex(self.mfsRspMgmtMfsRspDataBm_SACKI)
+ else:
+ print "mfsRspMgmt = "+hex(self.mfsRspMgmt)
+ print "mfsRspData = "+hex(self.mfsRspData)
+ print "bm_SACKI = "+hex(self.bm_SACKI)
+ self.mfsRspMgmtMfsRspDataBm_SACKIField = pack('B',self.mfsRspMgmtMfsRspDataBm_SACKI)
+
+ #cfs = 0 #Contesion Free Session #CSMA Allocation by default
+ #bdf = 0 #Beacon detect Flag #Not Heard by default
+ svn = 0 #SACK Version Number #Curent Version by default
+ rrtf = 0 #Request Reverse Transmission Flag #Not Requested by default
+ #mfsRspData = 1 #Data MFS Response #ACK by default
+ #mfsRspMgmt = 0 #Management MFS Response #ACK by default
+ cfsBdfSvnRrtfMfsRspDataMfsRspMgmt = int(cfs + bdf*pow(2,1) + svn*pow(2,2) + rrtf*pow(2,3) + mfsRspMgmt*pow(2,4) + mfsRspData*pow(2,6))
+ cfsBdfSvnRrtfMfsRspDataMfsRspMgmtField = pack('B',cfsBdfSvnRrtfMfsRspDataMfsRspMgmt)
+ def createCfsBdfSvnRrtfMfsRspDataMfsRspMgmt(self, myCfs=None, myBdf=None, mySvn=None, myRrtf=None, myMfsRspMgmt=None, myMfsRspData=None, myCfsBdfSvnRrtfMfsRspDataMfsRspMgmt=None):
+ if myCfs!=None or myBdf!=None or mySvn!=None or myRrtf!=None or myMfsRspMgmt!=None or myMfsRspData!=None:
+ if myCfs!=None:
+ self.cfs=myCfs
+ if myBdf!=None:
+ self.bdf=myBdf
+ if mySvn!=None:
+ self.svn=mySvn
+ if myRrtf!=None:
+ self.rrtf=myRrtf
+ if myMfsRspMgmt!=None:
+ self.mfsRspMgmt=myMfsRspMgmt
+ if myMfsRspData!=None:
+ self.mfsRspData=myMfsRspData
+ self.cfsBdfSvnRrtfMfsRspDataMfsRspMgmt = int(self.cfs + self.bdf*pow(2,1) + self.svn*pow(2,2) + self.rrtf*pow(2,3) + self.mfsRspMgmt*pow(2,4) + self.mfsRspData*pow(2,6))
+ if myCfsBdfSvnRrtfMfsRspDataMfsRspMgmt!=None:
+ self.cfsBdfSvnRrtfMfsRspDataMfsRspMgmt = myCfsBdfSvnRrtfMfsRspDataMfsRspMgmt
+ print "cfsBdfSvnRrtfMfsRspDataMfsRspMgmt = "+hex(self.cfsBdfSvnRrtfMfsRspDataMfsRspMgmt)
+ else:
+ print "cfs = "+hex(self.cfs)
+ print "bdf = "+hex(self.bdf)
+ print "svn = "+hex(self.svn)
+ print "rrtf = "+hex(self.rrtf)
+ print "mfsRspMgmt = "+hex(self.mfsRspMgmt)
+ print "mfsRspData = "+hex(self.mfsRspData)
+ self.cfsBdfSvnRrtfMfsRspDataMfsRspMgmtField = pack('B',self.cfsBdfSvnRrtfMfsRspDataMfsRspMgmt)
+
+ #SACKTs
+ sackts = []
+ sacktsField = ""
+ i = 0
+ while i < 4:
+ sackts.append(i)
+ i=i+1
+ sacktsField = pack('B', sackts[0] + sackts[1]*pow(2,2) + sackts[2]*pow(2,4) + sackts[3]*pow(2,6))
+ def createSackts(self, mySackt0=None, mySackt1=None, mySackt2=None, mySackt3=None):
+ print "sackts :"
+ if mySackt0!=None:
+ self.sackts[0]=mySackt0
+ print "sackts[0] = "+hex(self.sackts[0])
+ if mySackt1!=None:
+ self.sackts[1]=mySackt1
+ print "sackts[1] = "+hex(self.sackts[1])
+ if mySackt2!=None:
+ self.sackts[2]=mySackt2
+ print "sackts[2] = "+hex(self.sackts[2])
+ if mySackt3!=None:
+ self.sackts[3]=mySackt3
+ print "sackts[3] = "+hex(self.sackts[3])
+ self.sacktsField=pack('B',self.sackts[0] + self.sackts[1]*pow(2,2) + self.sackts[2]*pow(2,4) + self.sackts[3]*pow(2,6))
+
+ #SACK Infomation, Bit Pad, Receive Window Size and Request Reverse Transmission
+ sackiPad = 0 #8 or 9 octets size Field #0 by default
+ rxwsz = 0 #0 or 4 bits size Field #4 Segments by default
+ rrtl = 0 #0 or 4 bits size Field #163.84 µs by default
+ shortPad = False #size of sackiPadRxwszRrtl = 7 octets (instead of 10)
+ sackiPadRxwszRrtl = int((rrtl*pow(2,4)*rrtf + rxwsz*pow(2,4)*((rrtf+1)%2) + rxwsz*rrtf)*pow_2_63 + sackiPad)
+ sackiPadRxwszRrtlField = pack('Q',sackiPadRxwszRrtl%pow_2_64)+pack('B',sackiPadRxwszRrtl/pow_2_64)
+ def createSackiPadRxwszRrtl(self, mySackiPad=None, myRxwsz=None, myRrtl=None, myShortPad=None):
+ if mySackiPad!=None:
+ self.sackiPad=mySackiPad
+ print "sackiPad = "+hex(self.sackiPad)
+ if myRxwsz!=None:
+ self.rxwsz=myRxwsz
+ print "rxwsz = "+hex(self.rxwsz)
+ if myRrtl!=None:
+ self.rrtl=myRrtl
+ print "rrtl = "+hex(self.rrtl)
+ if myShortPad!=None:
+ self.shortPad=myShortPad
+ if self.shortPad == False:
+ self.sackiPadRxwszRrtl = int((self.rrtl*pow(2,4)*self.rrtf + self.rxwsz*pow(2,4)*((self.rrtf+1)%2) + self.rxwsz*self.rrtf)*pow_2_63 + self.sackiPad)
+ self.sackiPadRxwszRrtlField = pack('Q',self.sackiPadRxwszRrtl%pow_2_64) + pack('B',self.sackiPadRxwszRrtl/pow_2_64)
+ else:
+ self.sackiPadRxwszRrtl = int((self.rrtl*pow(2,4)*self.rrtf + self.rxwsz*pow(2,4)*((self.rrtf+1)%2) + self.rxwsz*self.rrtf)*pow(2,39) + self.sackiPad)
+ self.sackiPadRxwszRrtlField = pack('Q',self.sackiPadRxwszRrtl)[0:6]
+
+ #SACK Data, Bit Pad, Receive Window Size and Request Reverse Transmission
+ sackdPadRxwszRrtlField = sacktsField + sackiPadRxwszRrtlField
+ def createSackdPadRxwszRrtl(self, mySackt0=None, mySackt1=None, mySackt2=None, mySackt3=None, mySackiPad=None, myRxwsz=None, myRrtl=None, myShortPad=None):
+ self.createSackts(mySackt0, mySackt1, mySackt2, mySackt3)
+ self.createSackiPadRxwszRrtl(mySackiPad, myRxwsz, myRrtl, myShortPad)
+ self.sackdPadRxwszRrtlField = self.sacktsField + self.sackiPadRxwszRrtlField
+
+ #cfs = 0 #Contesion Free Session #CSMA Allocation by default
+ #bdf = 0 #Beacon detect Flag #Not Heard by default
+ #hp10df = 0 #Home Plug 1.0.1 Detect Flag #Not detected by default
+ #hp11df = 0 #Home Plug 1.1 Detect Flag #Not detected by default
+ rtsf = 0 #RTS Flag #CTS by default
+ igf = 0 #Immediate Grant Flag #0 by default
+ #mnbf = 0 #MultiNetwork Broadcast Flag #0 by default
+ #mcf = 0 #Multicast Flag #Unicast by default
+ cfsBdfHp10dfHp11dfRtsfIgfMnbfMcf = int(cfs + bdf*pow(2,1) + hp10df*pow(2,2) + hp11df*pow(2,3) + rtsf*pow(2,4) + igf*pow(2,5) + mnbf*pow(2,6) + mcf*pow(2,7))
+ cfsBdfHp10dfHp11dfRtsfIgfMnbfMcfField = pack('B',cfsBdfHp10dfHp11dfRtsfIgfMnbfMcf)
+ def createCfsBdfHp10dfHp11dfRtsfIgfMnbfMcf(self, myCfs=None, myBdf=None, myHp10df=None, myHp11df=None, myRtsf=None, myIgf=None, myMnbf=None, myMcf=None, myCfsBdfHp10dfHp11dfRtsfIgfMnbfMcf=None):
+ if myCfs!=None or myBdf!=None or myHp10df!=None or myHp11df!=None or myRtsf!=None or myIgf!=None or myMnbf!=None or myMcf!=None:
+ if myCfs!=None:
+ self.cfs=myCfs
+ if myBdf!=None:
+ self.bdf=myBdf
+ if myHp10df!=None:
+ self.hp10df=myHp10df
+ if myHp11df!=None:
+ self.hp11df=myHp11df
+ if myRtsf!=None:
+ self.rtsf=myRtsf
+ if myIgf!=None:
+ self.igf=myIgf
+ if myMnbf!=None:
+ self.mnbf=myMnbf
+ if myMcf!=None:
+ self.mcf=myMcf
+ self.cfsBdfHp10dfHp11dfRtsfIgfMnbfMcf = int(self.cfs + self.bdf*pow(2,1) + self.hp10df*pow(2,2) + self.hp11df*pow(2,3) + self.rtsf*pow(2,4) + self.igf*pow(2,5) + self.mnbf*pow(2,6) + self.mcf*pow(2,7))
+ if myCfsBdfHp10dfHp11dfRtsfIgfMnbfMcf!=None:
+ self.cfsBdfHp10dfHp11dfRtsfIgfMnbfMcf = myCfsBdfHp10dfHp11dfRtsfIgfMnbfMcf
+ print "cfsBdfHp10dfHp11dfRtsfIgfMnbfMcf = "+hex(self.cfsBdfHp10dfHp11dfRtsfIgfMnbfMcf)
+ else:
+ print "cfs = "+hex(self.cfs)
+ print "bdf = "+hex(self.bdf)
+ print "hp10df = "+hex(self.hp10df)
+ print "hp11df = "+hex(self.hp11df)
+ print "rtsf = "+hex(self.rtsf)
+ print "igf = "+hex(self.igf)
+ print "mnbf = "+hex(self.mnbf)
+ print "mcf = "+hex(self.mcf)
+ self.cfsBdfHp10dfHp11dfRtsfIgfMnbfMcfField = pack('B',self.cfsBdfHp10dfHp11dfRtsfIgfMnbfMcf)
+
+ #Duration and reserved
+ durNRsvd = 10000 #10000 *1.28 µs = 12.8 ms by default
+ durNRsvdField = pack('Q',durNRsvd)
+ def createDurNRsvd(self, myDurNRsvd=None):
+ if myDurNRsvd!=None:
+ self.durNRsvd=myDurNRsvd
+ self.durNRsvdField = pack('Q',self.durNRsvd)
+ print "durNRsvd = "+hex(self.durNRsvd)
+
+ #cfs = 0 #Contesion Free Session #CSMA Allocation by default
+ #pbSz = 0 #PHY Block Size #520 octets by default
+ #bdf = 0 #Beacon detect Flag #Not Heard by default
+ saf = 0 #Sound ACK Flag #Sound MPDU by default
+ scf = 0 #Sound Complete Flag #Not Complete by default
+ req_TM = 7 #Max Tone Map Requested #7 Tone Maps supported by default
+ cfsPbSzBdfSafScfReq_TM = int(cfs + pbSz*pow(2,1) + bdf*pow(2,2) + saf*pow(2,3) + scf*pow(2,4) + req_TM*pow(2,5))
+ cfsPbSzBdfSafScfReq_TMField = pack('B',cfsPbSzBdfSafScfReq_TM)
+ def createCfsPbSzBdfSafScfReq_TM(self, myCfs=None, myPbSz=None, myBdf=None, mySaf=None, myScf=None, myReq_TM=None, myCfsPbSzBdfSafScfReq_TM=None):
+ if myCfs!=None or myPbSz!=None or myBdf!=None or mySaf!=None or myScf!=None or myReq_TM!=None:
+ if myCfs!=None:
+ self.cfs=myCfs
+ if myPbSz!=None:
+ self.pbSz=myPbSz
+ if myBdf!=None:
+ self.bdf=myBdf
+ if mySaf!=None:
+ self.saf=mySaf
+ if myScf!=None:
+ self.scf=myScf
+ if myReq_TM!=None:
+ self.req_TM=myReq_TM
+ self.cfsPbSzBdfSafScfReq_TM = int(self.cfs + self.pbSz*pow(2,1) + self.bdf*pow(2,2) + self.saf*pow(2,3) + self.scf*pow(2,4) + self.req_TM*pow(2,5))
+ if myCfsPbSzBdfSafScfReq_TM!=None:
+ self.cfsPbSzBdfSafScfReq_TM = myCfsPbSzBdfSafScfReq_TM
+ print "cfsPbSzBdfSafScfReq_TM = "+hex(self.cfsPbSzBdfSafScfReq_TM)
+ else:
+ print "cfs = "+hex(self.cfs)
+ print "pbSz = "+hex(self.pbSz)
+ print "bdf = "+hex(self.bdf)
+ print "saf = "+hex(self.saf)
+ print "scf = "+hex(self.scf)
+ print "req_TM = "+hex(self.req_TM)
+ self.cfsPbSzBdfSafScfReq_TMField = pack('B',self.cfsPbSzBdfSafScfReq_TM)
+
+ #fl_AV = 0x3E #Home Plug AV Frame Length #79.36 µs by default
+ #mpduCnt = 0 #MPDU Count #not a burst or last by default
+ fl_AVMpduCnt = int(fl_AV + mpduCnt*pow(2,12))
+ fl_AVMpduCntField = pack('H',fl_AVMpduCnt)
+ def createFl_AVMpduCnt(self, myFl_AV=None, myMpduCnt=None, myFl_AVMpduCnt=None):
+ if myFl_AV!=None or myMpduCnt!=None:
+ if myFl_AV!=None:
+ self.fl_AV=myFl_AV
+ if myMpduCnt!=None:
+ self.mpduCnt=myMpduCnt
+ self.fl_AVMpduCnt = int(self.fl_AV + self.mpduCnt*pow(2,12))
+ if myFl_AVMpduCnt!=None:
+ self.fl_AVMpduCnt = myFl_AVMpduCnt
+ print "fl_AVMpduCnt = "+hex(self.fl_AVMpduCnt)
+ else:
+ print "fl_AV = "+hex(self.fl_AV)
+ print "mpduCnt = "+hex(self.mpduCnt)
+ self.fl_AVMpduCntField = pack('H',self.fl_AVMpduCnt)
+
+ #Sound Reason Code
+ src = 4 #4 by default
+ srcField = pack('B',src)
+ def createSrc(self, mySrc=None):
+ if mySrc!=None:
+ self.src=mySrc
+ self.srcField = pack('B',self.src)
+ print "src = "+hex(self.src)
+
+ rsof_fl_AV = 0x3E #Reverse SOF Frame Length #79.36 µs by default
+ #tmi_AV = 0 #Home Plug AV Tone Map Index #ROBO by default
+ #pbSz = 0 #PHY Block Size #520 octets by default
+ rsof_fl_AVTmi_AVPbSz = int(rsof_fl_AV + tmi_AV*pow(2,12) + pbSz*pow(2,15))
+ rsof_fl_AVTmi_AVPbSzField = pack('H',rsof_fl_AVTmi_AVPbSz)
+ def createRsof_fl_AVTmi_AVPbSz(self, myRsof_fl_AV=None, myTmi_AV=None, myPbSz=None, myRsof_fl_AVTmi_AVPbSz=None):
+ if myRsof_fl_AV!=None or myTmi_AV!=None or myPbSz!=None:
+ if myRsof_fl_AV!=None:
+ self.rsof_fl_AV=myRsof_fl_AV
+ if myTmi_AV!=None:
+ self.tmi_AV=myTmi_AV
+ if myPbSz!=None:
+ self.pbSz=myPbSz
+ self.rsof_fl_AVTmi_AVPbSz = int(self.rsof_fl_AV + self.tmi_AV*pow(2,12) + self.pbSz*pow(2,15))
+ if myRsof_fl_AVTmi_AVPbSz!=None:
+ self.rsof_fl_AVTmi_AVPbSz = myRsof_fl_AVTmi_AVPbSz
+ print "rsof_fl_AVTmi_AVPbSz = "+hex(self.rsof_fl_AVTmi_AVPbSz)
+ else:
+ print "rsof_fl_AV = "+hex(self.rsof_fl_AV)
+ print "tmi_AV = "+hex(self.tmi_AV)
+ print "pbSz = "+hex(self.pbSz)
+ self.rsof_fl_AVTmi_AVPbSzField = pack('H',self.rsof_fl_AVTmi_AVPbSz)
+
+ #numSym = 1 #Number of symbol #1 by default
+ #mfsCmdMgmt = 4 #Management MFS Command #NOP by default
+ #mfsCmdData = 4 #Data MFS Command #NOP by default
+ numSymMfsCmdMgmtMfsCmdData = int(numSym + mfsCmdMgmt*pow(2,2) + mfsCmdData*pow(2,5))
+ numSymMfsCmdMgmtMfsCmdDataField = pack('B',numSymMfsCmdMgmtMfsCmdData)
+ def createNumSymMfsCmdMgmtMfsCmdData(self, myNumSym=None, myMfsCmdMgmt=None, myMfsCmdData=None, myNumSymMfsCmdMgmtMfsCmdData=None):
+ if myNumSym!=None or myMfsCmdMgmt!=None or myMfsCmdData!=None:
+ if myNumSym!=None:
+ self.numSym=myNumSym
+ if myMfsCmdMgmt!=None:
+ self.mfsCmdMgmt=myMfsCmdMgmt
+ if myMfsCmdData!=None:
+ self.mfsCmdData=myMfsCmdData
+ self.numSymMfsCmdMgmtMfsCmdData = int(self.numSym + self.mfsCmdMgmt*pow(2,2) + self.mfsCmdData*pow(2,5))
+ if myNumSymMfsCmdMgmtMfsCmdData!=None:
+ self.numSymMfsCmdMgmtMfsCmdData = myNumSymMfsCmdMgmtMfsCmdData
+ print "numSymMfsCmdMgmtMfsCmdData = "+hex(self.numSymMfsCmdMgmtMfsCmdData)
+ else:
+ print "numSym = "+hex(self.numSym)
+ print "mfsCmdMgmt = "+hex(self.mfsCmdMgmt)
+ print "mfsCmdData = "+hex(self.mfsCmdData)
+ self.numSymMfsCmdMgmtMfsCmdDataField = pack('B',self.numSymMfsCmdMgmtMfsCmdData)
+
+
+ #Beacon Variant Field
+ bvf = btsField + bto_0Field + bto_1Field + bto_2Field + bto_3Field
+ def createBvf(self, myBts=None, myBto_0=None, myBto_1=None, myBto_2=None, myBto_3=None, myBvf=None):
+ if myBvf!=None:
+ self.bvf = myBvf
+ print "bvf = "+self.bvf
+ else:
+ print "bvf :"
+ self.createBts(myBts)
+ self.createBto_0(myBto_0)
+ self.createBto_1(myBto_1)
+ self.createBto_2(myBto_2)
+ self.createBto_3(myBto_3)
+ self.bvf = self.btsField + self.bto_0Field + self.bto_1Field + self.bto_2Field + self.bto_3Field
+
+
+ #SOF Variant Field
+ sofvf = steiField + dteiField + lidField + cfsBdfHp10dfHp11dfEksField + ppbField + bleField + pbSzNumSymTmi_AVField + fl_AVMpduCntBurstCntField + bbfMrtflDcppcfMcfMnbfField + rsrClstMfsCmdMgmtMfsCmdDataField + mfsRspMgmtMfsRspDataBm_SACKIField
+ def createSofvf(self, myStei=None, myDtei=None, myLid=None, myCfs=None, myBdf=None, myHp10df=None, myHp11df=None, myEks=None, myPpb=None, myBle=None, myPbSz=None, myNumSym=None, myTmi_AV=None, myFl_AV=None, myMpduCnt=None, myBurstCnt=None, myBbf=None, myMrtfl=None, myDcppcf=None, myMcf=None, myMnbf=None, myRsr=None, myClst=None, myMfsCmdMgmt=None, myMfsCmdData=None, myMfsRspMgmt=None, myMfsRspData=None, myBm_SACKI=None, mySofvf=None):
+ if mySofvf!=None:
+ self.sofvf = mySofvf
+ print "sofvf = "+self.sofvf
+ else:
+ print "sofvf :"
+ self.createStei(myStei)
+ self.createDtei(myDtei)
+ self.createLid(myLid)
+ self.createCfsBdfHp10dfHp11dfEks(myCfs, myBdf, myHp10df, myHp11df, myEks)
+ self.createPpb(myPpb)
+ self.createBle(myBle)
+ self.createPbSzNumSymTmi_AV(myPbSz, myNumSym, myTmi_AV)
+ self.createFl_AVMpduCntBurstCnt(myFl_AV, myMpduCnt, myBurstCnt)
+ self.createRsrClstMfsCmdMgmtMfsCmdData(myRsr, myClst, myMfsCmdMgmt, myMfsCmdData)
+ self.createMfsRspMgmtMfsRspDataBm_SACKI(myMfsRspMgmt, myMfsRspData, myBm_SACKI)
+ self.createBbfMrtflDcppcfMcfMnbf(myBbf, myMrtfl, myDcppcf, myMcf, myMnbf)
+ self.sofvf = self.steiField + self.dteiField + self.lidField + self.cfsBdfHp10dfHp11dfEksField + self.ppbField + self.bleField + self.pbSzNumSymTmi_AVField + self.fl_AVMpduCntBurstCntField + self.bbfMrtflDcppcfMcfMnbfField + self.rsrClstMfsCmdMgmtMfsCmdDataField + self.mfsRspMgmtMfsRspDataBm_SACKIField
+
+
+ #SACK Variant Field
+ sackvf = dteiField + cfsBdfSvnRrtfMfsRspDataMfsRspMgmtField + sackdPadRxwszRrtlField
+ def createSackvf(self, myDtei=None, myCfs=None, myBdf=None, mySvn=None, myRrtf=None, myMfsRspMgmt=None, myMfsRspData=None, mySackt0=None, mySackt1=None, mySackt2=None, mySackt3=None, mySackiPad=None, myRxwsz=None, myRrtl=None, mySackvf=None):
+ if mySackvf!=None:
+ self.sackvf = mySackvf
+ print "sackvf = "+self.sackvf
+ else:
+ print "sackvf :"
+ self.createDtei(myDtei)
+ self.createCfsBdfSvnRrtfMfsRspDataMfsRspMgmt(myCfs, myBdf, mySvn, myRrtf, myMfsRspMgmt, myMfsRspData)
+ self.createSackdPadRxwszRrtl(mySackt0, mySackt1, mySackt2, mySackt3, mySackiPad, myRxwsz, myRrtl)
+ self.sackvf = self.dteiField + self.cfsBdfSvnRrtfMfsRspDataMfsRspMgmtField + self.sackdPadRxwszRrtlField
+
+
+ #RTS/CTS Variant Field
+ rtsctsvf = steiField + dteiField + lidField + cfsBdfHp10dfHp11dfRtsfIgfMnbfMcfField + durNRsvdField
+ def createRtsctsvf(self, myStei=None, myDtei=None, myLid=None, myCfs=None, myBdf=None, myHp10df=None, myHp11df=None, myRtsf=None, myIgf=None, myMnbf=None, myMcf=None, myDurNRsvd=None, myRtsctsvf=None):
+ if myRtsctsvf!=None:
+ self.rtsctsvf = myRtsctsvf
+ print "rtsctsvf = "+self.rtsctsvf
+ else:
+ print "rtsctsvf :"
+ self.createStei(myStei)
+ self.createDtei(myDtei)
+ self.createLid(myLid)
+ self.createCfsBdfHp10dfHp11dfRtsfIgfMnbfMcf(myCfs, myBdf, myHp10df, myHp11df, myRtsf, myIgf, myMnbf, myMcf)
+ self.createDurNRsvd(myDurNRsvd)
+ self.rtsctsvf = self.steiField + self.dteiField + self.lidField + self.cfsBdfHp10dfHp11dfRtsfIgfMnbfMcfField + self.durNRsvdField
+
+
+ #Sound Variant Field
+ soundvf = steiField + dteiField + lidField + cfsPbSzBdfSafScfReq_TMField + fl_AVMpduCntField + ppbField + srcField + pack('B',0)*4
+ def createSoundvf(self, myStei=None, myDtei=None, myLid=None, myCfs=None, myPbSz=None, myBdf=None, mySaf=None, myScf=None, myReq_TM=None, myFl_AV=None, myMpduCnt=None, myPpb=None, mySrc=None, mySoundvf=None):
+ if mySoundvf!=None:
+ self.soundvf = mySoundvf
+ print "soundvf = "+self.soundvf
+ else:
+ print "soundvf :"
+ self.createStei(myStei)
+ self.createDtei(myDtei)
+ self.createLid(myLid)
+ self.createCfsPbSzBdfSafScfReq_TM(myCfs, myPbSz, myBdf, mySaf, myScf, myReq_TM)
+ self.createFl_AVMpduCnt(myFl_AV, myMpduCnt)
+ self.createPpb(myPpb)
+ self.createSrc(mySrc)
+ self.soundvf = self.steiField + self.dteiField + self.lidField + self.cfsPbSzBdfSafScfReq_TMField + self.fl_AVMpduCntField + self.ppbField + self.srcField + pack('B',0)*4
+
+
+ #Reverse SOF Variant Field
+ sackiPadRxwszRrtl = int((rrtl*pow(2,4)*rrtf + rxwsz*pow(2,4)*((rrtf+1)%2) + rxwsz*rrtf)*pow(2,39) + sackiPad)
+ sackiPadRxwszRrtlField = pack('Q',sackiPadRxwszRrtl%pow_2_64)[0:6]
+ sackdPadRxwszRrtlField = sacktsField + sackiPadRxwszRrtlField
+ rsofvf = dteiField + cfsBdfSvnRrtfMfsRspDataMfsRspMgmtField + sackdPadRxwszRrtlField + rsof_fl_AVTmi_AVPbSzField + numSymMfsCmdMgmtMfsCmdDataField
+ def createRsofvf(self, myDtei=None, myCfs=None, myBdf=None, mySvn=None, myRrtf=None, myMfsRspMgmt=None, myMfsRspData=None, mySackt0=None, mySackt1=None, mySackt2=None, mySackt3=None, mySackiPad=None, myRxwsz=None, myRrtl=None, myShortPad=True, myRsof_fl_AV=None, myTmi_AV=None, myPbSz=None, myNumSym=None, myMfsCmdMgmt=None, myMfsCmdData=None, myRsofvf=None):
+ if myRsofvf!=None:
+ self.rsofvf = myRsofvf
+ print "rsofvf = "+self.rsofvf
+ else:
+ print "rsofvf :"
+ self.createDtei(myDtei)
+ self.createCfsBdfSvnRrtfMfsRspDataMfsRspMgmt(myCfs, myBdf, mySvn, myRrtf, myMfsRspMgmt, myMfsRspData)
+ self.createSackdPadRxwszRrtl(mySackt0, mySackt1, mySackt2, mySackt3, mySackiPad, myRxwsz, myRrtl, myShortPad)
+ self.createRsof_fl_AVTmi_AVPbSz(myRsof_fl_AV, myTmi_AV, myPbSz)
+ self.createNumSymMfsCmdMgmtMfsCmdData(myPbSz, myNumSym, myTmi_AV)
+ self.rsofvf = self.dteiField + self.cfsBdfSvnRrtfMfsRspDataMfsRspMgmtField + self.sackdPadRxwszRrtlField + self.rsof_fl_AVTmi_AVPbSzField + self.numSymMfsCmdMgmtMfsCmdDataField
+
+
+ #DT_AV - ACCESS - SNID
+ snid = 0xA
+ access = 0 #in home by default
+ dt_AV = 1 #SOF by default
+ dt_AVAccessSnid = int(dt_AV + access*pow(2,3) + snid*pow(2,4))
+ dt_AVAccessSnidField = pack('B',dt_AVAccessSnid)
+ def createDt_AVAccessSnid(self, myDt_AV=None, myAccess=None, mySnid=None, myDt_AVAccessSnid=None):
+ if myDt_AV!=None:
+ self.dt_AV=myDt_AV
+ if myAccess!=None:
+ self.access=myAccess
+ if mySnid!=None:
+ self.snid=mySnid
+ if myDt_AVAccessSnid!=None:
+ self.dt_AVAccessSnid=myDt_AVAccessSnid
+ print "dt_AVAccessSnid = "+hex(self.dt_AVAccessSnid)
+ else:
+ self.dt_AVAccessSnid = int(self.dt_AV + self.access*pow(2,3) + self.snid*pow(2,4))
+ print "dt_AV = "+DT_AV[self.dt_AV]
+ print "access = "+hex(self.access)
+ print "snid = "+hex(self.snid)
+ self.dt_AVAccessSnidField = pack('B',self.dt_AVAccessSnid)
+
+
+ #VF_AV
+ vf_AV = sofvf #SOF by default
+ def createVf_AV(self, myBts=None, myBto_0=None, myBto_1=None, myBto_2=None, myBto_3=None, myBvf=None, myStei=None, myDtei=None, myLid=None, myCfs=None, myBdf=None, myHp10df=None, myHp11df=None, myEks=None, myPpb=None, myBle=None, myPbSz=None, myNumSym=None, myTmi_AV=None, myFl_AV=None, myMpduCnt=None, myBurstCnt=None, myBbf=None, myMrtfl=None, myDcppcf=None, myMcf=None, myMnbf=None, myRsr=None, myClst=None, myMfsCmdMgmt=None, myMfsCmdData=None, myMfsRspMgmt=None, myMfsRspData=None, myBm_SACKI=None, mySofvf=None, mySvn=None, myRrtf=None, mySackt0=None, mySackt1=None, mySackt2=None, mySackt3=None, mySackiPad=None, myRxwsz=None, myRrtl=None, mySackvf=None, myRtsf=None, myIgf=None, myDurNRsvd=None, myRtsctsvf=None, mySaf=None, myScf=None, myReq_TM=None, mySrc=None, mySoundvf=None, myShortPad=True, myRsof_fl_AV=None, myRsofvf=None): #SOF by default
+ if self.dt_AV==beacon:
+ self.createBvf(myBts, myBto_0, myBto_1, myBto_2, myBto_3, myBvf)
+ self.vf_AV = self.bvf
+ elif self.dt_AV==sof:
+ self.createSofvf(myStei, myDtei, myLid, myCfs, myBdf, myHp10df, myHp11df, myEks, myPpb, myBle, myPbSz, myNumSym, myTmi_AV, myFl_AV, myMpduCnt, myBurstCnt, myBbf, myMrtfl, myDcppcf, myMcf, myMnbf, myRsr, myClst, myMfsCmdMgmt, myMfsCmdData, myMfsRspMgmt, myMfsRspData, myBm_SACKI, mySofvf)
+ self.vf_AV = self.sofvf
+ elif self.dt_AV==sack:
+ self.createSackvf(myDtei, myCfs, myBdf, mySvn, myRrtf, myMfsRspMgmt, myMfsRspData, mySackt0, mySackt1, mySackt2, mySackt3, mySackiPad, myRxwsz, myRrtl, mySackvf)
+ self.vf_AV = self.sackvf
+ elif self.dt_AV==rtsCts:
+ self.createRtsctsvf(myStei, myDtei, myLid, myCfs, myBdf, myHp10df, myHp11df, myRtsf, myIgf, myMnbf, myMcf, myDurNRsvd, myRtsctsvf)
+ self.vf_AVField = self.rtsctsvf
+ elif self.dt_AV==sound:
+ self.createSoundvf(myStei, myDtei, myLid, myCfs, myPbSz, myBdf, mySaf, myScf, myReq_TM, myFl_AV, myMpduCnt, myPpb, mySrc, mySoundvf)
+ self.vf_AV = self.soundvf
+ elif self.dt_AV==rsof:
+ self.createRsofvf(myDtei, myCfs, myBdf, mySvn, myRrtf, myMfsRspMgmt, myMfsRspData, mySackt0, mySackt1, mySackt2, mySackt3, mySackiPad, myRxwsz, myRrtl, myShortPad, myRsof_fl_AV, myTmi_AV, myPbSz, myNumSym, myMfsCmdMgmt, myMfsCmdData, myRsofvf)
+ self.vf_AV = self.rsofvf
+
+
+ #FCCS_AV
+ fccs_AV = check_string(dt_AVAccessSnidField + vf_AV)
+ fccs_AVField = pack('I',fccs_AV)[0:3]
+ def createFccs_AV(self, myFccs_AV=None):
+ if myFccs_AV!=None:
+ self.fccs_AV=myFccs_AV
+ else:
+ self.fccs_AV = check_string(self.dt_AVAccessSnidField + self.vf_AV)
+ self.fccs_AVField = pack('I',self.fccs_AV)[0:3]
+ print "fccs_AV = "+hex(self.fccs_AV)
+
+
+ #FC_AV
+ fc_AV = dt_AVAccessSnidField + vf_AV + fccs_AVField
+ iv_SOF = dt_AVAccessSnidField + vf_AV
+ def createFc_AV(self, myFc_AV=None, myDt_AV=None, myAccess=None, mySnid=None, myDt_AVAccessSnid=None, myBts=None, myBto_0=None, myBto_1=None, myBto_2=None, myBto_3=None, myBvf=None, myStei=None, myDtei=None, myLid=None, myCfs=None, myBdf=None, myHp10df=None, myHp11df=None, myEks=None, myPpb=None, myBle=None, myPbSz=None, myNumSym=None, myTmi_AV=None, myFl_AV=None, myMpduCnt=None, myBurstCnt=None, myBbf=None, myMrtfl=None, myDcppcf=None, myMcf=None, myMnbf=None, myRsr=None, myClst=None, myMfsCmdMgmt=None, myMfsCmdData=None, myMfsRspMgmt=None, myMfsRspData=None, myBm_SACKI=None, mySofvf=None, mySvn=None, myRrtf=None, mySackt0=None, mySackt1=None, mySackt2=None, mySackt3=None, mySackiPad=None, myRxwsz=None, myRrtl=None, mySackvf=None, myRtsf=None, myIgf=None, myDurNRsvd=None, myRtsctsvf=None, mySaf=None, myScf=None, myReq_TM=None, mySrc=None, mySoundvf=None, myShortPad=True, myRsof_fl_AV=None, myRsofvf=None, myFccs_AV=None, myIv_SOF=None):
+ print "fc_AV :"
+ if myFc_AV!=None:
+ self.fc_AV=myFc_AV
+ self.iv_SOF=self.fc_AV[0:12]
+ print "iv_SOF = "+hex(self.iv_SOF)
+ else:
+ self.createDt_AVAccessSnid(myDt_AV, myAccess, mySnid, myDt_AVAccessSnid)
+ self.createVf_AV(myBts, myBto_0, myBto_1, myBto_2, myBto_3, myBvf, myStei, myDtei, myLid, myCfs, myBdf, myHp10df, myHp11df, myEks, myPpb, myBle, myPbSz, myNumSym, myTmi_AV, myFl_AV, myMpduCnt, myBurstCnt, myBbf, myMrtfl, myDcppcf, myMcf, myMnbf, myRsr, myClst, myMfsCmdMgmt, myMfsCmdData, myMfsRspMgmt, myMfsRspData, myBm_SACKI, mySofvf, mySvn, myRrtf, mySackt0, mySackt1, mySackt2, mySackt3, mySackiPad, myRxwsz, myRrtl, mySackvf, myRtsf, myIgf, myDurNRsvd, myRtsctsvf, mySaf, myScf, myReq_TM, mySrc, mySoundvf, myShortPad, myRsof_fl_AV, myRsofvf)
+ self.createFccs_AV(myFccs_AV)
+ self.fc_AV = self.dt_AVAccessSnidField + self.vf_AV + self.fccs_AVField
+ self.iv_SOF = self.vf_AV
+
+ myFC_AV.set_dt_av(self.dt_AV)
+ myFC_AV.set_access(self.access)
+ myFC_AV.set_snid(self.snid)
+ myFC_AV.set_vf_av(self.vf_AV)
+ myFC_AV.set_fccs_av(self.fccs_AV)
+ myMacFrame.FC_AV = myFC_AV
+
+ print "iv_SOF = "+hex(unpack('QI',self.iv_SOF)[0]+unpack('QI',self.iv_SOF)[1]*pow_2_64)
+
+
+
diff --git a/cesar/maximus/python/lib/framing.py b/cesar/maximus/python/lib/framing.py
new file mode 100644
index 0000000000..8f86665aca
--- /dev/null
+++ b/cesar/maximus/python/lib/framing.py
@@ -0,0 +1,45 @@
+# -*- coding:Utf-8 -*-
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+#from maximus import *
+#import unittest
+#from interface import *
+
+##print "Instantiate a Maximus object and initialize it."
+#maximus = Maximus()
+#maximus.init(sys.argv)
+##print "Create a station."
+#myStaA = maximus.create_sta()
+##print "Set tonemask"
+#fcall1 = maximus.create_fcall('set_tonemask')
+#fcall1.send(myStaA)
+
+from binascii import * #binascii library is used : crc32(),
+
+from macFrame import *
+myMacFields = MacFields()
+
+#print "Create MME Header"
+myMmHeader = MMHeader()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cesar/maximus/python/lib/macFrame.py b/cesar/maximus/python/lib/macFrame.py
new file mode 100644
index 0000000000..6cfa5f34ed
--- /dev/null
+++ b/cesar/maximus/python/lib/macFrame.py
@@ -0,0 +1,122 @@
+# -*- coding:Utf-8 -*-
+
+#from maximus import *
+#import unittest
+from interface import *
+
+from mmentry import *
+mmentryMethod = MmentryMethod()
+from fcVf import *
+myFcVfFields = FcVfFields()
+
+
+
+#print "Instantiate a Maximus object and initialize it."
+maximus = Maximus()
+maximus.init(sys.argv)
+#print "Create a station."
+myStaA = maximus.create_sta()
+#myStaA.debug()
+#print "Set tonemask"
+fcall1 = maximus.create_fcall('set_tonemask')
+fcall1.send(myStaA)
+
+
+#print "Send an MPDU containing one PB of 128 octets"
+def create_fcall_128():
+ #print "Create a fcall for an MPDU containing one PB of 128 octets"
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ short_ppdu = False
+ mod = 2 # PHY_MOD_MINI_ROBO
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ pb_size = 0 # PHY_PB_SIZE_136
+ gil = 1 # PHY_GIL_567
+ pb_nb = 1
+ fcall_128 = maximus.create_fcall('prepare_rx')
+ fcall_128.add_param_ushort("fc_mode", fc_mode)
+ fcall_128.add_param_bool("short_ppdu", short_ppdu)
+ fcall_128.add_param_ushort("mod", mod)
+ fcall_128.add_param_ushort("fecrate", fecrate)
+ fcall_128.add_param_ushort("pb_size", pb_size)
+ fcall_128.add_param_ushort("gil", gil)
+ fcall_128.add_param_ushort("pb_nb", pb_nb)
+ return fcall_128
+
+# Send an MPDU containing "myPbNum" PBs of 512 octets
+def create_fcall_512(myPbNum = 1):
+ # Create a fcall for an MPDU containing "myPbNum" PBs of 512 octets
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ short_ppdu = False
+ mod = 3 # PHY_MOD_TM
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ pb_size = 1 # PHY_PB_SIZE_520
+ gil = 1 # PHY_GIL_567
+ pb_nb = myPbNum
+ fcall_512 = maximus.create_fcall('prepare_rx')
+ fcall_512.add_param_ushort("fc_mode", fc_mode)
+ fcall_512.add_param_bool("short_ppdu", short_ppdu)
+ fcall_512.add_param_ushort("mod", mod)
+ fcall_512.add_param_ushort("fecrate", fecrate)
+ fcall_512.add_param_ushort("pb_size", pb_size)
+ fcall_512.add_param_ushort("gil", gil)
+ fcall_512.add_param_ushort("pb_nb", pb_nb)
+ return fcall_512
+
+#macFields fill all fields existing in MAC Frame
+class MacFields():
+
+ #MAC Frame
+
+ def createMacFrame(self, myOda=staAAddress, myOsa=maxAddress, myVlanTag=0, myMtype=0xe188, myMmv=0, myMmtype=mmentryMethod.mmentryFields.mmtype, myNfmi=None, myFnMi=None, myFmsn=0, myMmentry=None, myEncapsulatedMmEntry=None, myFc_AV=None, myDt_AV=1, myAccess=None, mySnid=None, myDt_AVAccessSnid=None, myBts=None, myBto_0=None, myBto_1=None, myBto_2=None, myBto_3=None, myBvf=None, myStei=None, myDtei=None, myLid=None, myCfs=None, myBdf=None, myHp10df=None, myHp11df=None, myEks=None, myPpb=None, myBle=None, myPbSz=None, myNumSym=None, myTmi_AV=None, myFl_AV=None, myMpduCnt=None, myBurstCnt=None, myBbf=None, myMrtfl=None, myDcppcf=None, myMcf=None, myMnbf=None, myRsr=None, myClst=None, myMfsCmdMgmt=None, myMfsCmdData=None, myMfsRspMgmt=None, myMfsRspData=None, myBm_SACKI=None, mySofvf=None, mySvn=None, myRrtf=None, mySackt0=None, mySackt1=None, mySackt2=None, mySackt3=None, mySackiPad=None, myRxwsz=None, myRrtl=None, mySackvf=None, myRtsf=None, myIgf=None, myDurNRsvd=None, myRtsctsvf=None, mySaf=None, myScf=None, myReq_TM=None, mySrc=None, mySoundvf=None, myShortPad=True, myRsof_fl_AV=None, myRsofvf=None, myFccs_AV=None, myIv_SOF=None):
+ if myMmentry == None:
+ myMmentry = mmentryMethod.mmentryFields.mmentry
+ thisNfmi = (len(myMmentry)-1)/1492
+ thisFnMi = 0
+ rspu = ""
+ while thisFnMi<=thisNfmi:
+ myEncapsulatedMme.createEncapsulatedMmEntry(myOda, myOsa, myVlanTag, myMtype, myMmv, myMmtype, myNfmi, myFnMi, myFmsn, myMmentry, myEncapsulatedMmEntry, thisFnMi)
+ myMacFrameHeader.set_mft(mmeMft)
+ myMacFrameHeader.set_mfl(min(mmentryMethod.mmentryFields.mmeMfl,1518))
+ if mmentryMethod.mmentryFields.mmeMfl<=122:
+ fcall_128 = create_fcall_128()
+ fcall_128.send(myStaA)
+ else:
+ fcall_512 = create_fcall_512(int(((min(mmentryMethod.mmentryFields.mmeMfl,1518)-1)/506)+1))
+ fcall_512.send(myStaA)
+ mmentryMethod.mmentryFields.mmeMfl = mmentryMethod.mmentryFields.mmeMfl-1492
+ myMacFrame.set_macframeheader(myMacFrameHeader)
+ myMacFrame.set_ats(None)
+ confunder = randrange(0,pow(2,32)-1,1)
+ myMacFrame.set_msdu(myMme)
+ myMacFrame.set_confounder(confunder)
+ icv = unpack('I',pack('i',crc32(myMacFrame.get_msdu())))[0]
+ myMacFrame.set_icv(icv)
+ myFcVfFields.createFc_AV(myFc_AV, myDt_AV, myAccess, mySnid, myDt_AVAccessSnid, myBts, myBto_0, myBto_1, myBto_2, myBto_3, myBvf, myStei, myDtei, myLid, myCfs, myBdf, myHp10df, myHp11df, myEks, myPpb, myBle, myPbSz, myNumSym, myTmi_AV, myFl_AV, myMpduCnt, myBurstCnt, myBbf, myMrtfl, myDcppcf, myMcf, myMnbf, myRsr, myClst, myMfsCmdMgmt, myMfsCmdData, myMfsRspMgmt, myMfsRspData, myBm_SACKI, mySofvf, mySvn, myRrtf, mySackt0, mySackt1, mySackt2, mySackt3, mySackiPad, myRxwsz, myRrtl, mySackvf, myRtsf, myIgf, myDurNRsvd, myRtsctsvf, mySaf, myScf, myReq_TM, mySrc, mySoundvf, myShortPad, myRsof_fl_AV, myRsofvf, myFccs_AV, myIv_SOF)
+ myMacFrame.set_iv(myFcVfFields.iv_SOF) #IV_SOF NOT IV !!!
+ myMacFrame.set_nek(myFcVfFields.nekField)
+ myMacFrame.send(maximus)
+ rspc = recv(maximus) #PB Objects list
+ rspc = rspc[0].get_pblist()
+ receivedPbNum = len(rspc)
+ rspt = ""
+ i=0
+ while i<receivedPbNum:
+ rspt = rspt + rspc[i]
+ i=i+1
+ rspc = rspt[:int(unpack('H',rspt[0:2])[0]/4)+6+1-4]
+ maximus.wait(100000)
+ rspuH = rspc[:29]
+ rspu = rspu + rspc[29:]
+ thisFnMi = thisFnMi + 1
+ return rspuH + rspu
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cesar/maximus/python/lib/mmentry/Constants.py b/cesar/maximus/python/lib/mmentry/Constants.py
new file mode 100644
index 0000000000..bc0e69b526
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/Constants.py
@@ -0,0 +1,317 @@
+# -*- coding:Utf-8 -*-
+
+pow_2_64=18446744073709551616
+pow_2_63=9223372036854775808
+
+MAX_TONE_MAPS = 7
+
+
+#------ Maximus Python's constants -------
+
+#Maximus Simulator 48 bits address
+maxAddress = "MaxSim" #= 0x6D695378614D
+staAAddress = "myStaA" #= 0x41617453796D
+
+#Delimiter Type = DT_AV
+ #= First field of the HomePlug AV Frame Control Block
+ #= 3-bits field that identifies the "Frame Type of Message"
+beacon = 0
+sof = 1
+sack = 2
+rtsCts = 3
+sound = 4
+rsof = 5
+rsv0 = 6
+rsv1 = 7
+
+DT_AV = {0x00:"Beacon",
+0x01:"Start of Frame (SOF)",
+0x02:"Selective Acknowledgement (SACK)",
+0x03:"Request to Send (RTS)/Clear to Send(CTS)",
+0x04:"Sound",
+0x05:"Reverse Start of Frame (RSOF)",
+0x06:"Reserved",
+0x07:"Reserved"
+}
+
+#rx :
+timeOutRx = 5000 #timeOutRx default's value = 5s
+ #time count is here supposed to be in ms
+
+#MAC Frame Type = MFT
+ #= First field of the MAC Frame Header
+ #= 2-bits field that identifies the "MAC Frame Type"
+mfsMft = 0 #MAC Frame Stream
+msduWOatsMft = 1 #MSDU WithOut ATS
+msduWatsMft = 2 #MSDU With ATS
+mmeMft = 3 #Management Message
+
+
+#MME Interpretation
+#--- Station - Central Coordination ---
+CC_CCO_APPOINT_REQ = 0x0000 #(See Note #1)
+CC_CCO_APPOINT_CNF = 0x0001 #(See Note #1)
+CC_BACKUP_APPOINT_REQ = 0x0004
+CC_BACKUP_APPOINT_CNF = 0x0005
+CC_LINK_INFO_REQ = 0x0008
+CC_LINK_INFO_CNF = 0x0009
+CC_LINK_INFO_IND = 0x000A #(See Note #3)
+CC_LINK_INFO_RSP = 0x000B #(See Note #3)
+CC_HANDOVER_REQ = 0x000C #(See Note #4)
+CC_HANDOVER_CNF = 0x000D #(See Note #4)
+CC_HANDOVER_INFO_IND = 0x0010 #(See Note #4)
+CC_HANDOVER_INFO_RSP = 0x0011 #(See Note #4)
+CC_DISCOVER_LIST_REQ = 0x0014
+CC_DISCOVER_LIST_CNF = 0x0015
+CC_DISCOVER_LIST_IND = 0x0016
+CC_LINK_NEW_REQ = 0x0018 #(See Note #2)
+CC_LINK_NEW_CNF = 0x0019 #(See Note #2)
+CC_LINK_MOD_REQ = 0x001C #(See Note #2)
+CC_LINK_MOD_CNF = 0x001D #(See Note #2)
+CC_LINK_SQZ_REQ = 0x0020 #(See Note #5)
+CC_LINK_SQZ_CNF = 0x0021 #(See Note #5)
+CC_LINK_REL_REQ = 0x0024 #(See Note #2)
+CC_LINK_REL_IND = 0x0025 #(See Note #2)
+CC_DETECT_REPORT_REQ = 0x0028 #(See Note #6)
+CC_DETECT_REPORT_CNF = 0x0029 #(See Note #6)
+CC_WHO_RU_REQ = 0x002C
+CC_WHO_RU_CNF = 0x002D
+CC_ASSOC_REQ = 0x0030
+CC_ASSOC_CNF = 0x0031
+CC_LEAVE_REQ = 0x0034
+CC_LEAVE_CNF = 0x0035
+CC_LEAVE_IND = 0x0036
+CC_LEAVE_RSP = 0x0037
+CC_SET_TEI_MAP_REQ = 0x0038
+CC_SET_TEI_MAP_IND = 0x0039
+CC_RELAY_REQ = 0x003C #(See Note #7)
+CC_RELAY_IND = 0x003D #(See Note #7)
+CC_BEACON_RELIABILITY_REQ = 0x0040
+CC_BEACON_RELIABILITY_CNF = 0x0041
+CC_ALLOC_MOVE_REQ = 0x0044
+CC_ALLOC_MOVE_CNF = 0x0045
+CC_ACCESS_NEW_REQ = 0x0048
+CC_ACCESS_NEW_CNF = 0x0049
+CC_ACCESS_NEW_IND = 0x004A
+CC_ACCESS_NEW_RSP = 0x004B
+CC_ACCESS_REL_REQ = 0x004C
+CC_ACCESS_REL_CNF = 0x004D
+CC_ACCESS_REL_IND = 0x004E
+CC_ACCESS_REL_RSP = 0x004F
+CC_DCPPC_IND = 0x0050 #(See Note #8)
+CC_DCPPC_RSP = 0x0051 #(See Note #8)
+CC_HP1_DET_REQ = 0x0054
+CC_HP1_DET_CNF = 0x0055
+CC_BLE_UPDATE_IND = 0x0058
+#to 0x1FFC : Reserved for future use = 0x005C
+#--- Proxy Coordinator ---
+CP_PROXY_APPOINT_REQ = 0x2000 #(See Note #9)
+CP_PROXY_APPOINT_CNF = 0x2001 #(See Note #9)
+PH_PROXY_APPOINT_IND = 0x2004 #(See Note #9)
+CP_PROXY_WAKE_REQ = 0x2008 #(See Note #9)
+#to 0x3FFC : Reserved for future use = 0x200C
+#--- CCo - CCo ---
+NN_INL_REQ = 0x4000
+NN_INL_CNF = 0x4001
+NN_NEW_NET_REQ = 0x4004
+NN_NEW_NET_CNF = 0x4005
+NN_NEW_NET_IND = 0x4006
+NN_ADD_ALLOC_REQ = 0x4008
+NN_ADD_ALLOC_CNF = 0x4009
+NN_ADD_ALLOC_IND = 0x400A
+NN_REL_ALLOC_REQ = 0x400C
+NN_REL_ALLOC_CNF = 0x400D
+NN_REL_NET_IND = 0x4010
+#to 0x5FFC : Reserved for future use = 0x4014
+#--- Station - Station ---
+CM_UNASSOCIATED_STA_IND = 0x6000
+CM_ENCRYPTED_PAYLOAD_IND = 0x6004
+CM_ENCRYPTED_PAYLOAD_RSP = 0x6005
+CM_SET_KEY_REQ = 0x6008
+CM_SET_KEY_CNF = 0x6009
+CM_GET_KEY_REQ = 0x600C
+CM_GET_KEY_CNF = 0x600D
+CM_SC_JOIN_REQ = 0x6010
+CM_SC_JOIN_CNF = 0x6011
+CM_CHAN_EST_IND = 0x6014
+CM_TM_UPDATE_IND = 0x6018
+CM_AMP_MAP_REQ = 0x601C
+CM_AMP_MAP_CNF = 0x601D
+CM_BRG_INFO_REQ = 0x6020 #(See Note #10)
+CM_BRG_INFO_CNF = 0x6021 #(See Note #10)
+CM_CONN_NEW_REQ = 0x6024 #(See Note #2)
+CM_CONN_NEW_CNF = 0x6025 #(See Note #2)
+CM_CONN_REL_IND = 0x6028 #(See Note #2)
+CM_CONN_REL_RSP = 0x6029 #(See Note #2)
+CM_CONN_MOD_REQ = 0x602C #(See Note #2)
+CM_CONN_MOD_CNF = 0x602D #(See Note #2)
+CM_CONN_INFO_REQ = 0x6030
+CM_CONN_INFO_CNF = 0x6031
+CM_STA_CAP_REQ = 0x6034
+CM_STA_CAP_CNF = 0x6035
+CM_NW_INFO_REQ = 0x6038
+CM_NW_INFO_CNF = 0x6039
+CM_GET_BEACON_REQ = 0x603C
+CM_GET_BEACON_CNF = 0x603D
+CM_HFID_REQ = 0x6040
+CM_HFID_CNF = 0x6041
+CM_MME_ERROR_IND = 0x6044
+CM_NW_STATS_REQ = 0x6048
+CM_NW_STATS_CNF = 0x6049
+CM_LINK_STATS_REQ = 0x604C
+CM_LINK_STATS_CNF = 0x604D
+#to 0x7FFC : Reserved for future use = 0x6050
+#--- Manufacturer Specific ---
+#to 0x9FFC : Manufacturer Specific Messages = 0x8000
+#--- Vendor Specific ---
+#to 0xBFFC : Vendor-Specific Messages = 0xA000
+
+
+
+#1-octet Field Identifier (FID) field
+#CSPEC_Field
+Delay_Bound = 0x00
+Jitter_Bound = 0x01
+Average_MSDU_Size = 0x02
+Maximum_MSDU_Size = 0x03
+Average_Data_Rate = 0x04
+Minimum_Data_Rate = 0x05
+Maximum_Data_Rate = 0x06
+Maximum_Inter_TXOP_time = 0x07
+Minimum_Inter_TXOP_time = 0x08
+Maximum_Burst_Size = 0x09
+Exception_Policy = 0x0a
+Inactivity_Interval = 0x0b
+MSDU_Error_Rate = 0x0c
+CLST = 0x0d
+CDESC = 0x0e
+Vendor_Specific = 0x0f
+ATS_Tolerance = 0x10
+Smallest_Tolerable_Average_Data_Rate = 0x11
+Original_Average_Data_Rate = 0x12
+#QoS_and_MAC_Parameter_Field_(CM-CM)
+Rx_Window_Size = 0x13
+Smoothing_Buffer_Size = 0x14
+Bidirectional_Burst_CM_CM = 0x15
+#QoS_and_MAC_Parameter_Field_(CM-CCo)
+TXOPs_per_Beacon_Period = 0x80
+Average_Number_of_PBs_per_TXOP = 0x81
+Minimum_Number_of_PBs_per_TXOP = 0x82
+Maximum_Number_of_PBs_per_TXOP = 0x83
+PPB_Threshold = 0x84
+Surplus_Bandwidth = 0x85
+Exception_Policy = 0x0a
+CDESC = 0x0e
+Vendor_Specific = 0x86
+Smallest_Tolerable_Average_Number_of_PBs_per_TXOP = 0x87
+Original_Average_Number_of_PBs_per_TXOP = 0x88
+Bidirectional_Burst_CM_CCO = 0x89
+
+
+
+#Global ID
+globalId = []
+i=0x80
+while i <= 0xF7:
+ globalId.append(i)
+ i=i+1
+i=0xFC
+while i <= 0xFE:
+ globalId.append(i)
+ i=i+1
+
+
+
+#Classifier_Rule_Identifier = Classifier_Rule_Identifier
+Ethernet_Destination_Address_Identifier = 0x00
+Ethernet_Source_Address_Identifier = 0x01
+VLAN_User_Priority_Identifier = 0x02
+VLAN_ID_Identifier = 0x03
+IPv4_Type_of_Service_Identifier = 0x04
+IPv4_Protocol_Identifier = 0x05
+IPv4_Source_Address_Identifier = 0x06
+IPv4_Destination_Address_Identifier = 0x07
+IPv6_Traffic_Class_Identifier = 0x08
+IPv6_Flow_Label_Identifier = 0x09
+IPv6_Source_Address_Identifier = 0x0A
+IPv6_Destination_Address_Identifier = 0x0B
+TCP_Source_Port_Identifier = 0x0C
+TCP_Destination_Port_Identifier = 0x0D
+UDP_Source_Port_Identifier = 0x0E
+UDP_Destination_Port_Identifier = 0x0F
+#-_Identifier = 0x10_–_0xDF
+#Vendor_defined_Classifier_Rule_Identifier = 0xE0_–_0xFF
+
+
+
+#Classifier_Rule_Identifier:Classifier_Rule_Size_(Octets)
+classifierRuleSize = {
+Ethernet_Destination_Address_Identifier:6,
+Ethernet_Source_Address_Identifier:6,
+VLAN_User_Priority_Identifier:1,
+VLAN_ID_Identifier:2,
+IPv4_Type_of_Service_Identifier:1,
+IPv4_Protocol_Identifier:1,
+IPv4_Source_Address_Identifier:4,
+IPv4_Destination_Address_Identifier:4,
+IPv6_Traffic_Class_Identifier:1,
+IPv6_Flow_Label_Identifier:3,
+IPv6_Source_Address_Identifier:16,
+IPv6_Destination_Address_Identifier:16,
+TCP_Source_Port_Identifier:2,
+TCP_Destination_Port_Identifier:2,
+UDP_Source_Port_Identifier:2,
+UDP_Destination_Port_Identifier:2
+#-_Identifier:-
+#Vendor_defined_Classifier_Rule_Identifier:-
+}
+
+
+
+
+#Interpretation = BEHDR_Value
+Non_Persistent_Schedule_BENTRY = 0x00
+Persistent_Schedule_BENTRY = 0x01
+Regions_BENTRY = 0x02
+MAC_Address_BENTRY = 0x03
+Discover_BENTRY = 0x04
+Discovered_Info_BENTRY = 0x05
+Beacon_Period_Start_Time_Offset_BENTRY = 0x06
+Encryption_Key_Change_BENTRY = 0x07
+CCo_Handover_BENTRY = 0x08
+Beacon_Relocation_BENTRY = 0x09
+AC_Line_Sync_Countdown_BENTRY = 0x0A
+Change_NumSlots_BENTRY = 0x0B
+Change_HM_BENTRY = 0x0C
+Change_SNID_BENTRY = 0x0D
+#Reserved_for_future_use = 0x0E-0xFE
+Vendor_Specific_BENTRY = 0xFF
+
+
+#BMI
+BMI = {
+0x00:"Non_Persistent_Schedule_BENTRY",
+0x01:"Persistent_Schedule_BENTRY",
+0x02:"Regions_BENTRY",
+0x03:"MAC_Address_BENTRY",
+0x04:"Discover_BENTRY",
+0x05:"Discovered_Info_BENTRY",
+0x06:"Beacon_Period_Start_Time_Offset_BENTRY",
+0x07:"Encryption_Key_Change_BENTRY",
+0x08:"CCo_Handover_BENTRY",
+0x09:"Beacon_Relocation_BENTRY",
+0x0A:"AC_Line_Sync_Countdown_BENTRY",
+0x0B:"Change_NumSlots_BENTRY",
+0x0C:"Change_HM_BENTRY",
+0x0D:"Change_SNID_BENTRY",
+0xFF:"Vendor_Specific_BENTRY"
+}
+
+
+
+
+
+
+
+
+
diff --git a/cesar/maximus/python/lib/mmentry/__init__.py b/cesar/maximus/python/lib/mmentry/__init__.py
new file mode 100644
index 0000000000..e3f95270ae
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/__init__.py
@@ -0,0 +1 @@
+from mmentryMethod import *
diff --git a/cesar/maximus/python/lib/mmentry/aes128/AES.py b/cesar/maximus/python/lib/mmentry/aes128/AES.py
new file mode 100644
index 0000000000..8413f4c109
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/aes128/AES.py
@@ -0,0 +1,31 @@
+"""Abstract class for AES."""
+
+class AES:
+ def __init__(self, key, mode, IV, implementation):
+ if len(key) not in (16, 24, 32):
+ raise AssertionError()
+ if mode != 2:
+ raise AssertionError()
+ if len(IV) != 16:
+ raise AssertionError()
+ self.isBlockCipher = True
+ self.block_size = 16
+ self.implementation = implementation
+ if len(key)==16:
+ self.name = "aes128"
+ elif len(key)==24:
+ self.name = "aes192"
+ elif len(key)==32:
+ self.name = "aes256"
+ else:
+ raise AssertionError()
+
+ #CBC-Mode encryption, returns ciphertext
+ #WARNING: *MAY* modify the input as well
+ def encrypt(self, plaintext):
+ assert(len(plaintext) % 16 == 0)
+
+ #CBC-Mode decryption, returns plaintext
+ #WARNING: *MAY* modify the input as well
+ def decrypt(self, ciphertext):
+ assert(len(ciphertext) % 16 == 0) \ No newline at end of file
diff --git a/cesar/maximus/python/lib/mmentry/aes128/Python_AES.py b/cesar/maximus/python/lib/mmentry/aes128/Python_AES.py
new file mode 100644
index 0000000000..657152f892
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/aes128/Python_AES.py
@@ -0,0 +1,68 @@
+"""Pure-Python AES implementation."""
+
+from cryptomath import *
+
+from AES import *
+from rijndael import rijndael
+
+def new(key, mode, IV):
+ return Python_AES(key, mode, IV)
+
+class Python_AES(AES):
+ def __init__(self, key, mode, IV):
+ AES.__init__(self, key, mode, IV, "python")
+ self.rijndael = rijndael(key, 16)
+ self.IV = IV
+
+ def encrypt(self, plaintext):
+ AES.encrypt(self, plaintext)
+
+ plaintextBytes = stringToBytes(plaintext)
+ chainBytes = stringToBytes(self.IV)
+
+ #CBC Mode: For each block...
+ for x in range(len(plaintextBytes)/16):
+
+ #XOR with the chaining block
+ blockBytes = plaintextBytes[x*16 : (x*16)+16]
+ for y in range(16):
+ blockBytes[y] ^= chainBytes[y]
+ blockString = bytesToString(blockBytes)
+
+ #Encrypt it
+ encryptedBytes = stringToBytes(self.rijndael.encrypt(blockString))
+
+ #Overwrite the input with the output
+ for y in range(16):
+ plaintextBytes[(x*16)+y] = encryptedBytes[y]
+
+ #Set the next chaining block
+ chainBytes = encryptedBytes
+
+ self.IV = bytesToString(chainBytes)
+ return bytesToString(plaintextBytes)
+
+ def decrypt(self, ciphertext):
+ AES.decrypt(self, ciphertext)
+
+ ciphertextBytes = stringToBytes(ciphertext)
+ chainBytes = stringToBytes(self.IV)
+
+ #CBC Mode: For each block...
+ for x in range(len(ciphertextBytes)/16):
+
+ #Decrypt it
+ blockBytes = ciphertextBytes[x*16 : (x*16)+16]
+ blockString = bytesToString(blockBytes)
+ decryptedBytes = stringToBytes(self.rijndael.decrypt(blockString))
+
+ #XOR with the chaining block and overwrite the input with output
+ for y in range(16):
+ decryptedBytes[y] ^= chainBytes[y]
+ ciphertextBytes[(x*16)+y] = decryptedBytes[y]
+
+ #Set the next chaining block
+ chainBytes = blockBytes
+
+ self.IV = bytesToString(chainBytes)
+ return bytesToString(ciphertextBytes)
diff --git a/cesar/maximus/python/lib/mmentry/aes128/__init__.py b/cesar/maximus/python/lib/mmentry/aes128/__init__.py
new file mode 100644
index 0000000000..d6738ad516
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/aes128/__init__.py
@@ -0,0 +1 @@
+from Python_AES import *
diff --git a/cesar/maximus/python/lib/mmentry/aes128/compat.py b/cesar/maximus/python/lib/mmentry/aes128/compat.py
new file mode 100644
index 0000000000..7d2d9250d8
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/aes128/compat.py
@@ -0,0 +1,140 @@
+"""Miscellaneous functions to mask Python version differences."""
+
+import sys
+import os
+
+if sys.version_info < (2,2):
+ raise AssertionError("Python 2.2 or later required")
+
+if sys.version_info < (2,3):
+
+ def enumerate(collection):
+ return zip(range(len(collection)), collection)
+
+ class Set:
+ def __init__(self, seq=None):
+ self.values = {}
+ if seq:
+ for e in seq:
+ self.values[e] = None
+
+ def add(self, e):
+ self.values[e] = None
+
+ def discard(self, e):
+ if e in self.values.keys():
+ del(self.values[e])
+
+ def union(self, s):
+ ret = Set()
+ for e in self.values.keys():
+ ret.values[e] = None
+ for e in s.values.keys():
+ ret.values[e] = None
+ return ret
+
+ def issubset(self, other):
+ for e in self.values.keys():
+ if e not in other.values.keys():
+ return False
+ return True
+
+ def __nonzero__( self):
+ return len(self.values.keys())
+
+ def __contains__(self, e):
+ return e in self.values.keys()
+
+ def __iter__(self):
+ return iter(set.values.keys())
+
+
+if os.name != "java":
+
+ import array
+ def createByteArraySequence(seq):
+ return array.array('B', seq)
+ def createByteArrayZeros(howMany):
+ return array.array('B', [0] * howMany)
+ def concatArrays(a1, a2):
+ return a1+a2
+
+ def bytesToString(bytes):
+ return bytes.tostring()
+ def stringToBytes(s):
+ bytes = createByteArrayZeros(0)
+ bytes.fromstring(s)
+ return bytes
+
+ import math
+ def numBits(n):
+ if n==0:
+ return 0
+ s = "%x" % n
+ return ((len(s)-1)*4) + \
+ {'0':0, '1':1, '2':2, '3':2,
+ '4':3, '5':3, '6':3, '7':3,
+ '8':4, '9':4, 'a':4, 'b':4,
+ 'c':4, 'd':4, 'e':4, 'f':4,
+ }[s[0]]
+ return int(math.floor(math.log(n, 2))+1)
+
+ BaseException = Exception
+ import sys
+ import traceback
+ def formatExceptionTrace(e):
+ newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+ return newStr
+
+else:
+ #Jython 2.1 is missing lots of python 2.3 stuff,
+ #which we have to emulate here:
+ #NOTE: JYTHON SUPPORT NO LONGER WORKS, DUE TO USE OF GENERATORS.
+ #THIS CODE IS LEFT IN SO THAT ONE JYTHON UPDATES TO 2.2, IT HAS A
+ #CHANCE OF WORKING AGAIN.
+
+ import java
+ import jarray
+
+ def createByteArraySequence(seq):
+ if isinstance(seq, type("")): #If it's a string, convert
+ seq = [ord(c) for c in seq]
+ return jarray.array(seq, 'h') #use short instead of bytes, cause bytes are signed
+ def createByteArrayZeros(howMany):
+ return jarray.zeros(howMany, 'h') #use short instead of bytes, cause bytes are signed
+ def concatArrays(a1, a2):
+ l = list(a1)+list(a2)
+ return createByteArraySequence(l)
+
+ #WAY TOO SLOW - MUST BE REPLACED------------
+ def bytesToString(bytes):
+ return "".join([chr(b) for b in bytes])
+
+ def stringToBytes(s):
+ bytes = createByteArrayZeros(len(s))
+ for count, c in enumerate(s):
+ bytes[count] = ord(c)
+ return bytes
+ #WAY TOO SLOW - MUST BE REPLACED------------
+
+ def numBits(n):
+ if n==0:
+ return 0
+ n= 1L * n; #convert to long, if it isn't already
+ return n.__tojava__(java.math.BigInteger).bitLength()
+
+ #Adjust the string to an array of bytes
+ def stringToJavaByteArray(s):
+ bytes = jarray.zeros(len(s), 'b')
+ for count, c in enumerate(s):
+ x = ord(c)
+ if x >= 128: x -= 256
+ bytes[count] = x
+ return bytes
+
+ BaseException = java.lang.Exception
+ import sys
+ import traceback
+ def formatExceptionTrace(e):
+ newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+ return newStr \ No newline at end of file
diff --git a/cesar/maximus/python/lib/mmentry/aes128/cryptomath.py b/cesar/maximus/python/lib/mmentry/aes128/cryptomath.py
new file mode 100644
index 0000000000..51d6dff7c8
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/aes128/cryptomath.py
@@ -0,0 +1,400 @@
+"""cryptomath module
+
+This module has basic math/crypto code."""
+
+import os
+import math
+import base64
+import binascii
+import sha
+
+from compat import *
+
+
+# **************************************************************************
+# Load Optional Modules
+# **************************************************************************
+
+# Try to load M2Crypto/OpenSSL
+try:
+ from M2Crypto import m2
+ m2cryptoLoaded = True
+
+except ImportError:
+ m2cryptoLoaded = False
+
+
+# Try to load cryptlib
+try:
+ import cryptlib_py
+ try:
+ cryptlib_py.cryptInit()
+ except cryptlib_py.CryptException, e:
+ #If tlslite and cryptoIDlib are both present,
+ #they might each try to re-initialize this,
+ #so we're tolerant of that.
+ if e[0] != cryptlib_py.CRYPT_ERROR_INITED:
+ raise
+ cryptlibpyLoaded = True
+
+except ImportError:
+ cryptlibpyLoaded = False
+
+#Try to load GMPY
+try:
+ import gmpy
+ gmpyLoaded = True
+except ImportError:
+ gmpyLoaded = False
+
+#Try to load pycrypto
+try:
+ import Crypto.Cipher.AES
+ pycryptoLoaded = True
+except ImportError:
+ pycryptoLoaded = False
+
+
+# **************************************************************************
+# PRNG Functions
+# **************************************************************************
+
+# Get os.urandom PRNG
+try:
+ os.urandom(1)
+ def getRandomBytes(howMany):
+ return stringToBytes(os.urandom(howMany))
+ prngName = "os.urandom"
+
+except:
+ # Else get cryptlib PRNG
+ if cryptlibpyLoaded:
+ def getRandomBytes(howMany):
+ randomKey = cryptlib_py.cryptCreateContext(cryptlib_py.CRYPT_UNUSED,
+ cryptlib_py.CRYPT_ALGO_AES)
+ cryptlib_py.cryptSetAttribute(randomKey,
+ cryptlib_py.CRYPT_CTXINFO_MODE,
+ cryptlib_py.CRYPT_MODE_OFB)
+ cryptlib_py.cryptGenerateKey(randomKey)
+ bytes = createByteArrayZeros(howMany)
+ cryptlib_py.cryptEncrypt(randomKey, bytes)
+ return bytes
+ prngName = "cryptlib"
+
+ else:
+ #Else get UNIX /dev/urandom PRNG
+ try:
+ devRandomFile = open("/dev/urandom", "rb")
+ def getRandomBytes(howMany):
+ return stringToBytes(devRandomFile.read(howMany))
+ prngName = "/dev/urandom"
+ except IOError:
+ #Else get Win32 CryptoAPI PRNG
+ try:
+ import win32prng
+ def getRandomBytes(howMany):
+ s = win32prng.getRandomBytes(howMany)
+ if len(s) != howMany:
+ raise AssertionError()
+ return stringToBytes(s)
+ prngName ="CryptoAPI"
+ except ImportError:
+ #Else no PRNG :-(
+ def getRandomBytes(howMany):
+ raise NotImplementedError("No Random Number Generator "\
+ "available.")
+ prngName = "None"
+
+# **************************************************************************
+# Converter Functions
+# **************************************************************************
+
+def bytesToNumber(bytes):
+ total = 0L
+ multiplier = 1L
+ for count in range(len(bytes)-1, -1, -1):
+ byte = bytes[count]
+ total += multiplier * byte
+ multiplier *= 256
+ return total
+
+def numberToBytes(n):
+ howManyBytes = numBytes(n)
+ bytes = createByteArrayZeros(howManyBytes)
+ for count in range(howManyBytes-1, -1, -1):
+ bytes[count] = int(n % 256)
+ n >>= 8
+ return bytes
+
+def bytesToBase64(bytes):
+ s = bytesToString(bytes)
+ return stringToBase64(s)
+
+def base64ToBytes(s):
+ s = base64ToString(s)
+ return stringToBytes(s)
+
+def numberToBase64(n):
+ bytes = numberToBytes(n)
+ return bytesToBase64(bytes)
+
+def base64ToNumber(s):
+ bytes = base64ToBytes(s)
+ return bytesToNumber(bytes)
+
+def stringToNumber(s):
+ bytes = stringToBytes(s)
+ return bytesToNumber(bytes)
+
+def numberToString(s):
+ bytes = numberToBytes(s)
+ return bytesToString(bytes)
+
+def base64ToString(s):
+ try:
+ return base64.decodestring(s)
+ except binascii.Error, e:
+ raise SyntaxError(e)
+ except binascii.Incomplete, e:
+ raise SyntaxError(e)
+
+def stringToBase64(s):
+ return base64.encodestring(s).replace("\n", "")
+
+def mpiToNumber(mpi): #mpi is an openssl-format bignum string
+ if (ord(mpi[4]) & 0x80) !=0: #Make sure this is a positive number
+ raise AssertionError()
+ bytes = stringToBytes(mpi[4:])
+ return bytesToNumber(bytes)
+
+def numberToMPI(n):
+ bytes = numberToBytes(n)
+ ext = 0
+ #If the high-order bit is going to be set,
+ #add an extra byte of zeros
+ if (numBits(n) & 0x7)==0:
+ ext = 1
+ length = numBytes(n) + ext
+ bytes = concatArrays(createByteArrayZeros(4+ext), bytes)
+ bytes[0] = (length >> 24) & 0xFF
+ bytes[1] = (length >> 16) & 0xFF
+ bytes[2] = (length >> 8) & 0xFF
+ bytes[3] = length & 0xFF
+ return bytesToString(bytes)
+
+
+
+# **************************************************************************
+# Misc. Utility Functions
+# **************************************************************************
+
+def numBytes(n):
+ if n==0:
+ return 0
+ bits = numBits(n)
+ return int(math.ceil(bits / 8.0))
+
+def hashAndBase64(s):
+ return stringToBase64(sha.sha(s).digest())
+
+def getBase64Nonce(numChars=22): #defaults to an 132 bit nonce
+ bytes = getRandomBytes(numChars)
+ bytesStr = "".join([chr(b) for b in bytes])
+ return stringToBase64(bytesStr)[:numChars]
+
+
+# **************************************************************************
+# Big Number Math
+# **************************************************************************
+
+def getRandomNumber(low, high):
+ if low >= high:
+ raise AssertionError()
+ howManyBits = numBits(high)
+ howManyBytes = numBytes(high)
+ lastBits = howManyBits % 8
+ while 1:
+ bytes = getRandomBytes(howManyBytes)
+ if lastBits:
+ bytes[0] = bytes[0] % (1 << lastBits)
+ n = bytesToNumber(bytes)
+ if n >= low and n < high:
+ return n
+
+def gcd(a,b):
+ a, b = max(a,b), min(a,b)
+ while b:
+ a, b = b, a % b
+ return a
+
+def lcm(a, b):
+ #This will break when python division changes, but we can't use // cause
+ #of Jython
+ return (a * b) / gcd(a, b)
+
+#Returns inverse of a mod b, zero if none
+#Uses Extended Euclidean Algorithm
+def invMod(a, b):
+ c, d = a, b
+ uc, ud = 1, 0
+ while c != 0:
+ #This will break when python division changes, but we can't use //
+ #cause of Jython
+ q = d / c
+ c, d = d-(q*c), c
+ uc, ud = ud - (q * uc), uc
+ if d == 1:
+ return ud % b
+ return 0
+
+
+if gmpyLoaded:
+ def powMod(base, power, modulus):
+ base = gmpy.mpz(base)
+ power = gmpy.mpz(power)
+ modulus = gmpy.mpz(modulus)
+ result = pow(base, power, modulus)
+ return long(result)
+
+else:
+ #Copied from Bryan G. Olson's post to comp.lang.python
+ #Does left-to-right instead of pow()'s right-to-left,
+ #thus about 30% faster than the python built-in with small bases
+ def powMod(base, power, modulus):
+ nBitScan = 5
+
+ """ Return base**power mod modulus, using multi bit scanning
+ with nBitScan bits at a time."""
+
+ #TREV - Added support for negative exponents
+ negativeResult = False
+ if (power < 0):
+ power *= -1
+ negativeResult = True
+
+ exp2 = 2**nBitScan
+ mask = exp2 - 1
+
+ # Break power into a list of digits of nBitScan bits.
+ # The list is recursive so easy to read in reverse direction.
+ nibbles = None
+ while power:
+ nibbles = int(power & mask), nibbles
+ power = power >> nBitScan
+
+ # Make a table of powers of base up to 2**nBitScan - 1
+ lowPowers = [1]
+ for i in xrange(1, exp2):
+ lowPowers.append((lowPowers[i-1] * base) % modulus)
+
+ # To exponentiate by the first nibble, look it up in the table
+ nib, nibbles = nibbles
+ prod = lowPowers[nib]
+
+ # For the rest, square nBitScan times, then multiply by
+ # base^nibble
+ while nibbles:
+ nib, nibbles = nibbles
+ for i in xrange(nBitScan):
+ prod = (prod * prod) % modulus
+ if nib: prod = (prod * lowPowers[nib]) % modulus
+
+ #TREV - Added support for negative exponents
+ if negativeResult:
+ prodInv = invMod(prod, modulus)
+ #Check to make sure the inverse is correct
+ if (prod * prodInv) % modulus != 1:
+ raise AssertionError()
+ return prodInv
+ return prod
+
+
+#Pre-calculate a sieve of the ~100 primes < 1000:
+def makeSieve(n):
+ sieve = range(n)
+ for count in range(2, int(math.sqrt(n))):
+ if sieve[count] == 0:
+ continue
+ x = sieve[count] * 2
+ while x < len(sieve):
+ sieve[x] = 0
+ x += sieve[count]
+ sieve = [x for x in sieve[2:] if x]
+ return sieve
+
+sieve = makeSieve(1000)
+
+def isPrime(n, iterations=5, display=False):
+ #Trial division with sieve
+ for x in sieve:
+ if x >= n: return True
+ if n % x == 0: return False
+ #Passed trial division, proceed to Rabin-Miller
+ #Rabin-Miller implemented per Ferguson & Schneier
+ #Compute s, t for Rabin-Miller
+ if display: print "*",
+ s, t = n-1, 0
+ while s % 2 == 0:
+ s, t = s/2, t+1
+ #Repeat Rabin-Miller x times
+ a = 2 #Use 2 as a base for first iteration speedup, per HAC
+ for count in range(iterations):
+ v = powMod(a, s, n)
+ if v==1:
+ continue
+ i = 0
+ while v != n-1:
+ if i == t-1:
+ return False
+ else:
+ v, i = powMod(v, 2, n), i+1
+ a = getRandomNumber(2, n)
+ return True
+
+def getRandomPrime(bits, display=False):
+ if bits < 10:
+ raise AssertionError()
+ #The 1.5 ensures the 2 MSBs are set
+ #Thus, when used for p,q in RSA, n will have its MSB set
+ #
+ #Since 30 is lcm(2,3,5), we'll set our test numbers to
+ #29 % 30 and keep them there
+ low = (2L ** (bits-1)) * 3/2
+ high = 2L ** bits - 30
+ p = getRandomNumber(low, high)
+ p += 29 - (p % 30)
+ while 1:
+ if display: print ".",
+ p += 30
+ if p >= high:
+ p = getRandomNumber(low, high)
+ p += 29 - (p % 30)
+ if isPrime(p, display=display):
+ return p
+
+#Unused at the moment...
+def getRandomSafePrime(bits, display=False):
+ if bits < 10:
+ raise AssertionError()
+ #The 1.5 ensures the 2 MSBs are set
+ #Thus, when used for p,q in RSA, n will have its MSB set
+ #
+ #Since 30 is lcm(2,3,5), we'll set our test numbers to
+ #29 % 30 and keep them there
+ low = (2 ** (bits-2)) * 3/2
+ high = (2 ** (bits-1)) - 30
+ q = getRandomNumber(low, high)
+ q += 29 - (q % 30)
+ while 1:
+ if display: print ".",
+ q += 30
+ if (q >= high):
+ q = getRandomNumber(low, high)
+ q += 29 - (q % 30)
+ #Ideas from Tom Wu's SRP code
+ #Do trial division on p and q before Rabin-Miller
+ if isPrime(q, 0, display=display):
+ p = (2 * q) + 1
+ if isPrime(p, display=display):
+ if isPrime(q, display=display):
+ return p
diff --git a/cesar/maximus/python/lib/mmentry/aes128/rijndael.py b/cesar/maximus/python/lib/mmentry/aes128/rijndael.py
new file mode 100644
index 0000000000..cb2f547346
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/aes128/rijndael.py
@@ -0,0 +1,392 @@
+"""
+A pure python (slow) implementation of rijndael with a decent interface
+
+To include -
+
+from rijndael import rijndael
+
+To do a key setup -
+
+r = rijndael(key, block_size = 16)
+
+key must be a string of length 16, 24, or 32
+blocksize must be 16, 24, or 32. Default is 16
+
+To use -
+
+ciphertext = r.encrypt(plaintext)
+plaintext = r.decrypt(ciphertext)
+
+If any strings are of the wrong length a ValueError is thrown
+"""
+
+# ported from the Java reference code by Bram Cohen, bram@gawth.com, April 2001
+# this code is public domain, unless someone makes
+# an intellectual property claim against the reference
+# code, in which case it can be made public domain by
+# deleting all the comments and renaming all the variables
+
+import copy
+import string
+
+
+
+#-----------------------
+#TREV - ADDED BECAUSE THERE'S WARNINGS ABOUT INT OVERFLOW BEHAVIOR CHANGING IN
+#2.4.....
+import os
+if os.name != "java":
+ import exceptions
+ if hasattr(exceptions, "FutureWarning"):
+ import warnings
+ warnings.filterwarnings("ignore", category=FutureWarning, append=1)
+#-----------------------
+
+
+
+shifts = [[[0, 0], [1, 3], [2, 2], [3, 1]],
+ [[0, 0], [1, 5], [2, 4], [3, 3]],
+ [[0, 0], [1, 7], [3, 5], [4, 4]]]
+
+# [keysize][block_size]
+num_rounds = {16: {16: 10, 24: 12, 32: 14}, 24: {16: 12, 24: 12, 32: 14}, 32: {16: 14, 24: 14, 32: 14}}
+
+A = [[1, 1, 1, 1, 1, 0, 0, 0],
+ [0, 1, 1, 1, 1, 1, 0, 0],
+ [0, 0, 1, 1, 1, 1, 1, 0],
+ [0, 0, 0, 1, 1, 1, 1, 1],
+ [1, 0, 0, 0, 1, 1, 1, 1],
+ [1, 1, 0, 0, 0, 1, 1, 1],
+ [1, 1, 1, 0, 0, 0, 1, 1],
+ [1, 1, 1, 1, 0, 0, 0, 1]]
+
+# produce log and alog tables, needed for multiplying in the
+# field GF(2^m) (generator = 3)
+alog = [1]
+for i in xrange(255):
+ j = (alog[-1] << 1) ^ alog[-1]
+ if j & 0x100 != 0:
+ j ^= 0x11B
+ alog.append(j)
+
+log = [0] * 256
+for i in xrange(1, 255):
+ log[alog[i]] = i
+
+# multiply two elements of GF(2^m)
+def mul(a, b):
+ if a == 0 or b == 0:
+ return 0
+ return alog[(log[a & 0xFF] + log[b & 0xFF]) % 255]
+
+# substitution box based on F^{-1}(x)
+box = [[0] * 8 for i in xrange(256)]
+box[1][7] = 1
+for i in xrange(2, 256):
+ j = alog[255 - log[i]]
+ for t in xrange(8):
+ box[i][t] = (j >> (7 - t)) & 0x01
+
+B = [0, 1, 1, 0, 0, 0, 1, 1]
+
+# affine transform: box[i] <- B + A*box[i]
+cox = [[0] * 8 for i in xrange(256)]
+for i in xrange(256):
+ for t in xrange(8):
+ cox[i][t] = B[t]
+ for j in xrange(8):
+ cox[i][t] ^= A[t][j] * box[i][j]
+
+# S-boxes and inverse S-boxes
+S = [0] * 256
+Si = [0] * 256
+for i in xrange(256):
+ S[i] = cox[i][0] << 7
+ for t in xrange(1, 8):
+ S[i] ^= cox[i][t] << (7-t)
+ Si[S[i] & 0xFF] = i
+
+# T-boxes
+G = [[2, 1, 1, 3],
+ [3, 2, 1, 1],
+ [1, 3, 2, 1],
+ [1, 1, 3, 2]]
+
+AA = [[0] * 8 for i in xrange(4)]
+
+for i in xrange(4):
+ for j in xrange(4):
+ AA[i][j] = G[i][j]
+ AA[i][i+4] = 1
+
+for i in xrange(4):
+ pivot = AA[i][i]
+ if pivot == 0:
+ t = i + 1
+ while AA[t][i] == 0 and t < 4:
+ t += 1
+ assert t != 4, 'G matrix must be invertible'
+ for j in xrange(8):
+ AA[i][j], AA[t][j] = AA[t][j], AA[i][j]
+ pivot = AA[i][i]
+ for j in xrange(8):
+ if AA[i][j] != 0:
+ AA[i][j] = alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255]
+ for t in xrange(4):
+ if i != t:
+ for j in xrange(i+1, 8):
+ AA[t][j] ^= mul(AA[i][j], AA[t][i])
+ AA[t][i] = 0
+
+iG = [[0] * 4 for i in xrange(4)]
+
+for i in xrange(4):
+ for j in xrange(4):
+ iG[i][j] = AA[i][j + 4]
+
+def mul4(a, bs):
+ if a == 0:
+ return 0
+ r = 0
+ for b in bs:
+ r <<= 8
+ if b != 0:
+ r = r | mul(a, b)
+ return r
+
+T1 = []
+T2 = []
+T3 = []
+T4 = []
+T5 = []
+T6 = []
+T7 = []
+T8 = []
+U1 = []
+U2 = []
+U3 = []
+U4 = []
+
+for t in xrange(256):
+ s = S[t]
+ T1.append(mul4(s, G[0]))
+ T2.append(mul4(s, G[1]))
+ T3.append(mul4(s, G[2]))
+ T4.append(mul4(s, G[3]))
+
+ s = Si[t]
+ T5.append(mul4(s, iG[0]))
+ T6.append(mul4(s, iG[1]))
+ T7.append(mul4(s, iG[2]))
+ T8.append(mul4(s, iG[3]))
+
+ U1.append(mul4(t, iG[0]))
+ U2.append(mul4(t, iG[1]))
+ U3.append(mul4(t, iG[2]))
+ U4.append(mul4(t, iG[3]))
+
+# round constants
+rcon = [1]
+r = 1
+for t in xrange(1, 30):
+ r = mul(2, r)
+ rcon.append(r)
+
+del A
+del AA
+del pivot
+del B
+del G
+del box
+del log
+del alog
+del i
+del j
+del r
+del s
+del t
+del mul
+del mul4
+del cox
+del iG
+
+class rijndael:
+ def __init__(self, key, block_size = 16):
+ if block_size != 16 and block_size != 24 and block_size != 32:
+ raise ValueError('Invalid block size: ' + str(block_size))
+ if len(key) != 16 and len(key) != 24 and len(key) != 32:
+ raise ValueError('Invalid key size: ' + str(len(key)))
+ self.block_size = block_size
+
+ ROUNDS = num_rounds[len(key)][block_size]
+ BC = block_size / 4
+ # encryption round keys
+ Ke = [[0] * BC for i in xrange(ROUNDS + 1)]
+ # decryption round keys
+ Kd = [[0] * BC for i in xrange(ROUNDS + 1)]
+ ROUND_KEY_COUNT = (ROUNDS + 1) * BC
+ KC = len(key) / 4
+
+ # copy user material bytes into temporary ints
+ tk = []
+ for i in xrange(0, KC):
+ tk.append((ord(key[i * 4]) << 24) | (ord(key[i * 4 + 1]) << 16) |
+ (ord(key[i * 4 + 2]) << 8) | ord(key[i * 4 + 3]))
+
+ # copy values into round key arrays
+ t = 0
+ j = 0
+ while j < KC and t < ROUND_KEY_COUNT:
+ Ke[t / BC][t % BC] = tk[j]
+ Kd[ROUNDS - (t / BC)][t % BC] = tk[j]
+ j += 1
+ t += 1
+ tt = 0
+ rconpointer = 0
+ while t < ROUND_KEY_COUNT:
+ # extrapolate using phi (the round key evolution function)
+ tt = tk[KC - 1]
+ tk[0] ^= (S[(tt >> 16) & 0xFF] & 0xFF) << 24 ^ \
+ (S[(tt >> 8) & 0xFF] & 0xFF) << 16 ^ \
+ (S[ tt & 0xFF] & 0xFF) << 8 ^ \
+ (S[(tt >> 24) & 0xFF] & 0xFF) ^ \
+ (rcon[rconpointer] & 0xFF) << 24
+ rconpointer += 1
+ if KC != 8:
+ for i in xrange(1, KC):
+ tk[i] ^= tk[i-1]
+ else:
+ for i in xrange(1, KC / 2):
+ tk[i] ^= tk[i-1]
+ tt = tk[KC / 2 - 1]
+ tk[KC / 2] ^= (S[ tt & 0xFF] & 0xFF) ^ \
+ (S[(tt >> 8) & 0xFF] & 0xFF) << 8 ^ \
+ (S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ \
+ (S[(tt >> 24) & 0xFF] & 0xFF) << 24
+ for i in xrange(KC / 2 + 1, KC):
+ tk[i] ^= tk[i-1]
+ # copy values into round key arrays
+ j = 0
+ while j < KC and t < ROUND_KEY_COUNT:
+ Ke[t / BC][t % BC] = tk[j]
+ Kd[ROUNDS - (t / BC)][t % BC] = tk[j]
+ j += 1
+ t += 1
+ # inverse MixColumn where needed
+ for r in xrange(1, ROUNDS):
+ for j in xrange(BC):
+ tt = Kd[r][j]
+ Kd[r][j] = U1[(tt >> 24) & 0xFF] ^ \
+ U2[(tt >> 16) & 0xFF] ^ \
+ U3[(tt >> 8) & 0xFF] ^ \
+ U4[ tt & 0xFF]
+ self.Ke = Ke
+ self.Kd = Kd
+
+ def encrypt(self, plaintext):
+ if len(plaintext) != self.block_size:
+ raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(plaintext)))
+ Ke = self.Ke
+
+ BC = self.block_size / 4
+ ROUNDS = len(Ke) - 1
+ if BC == 4:
+ SC = 0
+ elif BC == 6:
+ SC = 1
+ else:
+ SC = 2
+ s1 = shifts[SC][1][0]
+ s2 = shifts[SC][2][0]
+ s3 = shifts[SC][3][0]
+ a = [0] * BC
+ # temporary work array
+ t = []
+ # plaintext to ints + key
+ for i in xrange(BC):
+ t.append((ord(plaintext[i * 4 ]) << 24 |
+ ord(plaintext[i * 4 + 1]) << 16 |
+ ord(plaintext[i * 4 + 2]) << 8 |
+ ord(plaintext[i * 4 + 3]) ) ^ Ke[0][i])
+ # apply round transforms
+ for r in xrange(1, ROUNDS):
+ for i in xrange(BC):
+ a[i] = (T1[(t[ i ] >> 24) & 0xFF] ^
+ T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^
+ T3[(t[(i + s2) % BC] >> 8) & 0xFF] ^
+ T4[ t[(i + s3) % BC] & 0xFF] ) ^ Ke[r][i]
+ t = copy.copy(a)
+ # last round is special
+ result = []
+ for i in xrange(BC):
+ tt = Ke[ROUNDS][i]
+ result.append((S[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
+ result.append((S[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
+ result.append((S[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
+ result.append((S[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
+ return string.join(map(chr, result), '')
+
+ def decrypt(self, ciphertext):
+ if len(ciphertext) != self.block_size:
+ raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(plaintext)))
+ Kd = self.Kd
+
+ BC = self.block_size / 4
+ ROUNDS = len(Kd) - 1
+ if BC == 4:
+ SC = 0
+ elif BC == 6:
+ SC = 1
+ else:
+ SC = 2
+ s1 = shifts[SC][1][1]
+ s2 = shifts[SC][2][1]
+ s3 = shifts[SC][3][1]
+ a = [0] * BC
+ # temporary work array
+ t = [0] * BC
+ # ciphertext to ints + key
+ for i in xrange(BC):
+ t[i] = (ord(ciphertext[i * 4 ]) << 24 |
+ ord(ciphertext[i * 4 + 1]) << 16 |
+ ord(ciphertext[i * 4 + 2]) << 8 |
+ ord(ciphertext[i * 4 + 3]) ) ^ Kd[0][i]
+ # apply round transforms
+ for r in xrange(1, ROUNDS):
+ for i in xrange(BC):
+ a[i] = (T5[(t[ i ] >> 24) & 0xFF] ^
+ T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^
+ T7[(t[(i + s2) % BC] >> 8) & 0xFF] ^
+ T8[ t[(i + s3) % BC] & 0xFF] ) ^ Kd[r][i]
+ t = copy.copy(a)
+ # last round is special
+ result = []
+ for i in xrange(BC):
+ tt = Kd[ROUNDS][i]
+ result.append((Si[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
+ result.append((Si[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
+ result.append((Si[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
+ result.append((Si[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
+ return string.join(map(chr, result), '')
+
+def encrypt(key, block):
+ return rijndael(key, len(block)).encrypt(block)
+
+def decrypt(key, block):
+ return rijndael(key, len(block)).decrypt(block)
+
+def test():
+ def t(kl, bl):
+ b = 'b' * bl
+ r = rijndael('a' * kl, bl)
+ assert r.decrypt(r.encrypt(b)) == b
+ t(16, 16)
+ t(16, 24)
+ t(16, 32)
+ t(24, 16)
+ t(24, 24)
+ t(24, 32)
+ t(32, 16)
+ t(32, 24)
+ t(32, 32)
+
diff --git a/cesar/maximus/python/lib/mmentry/bmi/__init__.py b/cesar/maximus/python/lib/mmentry/bmi/__init__.py
new file mode 100644
index 0000000000..f189dd89ca
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/bmi/__init__.py
@@ -0,0 +1 @@
+from bmiMethod import *
diff --git a/cesar/maximus/python/lib/mmentry/bmi/bmiBody.py b/cesar/maximus/python/lib/mmentry/bmi/bmiBody.py
new file mode 100644
index 0000000000..a4077ea200
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/bmi/bmiBody.py
@@ -0,0 +1,21 @@
+# -*- coding:Utf-8 -*-
+class BmiBody():
+
+
+ #Interpretation
+ Non_Persistent_Schedule_BENTRY = "NS+RSVD+SAI(STPF+GLID+ST+ET)*NS=6Fields"
+ Persistent_Schedule_BENTRY = ""
+ Regions_BENTRY = ""
+ MAC_Address_BENTRY = ""
+ Discover_BENTRY = ""
+ Discovered_Info_BENTRY = ""
+ Beacon_Period_Start_Time_Offset_BENTRY = ""
+ Encryption_Key_Change_BENTRY = ""
+ CCo_Handover_BENTRY = ""
+ Beacon_Relocation_BENTRY = ""
+ AC_Line_Sync_Countdown_BENTRY = ""
+ Change_NumSlots_BENTRY = ""
+ Change_HM_BENTRY = ""
+ Change_SNID_BENTRY = ""
+ #Reserved_for_future_use
+ Vendor_Specific_BENTRY = ""
diff --git a/cesar/maximus/python/lib/mmentry/bmi/bmiMethod.py b/cesar/maximus/python/lib/mmentry/bmi/bmiMethod.py
new file mode 100644
index 0000000000..a0fa7fb6fb
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/bmi/bmiMethod.py
@@ -0,0 +1,482 @@
+# -*- coding:Utf-8 -*-
+#BMI Methods
+
+from bmiBody import *
+from struct import *
+import sys
+sys.path.append('../../python/lib/mmentry')
+from Constants import *
+from random import *
+
+
+#BmiMethod can create every BMI Body of Beacons
+# from BMI format
+class BmiMethod():
+
+ bmiBody = BmiBody()
+
+ #createNon_Persistent_Schedule_BENTRY creates
+ # the BENTRY Field of the Beacon
+ ns = 63
+ #SAIs :
+ stpf = [] #Star Time Field present by default
+ glid = [] #Local CSMA allocation by default
+ st = [] #0 µs by default
+ et = [] #AllocationTimeUnit by default
+ rsvd = 0 #Reserved = 0 by default
+ sais = []
+ saisField = []
+ i = 0
+ stpf.append(1)
+ glid.append(0x7F)
+ st.append(0)
+ et.append(int(randrange(0,3906/(ns-i),1)))
+ sai = (stpf[i]+glid[i]*pow(2,1)+st[i]*pow(2,8)+et[i]*pow(2,20))*stpf[i] + (stpf[i]+glid[i]*pow(2,1)+et[i]*pow(2,8))*((stpf[i]+1)%2)
+ sais.append(sai)
+ saisField.append(pack('I',sai)[0:3+stpf[i]])
+ i = i + 1
+ while i < ns-1:
+ stpf.append(0)
+ glid.append(0x7F)
+ st.append(et[i-1])
+ et.append(int(randrange(et[i-1],((3906-et[i-1])/(ns-i))+et[i-1],1)))
+ sai = (stpf[i]+glid[i]*pow(2,1)+st[i]*pow(2,8)+et[i]*pow(2,20))*stpf[i] + (stpf[i]+glid[i]*pow(2,1)+et[i]*pow(2,8))*((stpf[i]+1)%2)
+ sais.append(sai)
+ saisField.append(pack('I',sai)[0:3+stpf[i]])
+ i = i + 1
+ stpf.append(0)
+ glid.append(0x7F)
+ st.append(et[i-1])
+ et.append(3906)
+ sai = (stpf[i]+glid[i]*pow(2,1)+st[i]*pow(2,8)+et[i]*pow(2,20))*stpf[i] + (stpf[i]+glid[i]*pow(2,1)+et[i]*pow(2,8))*((stpf[i]+1)%2)
+ sais.append(sai)
+ saisField.append(pack('I',sai)[0:3+stpf[i]])
+ i = i + 1
+ def createNon_Persistent_Schedule_BENTRY(self, myNs=None, myStpf=None, myGlid=None, myFirtsSt=None, MyRandomEt=False, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myNs!=None:
+ self.ns=myNs
+ self.i = 0
+ if myStpf!=None:
+ self.stpf[self.i] = myStpf
+ if myGlid!=None:
+ self.glid[self.i] = myGlid
+ if myFirtsSt!=None:
+ self.stpf[self.i] = 1
+ self.st[self.i] = myFirtsSt
+ if MyRandomEt!=False:
+ self.et[self.i] = int(randrange(0,3906/(self.ns-self.i),1))
+ self.sai = (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.st[self.i]*pow(2,8)+self.et[self.i]*pow(2,20))*self.stpf[self.i] + (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.et[self.i]*pow(2,8))*((self.stpf[self.i]+1)%2)
+ self.sais[self.i] = self.sai
+ self.saisField[self.i] = pack('I',self.sai)[0:3+self.stpf[self.i]]
+ self.i = self.i + 1
+ while self.i < self.ns-1:
+ if myStpf!=None:
+ self.stpf[self.i] = myStpf
+ if myGlid!=None:
+ self.glid[self.i] = myGlid
+ if self.stpf[self.i]==0:
+ self.st[self.i] = self.et[self.i-1]
+ if MyRandomEt!=False:
+ self.et[self.i] = int(randrange(self.et[self.i-1],((3906-self.et[self.i-1])/(self.ns-self.i))+self.et[self.i-1],1))
+ self.sai = (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.st[self.i]*pow(2,8)+self.et[self.i]*pow(2,20))*self.stpf[self.i] + (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.et[self.i]*pow(2,8))*((self.stpf[self.i]+1)%2)
+ self.sais[self.i] = self.sai
+ self.saisField[self.i] = pack('I',self.sai)[0:3+self.stpf[self.i]]
+ self.i = self.i + 1
+ if myStpf!=None:
+ self.stpf[self.i] = myStpf
+ if myGlid!=None:
+ self.glid[self.i] = myGlid
+ if self.stpf[self.i]==0:
+ self.st[self.i] = self.et[self.i-1]
+ self.et[self.i] = 3906
+ self.sai = (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.st[self.i]*pow(2,8)+self.et[self.i]*pow(2,20))*self.stpf[self.i] + (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.et[self.i]*pow(2,8))*((self.stpf[self.i]+1)%2)
+ self.sais[self.i] = self.sai
+ self.saisField[self.i] = pack('I',self.sai)[0:3+self.stpf[self.i]]
+ self.i = self.i + 1
+ self.bmiBody.Non_Persistent_Schedule_BENTRY = pack('B',self.ns)
+ self.i = 0
+ print "ns = "+hex(self.ns)
+ while self.i < self.ns:
+ self.bmiBody.Non_Persistent_Schedule_BENTRY = self.bmiBody.Non_Persistent_Schedule_BENTRY + self.saisField[self.i]
+ print "stpf["+str(self.i)+"] = "+hex(self.stpf[self.i])
+ print "glid["+str(self.i)+"] = "+hex(self.glid[self.i])
+ print "st["+str(self.i)+"] = "+hex(self.st[self.i])
+ print "et["+str(self.i)+"] = "+hex(self.et[self.i])
+ self.i = self.i + 1
+ return self.bmiBody.Non_Persistent_Schedule_BENTRY
+
+ #createPersistent_Schedule_BENTRY creates
+ # the BENTRY Field of the Beacon
+ pscd = 0 #Currently used schedule by default
+ cscd = 0 #Only for the current period by default
+ #ns = 63
+ ##SAIs :
+ #stpf = [] #Star Time Field present by default
+ #glid = [] #Local CSMA allocation by default
+ #st = [] #0 µs by default
+ #et = [] #AllocationTimeUnit by default
+ #rsvd = 0 #Reserved = 0 by default
+ #sais = []
+ #saisField = []
+ #i = 0
+ #stpf.append(1)
+ #glid.append(0x7F)
+ #st.append(0)
+ #et.append(int(randrange(0,3906/(ns-i),1)))
+ #sai = (stpf[i]+glid[i]*pow(2,1)+st[i]*pow(2,8)+et[i]*pow(2,20))*stpf[i] + (stpf[i]+glid[i]*pow(2,1)+et[i]*pow(2,8))*((stpf[i]+1)%2)
+ #sais.append(sai)
+ #saisField.append(pack('I',sai)[0:3+stpf[i]])
+ #i = i + 1
+ #while i < ns-1:
+ #stpf.append(0)
+ #glid.append(0x7F)
+ #st.append(et[i-1])
+ #et.append(int(randrange(et[i-1],((3906-et[i-1])/(ns-i))+et[i-1],1)))
+ #sai = (stpf[i]+glid[i]*pow(2,1)+st[i]*pow(2,8)+et[i]*pow(2,20))*stpf[i] + (stpf[i]+glid[i]*pow(2,1)+et[i]*pow(2,8))*((stpf[i]+1)%2)
+ #sais.append(sai)
+ #saisField.append(pack('I',sai)[0:3+stpf[i]])
+ #i = i + 1
+ #stpf.append(0)
+ #glid.append(0x7F)
+ #st.append(et[i-1])
+ #et.append(3906)
+ #sai = (stpf[i]+glid[i]*pow(2,1)+st[i]*pow(2,8)+et[i]*pow(2,20))*stpf[i] + (stpf[i]+glid[i]*pow(2,1)+et[i]*pow(2,8))*((stpf[i]+1)%2)
+ #sais.append(sai)
+ #saisField.append(pack('I',sai)[0:3+stpf[i]])
+ #i = i + 1
+ def createPersistent_Schedule_BENTRY(self, myPscd=None, myCscd=None, myNs=None, myStpf=None, myGlid=None, myFirtsSt=None, MyRandomEt=False, param8=None, param9=None, paramA=None, paramB=None):
+ if myPscd!=None:
+ self.pscd=myPscd
+ if myCscd!=None:
+ self.cscd=myCscd
+ if myNs!=None:
+ self.ns=myNs
+ self.i = 0
+ if myStpf!=None:
+ self.stpf[self.i] = myStpf
+ if myGlid!=None:
+ self.glid[self.i] = myGlid
+ if myFirtsSt!=None:
+ self.stpf[self.i] = 1
+ self.st[self.i] = myFirtsSt
+ if MyRandomEt!=False:
+ self.et[self.i] = int(randrange(0,3906/(self.ns-self.i),1))
+ self.sai = (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.st[self.i]*pow(2,8)+self.et[self.i]*pow(2,20))*self.stpf[self.i] + (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.et[self.i]*pow(2,8))*((self.stpf[self.i]+1)%2)
+ self.sais[self.i] = self.sai
+ self.saisField[self.i] = pack('I',self.sai)[0:3+self.stpf[self.i]]
+ self.i = self.i + 1
+ while self.i < self.ns-1:
+ if myStpf!=None:
+ self.stpf[self.i] = myStpf
+ if myGlid!=None:
+ self.glid[self.i] = myGlid
+ if self.stpf[self.i]==0:
+ self.st[self.i] = self.et[self.i-1]
+ if MyRandomEt!=False:
+ self.et[self.i] = int(randrange(self.et[self.i-1],((3906-self.et[self.i-1])/(self.ns-self.i))+self.et[self.i-1],1))
+ self.sai = (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.st[self.i]*pow(2,8)+self.et[self.i]*pow(2,20))*self.stpf[self.i] + (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.et[self.i]*pow(2,8))*((self.stpf[self.i]+1)%2)
+ self.sais[self.i] = self.sai
+ self.saisField[self.i] = pack('I',self.sai)[0:3+self.stpf[self.i]]
+ self.i = self.i + 1
+ if myStpf!=None:
+ self.stpf[self.i] = myStpf
+ if myGlid!=None:
+ self.glid[self.i] = myGlid
+ if self.stpf[self.i]==0:
+ self.st[self.i] = self.et[self.i-1]
+ self.et[self.i] = 3906
+ self.sai = (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.st[self.i]*pow(2,8)+self.et[self.i]*pow(2,20))*self.stpf[self.i] + (self.stpf[self.i]+self.glid[self.i]*pow(2,1)+self.et[self.i]*pow(2,8))*((self.stpf[self.i]+1)%2)
+ self.sais[self.i] = self.sai
+ self.saisField[self.i] = pack('I',self.sai)[0:3+self.stpf[self.i]]
+ self.i = self.i + 1
+ self.bmiBody.Persistent_Schedule_BENTRY = pack('B',self.pscd + self.cscd*pow(2,3)) + pack('B',self.ns)
+ self.i = 0
+ print "pscd = "+hex(self.pscd)
+ print "cscd = "+hex(self.cscd)
+ print "ns = "+hex(self.ns)
+ while self.i < self.ns:
+ self.bmiBody.Persistent_Schedule_BENTRY = self.bmiBody.Persistent_Schedule_BENTRY + self.saisField[self.i]
+ print "stpf["+str(self.i)+"] = "+hex(self.stpf[self.i])
+ print "glid["+str(self.i)+"] = "+hex(self.glid[self.i])
+ print "st["+str(self.i)+"] = "+hex(self.st[self.i])
+ print "et["+str(self.i)+"] = "+hex(self.et[self.i])
+ self.i = self.i + 1
+ return self.bmiBody.Persistent_Schedule_BENTRY
+
+ #createRegions_BENTRY creates
+ # the BENTRY Field of the Beacon
+ nr = 63
+ rt = [] #Reserved Regions by default
+ ret = [] #AllocationTimeUnit by default
+ rtRets = []
+ rtRetsField = []
+ i = 0
+ rt.append(0)
+ ret.append(int(randrange(0,3906/(nr-i),1)))
+ rtRet = rt[i] + ret[i]*pow(2,4)
+ rtRets.append(rtRet)
+ rtRetsField.append(pack('H',rtRet))
+ i = i + 1
+ while i < nr-1:
+ rt.append(0)
+ ret.append(int(randrange(ret[i-1],((3906-ret[i-1])/(nr-i))+ret[i-1],1)))
+ rtRet = rt[i] + ret[i]*pow(2,4)
+ rtRets.append(rtRet)
+ rtRetsField.append(pack('H',rtRet))
+ i = i + 1
+ rt.append(0)
+ ret.append(3906)
+ rtRet = rt[i] + ret[i]*pow(2,4)
+ rtRets.append(rtRet)
+ rtRetsField.append(pack('H',rtRet))
+ i = i + 1
+ def createRegions_BENTRY(self, myNr=None, myRt=None, MyRandomRet=False, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myNr!=None:
+ self.nr=myNr
+ self.i = 0
+ if myRt!=None:
+ self.rt[self.i] = myRt
+ if MyRandomRet!=False:
+ self.ret[self.i] = int(randrange(0,3906/(self.nr-self.i),1))
+ self.rtRet = self.rt[self.i] + self.ret[self.i]*pow(2,4)
+ self.rtRets[self.i] = self.rtRet
+ self.rtRetsField[self.i] = pack('H',self.rtRet)
+ self.i = self.i + 1
+ while self.i < self.nr-1:
+ if myRt!=None:
+ self.rt[self.i] = myRt
+ if MyRandomRet!=False:
+ self.ret[self.i] = int(randrange(self.ret[self.i-1],((3906-self.ret[self.i-1])/(self.nr-self.i))+self.ret[self.i-1],1))
+ self.rtRet = self.rt[self.i] + self.ret[self.i]*pow(2,4)
+ self.rtRets[self.i] = self.rtRet
+ self.rtRetsField[self.i] = pack('H',self.rtRet)
+ self.i = self.i + 1
+ if myRt!=None:
+ self.rt[self.i] = myRt
+ self.ret[self.i] = 3906
+ self.rtRet = self.rt[self.i] + self.ret[self.i]*pow(2,4)
+ self.rtRets[self.i] = self.rtRet
+ self.rtRetsField[self.i] = pack('H',self.rtRet)
+ self.i = self.i + 1
+ self.bmiBody.Regions_BENTRY = pack('B',self.nr)
+ self.i = 0
+ print "nr = "+hex(self.nr)
+ while self.i < self.nr:
+ self.bmiBody.Regions_BENTRY = self.bmiBody.Regions_BENTRY + self.rtRetsField[self.i]
+ print "rt["+str(self.i)+"] = "+hex(self.rt[self.i])
+ print "ret["+str(self.i)+"] = "+hex(self.ret[self.i])
+ self.i = self.i + 1
+ return self.bmiBody.Regions_BENTRY
+
+ #createMAC_Address_BENTRY creates
+ # the BENTRY Field of the Beacon
+ macAddress = 0x5952544E4542 #="BENTRY"
+ def createMAC_Address_BENTRY(self, myMacAddress=None, param2=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myMacAddress!=None:
+ self.macAddress=myMacAddress
+ self.bmiBody.MAC_Address_BENTRY = pack('Q',self.macAddress)[0:6]
+ print "macAddress = "+hex(self.macAddress)
+ return self.bmiBody.MAC_Address_BENTRY
+
+ #createDiscover_BENTRY creates
+ # the BENTRY Field of the Beacon
+ tei = 0x54
+ def createDiscover_BENTRY(self, myTei=None, param2=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myTei!=None:
+ self.tei=myTei
+ self.bmiBody.Discover_BENTRY = pack('B',self.tei)
+ print "tei = "+hex(self.tei)
+ return self.bmiBody.Discover_BENTRY
+
+ #createDiscovered_Info_BENTRY creates
+ # the BENTRY Field of the Beacon
+ updated = 0 #Not changed by default
+ ccoCapability = 0 #Level 0 by default
+ proxyNetworkCapability = 0 #Not supported by default
+ backupCcoCapability = 0 #Not supported by default
+ ccoStatus = 0 #Not CCo by default
+ pcoStatus = 0 #Not PCo by default
+ backupCcoStatus = 0 #Not Backup CCo by default
+ numDisSta = 0 #0 by default
+ numDisNet = 0 #0 by default
+ authenticationStatus = 0 #Not Authenticated by default
+ userAppointedCcoStatus = 0 #Not User Appointed CCo by default
+ def createDiscovered_Info_BENTRY(self, myUpdated=None, myCcoCapability=None, myProxyNetworkCapability=None, myBackupCcoCapability=None, myCcoStatus=None, myPcoStatus=None, myBackupCcoStatus=None, myNumDisSta=None, myNumDisNet=None, myAuthenticationStatus=None, myUserAppointedCcoStatus=None):
+ if myUpdated!=None:
+ self.updated=myUpdated
+ if myCcoCapability!=None:
+ self.ccoCapability=myCcoCapability
+ if myProxyNetworkCapability!=None:
+ self.proxyNetworkCapability=myProxyNetworkCapability
+ if myBackupCcoCapability!=None:
+ self.backupCcoCapability=myBackupCcoCapability
+ if myCcoStatus!=None:
+ self.ccoStatus=myCcoStatus
+ if myPcoStatus!=None:
+ self.pcoStatus=myPcoStatus
+ if myBackupCcoStatus!=None:
+ self.backupCcoStatus=myBackupCcoStatus
+ if myNumDisSta!=None:
+ self.numDisSta=myNumDisSta
+ if myNumDisNet!=None:
+ self.numDisNet=myNumDisNet
+ if myAuthenticationStatus!=None:
+ self.authenticationStatus=myAuthenticationStatus
+ if myUserAppointedCcoStatus!=None:
+ self.userAppointedCcoStatus=myUserAppointedCcoStatus
+ self.bmiBody.Discovered_Info_BENTRY = pack('B',self.updated + self.ccoCapability*pow(2,1) + self.proxyNetworkCapability*pow(2,3) + self.backupCcoCapability*pow(2,4) + self.ccoStatus*pow(2,5) + self.pcoStatus*pow(2,6) + self.backupCcoStatus*pow(2,7)) + pack('B',self.numDisSta) + pack('B',self.numDisNet) + pack('B',self.authenticationStatus + self.userAppointedCcoStatus*pow(2,1))
+ print "updated = "+hex(self.updated)
+ print "ccoCapability = "+hex(self.ccoCapability)
+ print "proxyNetworkCapability = "+hex(self.proxyNetworkCapability)
+ print "backupCcoCapability = "+hex(self.backupCcoCapability)
+ print "ccoStatus = "+hex(self.ccoStatus)
+ print "pcoStatus = "+hex(self.pcoStatus)
+ print "backupCcoStatus = "+hex(self.backupCcoStatus)
+ print "numDisSta = "+hex(self.numDisSta)
+ print "numDisNet = "+hex(self.numDisNet)
+ print "authenticationStatus = "+hex(self.authenticationStatus)
+ print "userAppointedCcoStatus = "+hex(self.userAppointedCcoStatus)
+ return self.bmiBody.Discovered_Info_BENTRY
+
+ #createBeacon_Period_Start_Time_Offset_BENTRY creates
+ # the BENTRY Field of the Beacon
+ bpsto = 0 #0 by default
+ def createBeacon_Period_Start_Time_Offset_BENTRY(self, myBpsto=None, param2=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myBpsto!=None:
+ self.bpsto=myBpsto
+ self.bmiBody.Beacon_Period_Start_Time_Offset_BENTRY = pack('I',self.bpsto)[0:3]
+ print "bpsto = "+hex(self.bpsto)
+ return self.bmiBody.Beacon_Period_Start_Time_Offset_BENTRY
+
+ #createEncryption_Key_Change_BENTRY creates
+ # the BENTRY Field of the Beacon
+ kccd = 1 #Next Beacon Period by default
+ kbc = 0 #NEK Period by default
+ newEks = 0 #0 by default
+ def createEncryption_Key_Change_BENTRY(self, myKccd=None, myKbc=None, myNewEks=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myKccd!=None:
+ self.kccd=myKccd
+ if myKbc!=None:
+ self.kbc=myKbc
+ if myNewEks!=None:
+ self.newEks=myNewEks
+ self.bmiBody.Encryption_Key_Change_BENTRY = pack('B',self.kccd + self.kbc*pow(2,6)) + pack('B',self.newEks)
+ print "kccd = "+hex(self.kccd)
+ print "kbc = "+hex(self.kbc)
+ print "newEks = "+hex(self.newEks)
+ return self.bmiBody.Encryption_Key_Change_BENTRY
+
+ #createCCo_Handover_BENTRY creates
+ # the BENTRY Field of the Beacon
+ hcd = 0 #0 by default
+ nctei = 0x4e #='N' by default
+ def createCCo_Handover_BENTRY(self, myHcd=None, myNtcei=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myHcd!=None:
+ self.hcd=myHcd
+ if myNtcei!=None:
+ self.nctei=myNtcei
+ self.bmiBody.CCo_Handover_BENTRY = pack('B',self.hcd) + pack('B',self.nctei)
+ print "hcd = "+hex(self.hcd)
+ print "nctei = "+hex(self.nctei)
+ return self.bmiBody.CCo_Handover_BENTRY
+
+ #createBeacon_Relocation_BENTRY creates
+ # the BENTRY Field of the Beacon
+ rcd = 0 #0 by default
+ rlt = 0 #0 by default
+ lgf = 0 #0 by default
+ rlo = 0 #0 by default
+ rlSlotId = 0 #0 by default
+ def createBeacon_Relocation_BENTRY(self, myRcd=None, myRlt=None, myLgf=None, myRlo=None, myRlSlotId=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myRcd!=None:
+ self.rcd=myRcd
+ if myRlt!=None:
+ self.rlt=myRlt
+ if myLgf!=None:
+ self.lgf=myLgf
+ if myRlo!=None:
+ self.rlo=myRlo
+ if myRlSlotId!=None:
+ self.rlSlotId=myRlSlotId
+ self.bmiBody.Beacon_Relocation_BENTRY = pack('B',self.rcd + self.rlt*pow(2,6) + self.lgf*pow(2,7)) + pack('Q',self.rlo + self.rlSlotId*pow(2,17))[0:3]
+ print "rcd = "+hex(self.rcd)
+ print "rlt = "+hex(self.rlt)
+ print "lgf = "+hex(self.lgf)
+ print "rlo = "+hex(self.rlo)
+ print "rlSlotId = "+hex(self.rlSlotId)
+ return self.bmiBody.Beacon_Relocation_BENTRY
+
+ #createAC_Line_Sync_Countdown_BENTRY creates
+ # the BENTRY Field of the Beacon
+ countDown = 1 #Next Beacon Period by default
+ reasonCode = 0 #Shut down by default
+ def createAC_Line_Sync_Countdown_BENTRY(self, myCountDown=None, myReasonCode=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myCountDown!=None:
+ self.countDown=myCountDown
+ if myReasonCode!=None:
+ self.reasonCode=myReasonCode
+ self.bmiBody.AC_Line_Sync_Countdown_BENTRY = pack('B',self.countDown) + pack('B',self.reasonCode)
+ print "countDown = "+hex(self.countDown)
+ print "reasonCode = "+hex(self.reasonCode)
+ return self.bmiBody.AC_Line_Sync_Countdown_BENTRY
+
+ #createChange_NumSlots_BENTRY creates
+ # the BENTRY Field of the Beacon
+ nsccd = 1 #Next Beacon Period by default
+ newNumSlot = 0 #0 by default
+ def createChange_NumSlots_BENTRY(self, myNsccd=None, myNewNumSlot=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myNsccd!=None:
+ self.nsccd=myNsccd
+ if myNewNumSlot!=None:
+ self.newNumSlot=myNewNumSlot
+ self.bmiBody.Change_NumSlots_BENTRY = pack('B',self.nsccd) + pack('B',self.newNumSlot)
+ print "nsccd = "+hex(self.nsccd)
+ print "newNumSlot = "+hex(self.newNumSlot)
+ return self.bmiBody.Change_NumSlots_BENTRY
+
+ #createChange_HM_BENTRY creates
+ # the BENTRY Field of the Beacon
+ hmccd = 1 #Next Beacon Period by default
+ newHm = 0 #0 by default
+ def createChange_HM_BENTRY(self, myHmccd=None, myNewHm=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myHmccd!=None:
+ self.hmccd=myHmccd
+ if myNewHm!=None:
+ self.newHm=myNewHm
+ self.bmiBody.Change_HM_BENTRY = pack('B',self.hmccd + self.newHm*pow(2,6))
+ print "hmccd = "+hex(self.hmccd)
+ print "newHm = "+hex(self.newHm)
+ return self.bmiBody.Change_HM_BENTRY
+
+ #createChange_SNID_BENTRY creates
+ # the BENTRY Field of the Beacon
+ sccd = 1 #Next Beacon Period by default
+ newSnid = 0 #0 by default
+ def createChange_SNID_BENTRY(self, mySccd=None, myNewSnid=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if mySccd!=None:
+ self.sccd=mySccd
+ if myNewSnid!=None:
+ self.newSnid=myNewSnid
+ self.bmiBody.Change_SNID_BENTRY = pack('B',self.sccd + self.newSnid*pow(2,4))
+ print "sccd = "+hex(self.sccd)
+ print "newSnid = "+hex(self.newSnid)
+ return self.bmiBody.Change_SNID_BENTRY
+
+ #
+ def __init__(self):
+ #Beacon_Field
+ self.dico = {Non_Persistent_Schedule_BENTRY:self.createNon_Persistent_Schedule_BENTRY,
+ Persistent_Schedule_BENTRY:self.createPersistent_Schedule_BENTRY,
+ Regions_BENTRY:self.createRegions_BENTRY,
+ MAC_Address_BENTRY:self.createMAC_Address_BENTRY,
+ Discover_BENTRY:self.createDiscover_BENTRY,
+ Discovered_Info_BENTRY:self.createDiscovered_Info_BENTRY,
+ Beacon_Period_Start_Time_Offset_BENTRY:self.createBeacon_Period_Start_Time_Offset_BENTRY,
+ Encryption_Key_Change_BENTRY:self.createEncryption_Key_Change_BENTRY,
+ CCo_Handover_BENTRY:self.createCCo_Handover_BENTRY,
+ Beacon_Relocation_BENTRY:self.createBeacon_Relocation_BENTRY,
+ AC_Line_Sync_Countdown_BENTRY:self.createAC_Line_Sync_Countdown_BENTRY,
+ Change_NumSlots_BENTRY:self.createChange_NumSlots_BENTRY,
+ Change_HM_BENTRY:self.createChange_HM_BENTRY,
+ Change_SNID_BENTRY:self.createChange_SNID_BENTRY
+ }
diff --git a/cesar/maximus/python/lib/mmentry/encapsulation/__init__.py b/cesar/maximus/python/lib/mmentry/encapsulation/__init__.py
new file mode 100644
index 0000000000..5660af2567
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/encapsulation/__init__.py
@@ -0,0 +1 @@
+from encapsulation import *
diff --git a/cesar/maximus/python/lib/mmentry/encapsulation/encapsulation.py b/cesar/maximus/python/lib/mmentry/encapsulation/encapsulation.py
new file mode 100644
index 0000000000..d09deedfbf
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/encapsulation/encapsulation.py
@@ -0,0 +1,250 @@
+# -*- coding:Utf-8 -*-
+
+#------ Encapsulated MME Library Prototypes -------
+
+import sys
+sys.path.append('../../python/lib/mmentry')
+
+from Constants import * #Constants library is used : mme
+from struct import * #struct library is used : pack(),
+
+#import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+from maximus import *
+
+#print "Create MME"
+myMme = MME()
+
+#The Encapsulated MME is composed by :
+
+class EncapsulatedMme():
+
+ #Original Destination address in the MME is a 6 Bytes field
+ oda = unpack('Q',staAAddress+"\x00\x00")[0]
+ odaField = staAAddress
+ #createOda creates the Original Destination Address Field in the MME
+ def createOda(self, myOda=None):
+ try:
+ if myOda!=None:
+ self.oda=myOda
+ self.odaField = pack('Q',self.oda)[0:6]
+ except:
+ if myOda!=None:
+ self.odaField=myOda
+ self.oda = unpack('Q',self.odaField+"\x00\x00")[0]
+ print "oda = "+hex(self.oda)
+
+ #Original source address in the MME is a 6 Bytes field
+ # by default equals to the Maximus Simulator Address
+ osa = unpack('Q',maxAddress+"\x00\x00")[0]
+ osaField = maxAddress
+ #osa = maxAddress
+ #osaField = pack('Q',osa)[0:6]
+ #createOsa creates the Original Destination Address Field in the MME
+ def createOsa(self, myOsa=None):
+ try:
+ if myOsa!=None:
+ self.osa=myOsa
+ self.osaField = pack('Q',self.osa)[0:6]
+ except:
+ if myOsa!=None:
+ self.osaField=myOsa
+ self.osa = unpack('Q',self.osaField+"\x00\x00")[0]
+ print "osa = "+hex(self.osa)
+
+ #VLAN Tag in the MME is an optional 4 Bytes field
+ # by convention if vlanTag = 0, there is no VLAN Tag Field in the MME
+ vlanTag = 0x00000000
+ vlanTagField = pack('I',vlanTag)
+ #createVlanTag creates the otional VLAN Tag Field in The MME
+ def createVlanTag(self, myVlanTag=None):
+ try:
+ if myVlanTag!=None:
+ self.vlanTagField=myVlanTag
+ self.vlanTag = unpack('I',self.vlanTagField)[0]
+ except:
+ if myVlanTag!=None:
+ self.vlanTag=myVlanTag
+ self.vlanTagField = pack('I',self.vlanTag)
+ print "vlanTag = "+hex(self.vlanTag)
+
+ #mtype in the MME is a 2 Bytes Field
+ mtype = 0xe188 #Default IEEE value
+ mtypeField = pack('H',mtype)
+ #createMtype creates the MTYPE Field in the MME
+ def createMtype(self, myMtype=None):
+ try:
+ if myMtype!=None:
+ self.mtype=myMtype
+ self.mtypeField = pack('H',self.mtype)
+ except:
+ if myMtype!=None:
+ self.mtypeField=myMtype
+ self.mtype = unpack('H',self.mtypeField)[0]
+ print "mtype = "+hex(self.mtype)
+
+ #MMV in the MME is a 1 Byte Field
+ # equals to 0 for HPAV Specification V1.0
+ # equals to 1 for HPAV Specification V1.1
+ # all others values are reserved
+ mmv = 0
+ mmvField = pack('B',mmv)
+ #createMmv creates the MMV Field in the MME
+ def createMmv(self, myMmv=None):
+ try:
+ if myMmv!=None:
+ self.mmv=myMmv
+ self.mmvField = pack('B',self.mmv)
+ except:
+ if myMmv!=None:
+ self.mmvField=myMmv
+ self.mmv = unpack('B',self.mmvField)[0]
+ print "mmv = "+hex(self.mmv)
+
+ #MMTYPE in the MME is a 2 Bytes Field
+ # corresponding to the MME Type
+ # see MME interpretation in the Constants
+ mmtype = 0
+ mmtypeField = pack('H',mmtype)
+ #createMmtype creates the MMTYPE Field in the MME
+ def createMmtype(self, myMmtype=None):
+ try:
+ if myMmtype!=None:
+ self.mmtype=myMmtype
+ self.mmtypeField = pack('H',self.mmtype)
+ except:
+ if myMmtype!=None:
+ self.mmtypeField=myMmtype
+ self.mmtype = unpack('H',self.mmtypeField)[0]
+ print "mmtype = "+hex(self.mmtype)
+
+ #FMI in the MME is a 2 Bytes Field composed by :
+ # - MSByte :
+ # - 4 MSBits = NF_MI = Number of fragments
+ # - 4 LSBits = FN_MI = Fragment Number
+ # - LSByte = FMSN = Fragmentation Message Sequence Number
+ nfMi = 0 #by default MMENTRY is not Fragmented
+ fnMi = 0 #by default First or Only Fragment
+ fmsn = 0 #initialized to 0 by default
+ #FMI equals to NF_MI 12 bits left shifted
+ # +FN_MI 4 bits left shifted
+ # +FNSM
+ #First or Only fragment FMI
+ fmi = nfMi*pow(2,8+4)+fnMi*pow(2,8)+fmsn
+ #First or Only fragment FMI Field
+ fmiField = pack('H',fmi)
+ #creatFmi creates the FMI Field in the MME
+ def createFmi(self, myNfmi=None, myFnMi=None, myFmsn=None, myFmi=None):
+ if myFmi!=None:
+ try:
+ self.fmi = myFmi
+ self.fmiField = pack('H',self.fmi)
+ self.fmsn = self.fmi%pow(2,8)
+ self.fnMi = (self.fmi/pow(2,8))%pow(2,4)
+ self.nfMi = self.fmi/pow(2,12)
+ except:
+ self.fmiField = myFmi
+ self.fmi = unpack('H',self.fmiField)[0]
+ self.fmsn = int(self.fmi%pow(2,8))
+ self.fnMi = int((self.fmi/pow(2,8))%pow(2,4))
+ self.nfMi = int(self.fmi/pow(2,12))
+ else:
+ if myNfmi!=None:
+ self.nfMi=myNfmi
+ if myFnMi!=None:
+ self.fnMi=myFnMi
+ if myFmsn!=None:
+ self.fmsn=myFmsn
+ #FMI computation
+ self.fmi=self.nfMi*pow(2,8+4)+self.fnMi*pow(2,8)+self.fmsn
+ #FMI Field creation
+ self.fmiField = pack('H',self.fmi)
+ print "nfMi = "+hex(self.nfMi)
+ print "fnMi = "+hex(self.fnMi)
+ print "fmsn = "+hex(self.fmsn)
+
+ #MMENTRY in the MME is a m Bytes field
+ mmentryField = ""
+ #createMmentry creates the MMENTRY Field in the MME
+ def createMmentry(self, myMmentry=None):
+ if myMmentry!=None:
+ self.mmentryField=myMmentry
+ #print "mmentry = "+self.mmentryField
+
+
+ #MME Frame (CM_ENCRYPTED_PAYLOAD.IND Encapsulated MM Entry Field)
+ encapsulatedMmEntry = ""
+ #createEncapsulatedMmEntry creates the Encapsulated MM Entry Field in the encrypted MME
+ def createEncapsulatedMmEntry(self, myOda=None, myOsa=None, myVlanTag=None, myMtype=None, myMmv=None, myMmtype=None, myNfmi=None, myFnMi=0, myFmsn=0, myMmentry=None, myEncapsulatedMmEntry=None, myThisFnMi=None):
+ if myEncapsulatedMmEntry=="ToEncrypt":
+ print "encapsulatedMmEntry :"
+ self.createOda(myOda)
+ self.createOsa(myOsa)
+ self.createVlanTag(myVlanTag)
+ self.createMtype(myMtype)
+ self.createMmv(myMmv)
+ self.createMmtype(myMmtype)
+ if myNfmi == None:
+ myNfmi = int((len(myMmentry)-1)/1492)
+ if myFnMi==None:
+ myFnMi = myThisFnMi
+ self.createFmi(myNfmi, myFnMi, myFmsn)
+ if myThisFnMi == None:
+ myThisFnMi = self.fnMi
+ self.createMmentry(myMmentry) #No fragmentation before encryption
+ self.encapsulatedMmEntry = self.odaField + self.osaField + self.vlanTagField + self.mtypeField + self.mmvField + self.mmtypeField + self.fmiField + self.mmentryField
+ try:
+ myMme.set_mmheader(self.encapsulatedMmEntry[:23])
+ myMme.set_mmentry(self.mmentryField)
+ except:
+ print "MM Entry too long"
+ return self.encapsulatedMmEntry
+ elif myEncapsulatedMmEntry!=None:
+ self.encapsulatedMmEntry=myEncapsulatedMmEntry
+ self.createOda(myOda=self.encapsulatedMmEntry[0:6])
+ self.createOsa(myOsa=self.encapsulatedMmEntry[6:12])
+ self.createVlanTag(myVlanTag=self.encapsulatedMmEntry[12:16])
+ self.createMtype(myMtype=self.encapsulatedMmEntry[16:18])
+ self.createMmv(myMmv=self.encapsulatedMmEntry[18:19])
+ self.createMmtype(myMmtype=self.encapsulatedMmEntry[19:21])
+ self.createFmi(myFmi = self.encapsulatedMmEntry[21:23])
+ self.createMmentry(myMmentry=self.encapsulatedMmEntry[23:])
+ return self.mmentryField
+ else:
+ print "encapsulatedMmEntry :"
+ self.createOda(myOda)
+ self.createOsa(myOsa)
+ self.createVlanTag(myVlanTag)
+ self.createMtype(myMtype)
+ self.createMmv(myMmv)
+ self.createMmtype(myMmtype)
+ if myNfmi == None:
+ myNfmi = int((len(myMmentry)-1)/1492)
+ if myFnMi==None:
+ myFnMi = myThisFnMi
+ self.createFmi(myNfmi, myFnMi, myFmsn)
+ if myThisFnMi == None:
+ myThisFnMi = self.fnMi
+ self.createMmentry(myMmentry[myThisFnMi*1492:(myThisFnMi+1)*1492])
+ self.encapsulatedMmEntry = self.odaField + self.osaField + self.vlanTagField + self.mtypeField + self.mmvField + self.mmtypeField + self.fmiField + self.mmentryField
+ try:
+ myMme.set_mmheader(self.encapsulatedMmEntry[:23])
+ myMme.set_mmentry(self.mmentryField)
+ except:
+ print "MM Entry too long"
+ return self.encapsulatedMmEntry
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cesar/maximus/python/lib/mmentry/fid/__init__.py b/cesar/maximus/python/lib/mmentry/fid/__init__.py
new file mode 100644
index 0000000000..76061d23cf
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/fid/__init__.py
@@ -0,0 +1 @@
+from fidMethod import *
diff --git a/cesar/maximus/python/lib/mmentry/fid/fidBody.py b/cesar/maximus/python/lib/mmentry/fid/fidBody.py
new file mode 100644
index 0000000000..867c101e0b
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/fid/fidBody.py
@@ -0,0 +1,39 @@
+# -*- coding:Utf-8 -*-
+class FidBody():
+ #CSPEC_Field
+ Delay_Bound = "1234"
+ Jitter_Bound = "1234"
+ Average_MSDU_Size = "12"
+ Maximum_MSDU_Size = "12"
+ Average_Data_Rate = "12"
+ Minimum_Data_Rate = "12"
+ Maximum_Data_Rate = "12"
+ Maximum_Inter_TXOP_time = "12"
+ Minimum_Inter_TXOP_time = "12"
+ Maximum_Burst_Size = "12"
+ Exception_Policy = "1"
+ Inactivity_Interval = "1234"
+ MSDU_Error_Rate = "12"
+ CLST = "1"
+ CDESC = "13or37"
+ Vendor_Specific = "Var"
+ ATS_Tolerance = "12"
+ Smallest_Tolerable_Average_Data_Rate = "12"
+ Original_Average_Data_Rate = "12"
+ #QoS_and_MAC_Parameter_Field_(CM-CM)
+ Rx_Window_Size = "12"
+ Smoothing_Buffer_Size = "123"
+ Bidirectional_Burst_CM_CM = "1"
+ #QoS_and_MAC_Parameter_Field_(CM-CCo)
+ TXOPs_per_Beacon_Period = "1"
+ Average_Number_of_PBs_per_TXOP = "12"
+ Minimum_Number_of_PBs_per_TXOP = "12"
+ Maximum_Number_of_PBs_per_TXOP = "12"
+ PPB_Threshold = "12"
+ Surplus_Bandwidth = "12"
+ #Exception_Policy = "1" #Twice Defined
+ #CDESC = "13or37" #Twice Defined
+ #Vendor_Specific = "Var" #Twice Defined ???
+ Smallest_Tolerable_Average_Number_of_PBs_per_TXOP = "12"
+ Original_Average_Number_of_PBs_per_TXOP = "12"
+ Bidirectional_Burst_CM_CCO = "1"
diff --git a/cesar/maximus/python/lib/mmentry/fid/fidMethod.py b/cesar/maximus/python/lib/mmentry/fid/fidMethod.py
new file mode 100644
index 0000000000..d9072b0388
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/fid/fidMethod.py
@@ -0,0 +1,528 @@
+# -*- coding:Utf-8 -*-
+#FID Methods
+
+from fidBody import *
+from struct import *
+import sys
+sys.path.append('../../python/lib/mmentry')
+from Constants import *
+
+#FidMethod can create every FID Body of CSPEC
+# from FID format
+class FidMethod():
+
+ fidBody = FidBody()
+
+ #createDelay_Bound_FID creates
+ # the FID Field of the CSPEC
+ Delay_Bound = 10000000 #10 seconds by default
+ def createDelay_Bound_FID(self, myDelay_Bound=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myDelay_Bound!=None:
+ self.Delay_Bound=myDelay_Bound
+ self.fidBody.Delay_Bound = pack('I',self.Delay_Bound)
+ print "Delay_Bound = "+hex(self.Delay_Bound)
+ return self.fidBody.Delay_Bound
+
+ #createJitter_Bound_FID creates
+ # the FID Field of the CSPEC
+ Jitter_Bound = 10000000 #10 seconds by default
+ def createJitter_Bound_FID(self, myJitter_Bound=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myJitter_Bound!=None:
+ self.Jitter_Bound=myJitter_Bound
+ self.fidBody.Jitter_Bound = pack('I',self.Jitter_Bound)
+ print "Jitter_Bound = "+hex(self.Jitter_Bound)
+ return self.fidBody.Jitter_Bound
+
+ #createAverage_MSDU_Size_FID creates
+ # the FID Field of the CSPEC
+ Average_MSDU_Size = 502 #502 octets by default (ie 1 fragment = 1/3 Max size)
+ def createAverage_MSDU_Size_FID(self, myAverage_MSDU_Size=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myAverage_MSDU_Size!=None:
+ self.Average_MSDU_Size=myAverage_MSDU_Size
+ self.fidBody.Average_MSDU_Size = pack('H',self.Average_MSDU_Size)
+ print "Average_MSDU_Size = "+hex(self.Average_MSDU_Size)
+ return self.fidBody.Average_MSDU_Size
+
+ #createMaximum_MSDU_Size_FID creates
+ # the FID Field of the CSPEC
+ Maximum_MSDU_Size = 1506 #1506 octets by default (ie 3 fragments)
+ def createMaximum_MSDU_Size_FID(self, myMaximum_MSDU_Size=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myMaximum_MSDU_Size!=None:
+ self.Maximum_MSDU_Size=myMaximum_MSDU_Size
+ self.fidBody.Maximum_MSDU_Size = pack('H',self.Maximum_MSDU_Size)
+ print "Maximum_MSDU_Size = "+hex(self.Maximum_MSDU_Size)
+ return self.fidBody.Maximum_MSDU_Size
+
+ #createAverage_Data_Rate_FID creates
+ # the FID Field of the CSPEC
+ Average_Data_Rate = 10000 #100 Mbps by default (ie 1/2 Max Rate)
+ def createAverage_Data_Rate_FID(self, myAverage_Data_Rate=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myAverage_Data_Rate!=None:
+ self.Average_Data_Rate=myAverage_Data_Rate
+ self.fidBody.Average_Data_Rate = pack('H',self.Average_Data_Rate)
+ print "Average_Data_Rate = "+hex(self.Average_Data_Rate)
+ return self.fidBody.Average_Data_Rate
+
+ #createMinimum_Data_Rate_FID creates
+ # the FID Field of the CSPEC
+ Minimum_Data_Rate = 1 #10 Kbps by default (ie Min Rate)
+ def createMinimum_Data_Rate_FID(self, myMinimum_Data_Rate=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myMinimum_Data_Rate!=None:
+ self.Minimum_Data_Rate=myMinimum_Data_Rate
+ self.fidBody.Minimum_Data_Rate = pack('H',self.Minimum_Data_Rate)
+ print "Minimum_Data_Rate = "+hex(self.Minimum_Data_Rate)
+ return self.fidBody.Minimum_Data_Rate
+
+ #createMaximum_Data_Rate_FID creates
+ # the FID Field of the CSPEC
+ Maximum_Data_Rate = 20000 #200 Mbps by default (ie Max Rate)
+ def createMaximum_Data_Rate_FID(self, myMaximum_Data_Rate=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myMaximum_Data_Rate!=None:
+ self.Maximum_Data_Rate=myMaximum_Data_Rate
+ self.fidBody.Maximum_Data_Rate = pack('H',self.Maximum_Data_Rate)
+ print "Maximum_Data_Rate = "+hex(self.Maximum_Data_Rate)
+ return self.fidBody.Maximum_Data_Rate
+
+ #createMaximum_Inter-TXOP_time_FID creates
+ # the FID Field of the CSPEC
+ Maximum_Inter_TXOP_time = 10000 #10 milliseconds by default
+ def createMaximum_Inter_TXOP_time_FID(self, myMaximum_Inter_TXOP_time=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myMaximum_Inter_TXOP_time!=None:
+ self.Maximum_Inter_TXOP_time=myMaximum_Inter_TXOP_time
+ self.fidBody.Maximum_Inter_TXOP_time = pack('H',self.Maximum_Inter_TXOP_time)
+ print "Maximum_Inter_TXOP_time = "+hex(self.Maximum_Inter_TXOP_time)
+ return self.fidBody.Maximum_Inter_TXOP_time
+
+ #createMinimum_Inter-TXOP_time_FID creates
+ # the FID Field of the CSPEC
+ Minimum_Inter_TXOP_time = 40 #40 microseconds by default
+ def createMinimum_Inter_TXOP_time_FID(self, myMinimum_Inter_TXOP_time=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myMinimum_Inter_TXOP_time!=None:
+ self.Minimum_Inter_TXOP_time=myMinimum_Inter_TXOP_time
+ self.fidBody.Minimum_Inter_TXOP_time = pack('H',self.Minimum_Inter_TXOP_time)
+ print "Minimum_Inter_TXOP_time = "+hex(self.Minimum_Inter_TXOP_time)
+ return self.fidBody.Minimum_Inter_TXOP_time
+
+ #createMaximum_Burst_Size_FID creates
+ # the FID Field of the CSPEC
+ Maximum_Burst_Size = 1506 #1506 octets by default (ie 3 fragments)
+ def createMaximum_Burst_Size_FID(self, myMaximum_Burst_Size=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myMaximum_Burst_Size!=None:
+ self.Maximum_Burst_Size=myMaximum_Burst_Size
+ self.fidBody.Maximum_Burst_Size = pack('H',self.Maximum_Burst_Size)
+ print "Maximum_Burst_Size = "+hex(self.Maximum_Burst_Size)
+ return self.fidBody.Maximum_Burst_Size
+
+ #createException_Policy_FID creates
+ # the FID Field of the CSPEC
+ Exception_Policy = 0 #0=terminate the connection by default
+ def createException_Policy_FID(self, myException_Policy=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myException_Policy!=None:
+ self.Exception_Policy=myException_Policy
+ self.fidBody.Exception_Policy = pack('B',self.Exception_Policy)
+ print "Exception_Policy = "+hex(self.Exception_Policy)
+ return self.fidBody.Exception_Policy
+
+ #createInactivity_Interval_FID creates
+ # the FID Field of the CSPEC
+ Inactivity_Interval = 60000000 #60 seconds by default
+ def createInactivity_Interval_FID(self, myInactivity_Interval=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myInactivity_Interval!=None:
+ self.Inactivity_Interval=myInactivity_Interval
+ self.fidBody.Inactivity_Interval = pack('I',self.Inactivity_Interval)
+ print "Inactivity_Interval = "+hex(self.Inactivity_Interval)
+ return self.fidBody.Inactivity_Interval
+
+ #createMSDU_Error_Rate_FID creates
+ # the FID Field of the CSPEC
+ xMSDU_Error_Rate = 1 #x*10^-y :
+ yMSDU_Error_Rate = 2 #1% by default
+ def createMSDU_Error_Rate_FID(self, myXMSDU_Error_Rate=None, myYMSDU_Error_Rate=None, param3=None, param4=None, param5=None, param6=None):
+ if myXMSDU_Error_Rate!=None:
+ self.xMSDU_Error_Rate=myXMSDU_Error_Rate
+ if myYMSDU_Error_Rate!=None:
+ self.yMSDU_Error_Rate=myYMSDU_Error_Rate
+ self.fidBody.MSDU_Error_Rate = pack('B',self.xMSDU_Error_Rate) + pack('B',self.yMSDU_Error_Rate)
+ print "xMSDU_Error_Rate = "+hex(self.xMSDU_Error_Rate)
+ print "yMSDU_Error_Rate = "+hex(self.yMSDU_Error_Rate)
+ return self.fidBody.MSDU_Error_Rate
+
+ #createCLST_FID creates
+ # the FID Field of the CSPEC
+ CLST = 0 #0=IEEE 802.3 SAP by default
+ def createCLST_FID(self, myCLST=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myCLST!=None:
+ self.CLST=myCLST
+ self.fidBody.CLST = pack('B',self.CLST)
+ print "CLST = "+hex(self.CLST)
+ return self.fidBody.CLST
+
+ #CDESC Fields :
+
+ # IP Protocol Version
+ # =0=IPv4
+ # =1=IPv6
+ ipVersion = 0
+ ipVersionField = pack('B',ipVersion)
+ def createIpVersion(self, myIpVersion=None):
+ if myIpVersion!=None:
+ self.ipVersion=myIpVersion
+ self.ipVersionField = pack('B',self.ipVersion)
+ print "ipVersion = "+hex(self.ipVersion)
+
+ # IP Address or Source HLE
+ # 4 octets long for IPv4
+ # 16 octets long for IPv6
+ sourceIpAddress = 0x41424344
+ if ipVersion == 0:
+ sourceIpAddressField = pack('I',sourceIpAddress)
+ else:
+ #if IPv6 : IP Address = "8 MSBytes" + "8 LSBytes"
+ sourceIpAddressField = pack('Q',sourceIpAddress/pow_2_64) + pack('Q',sourceIpAddress%pow_2_64) #pow_2_64=2^64
+ def createSourceIpAddress(self, mySourceIpAddress=None):
+ if mySourceIpAddress!=None:
+ self.sourceIpAddress=mySourceIpAddress
+ if self.ipVersion == 0:
+ self.sourceIpAddressField = pack('I',self.sourceIpAddress)
+ else:
+ #if IPv6 : IP Address = "8 MSBytes" + "8 LSBytes"
+ self.sourceIpAddressField = pack('Q',self.sourceIpAddress/pow_2_64) + pack('Q',self.sourceIpAddress%pow_2_64)
+ print "sourceIpAddress = "+hex(self.sourceIpAddress)
+
+ # IP Port Number of Source HLE
+ sourceIpPort = 0x6162
+ sourceIpPortField = pack('H',sourceIpPort)
+ def createSourceIpPort(self, mySourceIpPort=None):
+ if mySourceIpPort!=None:
+ self.sourceIpPort=mySourceIpPort
+ self.sourceIpPortField = pack('H',self.sourceIpPort)
+ print "sourceIpPort = "+hex(self.sourceIpPort)
+
+ # IP Address of Destination HLE
+ # 4 octets long for IPv4
+ # 16 octets long for IPv6
+ destinationIpAddress = 0x61626364
+ if ipVersion == 0:
+ destinationIpAddressField = pack('I',destinationIpAddress)
+ else:
+ #if IPv6 : IP Address = "8 MSBytes" + "8 LSBytes"
+ destinationIpAddressField = pack('Q',destinationIpAddress/pow_2_64) + pack('Q',destinationIpAddress%pow_2_64)
+ def createDestinationIpAddress(self, myDestinationIpAddress=None):
+ if myDestinationIpAddress!=None:
+ self.destinationIpAddress=myDestinationIpAddress
+ if self.ipVersion == 0:
+ self.destinationIpAddressField = pack('I',self.destinationIpAddress)
+ else:
+ #if IPv6 : IP Address = "8 MSBytes" + "8 LSBytes"
+ self.destinationIpAddressField = pack('Q',self.destinationIpAddress/pow_2_64) + pack('Q',self.destinationIpAddress%pow_2_64)
+ print "destinationIpAddress = "+hex(self.destinationIpAddress)
+
+ # IP Port Number of destination HLE
+ destinationIpPort = 0x7879
+ destinationIpPortField = pack('H',destinationIpPort)
+ def createDestinationIpPort(self, myDestinationIpPort=None):
+ if myDestinationIpPort!=None:
+ self.destinationIpPort=myDestinationIpPort
+ self.destinationIpPortField = pack('H',self.destinationIpPort)
+ print "destinationIpPort = "+hex(self.destinationIpPort)
+
+ # IP Protocol Type
+ #
+ # ASSIGNED INTERNET PROTOCOL NUMBERS
+ #
+ #In the Internet Protocol (IP) [33] there is a field, called Protocol,
+ #to identify the the next level protocol. This is an 8 bit field.
+ #
+ #Assigned Internet Protocol Numbers
+ #
+ #Decimal Protocol Numbers
+ #------- ----------------
+ #0 Reserved
+ #1 ICMP
+ #2 Unassigned
+ #3 Gateway-to-Gateway
+ #4 CMCC Gateway Monitoring Message
+ #5 ST
+ #6 TCP
+ #7 UCL
+ #8 Unassigned
+ #9 Secure
+ #10 BBN RCC Monitoring
+ #11 NVP
+ #12 PUP
+ #13 Pluribus
+ #14 Telenet
+ #15 XNET
+ #16 Chaos
+ #17 User Datagram
+ #18 Multiplexing
+ #19 DCN
+ #20 TAC Monitoring
+ #21-62 Unassigned
+ #63 any local network
+ #64 SATNET and Backroom EXPAK
+ #65 MIT Subnet Support
+ #66-68 Unassigned
+ #69 SATNET Monitoring
+ #70 Unassigned
+ #71 Internet Packet Core Utility
+ #72-75 Unassigned
+ #76 Backroom SATNET Monitoring
+ #77 Unassigned
+ #78 WIDEBAND Monitoring
+ #79 WIDEBAND EXPAK
+ #80-254 Unassigned
+ #255 Reserved
+ protocolType = 6 #TCP by default
+ protocolTypeField = pack('B',protocolType)
+ def createProtocolType(self, myProtocolType=None):
+ if myProtocolType!=None:
+ self.protocolType=myProtocolType
+ self.protocolTypeField = pack('B',self.protocolType)
+ print "protocolType = "+hex(self.protocolType)
+
+ #createCDESC_FID creates
+ # the FID Field of the CSPEC
+ CDESC = 0
+ def createCDESC_FID(self, myIpVersion=None, mySourceIpAddress=None, mySourceIpPort=None, myDestinationIpAddress=None, myDestinationIpPort=None, myProtocolType=None):
+ print "CDESC :"
+ self.createIpVersion(myIpVersion)
+ self.createSourceIpAddress(mySourceIpAddress)
+ self.createSourceIpPort(mySourceIpPort)
+ self.createDestinationIpAddress(myDestinationIpAddress)
+ self.createDestinationIpPort(myDestinationIpPort)
+ self.createProtocolType(myProtocolType)
+ self.fidBody.CDESC = self.ipVersionField + self.sourceIpAddressField + self.sourceIpPortField + self.destinationIpAddressField + self.destinationIpPortField + self.protocolTypeField
+ return self.fidBody.CDESC
+
+ #Vendor Specific Fields :
+
+ # Organizationally Unique Identifier
+ oui = 0x535043 #OUI = "SPC" = SPiDCOM
+ ouiField = pack('I',oui)[0:3]
+ def createOui(self, myOui=None):
+ if myOui!=None:
+ self.oui=myOui
+ self.ouiField = pack('I',self.oui)[0:3]
+ print "oui = "+hex(self.oui)
+
+ # Vendor Defined Fields
+ vendorDefined = 0
+ if vendorDefined == 0:
+ vendorDefinedField = ""
+ else:
+ vendorDefinedField = pack('Q',vendorDefined)
+ def createVendorDefined(self, myVendorDefined=None):
+ if myVendorDefined!=None:
+ self.vendorDefined=myVendorDefined
+ if self.vendorDefined == 0:
+ self.vendorDefinedField = ""
+ else:
+ self.vendorDefinedField = pack('Q',self.vendorDefined)
+ print "vendorDefined = "+hex(self.vendorDefined)
+
+ #createVendor_Specific_FID creates
+ # the FID Field of the CSPEC
+ Vendor_Specific = 0
+ def createVendor_Specific_FID(self, myOui=None, myVendorDefined=None, param3=None, param4=None, param5=None, param6=None):
+ print "Vendor_Specific = "+hex(self.Vendor_Specific)
+ createOui(myOui)
+ createVendorDefined(myVendorDefined)
+ self.fidBody.Vendor_Specific = self.ouiField + self.vendorDefinedField
+ return self.fidBody.Vendor_Specific
+
+ #createVendor_Specific_FID creates
+ # the FID Field of the CSPEC
+ ATS_Tolerance = 0 #0 microseconds by default
+ def createATS_Tolerance_FID(self, myATS_Tolerance=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myATS_Tolerance!=None:
+ self.ATS_Tolerance=myATS_Tolerance
+ self.fidBody.ATS_Tolerance = pack('H',self.ATS_Tolerance)
+ print "ATS_Tolerance = "+hex(self.ATS_Tolerance)
+ return self.fidBody.ATS_Tolerance
+
+ #createSmallest_Tolerable_Average_Data_Rate_FID creates
+ # the FID Field of the CSPEC
+ Smallest_Tolerable_Average_Data_Rate = 1 #10 Kbps by default (ie Min Rate)
+ def createSmallest_Tolerable_Average_Data_Rate_FID(self, mySmallest_Tolerable_Average_Data_Rate=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if mySmallest_Tolerable_Average_Data_Rate!=None:
+ self.Smallest_Tolerable_Average_Data_Rate=mySmallest_Tolerable_Average_Data_Rate
+ self.fidBody.Smallest_Tolerable_Average_Data_Rate = pack('H',self.Smallest_Tolerable_Average_Data_Rate)
+ print "Smallest_Tolerable_Average_Data_Rate = "+hex(self.Smallest_Tolerable_Average_Data_Rate)
+ return self.fidBody.Smallest_Tolerable_Average_Data_Rate
+
+ #createOriginal_Average_Data_Rate_FID creates
+ # the FID Field of the CSPEC
+ Original_Average_Data_Rate = 10000 #100 Mbps by default (ie 1/2 Max Rate)
+ def createOriginal_Average_Data_Rate_FID(self, myOriginal_Average_Data_Rate=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myOriginal_Average_Data_Rate!=None:
+ self.Original_Average_Data_Rate=myOriginal_Average_Data_Rate
+ self.fidBody.Original_Average_Data_Rate = pack('H',self.Original_Average_Data_Rate)
+ print "Original_Average_Data_Rate = "+hex(self.Original_Average_Data_Rate)
+ return self.fidBody.Original_Average_Data_Rate
+
+ #createRx_Window_Size_FID creates
+ # the FID Field of the CSPEC
+ Rx_Window_Size = 1 #512 octets by default
+ def createRx_Window_Size_FID(self, myRx_Window_Size=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myRx_Window_Size!=None:
+ self.Rx_Window_Size=myRx_Window_Size
+ self.fidBody.Rx_Window_Size = pack('H',self.Rx_Window_Size)
+ print "Rx_Window_Size = "+hex(self.Rx_Window_Size)
+ return self.fidBody.Rx_Window_Size
+
+ #createSmoothing_Buffer_Size_FID creates
+ # the FID Field of the CSPEC
+ Smoothing_Buffer_Size = 0x100000 #1 Mo by default
+ def createSmoothing_Buffer_Size_FID(self, mySmoothing_Buffer_Size=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if mySmoothing_Buffer_Size!=None:
+ self.Smoothing_Buffer_Size=mySmoothing_Buffer_Size
+ self.fidBody.Smoothing_Buffer_Size = pack('I',self.Smoothing_Buffer_Size)[0:3]
+ print "Smoothing_Buffer_Size = "+hex(self.Smoothing_Buffer_Size)
+ return self.fidBody.Smoothing_Buffer_Size
+
+ #createBidirectional_Burst_CM_CM_FID creates
+ # the FID Field of the CSPEC
+ # 0 : both links are local links
+ # 1 : Bidirectional Bursts in CFP will always end with a SACK
+ # 2 : Bidirectional Burst in CFP may end with a Reverse SOF
+ Bidirectional_Burst_CM_CM = 0 #Local links by default
+ def createBidirectional_Burst_CM_CM_FID(self, myBidirectional_Burst_CM_CM=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myBidirectional_Burst_CM_CM!=None:
+ self.Bidirectional_Burst_CM_CM=myBidirectional_Burst_CM_CM
+ self.fidBody.Bidirectional_Burst_CM_CM = pack('B',self.Bidirectional_Burst_CM_CM)
+ print "Bidirectional_Burst_CM_CM = "+hex(self.Bidirectional_Burst_CM_CM)
+ return self.fidBody.Bidirectional_Burst_CM_CM
+
+ #createTXOPs_per_Beacon_Period_FID creates
+ # the FID Field of the CSPEC
+ TXOPs_per_Beacon_Period = 0 #1 TXOP per Beacon Period by default
+ def createTXOPs_per_Beacon_Period_FID(self, myTXOPs_per_Beacon_Period=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myTXOPs_per_Beacon_Period!=None:
+ self.TXOPs_per_Beacon_Period=myTXOPs_per_Beacon_Period
+ self.fidBody.TXOPs_per_Beacon_Period = pack('B',self.TXOPs_per_Beacon_Period)
+ print "TXOPs_per_Beacon_Period = "+hex(self.TXOPs_per_Beacon_Period)
+ return self.fidBody.TXOPs_per_Beacon_Period
+
+ #createAverage_Number_of_PBs_per_TXOP_FID creates
+ # the FID Field of the CSPEC
+ Average_Number_of_PBs_per_TXOP = 2 #2 PB per TXOP by default
+ def createAverage_Number_of_PBs_per_TXOP_FID(self, myAverage_Number_of_PBs_per_TXOP=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myAverage_Number_of_PBs_per_TXOP!=None:
+ self.Average_Number_of_PBs_per_TXOP=myAverage_Number_of_PBs_per_TXOP
+ self.fidBody.Average_Number_of_PBs_per_TXOP = pack('H',self.Average_Number_of_PBs_per_TXOP)
+ print "Average_Number_of_PBs_per_TXOP = "+hex(self.Average_Number_of_PBs_per_TXOP)
+ return self.fidBody.Average_Number_of_PBs_per_TXOP
+
+ #createMinimum_Number_of_PBs_per_TXOP_FID creates
+ # the FID Field of the CSPEC
+ Minimum_Number_of_PBs_per_TXOP = 1 #1 PB per TXOP by default
+ def createMinimum_Number_of_PBs_per_TXOP_FID(self, myMinimum_Number_of_PBs_per_TXOP=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myMinimum_Number_of_PBs_per_TXOP!=None:
+ self.Minimum_Number_of_PBs_per_TXOP=myMinimum_Number_of_PBs_per_TXOP
+ self.fidBody.Minimum_Number_of_PBs_per_TXOP = pack('H',self.Minimum_Number_of_PBs_per_TXOP)
+ print "Minimum_Number_of_PBs_per_TXOP = "+hex(self.Minimum_Number_of_PBs_per_TXOP)
+ return self.fidBody.Minimum_Number_of_PBs_per_TXOP
+
+ #createMaximum_Number_of_PBs_per_TXOP_FID creates
+ # the FID Field of the CSPEC
+ Maximum_Number_of_PBs_per_TXOP = 3 #3 PB per TXOP by default
+ def createMaximum_Number_of_PBs_per_TXOP_FID(self, myMaximum_Number_of_PBs_per_TXOP=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myMaximum_Number_of_PBs_per_TXOP!=None:
+ self.Maximum_Number_of_PBs_per_TXOP=myMaximum_Number_of_PBs_per_TXOP
+ self.fidBody.Maximum_Number_of_PBs_per_TXOP = pack('H',self.Maximum_Number_of_PBs_per_TXOP)
+ print "Maximum_Number_of_PBs_per_TXOP = "+hex(self.Maximum_Number_of_PBs_per_TXOP)
+ return self.fidBody.Maximum_Number_of_PBs_per_TXOP
+
+ #createPPB_Threshold_FID creates
+ # the FID Field of the CSPEC
+ PPB_Threshold = 3 #3 PB by default
+ def createPPB_Threshold_FID(self, myPPB_Threshold=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myPPB_Threshold!=None:
+ self.PPB_Threshold=myPPB_Threshold
+ self.fidBody.PPB_Threshold = pack('H',self.PPB_Threshold)
+ print "PPB_Threshold = "+hex(self.PPB_Threshold)
+ return self.fidBody.createPPB_Threshold_FID
+
+ #createSurplus_Bandwidth_FID creates
+ # the FID Field of the CSPEC
+ Surplus_Bandwidth = 0 #0 No surplus Bandwith required by default
+ def createSurplus_Bandwidth_FID(self, mySurplus_Bandwidth=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if mySurplus_Bandwidth!=None:
+ self.Surplus_Bandwidth=mySurplus_Bandwidth
+ self.fidBody.Surplus_Bandwidth = pack('H',self.Surplus_Bandwidth)
+ print "Surplus_Bandwidth = "+hex(self.Surplus_Bandwidth)
+ return self.fidBody.createSurplus_Bandwidth_FID
+
+ #createSmallest_Tolerable_Average_Number_of_PBs_per_TXOP_FID creates
+ # the FID Field of the CSPEC
+ Smallest_Tolerable_Average_Number_of_PBs_per_TXOP = 1 #1 PB per TXOP by default
+ def createSmallest_Tolerable_Average_Number_of_PBs_per_TXOP_FID(self, mySmallest_Tolerable_Average_Number_of_PBs_per_TXOP=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if mySmallest_Tolerable_Average_Number_of_PBs_per_TXOP!=None:
+ self.Smallest_Tolerable_Average_Number_of_PBs_per_TXOP=mySmallest_Tolerable_Average_Number_of_PBs_per_TXOP
+ self.fidBody.Smallest_Tolerable_Average_Number_of_PBs_per_TXOP = pack('H',self.Smallest_Tolerable_Average_Number_of_PBs_per_TXOP)
+ print "Smallest_Tolerable_Average_Number_of_PBs_per_TXOP = "+hex(self.Smallest_Tolerable_Average_Number_of_PBs_per_TXOP)
+ return self.fidBody.Smallest_Tolerable_Average_Number_of_PBs_per_TXOP
+
+ #createOriginal_Average_Number_of_PBs_per_TXOP_FID creates
+ # the FID Field of the CSPEC
+ Original_Average_Number_of_PBs_per_TXOP = 2 #2 PB per TXOP by default
+ def createOriginal_Average_Number_of_PBs_per_TXOP_FID(self, myOriginal_Average_Number_of_PBs_per_TXOP=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myOriginal_Average_Number_of_PBs_per_TXOP!=None:
+ self.Original_Average_Number_of_PBs_per_TXOP=myOriginal_Average_Number_of_PBs_per_TXOP
+ self.fidBody.Original_Average_Number_of_PBs_per_TXOP = pack('H',self.Original_Average_Number_of_PBs_per_TXOP)
+ print "Original_Average_Number_of_PBs_per_TXOP = "+hex(self.Original_Average_Number_of_PBs_per_TXOP)
+ return self.fidBody.Original_Average_Number_of_PBs_per_TXOP
+
+ #createBidirectional_Burst_CM_CM_FID creates
+ # the FID Field of the CSPEC
+ # 0 : Bidirectional Bursts will always end with a SACK
+ # 1 : Bidirectional Burst may end with a Reverse SOF
+ Bidirectional_Burst_CM_CCO = 0 #SACK by default
+ def createBidirectional_Burst_CM_CCO_FID(self, myBidirectional_Burst_CM_CCO=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ if myBidirectional_Burst_CM_CCO!=None:
+ self.Bidirectional_Burst_CM_CCO=myBidirectional_Burst_CM_CCO
+ self.fidBody.Bidirectional_Burst_CM_CCO = pack('B',self.Bidirectional_Burst_CM_CCO)
+ print "Bidirectional_Burst_CM_CCO = "+hex(self.Bidirectional_Burst_CM_CCO)
+ return self.fidBody.Bidirectional_Burst_CM_CCO
+
+ #
+ def __init__(self):
+ #CSPEC_Field
+ self.dico = {Delay_Bound:self.createDelay_Bound_FID,
+ Jitter_Bound:self.createJitter_Bound_FID,
+ Average_MSDU_Size:self.createAverage_MSDU_Size_FID,
+ Maximum_MSDU_Size:self.createMaximum_MSDU_Size_FID,
+ Average_Data_Rate:self.createAverage_Data_Rate_FID,
+ Minimum_Data_Rate:self.createMinimum_Data_Rate_FID,
+ Maximum_Data_Rate:self.createMaximum_Data_Rate_FID,
+ Maximum_Inter_TXOP_time:self.createMaximum_Inter_TXOP_time_FID,
+ Minimum_Inter_TXOP_time:self.createMinimum_Inter_TXOP_time_FID,
+ Maximum_Burst_Size:self.createMaximum_Burst_Size_FID,
+ Exception_Policy:self.createException_Policy_FID,
+ Inactivity_Interval:self.createInactivity_Interval_FID,
+ MSDU_Error_Rate:self.createMSDU_Error_Rate_FID,
+ CLST:self.createCLST_FID,
+ CDESC:self.createCDESC_FID,
+ Vendor_Specific:self.createVendor_Specific_FID,
+ ATS_Tolerance:self.createATS_Tolerance_FID,
+ Smallest_Tolerable_Average_Data_Rate:self.createSmallest_Tolerable_Average_Data_Rate_FID,
+ Original_Average_Data_Rate:self.createOriginal_Average_Data_Rate_FID,
+ #QoS_and_MAC_Parameter_Field_(CM_CM):self.createQoS_and_MAC_Parameter_Field_(CM_CM)
+ Rx_Window_Size:self.createRx_Window_Size_FID,
+ Smoothing_Buffer_Size:self.createSmoothing_Buffer_Size_FID,
+ Bidirectional_Burst_CM_CM:self.createBidirectional_Burst_CM_CM_FID,
+ #QoS_and_MAC_Parameter_Field_(CM_CCo):self.createQoS_and_MAC_Parameter_Field_(CM_CCo)
+ TXOPs_per_Beacon_Period:self.createTXOPs_per_Beacon_Period_FID,
+ Average_Number_of_PBs_per_TXOP:self.createAverage_Number_of_PBs_per_TXOP_FID,
+ Minimum_Number_of_PBs_per_TXOP:self.createMinimum_Number_of_PBs_per_TXOP_FID,
+ Maximum_Number_of_PBs_per_TXOP:self.createMaximum_Number_of_PBs_per_TXOP_FID,
+ PPB_Threshold:self.createPPB_Threshold_FID,
+ Surplus_Bandwidth:self.createSurplus_Bandwidth_FID,
+ #Exception_Policy:self.createException_Policy
+ #CDESC:self.createCDESC
+ #Vendor_Specific:self.createVendor_Specific
+ Smallest_Tolerable_Average_Number_of_PBs_per_TXOP:self.createSmallest_Tolerable_Average_Number_of_PBs_per_TXOP_FID,
+ Original_Average_Number_of_PBs_per_TXOP:self.createOriginal_Average_Number_of_PBs_per_TXOP_FID,
+ Bidirectional_Burst_CM_CCO:self.createBidirectional_Burst_CM_CCO_FID
+ }
diff --git a/cesar/maximus/python/lib/mmentry/mmentry.py b/cesar/maximus/python/lib/mmentry/mmentry.py
new file mode 100644
index 0000000000..28321ea0dc
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/mmentry.py
@@ -0,0 +1,121 @@
+# -*- coding:Utf-8 -*-
+
+class Mmentry():
+ #MMENTRY format by MME
+ #--- Station - Central Coordination ---
+ CC_CCO_APPOINT_REQ = "1234567"
+ CC_CCO_APPOINT_CNF = "1"
+ CC_BACKUP_APPOINT_REQ = "1"
+ CC_BACKUP_APPOINT_CNF = "1"
+ CC_LINK_INFO_REQ = ""
+ CC_LINK_INFO_CNF = "1"+"Var"+"*N"+"=b"
+ CC_LINK_INFO_IND = "1"+"Var"+"*N"+"=b"
+ CC_LINK_INFO_RSP = ""
+ CC_HANDOVER_REQ = "12"
+ CC_HANDOVER_CNF = "1"
+ CC_HANDOVER_INFO_IND = "123"+"N*"+"123456789"+"=b"
+ CC_HANDOVER_INFO_RSP = ""
+ CC_DISCOVER_LIST_REQ = ""
+ CC_DISCOVER_LIST_CNF = "1"+"M*"+"123456789ABC"+"N*"+"123456789ABCD"+"=b"
+ CC_DISCOVER_LIST_IND = "1"+"M*"+"123456789ABC"+"N*"+"123456789ABCD"+"=b"
+ CC_LINK_NEW_REQ = "123456789ABCDE"+"Var"+"1"+"123"+"*N"+"1"+"123"+"*K"+"=a"
+ CC_LINK_NEW_CNF = "12345"+"Var"+"=a"
+ CC_LINK_MOD_REQ = "12"+"Var"+"Var"+"Var"+"=a"
+ CC_LINK_MOD_CNF = "123"+"Var"+"=a"
+ CC_LINK_SQZ_REQ = "12"+"Var"+"=a"
+ CC_LINK_SQZ_CNF = "123"+"Var"+"=a"
+ CC_LINK_REL_REQ = "1234"+"Var"+"=a"
+ CC_LINK_REL_IND = "123456789"+"Var"+"Var"+"=a"
+ CC_DETECT_REPORT_REQ = "12"+"N"+"=a"
+ CC_DETECT_REPORT_CNF = "1"+"123456"+"*N"+"=a"
+ CC_WHO_RU_REQ = "1234567"
+ CC_WHO_RU_CNF = "1234567"+"123456"+"12345678*8"
+ CC_ASSOC_REQ = "123456789A"
+ CC_ASSOC_CNF = "123456789ABC"
+ CC_LEAVE_REQ = "1"
+ CC_LEAVE_CNF = ""
+ CC_LEAVE_IND = "12345678"
+ CC_LEAVE_RSP = ""
+ CC_SET_TEI_MAP_REQ = ""
+ CC_SET_TEI_MAP_IND = "12"+"12345678"+"*n"+"=b"
+ CC_RELAY_REQ = "123456789"+"Var"+"=a"
+ CC_RELAY_IND = "123456789"+"Var"+"=a"
+ CC_BEACON_RELIABILITY_REQ = ""
+ CC_BEACON_RELIABILITY_CNF = "1234"
+ CC_ALLOC_MOVE_REQ = "1234"+"Var"+"Var"+"=a"
+ CC_ALLOC_MOVE_CNF = "123"
+ CC_ACCESS_NEW_REQ = "12345678"+"Var"+"Var"+"=a"
+ CC_ACCESS_NEW_CNF = "123456"
+ CC_ACCESS_NEW_IND = "123456789ABC"
+ CC_ACCESS_NEW_RSP = "1234"+"Var"+"Var"+"=a"
+ CC_ACCESS_REL_REQ = "123"
+ CC_ACCESS_REL_CNF = "123"
+ CC_ACCESS_REL_IND = "123"
+ CC_ACCESS_REL_RSP = "123"
+ CC_DCPPC_IND = "1"
+ CC_DCPPC_RSP = ""
+ CC_HP1_DET_REQ = ""
+ CC_HP1_DET_CNF = "123456"
+ CC_BLE_UPDATE_IND = "1"+"Var"+"=a"
+ #to 0x1FFC : Reserved for future use
+ #--- Proxy Coordinator ---
+ CP_PROXY_APPOINT_REQ = "1234"+"12345678"+"*N"+"=b"
+ CP_PROXY_APPOINT_CNF = "12"
+ PH_PROXY_APPOINT_IND = "123456789ABCDEF"
+ CP_PROXY_WAKE_REQ = ""
+ #to 0x3FFC : Reserved for future use
+ #--- CCo - CCo ---
+ NN_INL_REQ = "123456789ABCDE"+"123456789ABCD"+"*N"+"=a"
+ NN_INL_CNF = "123456789ABCDE"+"123456789ABCD"+"*N"+"=a"
+ NN_NEW_NET_REQ = "123456789ABCDE"
+ NN_NEW_NET_CNF = "1234"+"Var"+"=a"
+ NN_NEW_NET_IND = "1234"
+ NN_ADD_ALLOC_REQ = "1234567"+"1234"+"*n"+"=a"
+ NN_ADD_ALLOC_CNF = "1234"
+ NN_ADD_ALLOC_IND = "1234"
+ NN_REL_ALLOC_REQ = "1234567"+"1234"+"*n"+"=a"
+ NN_REL_ALLOC_CNF = "1234"
+ NN_REL_NET_IND = "1234567"+"1234"+"*n"+"=a"
+ #to 0x5FFC : Reserved for future use
+ #--- Station - Station ---
+ CM_UNASSOCIATED_STA_IND = "12345678"
+ CM_ENCRYPTED_PAYLOAD_IND = "123456"+"12345678"+"12345678"+"12"+"0-15"+"Var"+"0or4"+"0or1"+"0or2"+"0or1"+"0-15"+"0or1"+"=a"
+ CM_ENCRYPTED_PAYLOAD_RSP = "1234"
+ CM_SET_KEY_REQ = "123456789ABCDE"+"1234567"+"1"+"12345678"+"12345678"
+ CM_SET_KEY_CNF = "123456789ABCDE"
+ CM_GET_KEY_REQ = "123456789"+"12345678"+"Var"+"=a"
+ CM_GET_KEY_CNF = "123456789A"+"123456789ABC"+"Var"+"=a"
+ CM_SC_JOIN_REQ = "1"
+ CM_SC_JOIN_CNF = "12345678"
+ CM_CHAN_EST_IND = "123456789AB"+"L"+"1"+"123"+"*M"+"1234567"+"N*0_5"+"(N%2)*0_5"
+ CM_TM_UPDATE_IND = "12"+"L"+"1"+"123"+"*M"+"1234567"+"12"+"*N"+"=a"
+ CM_AMP_MAP_REQ = "12"+"N*0_5"+"=a" #+"(N%2)*0_5"???
+ CM_AMP_MAP_CNF = "1"
+ CM_BRG_INFO_REQ = ""
+ CM_BRG_INFO_CNF = "1"+"Var"+"=a"
+ CM_CONN_NEW_REQ = "12"+"Var"+"Var"+"=a"
+ CM_CONN_NEW_CNF = "1234"+"Var"+"=a"
+ CM_CONN_REL_IND = "123"+"Var"+"=a"
+ CM_CONN_REL_RSP = "12"
+ CM_CONN_MOD_REQ = "12"+"Var"+"=a"
+ CM_CONN_MOD_CNF = "123"+"Var"+"=a"
+ CM_CONN_INFO_REQ = "1234"
+ CM_CONN_INFO_CNF = "1"+"Var"+"*N"+"=b"
+ CM_STA_CAP_REQ = ""
+ CM_STA_CAP_CNF = "123456789ABCDEF"+"123456789A"
+ CM_NW_INFO_REQ = ""
+ CM_NW_INFO_CNF = "1"+"Var"+"*N"+"=a"
+ CM_GET_BEACON_REQ = "1234567"
+ CM_GET_BEACON_CNF = "123456789ABC"+"Var"+"=a"
+ CM_HFID_REQ = "1"+"0or6"+"0or64"+"=a"
+ CM_HFID_CNF = "1"+"12345678"+"12345678"+"12345678"+"12345678"+"12345678"+"12345678"+"12345678"+"12345678"
+ CM_MME_ERROR_IND = "123456"
+ CM_NW_STATS_REQ = ""
+ CM_NW_STATS_CNF = "1"+"12345678"+"*L"+"=b"
+ CM_LINK_STATS_REQ = "12345678"+"12345678"+"12"
+ CM_LINK_STATS_CNF = "12"+"Var"+"=a"
+ #to 0x7FFC : Reserved for future use
+ #--- Manufacturer Specific ---
+ #to 0x9FFC : Manufacturer Specific Messages
+ #--- Vendor Specific ---
+ #to 0xBFFC : Vendor-Specific Messages
diff --git a/cesar/maximus/python/lib/mmentry/mmentryFields.py b/cesar/maximus/python/lib/mmentry/mmentryFields.py
new file mode 100644
index 0000000000..8a81d1473d
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/mmentryFields.py
@@ -0,0 +1,3258 @@
+# -*- coding:Utf-8 -*-
+
+
+
+#MMENTRY Fields
+
+from struct import *
+from fid import *
+from math import *
+from random import randrange #random library is used : randrange(),
+from Constants import * #Constants library is used : classifierRuleSize[], MAX_TONE_MAPS,
+from binascii import * #binascii library is used : crc32(),
+from bmi import *
+from aes128 import *
+
+from encapsulation import *
+myEncapsulatedMme=EncapsulatedMme()
+
+#CINFO identifies the attributes of the Connection and the MAC and PAL
+# operations required by the Connection at the source and destinations
+# STAs. The format of the CINFO fields is shown in Table 7-145.
+# A separate CINFO field is required for the forward and reverse
+# directions of the Connection.
+# The CINFO, QoS, and MAC parameter fields specifically apply to the
+# forward or Reverse Links, as indicated in the CSPEC.
+class Cinfo():
+ #CINFO :
+
+ # CINFO Validity
+ valid = 1 #1:CINFO is Valid, 0:CINFO is not Valid
+ validField = pack('B',valid)
+ def createValid(self, myValid=None):
+ if myValid!=None:
+ self.valid=myValid
+ self.validField = pack('B',self.valid)
+ print "valid = "+hex(self.valid)
+
+ # Connections and Network Modes
+ # 0=contention-free service
+ # 1=contention-based service
+ # 2=contention-free sevice prefered
+ macServiceType = 2
+ if valid == 1:
+ macServiceTypeField = pack('B',macServiceType)
+ else:
+ macServiceTypeField = ""
+ def createMacServiceType(self, myMacServiceType=None):
+ if myMacServiceType!=None:
+ self.macServiceType=myMacServiceType
+ if self.valid == 1:
+ self.macServiceTypeField = pack('B',self.macServiceType)
+ else:
+ self.macServiceTypeField = ""
+ print "macServiceType = "+hex(self.macServiceType)
+
+ # Channel Access Priority
+ userPriority = 0
+ if valid == 1:
+ userPriorityField = pack('B',userPriority)
+ else:
+ userPriorityField = ""
+ def createUserPriority(self, myUserPriority=None):
+ if myUserPriority!=None:
+ self.userPriority=myUserPriority
+ if self.valid == 1:
+ self.userPriorityField = pack('B',self.userPriority)
+ else:
+ self.userPriorityField = ""
+ print "userPriority = "+hex(self.userPriority)
+
+ # Arrival Time Stamp to HLE
+ # 0=ATS should not be passed to HLE
+ # 1=ATS should be passed to HLE
+ ats = 1
+ if valid == 1:
+ atsField = pack('B',ats)
+ else:
+ atsField = ""
+ def createAts(self, myAts=None):
+ if myAts!=None:
+ self.ats=myAts
+ if self.valid == 1:
+ self.atsField = pack('B',self.ats)
+ else:
+ self.atsField = ""
+ print "ats = "+hex(self.ats)
+
+ # Smoothing Requested
+ # 0=Smotthing is not requested
+ # 1=if supported receiver should activate smoothing
+ smoothing = 1
+ if valid == 1:
+ smoothingField = pack('B',smoothing)
+ else:
+ smoothingField = ""
+ def createSmoothing(self, mySmoothing=None):
+ if mySmoothing!=None:
+ self.smoothing=mySmoothing
+ if self.valid == 1:
+ self.smoothingField = pack('B',self.smoothing)
+ else:
+ self.smoothingField = ""
+ print "smoothing = "+hex(self.smoothing)
+
+ #CINFO Field :
+ cinfo = validField + macServiceTypeField + userPriorityField + atsField + smoothingField
+ def createCinfo(self, myValid=None, myMacServiceType=None, myUserPriority=None, myAts=None, mySmoothing=None):
+ self.createValid(myValid)
+ self.createMacServiceType(myMacServiceType)
+ self.createUserPriority(myUserPriority)
+ self.createAts(myAts)
+ self.createSmoothing(mySmoothing)
+ self.cinfo = self.validField + self.macServiceTypeField + self.userPriorityField + self.atsField + self.smoothingField
+
+#The QoS and MAC parameters identify the QoS requirements (delay, jitter, data
+# rates), as well as MAC parameters that are specific to the particular
+# Connection. The QoS parameters are generated by the Connection Manager using
+# the Auto-Connect function or through PAL-specific primitives exchanged
+# between the higher layer applications and the CM.Each QoS and MAC parameter
+# field consists of a Forward/Reverse (F/R) field, a Length (LEN) field, and a
+# 1-octet Field Identifier (FID) field, followed by the Body of the QoS and MAC
+# Parameter field. Table 7-146 shows the format of a QoS and MAC parameter
+# field. The QMPs exchanged between the HLE and Connection Manager are shown in
+# Table 7-147. The QoS and MAC parameters exchanged between two CMs include the
+# parameters shown in Table 7-147 and Table 7-148. The QoS and MAC parameters
+# exchanged between the CM and CCo are shown in Table 7-149.
+class Qmp():
+ #QMP :
+
+ # Forward/Reverse Field
+ # 0=Forward from source to receiver
+ # 1=Reverse from receiver to source
+ fR = 0
+ fRField = pack('B',fR)
+ def createFR(self, myFR=None):
+ if myFR!=None:
+ self.fR=myFR
+ self.fRField = pack('B',self.fR)
+ print "fR = "+hex(self.fR)
+
+ #Length of the Body Field
+ length = 1
+ lengthField = pack('B',length)
+ def createLength(self):
+ self.length = len(self.dataField)
+ self.lengthField = pack('B',self.length)
+ print "length = "+hex(self.length)
+
+ #Identifier of the QoS and MAC Parameter Field
+ fid = Delay_Bound #Delay_Bound by default
+ fidField = pack('B',fid)
+ def createFid(self, myFid=None):
+ if myFid!=None:
+ self.fid=myFid
+ self.fidField = pack('B',self.fid)
+ print "fid = "+hex(self.fid)
+
+ #Data of the QoS and MAC Parameter Field
+ data = FidMethod()
+ dataField = data.dico[fid]()
+ def createBody(self, param1=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ print "fidBody :"
+ #print self.data.dico[self.fid]
+ self.dataField = self.data.dico[self.fid](param1, param2, param3, param4, param5, param6)
+ self.createLength()
+
+ #QMP Field :
+ qmp = fRField + lengthField + fidField + dataField
+ def createQmp(self, myFR=None, myFid=None, param1=None, param2=None, param3=None, param4=None, param5=None, param6=None):
+ self.createFR(myFR)
+ self.createFid(myFid)
+ self.createBody(param1, param2, param3, param4, param5, param6)
+ #self.createLength()
+ self.qmp = self.fRField + self.lengthField + self.fidField + self.dataField
+
+#ConnectionSpecification
+class Cspec():
+ #Length of CSPEC including the 2 CSPEC_LEN field octets
+ cspecLen = 2
+ cspecLenField = pack('H',cspecLen)
+ def createCspecLen(self):
+ if self.cspecLen != 0:
+ self.cspecLen = 2 + len(self.cinfoForward.cinfo) + len(self.cinfoReverse.cinfo) + len(self.qmpForward.qmp) + len(self.qmpReverse.qmp)
+ self.cspecLenField = pack('H',self.cspecLen)
+ print "cspecLen = "+hex(self.cspecLen)
+
+ #CINFO Forward Field
+ print "cinfoForward :"
+ cinfoForward = Cinfo()
+
+ #CINFO Reverse Field
+ print "cinfoReverse :"
+ cinfoReverse = Cinfo()
+
+ #QMP Forward Field
+ print "qmpForward :"
+ qmpForward = Qmp()
+
+ #QMP Reverse Field
+ print "qmpReverse :"
+ qmpReverse = Qmp()
+
+ #CSPEC Field :
+ cspec = cspecLenField + cinfoForward.cinfo + cinfoReverse.cinfo + qmpForward.qmp + qmpReverse.qmp
+ def createCspec(self, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ if myCsepcLen!=None:
+ self.cspecLen=myCsepcLen
+ if self.cspecLen != 0:
+ print "cinfoForward :"
+ self.cinfoForward.createCinfo(myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF)
+ print "cinfoReverse :"
+ self.cinfoReverse.createCinfo(myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR)
+ print "qmpForward :"
+ self.qmpForward.createQmp(myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F)
+ print "qmpReverse :"
+ self.qmpReverse.createQmp(myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.createCspecLen()
+ self.cspec = self.cspecLenField + self.cinfoForward.cinfo + self.cinfoReverse.cinfo + self.qmpForward.qmp + self.qmpReverse.qmp
+ else:
+ self.createCspecLen()
+ self.cspec = self.cspecLenField
+
+#Bit Loading Estimate
+class Ble():
+
+ #Number of intervals
+ num = 255 #By default MAX Bit Loading Estimates are available
+ numField = pack('B',num)
+ def createNum(self, myNum=None):
+ if myNum!=None:
+ self.num=myNum
+ self.numField = pack('B',self.num)
+ print "num = "+hex(self.num)
+
+ #Interval End Time #1-N and Bit Loading Estimate #1-N
+ endTime = []
+ endTimeField = []
+ intBle = [] #BLE integer format
+ exponent = []
+ mantissa = []
+ interval = [] #BLE is splited into 5 mantissa MSbits and 3 exponent LSbits
+ intervalField = []
+ i = 0
+ while i < num:
+ endTime.append(0)
+ endTimeField.append(pack('H',endTime[i]))
+ intBle.append(0)
+ exponent.append(max(0,int(log(max(2,intBle[0]),2))-1))
+ mantissa.append(max(0,int(32*(intBle[0]/pow(2,exponent[0]+1)-1))))
+ interval.append(int(mantissa[i]*pow(2,3)+exponent[i])) #is the Bit Loading Estimate #1-N
+ intervalField.append(pack('B',interval[i]))
+ i=i+1
+ num=0
+ def createIntervalEndTimeAndBitLoadingEstimate(self, myEndTime=None, myIntBle=None, myInterval=None):
+ self.i = 0
+ while self.i < self.num:
+ if myEndTime!=None:
+ self.endTime[self.i]=myEndTime
+ print "endTime["+str(self.i)+"] = "+hex(self.endTime[self.i])
+ self.endTimeField[self.i] = pack('H',self.endTime[self.i])
+ if myIntBle!=None:
+ self.intBle[self.i]=myIntBle
+ self.exponent[self.i] = max(0,int(log(max(2,self.intBle[self.i]),2))-1)
+ self.mantissa[self.i] = max(0,int(32*(self.intBle[self.i]/pow(2,self.exponent[self.i]+1)-1)))
+ self.interval[self.i] = int(self.mantissa[self.i]*pow(2,3)+self.exponent[self.i])
+ if myInterval!=None:
+ self.interval[self.i]=myInterval
+ print "interval["+str(self.i)+"] = "+hex(self.interval[self.i])
+ self.intervalField[self.i] = pack('B',self.interval[self.i])
+ self.i = self.i + 1
+
+ #BLE Field :
+ ble = numField
+ i = 0
+ while i < num:
+ ble = ble + endTimeField[i] + intervalField[i]
+ i = i + 1
+ def createBle(self, myNum=None, myEndTime=None, myIntBle=None, myInterval=None):
+ self.createNum(myNum)
+ self.createIntervalEndTimeAndBitLoadingEstimate(myEndTime, myIntBle, myInterval)
+ self.ble = self.numField
+ self.i = 0
+ while self.i < self.num:
+ self.ble = self.ble + self.endTimeField[self.i] + self.intervalField[self.i]
+ self.i = self.i + 1
+
+#Connection Identifier
+class Cid():
+ tei = 0
+ teiField = pack('B',tei)
+ def createTei(self, myTei=None):
+ if myTei!=None:
+ self.tei=myTei
+ self.teiField = pack('B',self.tei)
+ print "tei = "+hex(self.tei)
+ llidF = 0
+ llidFField = pack('B',llidF)
+ def createLlidF(self, myLlidF=None):
+ if myLlidF!=None:
+ self.llidF=myLlidF
+ self.llidFField = pack('B',self.llidF)
+ print "llidF = "+hex(self.llidF)
+ cid = teiField + llidFField
+ def createCid(self, myTei=None, myLlidF=None):
+ self.createTei(myTei)
+ self.createLlidF(myLlidF)
+ self.cid = self.teiField + self.llidFField
+
+#Global Link Informations
+class GlobalLinkInfo():
+ print "cid :"
+ cid = Cid()
+ stei = 0
+ steiField = pack('B',stei)
+ def createStei(self, myStei=None):
+ if myStei!=None:
+ self.stei=myStei
+ self.steiField = pack('B',self.stei)
+ print "stei = "+hex(self.stei)
+ dtei = 0
+ dteiField = pack('B',dtei)
+ def createDtei(self, myDtei=None):
+ if myDtei!=None:
+ self.dtei=myDtei
+ self.dteiField = pack('B',self.dtei)
+ print "dtei = "+hex(self.dtei)
+ lidF = 0xFF
+ lidFField = pack('B',lidF)
+ def createLidF(self, myLidF=None):
+ if myLidF!=None:
+ self.lidF=myLidF
+ self.lidFField = pack('B',self.lidF)
+ print "lidF = "+hex(self.lidF)
+ lidR = 0xFF
+ lidRField = pack('B',lidR)
+ def createLidR(self, myLidR=None):
+ if myLidR!=None:
+ self.lidR=myLidR
+ self.lidRField = pack('B',self.lidR)
+ print "lidR = "+hex(self.lidR)
+ cspec = Cspec()
+ bleForward = Ble()
+ bleReverse = Ble()
+
+ globalLinkInfo = cid.cid + steiField + dteiField + lidFField + lidRField + cspec.cspec + bleForward.ble + bleReverse.ble
+ def createGlobalLinkInfo(self, myTei=None, myLlidF=None, myStei=None, myDtei=None, myLidF=None, myLidR=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None, myNumF=None, myEndTimeL=None, myIntBleL=None, myIntervalL=None, myNumR=None, myEndTimeR=None, myIntBleR=None, myIntervalR=None):
+ self.cid.createCid(myTei, myLlidF)
+ self.createStei(myStei)
+ self.createDtei(myDtei)
+ self.createLidF(myLidF)
+ self.createLidR(myLidR)
+ print "cspec :"
+ self.cspec.createCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ print "bleForward :"
+ self.bleForward.createBle(myNumF, myEndTimeL, myIntBleL, myIntervalL)
+ print "bleReverse :"
+ self.bleReverse.createBle(myNumR, myEndTimeR, myIntBleR, myIntervalR)
+ self.globalLinkInfo = self.cid.cid + self.steiField + self.dteiField + self.lidFField + self.lidRField + self.cspec.cspec + self.bleForward.ble + self.bleReverse.ble
+
+#Connection Informations
+class ConnInfo():
+ print "cid :"
+ cid = Cid()
+ stei = 0
+ steiField = pack('B',stei)
+ def createStei(self, myStei=None):
+ if myStei!=None:
+ self.stei=myStei
+ self.steiField = pack('B',self.stei)
+ print "stei = "+hex(self.stei)
+ dtei = 0
+ dteiField = pack('B',dtei)
+ def createDtei(self, myDtei=None):
+ if myDtei!=None:
+ self.dtei=myDtei
+ self.dteiField = pack('B',self.dtei)
+ print "dtei = "+hex(self.dtei)
+ lidF = 0xFF
+ lidFField = pack('B',lidF)
+ def createLidF(self, myLidF=None):
+ if myLidF!=None:
+ self.lidF=myLidF
+ self.lidFField = pack('B',self.lidF)
+ print "lidF = "+hex(self.lidF)
+ lidR = 0xFF
+ lidRField = pack('B',lidR)
+ def createLidR(self, myLidR=None):
+ if myLidR!=None:
+ self.lidR=myLidR
+ self.lidRField = pack('B',self.lidR)
+ print "lidR = "+hex(self.lidR)
+ cspec = Cspec()
+
+ ConnInfo = cid.cid + steiField + dteiField + lidFField + lidRField + cspec.cspec
+ def createConnInfo(self, myTei=None, myLlidF=None, myStei=None, myDtei=None, myLidF=None, myLidR=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ self.cid.createCid(myTei, myLlidF)
+ self.createStei(myStei)
+ self.createDtei(myDtei)
+ self.createLidF(myLidF)
+ self.createLidR(myLidR)
+ print "cspec :"
+ self.cspec.createCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.ConnInfo = self.cid.cid + self.steiField + self.dteiField + self.lidFField + self.lidRField + self.cspec.cspec
+
+#Station Informations
+class StaInfo():
+ tei = 0
+ teiField = pack('B',tei)
+ def createTei(self, myTei=None):
+ if myTei!=None:
+ self.tei=myTei
+ self.teiField = pack('B',self.tei)
+ print "tei = "+hex(self.tei)
+ macAddress = 0
+ macAddressField = pack('Q',macAddress)[0:6]
+ def createMacAddress(self, myMacAddress=None):
+ if myMacAddress!=None:
+ self.macAddress=myMacAddress
+ self.macAddressField = pack('Q',self.macAddress)[0:6]
+ print "macAddress = "+hex(self.macAddress)
+ status = 0
+ statusField = pack('B',status)
+ def createStatus(self, myStatus=None):
+ if myStatus!=None:
+ self.status=myStatus
+ self.statusField = pack('B',self.status)
+ print "status = "+hex(self.status)
+ ptei = 0
+ pteiField = pack('B',ptei)
+ def createPtei(self, myPtei=None):
+ if myPtei!=None:
+ self.ptei=myPtei
+ self.pteiField = pack('B',self.ptei)
+ print "ptei = "+hex(self.ptei)
+ staInfo = teiField + macAddressField + statusField + pteiField
+ def createStaInfo(self, myTei=None, myMacAddress=None, myStatus=None, myPtei=None):
+ self.createTei(myTei)
+ self.createMacAddress(myMacAddress)
+ self.createStatus(myStatus)
+ self.createPtei(myPtei)
+ self.staInfo = self.teiField + self.macAddressField + self.statusField + self.pteiField
+
+#STA Info
+class StationInfo():
+ macAddress = 0
+ macAddressField = pack('Q',macAddress)[0:6]
+ def createMacAddress(self, myMacAddress=None):
+ if myMacAddress!=None:
+ self.macAddress=myMacAddress
+ self.macAddressField = pack('Q',self.macAddress)[0:6]
+ print "macAddress = "+hex(self.macAddress)
+ tei = 0
+ teiField = pack('B',tei)
+ def createTei(self, myTei=None):
+ if myTei!=None:
+ self.tei=myTei
+ self.teiField = pack('B',self.tei)
+ print "tei = "+hex(self.tei)
+ sameNetwork = 1 #SameNetwork by default
+ sameNetworkField = pack('B',sameNetwork)
+ def createSameNetwork(self, mySameNetwork=None):
+ if mySameNetwork!=None:
+ self.sameNetwork=mySameNetwork
+ self.sameNetworkField = pack('B',self.sameNetwork)
+ print "sameNetwork = "+hex(self.sameNetwork)
+ snid = 0xA
+ access = 0 #in home by default
+ snidAccess = int(snid + access*pow(2,4))
+ snidAccessField = pack('B',snidAccess)
+ def createSnidAccess(self, mySnid=None, myAccess=None, mySnidAccess=None):
+ if mySnidAccess!=None:
+ try:
+ self.snidAccess=mySnidAccess
+ self.snidAccessField = pack('B',self.snidAccess)
+ except:
+ self.snidAccessField=mySnidAccess
+ self.snidAccess = unpack('B',self.snidAccessField[0])[0]
+ else:
+ if mySnid!=None:
+ self.snid=mySnid
+ if myAccess!=None:
+ self.access=myAccess
+ else:
+ self.snidAccess = int(self.snid + self.access*pow(2,4))
+ self.snidAccessField = pack('B',self.snidAccess)
+ print "snidAccess = "+hex(self.snidAccess)
+ reserved = 0
+ ccoCapability = 0 #does not support QoS and TDMA by default
+ proxyNetworkCapability = 0 #STA does not support Proxy Networking by default
+ backupCcoCapability = 0 #STA does not support the Backup CCo function by default
+ ccoStatus = 0 #STA is not the CCo by default
+ pcoStatus = 0 #STA is not a PCo by default
+ backupCcoStatus = 0 #STA is not a Backup CCo by default
+ ninthOctet = int(reserved + ccoCapability*pow(2,1) + proxyNetworkCapability*pow(2,3) + backupCcoCapability*pow(2,4) + ccoStatus*pow(2,5) + pcoStatus*pow(2,6) + backupCcoStatus*pow(2,7))
+ ninthOctetField = pack('B',ninthOctet)
+ def createNinthOctet(self, myCcoCapability=None, myProxyNetworkCapability=None, myBackupCcoCapability=None, myCcoStatus=None, myPcoStatus=None, myBackupCcoStatus=None, myNinthOctet=None):
+ if myCcoCapability!=None:
+ self.ccoCapability=myCcoCapability
+ if myProxyNetworkCapability!=None:
+ self.proxyNetworkCapability=myProxyNetworkCapability
+ if myBackupCcoCapability!=None:
+ self.backupCcoCapability=myBackupCcoCapability
+ if myCcoStatus!=None:
+ self.ccoStatus=myCcoStatus
+ if myPcoStatus!=None:
+ self.pcoStatus=myPcoStatus
+ if myBackupCcoStatus!=None:
+ self.backupCcoStatus=myBackupCcoStatus
+ if myNinthOctet!=None:
+ self.ninthOctet=myNinthOctet
+ else:
+ self.ninthOctet = int(self.reserved + self.ccoCapability*pow(2,1) + self.proxyNetworkCapability*pow(2,3) + self.backupCcoCapability*pow(2,4) + self.ccoStatus*pow(2,5) + self.pcoStatus*pow(2,6) + self.backupCcoStatus*pow(2,7))
+ self.ninthOctetField = pack('B',self.ninthOctet)
+ print "ninthOctet = "+hex(self.ninthOctet)
+ signalLevel = 0 #information not available by default
+ signalLevelField = pack('B',signalLevel)
+ def createSignalLevel(self, mySignalLevel=None):
+ if mySignalLevel!=None:
+ self.signalLevel=mySignalLevel
+ self.signalLevelField = pack('B',self.signalLevel)
+ print "signalLevel = "+hex(self.signalLevel)
+ averageBle = Ble()
+
+ stationInfo = macAddressField + teiField + sameNetworkField + snidAccessField + ninthOctetField + signalLevelField + averageBle.intervalField[0]
+ def createStationInfo(self, myMacAddress=None, myTei=None, mySameNetwork=None, mySnid=None, myAccess=None, mySnidAccess=None, myCcoCapability=None, myProxyNetworkCapability=None, myBackupCcoCapability=None, myCcoStatus=None, myPcoStatus=None, myBackupCcoStatus=None, myNinthOctet=None, mySignalLevel=None, myEndTime=None, myIntBle=None, myInterval=None):
+ self.createMacAddress(myMacAddress)
+ self.createTei(myTei)
+ self.createSameNetwork(mySameNetwork)
+ self.createSnidAccess(mySnid, myAccess, mySnidAccess)
+ self.createNinthOctet(myCcoCapability, myProxyNetworkCapability, myBackupCcoCapability, myCcoStatus, myPcoStatus, myBackupCcoStatus, myNinthOctet)
+ self.createSignalLevel(mySignalLevel)
+ print "averageBle :"
+ self.averageBle.createBle(1, myEndTime, myIntBle, myInterval)
+ self.stationInfo = self.macAddressField + self.teiField + self.sameNetworkField + self.snidAccessField + self.ninthOctetField + self.signalLevelField + self.averageBle.intervalField[0]
+
+#Network Info
+class NetworkInfo():
+ reserved = 0
+ securityLevel = 0 #Simple connect by default
+ nidOffset = 0x0f0e0d0c
+ nid = int(nidOffset + securityLevel*pow(2,52) + reserved*pow(2,54))
+ nidField = pack('Q',nid)[0:7]
+ def createNid(self, mySecurityLevel=None, myNidOffset=None, myNid=None):
+ if mySecurityLevel!=None:
+ self.securityLevel=mySecurityLevel
+ if myNidOffset!=None:
+ self.nidOffset=myNidOffset
+ if myNid!=None:
+ self.nid=myNid
+ else:
+ self.nid = int(self.nidOffset + self.securityLevel*pow(2,52) + self.reserved*pow(2,54))
+ self.nidField = pack('Q',self.nid)[0:7]
+ print "nid = "+hex(self.nid)
+ snid = 0xA
+ access = 0 #in home by default
+ snidAccess = int(snid + access*pow(2,4))
+ snidAccessField = pack('B',snidAccess)
+ def createSnidAccess(self, mySnid=None, myAccess=None, mySnidAccess=None):
+ if mySnid!=None:
+ self.snid=mySnid
+ if myAccess!=None:
+ self.access=myAccess
+ if mySnidAccess!=None:
+ self.snidAccess=mySnidAccess
+ else:
+ self.snidAccess = int(self.snid + self.access*pow(2,4))
+ self.snidAccessField = pack('B',self.snidAccess)
+ print "snidAccess = "+hex(self.snidAccess)
+ hm=0 #AV Only Mode by default
+ hmField = pack('B',hm)
+ def createHm(self, myHm=None):
+ if myHm!=None:
+ self.hm=myHm
+ self.hmField = pack('B',self.hm)
+ print "hm = "+hex(self.hm)
+ numSlot = 0 #1 beacon slot by default
+ numSlotField = pack('B',numSlot)
+ def createNumSlot(self, myNumSlot=None):
+ if myNumSlot!=None:
+ self.numSlot=myNumSlot
+ self.numSlotField = pack('B',self.numSlot)
+ print "numSlot = "+hex(self.numSlot)
+ coordonatingStatus = 0 #Unknow by default
+ coordonatingStatusField = pack('B',coordonatingStatus)
+ def createCoordonatingStatus(self, myCoordonatingStatus=None):
+ if myCoordonatingStatus!=None:
+ self.coordonatingStatus=myCoordonatingStatus
+ self.coordonatingStatusField = pack('B',self.coordonatingStatus)
+ print "coordonatingStatus = "+hex(self.coordonatingStatus)
+ offset = 0 #In the same group by default
+ offsetField = pack('H',offset)
+ def createOffset(self, myOffset=None):
+ if myOffset!=None:
+ self.offset=myOffset
+ self.offsetField = pack('H',self.offset)
+ print "offset = "+hex(self.offset)
+ networkInfo = nidField + snidAccessField + hmField + numSlotField + coordonatingStatusField + offsetField
+ def createNetworkInfo(self, mySecurityLevel=None, myNidOffset=None, myNid=None, mySnid=None, myAccess=None, mySnidAccess=None, myHm=None, myNumSlot=None, myCoordonatingStatus=None, myOffset=None):
+ self.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.createSnidAccess(mySnid, myAccess, mySnidAccess)
+ self.createHm(myHm)
+ self.createNumSlot(myNumSlot)
+ self.createCoordonatingStatus(myCoordonatingStatus)
+ self.createOffset(myOffset)
+ self.networkInfo = self.nidField + self.snidAccessField + self.hmField + self.numSlotField + self.coordonatingStatusField + self.offsetField
+
+#Network Information of the AVLN
+class NwInfo():
+ reserved = 0
+ securityLevel = 0 #Simple connect by default
+ nidOffset = 0x0f0e0d0c
+ nid = int(nidOffset + securityLevel*pow(2,52) + reserved*pow(2,54))
+ nidField = pack('Q',nid)[0:7]
+ def createNid(self, mySecurityLevel=None, myNidOffset=None, myNid=None):
+ if mySecurityLevel!=None:
+ self.securityLevel=mySecurityLevel
+ if myNidOffset!=None:
+ self.nidOffset=myNidOffset
+ if myNid!=None:
+ self.nid=myNid
+ else:
+ self.nid = int(self.nidOffset + self.securityLevel*pow(2,52) + self.reserved*pow(2,54))
+ self.nidField = pack('Q',self.nid)[0:7]
+ print "nid = "+hex(self.nid)
+ snid = 0xA
+ snidField = pack('B',snid)
+ def createSnid(self, mySnid=None):
+ if mySnid!=None:
+ self.snid=mySnid
+ self.snidField = pack('B',self.snid)
+ print "snid = "+hex(self.snid)
+ tei=0
+ teiField = pack('B',tei)
+ def createTei(self, myTei=None):
+ if myTei!=None:
+ self.tei=myTei
+ self.teiField = pack('B',self.tei)
+ print "tei = "+hex(self.tei)
+ stationRole = 0 #Station by default
+ stationRoleField = pack('B',stationRole)
+ def createStationRole(self, myStationRole=None):
+ if myStationRole!=None:
+ self.stationRole=myStationRole
+ self.stationRoleField = pack('B',self.stationRole)
+ print "stationRole = "+hex(self.stationRole)
+ cco_MacAddress = 0x63614D6F4343 #A default CCo MAC Address by default
+ cco_MacAddressField = pack('Q',cco_MacAddress)[0:6]
+ def createCco_MacAddress(self, myCco_MacAddress=None):
+ if myCco_MacAddress!=None:
+ self.cco_MacAddress=myCco_MacAddress
+ self.cco_MacAddressField = pack('Q',self.cco_MacAddress)[0:6]
+ print "cco_MacAddress = "+hex(self.cco_MacAddress)
+ access = 0 #in home by default
+ accessField = pack('B',access)
+ def createAccess(self, myAccess=None):
+ if myAccess!=None:
+ self.access=myAccess
+ self.accessField = pack('B',self.access)
+ print "access = "+hex(self.access)
+ numCordNws = 0 #in home by default
+ numCordNwsField = pack('B',numCordNws)
+ def createNumCordNws(self, myNumCordNws=None):
+ if myNumCordNws!=None:
+ self.numCordNws=myNumCordNws
+ self.numCordNwsField = pack('B',self.numCordNws)
+ print "numCordNws = "+hex(self.numCordNws)
+ nwInfo = nidField + snidField + teiField + stationRoleField + cco_MacAddressField + accessField + numCordNwsField
+ def createNwInfo(self, mySecurityLevel=None, myNidOffset=None, myNid=None, mySnid=None, myTei=None, myStationRole=None, myCco_MacAddress=None, myAccess=None, myNumCordNws=None):
+ self.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.createSnid(mySnid)
+ self.createTei(myTei)
+ self.createStationRole(myStationRole)
+ self.createCco_MacAddress(myCco_MacAddress)
+ self.createAccess(myAccess)
+ self.createNumCordNws(myNumCordNws)
+ self.nwInfo = self.nidField + self.snidField + self.teiField + self.stationRoleField + self.cco_MacAddressField + self.accessField + self.numCordNwsField
+
+#GLIDs
+class Glids():
+ glids = []
+ glidsField = []
+ numGlid = 255
+ i = 0
+ while i < numGlid:
+ glids.append(0xFF) #Local CSMA allocation by default
+ glidsField.append(pack('B',glids[i]))
+ i=i+1
+ def createGlids(self, myNumGlid=None, myGlids=None):
+ if myNumGlid!=None:
+ self.numGlid=myNumGlid
+ self.i = 0
+ while self.i < self.numGlid:
+ if myGlids!=None:
+ self.glids[self.i]=myGlids
+ self.glidsField[self.i]=pack('B',self.glids[self.i])
+ print "glids["+str(self.i)+"] = "+hex(self.glids[self.i])
+ self.i = self.i + 1
+
+#GLID Info
+class GlidsInfo():
+ glidsInfo = []
+ cfDetecteds = []
+ cfDetectedsField = []
+ csmaDetecteds = []
+ csmaDetectedsField = []
+ hp1Detecteds = []
+ hp1DetectedsField = []
+ othersDetecteds = []
+ othersDetectedsField = []
+ signalLevels = []
+ signalLevelsField = []
+ numGlid = 255
+ glids = Glids()
+ #glids.createGlids(numGlid)
+ def createGlids(self, myNumGlid=None, myGlids=None):
+ if myNumGlid!=None:
+ self.numGlid=myNumGlid
+ self.glids.createGlids(self.numGlid, myGlids)
+ i=0
+ while i<numGlid:
+ cfDetecteds.append(0) #Not detected by default
+ cfDetectedsField.append(pack('B',cfDetecteds[i]))
+ i=i+1
+ def createCfDetecteds(self, myCfDetecteds=None):
+ self.i=0
+ while self.i<self.numGlid:
+ if myCfDetecteds!=None:
+ self.cfDetecteds[self.i]=myCfDetecteds
+ self.cfDetectedsField[self.i] = pack('B',self.cfDetecteds[self.i])
+ print "cfDetecteds["+str(self.i)+"] = "+hex(self.cfDetecteds[self.i])
+ self.i=self.i+1
+ i=0
+ while i<numGlid:
+ csmaDetecteds.append(0) #Not detected by default
+ csmaDetectedsField.append(pack('B',csmaDetecteds[i]))
+ i=i+1
+ def createCsmaDetecteds(self, myCsmaDetecteds=None):
+ self.i=0
+ while self.i<self.numGlid:
+ if myCsmaDetecteds!=None:
+ self.csmaDetecteds[self.i]=myCsmaDetecteds
+ self.csmaDetectedsField[self.i] = pack('B',self.csmaDetecteds[self.i])
+ print "csmaDetecteds["+str(self.i)+"] = "+hex(self.csmaDetecteds[self.i])
+ self.i=self.i+1
+ i=0
+ while i<numGlid:
+ hp1Detecteds.append(0) #Not detected by default
+ hp1DetectedsField.append(pack('B',hp1Detecteds[i]))
+ i=i+1
+ def createHp1Detecteds(self, myHp1Detecteds=None):
+ self.i=0
+ while self.i<self.numGlid:
+ if myHp1Detecteds!=None:
+ self.hp1Detecteds[self.i]=myHp1Detecteds
+ self.hp1DetectedsField[self.i] = pack('B',self.hp1Detecteds[self.i])
+ print "hp1Detecteds["+str(self.i)+"] = "+hex(self.hp1Detecteds[self.i])
+ self.i=self.i+1
+ i=0
+ while i<numGlid:
+ othersDetecteds.append(0) #Not detected by default
+ othersDetectedsField.append(pack('B',othersDetecteds[i]))
+ i=i+1
+ def createOthersDetecteds(self, myOthersDetecteds=None):
+ self.i=0
+ while self.i<self.numGlid:
+ if myOthersDetecteds!=None:
+ self.othersDetecteds[self.i]=myOthersDetecteds
+ self.othersDetectedsField[self.i] = pack('B',self.othersDetecteds[self.i])
+ print "othersDetecteds["+str(self.i)+"] = "+hex(self.othersDetecteds[self.i])
+ self.i=self.i+1
+ i=0
+ while i<numGlid:
+ signalLevels.append(0) #Not detected by default
+ signalLevelsField.append(pack('B',signalLevels[i]))
+ i=i+1
+ def createSignalLevels(self, mySignalLevels=None):
+ self.i=0
+ while self.i<self.numGlid:
+ if mySignalLevels!=None:
+ self.signalLevels[self.i]=mySignalLevels
+ self.signalLevelsField[self.i] = pack('B',self.signalLevels[self.i])
+ print "signalLevels["+str(self.i)+"] = "+hex(self.signalLevels[self.i])
+ self.i=self.i+1
+ averageBle = Ble()
+
+ i=0
+ while i<numGlid:
+ glidsInfo.append(glids.glidsField[i] + cfDetectedsField[i] + csmaDetectedsField[i] + hp1DetectedsField[i] + othersDetectedsField[i] + signalLevelsField[i] + averageBle.intervalField[i])
+ i=i+1
+ def createGlidsInfo(self, myNumGlid=None, myGlids=None, myCfDetecteds=None, myCsmaDetecteds=None, myHp1Detecteds=None, myOthersDetecteds=None, mySignalLevels=None, myEndTime=None, myIntBle=None, myInterval=None):
+ self.createGlids(myNumGlid, myGlids)
+ self.createCfDetecteds(myCfDetecteds)
+ self.createCsmaDetecteds(myCsmaDetecteds)
+ self.createHp1Detecteds(myHp1Detecteds)
+ self.createOthersDetecteds(myOthersDetecteds)
+ self.createSignalLevels(mySignalLevels)
+ print "averageBle :"
+ self.averageBle.createBle(self.numGlid, myEndTime, myIntBle, myInterval)
+ self.i=0
+ while self.i<self.numGlid:
+ self.glidsInfo[self.i] = self.glids.glidsField[self.i] + self.cfDetectedsField[self.i] + self.csmaDetectedsField[self.i] + self.hp1DetectedsField[self.i] + self.othersDetectedsField[self.i] + self.signalLevelsField[self.i] + self.averageBle.intervalField[self.i]
+ self.i=self.i+1
+
+
+
+
+#MmentryFields lists all fields existing in every MMENTRY
+class MmentryFields():
+
+ #MMENTRY
+ mmentry = ""
+
+ #MMTYPE
+ mmtype = 0
+
+ #Request Type
+ reqType = 0 #0 is the default processed value
+ reqTypeField = pack('B',reqType)
+ def createReqType(self, myReqType=None):
+ try:
+ if myReqType!=None:
+ self.reqType=myReqType
+ self.reqTypeField = pack('B',self.reqType)
+ except:
+ if myReqType!=None:
+ self.reqTypeField=myReqType
+ self.reqType = unpack('B',self.reqTypeField[0])[0]
+ print "reqType = "+hex(self.reqType)
+
+ #Response Type
+ resType = 0 #0 is the default processed value
+ resTypeField = pack('B',resType)
+ def createResType(self, myResType=None):
+ if myResType!=None:
+ self.resType=myResType
+ self.resTypeField = pack('B',self.resType)
+ print "resType = "+hex(self.resType)
+
+ #Request Identifier
+ reqId = 0 #0 is the default processed value
+ reqIdField = pack('B',reqId)
+ def createReqId(self, myReqId=None):
+ if myReqId!=None:
+ self.reqId=myReqId
+ self.reqIdField = pack('B',self.reqId)
+ print "reqId = "+hex(self.reqId)
+
+ #MAC Address of the STA
+ macAddress = 0
+ macAddressField = pack('Q',macAddress)[0:6]
+ def createMacAddress(self,myMacAddress=None):
+ try:
+ if myMacAddress!=None:
+ self.macAddress=myMacAddress
+ self.macAddressField = pack('Q',self.macAddress)[0:6]
+ except:
+ if myMacAddress!=None:
+ self.macAddressField=myMacAddress
+ self.macAddress = unpack('Q',self.macAddressField[:6]+"\x00\x00")[0]
+ print "macAddress = "+hex(self.macAddress)
+
+ #Results Codes
+ result = 0
+ resultField = pack('B',result)
+ def createResult(self, myResult=None):
+ if myResult!=None:
+ try:
+ self.result=myResult
+ self.resultField = pack('B',self.result)
+ except:
+ self.resultField=myResult
+ self.result = unpack('B',self.resultField[0])[0]
+ print "result = "+hex(self.result)
+
+ #Become Backup CCo or Release Duty
+ appointRelease = 0
+ appointReleaseField = pack('B',appointRelease)
+ def createAppointRelease(self, myAppointRelease=None):
+ if myAppointRelease!=None:
+ self.appointRelease=myAppointRelease
+ self.appointReleaseField = pack('B',self.appointRelease)
+ print "appointRelease = "+hex(self.appointRelease)
+
+ #Number
+ num = 255
+ numField = pack('B',num)
+ def createNum(self, myNum=None):
+ if myNum!=None:
+ try:
+ self.num=myNum
+ self.numField = pack('B',self.num)
+ except:
+ self.numField=myNum
+ self.num = unpack('B',self.numField[0])[0]
+ print "num = "+hex(self.num)
+
+ #Link Information of the Global Links
+ globalLinks = []
+ i = 0
+ while i < num:
+ globalLinks.append(GlobalLinkInfo())
+ i=i+1
+ def createGlobalLinks(self, myNum=None, myTei=None, myLlidF=None, myStei=None, myDtei=None, myLidF=None, myLidR=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None, myNumF=None, myEndTimeL=None, myIntBleL=None, myIntervalL=None, myNumR=None, myEndTimeR=None, myIntBleR=None, myIntervalR=None):
+ self.createNum(myNum)
+ self.i = 0
+ while self.i < self.num:
+ print "globalLinks["+str(self.i)+"] :"
+ self.globalLinks[self.i].createGlobalLinkInfo(myTei, myLlidF, myStei, myDtei, myLidF, myLidR, myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R, myNumF, myEndTimeL, myIntBleL, myIntervalL, myNumR, myEndTimeR, myIntBleR, myIntervalR)
+ self.i = self.i + 1
+
+ #Soft/Hard
+ softHard = 0 #Soft Handover by default
+ softHardField = pack('B',softHard)
+ def createSoftHard(self, mySoftHard=None):
+ if mySoftHard!=None:
+ self.softHard=mySoftHard
+ self.softHardField = pack('B',self.softHard)
+ print "softHard = "+hex(self.softHard)
+
+ #Reason
+ reason = 0 #User-appointed by default
+ reasonField = pack('B',reason)
+ def createReason(self, myReason=None):
+ if myReason!=None:
+ self.reason=myReason
+ self.reasonField = pack('B',self.reason)
+ print "reason = "+hex(self.reason)
+
+ #Reason Code indicating the reason for sending CC_HANDOVER_INFO.IND
+ rsc = 0 #Handover in progress by default
+ rscField = pack('B',rsc)
+ def createRsc(self, myRsc=None):
+ if myRsc!=None:
+ self.rsc=myRsc
+ self.rscField = pack('B',self.rsc)
+ print "rsc = "+hex(self.rsc)
+
+ #TEI of the Backup CCo
+ backupCco = 0 #no backupCco by default
+ backupCcoField = pack('B',backupCco)
+ def createBackupCco(self, myBackupCco=None):
+ if myBackupCco!=None:
+ self.backupCco=myBackupCco
+ self.backupCcoField = pack('B',self.backupCco)
+ print "backupCco = "+hex(self.backupCco)
+
+ #Information of the Stations
+ stasInfo = []
+ i = 0
+ while i < num:
+ stasInfo.append(StaInfo())
+ i=i+1
+ def createStasInfo(self, myNum=None, myTei=None, myMacAddress=None, myStatus=None, myPtei=None):
+ self.createNum(myNum)
+ self.i = 0
+ while self.i < self.num:
+ print "stasInfo["+str(self.i)+"] :"
+ self.stasInfo[self.i].createStaInfo(myTei, myMacAddress, myStatus, myPtei)
+ self.i = self.i + 1
+
+ #Number of STA
+ numSta = 255
+ numStaField = pack('B',numSta)
+ def createNumSta(self, myNumSta=None):
+ if myNumSta!=None:
+ self.numSta=myNumSta
+ self.numStaField = pack('B',self.numSta)
+ print "numSta = "+hex(self.numSta)
+
+ #Number of Network
+ numNet = 255
+ numNetField = pack('B',numNet)
+ def createNumNet(self, myNumNet=None):
+ if myNumNet!=None:
+ self.numNet=myNumNet
+ self.numNetField = pack('B',self.numNet)
+ print "numNet = "+hex(self.numNet)
+
+ #Number of AVLN that the station is a member
+ numNws = 255
+ numNwsField = pack('B',numNws)
+ def createNumNws(self, myNumNws=None):
+ if myNumNws!=None:
+ self.numNws=myNumNws
+ self.numNwsField = pack('B',self.numNws)
+ print "numNws = "+hex(self.numNws)
+
+ #STAs Info
+ stationsInfo = []
+ i = 0
+ while i < numSta:
+ stationsInfo.append(StationInfo())
+ i=i+1
+ def createStationsInfo(self, myNumSta=None, myMacAddress=None, myTei=None, mySameNetwork=None, mySnid=None, myAccess=None, mySnidAccess=None, myCcoCapability=None, myProxyNetworkCapability=None, myBackupCcoCapability=None, myCcoStatus=None, myPcoStatus=None, myBackupCcoStatus=None, myNinthOctet=None, mySignalLevel=None, myEndTime=None, myIntBle=None, myInterval=None):
+ self.createNumSta(myNumSta)
+ self.i = 0
+ while self.i < self.numSta:
+ print "stationsInfo["+str(self.i)+"] :"
+ self.stationsInfo[self.i].createStationInfo(myMacAddress, myTei, mySameNetwork, mySnid, myAccess, mySnidAccess, myCcoCapability, myProxyNetworkCapability, myBackupCcoCapability, myCcoStatus, myPcoStatus, myBackupCcoStatus, myNinthOctet, mySignalLevel, myEndTime, myIntBle, myInterval)
+ self.i = self.i + 1
+
+ #Networks Info
+ networksInfo = []
+ i = 0
+ while i < numNet:
+ networksInfo.append(NetworkInfo())
+ i=i+1
+ def createNetworksInfo(self, myNumNet=None, mySecurityLevel=None, myNidOffset=None, myNid=None, mySnid=None, myAccess=None, mySnidAccess=None, myHm=None, myNumSlot=None, myCoordonatingStatus=None, myOffset=None):
+ self.createNumNet(myNumNet)
+ self.i = 0
+ while self.i < self.numNet:
+ print "networksInfo["+str(self.i)+"] :"
+ self.networksInfo[self.i].createNetworkInfo(mySecurityLevel, myNidOffset, myNid, mySnid, myAccess, mySnidAccess, myHm, myNumSlot, myCoordonatingStatus, myOffset)
+ self.i = self.i + 1
+
+ #Networks Informations
+ nwsInfo = []
+ i = 0
+ while i < numNws:
+ nwsInfo.append(NwInfo())
+ i=i+1
+ def createNwsInfo(self, myNumNws=None, mySecurityLevel=None, myNidOffset=None, myNid=None, mySnid=None, myTei=None, myStationRole=None, myCco_MacAddress=None, myAccess=None, myNumCordNws=None):
+ self.createNumNws(myNumNws)
+ self.i = 0
+ while self.i < self.numNws:
+ print "nwsInfo["+str(self.i)+"] :"
+ self.nwsInfo[self.i].createNwInfo(mySecurityLevel, myNidOffset, myNid, mySnid, myTei, myStationRole, myCco_MacAddress, myAccess, myNumCordNws)
+ self.i = self.i + 1
+
+ #Init MAC Address of the STA
+ initMacAddress = 0
+ initMacAddressField = pack('Q',initMacAddress)[0:6]
+ def createInitMacAddress(self, myInitMacAddress=None):
+ if myInitMacAddress!=None:
+ self.initMacAddress=myInitMacAddress
+ self.initMacAddressField = pack('Q',self.initMacAddress)[0:6]
+ print "initMacAddress = "+hex(self.initMacAddress)
+
+ #Term MAC Address of the STA
+ termMacAddress = 0
+ termMacAddressField = pack('Q',termMacAddress)[0:6]
+ def createTermMacAddress(self, myTermMacAddress=None):
+ if myTermMacAddress!=None:
+ self.termMacAddress=myTermMacAddress
+ self.termMacAddressField = pack('Q',self.termMacAddress)[0:6]
+ print "termMacAddress = "+hex(self.termMacAddress)
+
+ #Connection Identifier
+ cid = Cid()
+ cidField = cid.cid
+ def createCid(self, myTei=None, myLlidF=None):
+ print "cid :"
+ self.cid.createCid(myTei, myLlidF)
+ self.cidField=self.cid.cid
+
+ #Connection Specification
+ cspec = Cspec()
+ cspecField = cspec.cspec
+ def createCspec(self, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "cspec :"
+ self.cspec.createCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.cspecField=self.cspec.cspec
+
+ #Forward Link Bit Loading Estimates
+ forwardLinkBle = Ble()
+ forwardLinkBleField=forwardLinkBle.ble
+ def createForwardLinkBle(self, myNum=None, myEndTime=None, myIntBle=None, myInterval=None):
+ print "forwardLinkBle :"
+ self.createNum(myNum)
+ self.forwardLinkBle.createBle(self.num, myEndTime, myIntBle, myInterval)
+ self.forwardLinkBleField=self.forwardLinkBle.ble
+
+ #Reverse Link Bit Loading Estimates
+ reverseLinkBle = Ble()
+ reverseLinkBleField=reverseLinkBle.ble
+ def createReverseLinkBle(self, myNum=None, myEndTime=None, myIntBle=None, myInterval=None):
+ print "reverseLinkBle :"
+ self.createNum(myNum)
+ self.reverseLinkBle.createBle(self.num, myEndTime, myIntBle, myInterval)
+ self.reverseLinkBleField=self.reverseLinkBle.ble
+
+ #Forward Link GLID
+ glidF = 0xFF #Local CSMA allocation by default
+ glidFField = pack('B',glidF)
+ def createGlidF(self, myGlidF=None):
+ if myGlidF!=None:
+ self.glidF=myGlidF
+ self.glidFField = pack('B',self.glidF)
+ print "glidF = "+hex(self.glidF)
+
+ #Reverse Link GLID
+ glidR = 0xFF #Local CSMA allocation by default
+ glidRField = pack('B',glidR)
+ def createGlidR(self, myGlidR=None):
+ if myGlidR!=None:
+ self.glidR=myGlidR
+ self.glidRField = pack('B',self.glidR)
+ print "glidR = "+hex(self.glidR)
+
+ #Proposed CSPEC
+ proposedCspec = Cspec()
+ proposedCspecField = proposedCspec.cspec
+ def createProposedCspec(self, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "proposedCspec :"
+ self.proposedCspec.createCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.proposedCspecField=self.proposedCspec.cspec
+
+ #Modified CSPEC
+ modifiedCspec = Cspec()
+ modifiedCspecField = modifiedCspec.cspec
+ def createModifiedCspec(self, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "modifiedCspec :"
+ self.modifiedCspec.createCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.modifiedCspecField=self.modifiedCspec.cspec
+
+ #Terminal Equipment identifier
+ tei = 0
+ teiField = pack('B',tei)
+ def createTei(self, myTei=None):
+ if myTei!=None:
+ self.tei=myTei
+ self.teiField = pack('B',self.tei)
+ print "tei = "+hex(self.tei)
+
+ #Violated CSPEC
+ violatedCspec = Cspec()
+ violatedCspecField = violatedCspec.cspec
+ def createViolatedCspec(self, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "violatedCspec :"
+ self.violatedCspec.createCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.violatedCspecField=self.violatedCspec.cspec
+
+ #Releasing Station MAC Address
+ releasingStationMacAddress = 0
+ releasingStationMacAddressField = pack('Q',releasingStationMacAddress)[0:6]
+ def createReleasingStationMacAddress(self, myReleasingStationMacAddress=None):
+ if myReleasingStationMacAddress!=None:
+ self.releasingStationMacAddress=myReleasingStationMacAddress
+ self.releasingStationMacAddressField = pack('Q',self.releasingStationMacAddress)[0:6]
+ print "releasingStationMacAddress = "+hex(self.releasingStationMacAddress)
+
+ #Duration
+ duration = 0 #0 beacon period by default
+ durationField = pack('B',duration)
+ def createDuration(self, myDuration=None):
+ if myDuration!=None:
+ self.duration=myDuration
+ self.durationField = pack('B',self.duration)
+ print "duration = "+hex(self.duration)
+
+ #Number of GLID
+ numGlid = 255
+ numGlidField = pack('B',numGlid)
+ def createNumGlid(self, myNumGlid=None):
+ if myNumGlid!=None:
+ self.numGlid=myNumGlid
+ self.numGlidField = pack('B',self.numGlid)
+ print "numGlid = "+hex(self.numGlid)
+
+ #GLIDs
+ glids = Glids()
+ glids.numGlid = numGlid
+ glids.createGlids()
+ def createGlids(self, myNumGlid=None, myGlids=None):
+ print "glids :"
+ self.createNumGlid(myNumGlid)
+ self.glids.createGlids(self.numGlid, myGlids)
+
+ #GLIDs Info
+ glidsInfo = GlidsInfo()
+ glidsInfo.numGlid = numGlid
+ glidsInfo.createGlidsInfo()
+ def createGlidsInfo(self, myNumGlid=None, myCfDetecteds=None, myCsmaDetecteds=None, myHp1Detecteds=None, myOthersDetecteds=None, mySignalLevels=None, myEndTime=None, myIntBle=None, myInterval=None):
+ print "glidsInfo :"
+ self.createNumGlid(myNumGlid)
+ self.glidsInfo.numGlid = self.numGlid
+ self.glidsInfo.createGlidsInfo(self.numGlid, myCfDetecteds, myCsmaDetecteds, myHp1Detecteds, myOthersDetecteds, mySignalLevels, myEndTime, myIntBle, myInterval)
+
+ #Network Identifier
+ reserved = 0
+ securityLevel = 0 #Simple connect by default
+ nidOffset = 0x0f0e0d0c
+ nid = int(nidOffset + securityLevel*pow(2,52) + reserved*pow(2,54))
+ nidField = pack('Q',nid)[0:7]
+ def createNid(self, mySecurityLevel=None, myNidOffset=None, myNid=None):
+ if myNid!=None:
+ try:
+ self.nid=myNid
+ self.nidField = pack('Q',self.nid)[0:7]
+ except:
+ self.nidField=myNid
+ self.nid = unpack('Q',self.nid[:7]+"\x00")[0]
+ elif mySecurityLevel!=None or myNidOffset!=None:
+ if mySecurityLevel!=None:
+ self.securityLevel=mySecurityLevel
+ if myNidOffset!=None:
+ self.nidOffset=myNidOffset
+ self.nid = int(self.nidOffset + self.securityLevel*pow(2,52) + self.reserved*pow(2,54))
+ self.nidField = pack('Q',self.nid)[0:7]
+ print "nid = "+hex(self.nid)
+
+ #CCo's MAC Address
+ cmac = 0x43414D6F4343 #="CCoMAC"
+ cmacField = pack('Q',cmac)[0:6]
+ def createCmac(self, myCmac=None):
+ if myCmac!=None:
+ self.cmac=myCmac
+ self.cmacField = pack('Q',self.cmac)[0:6]
+ print "cmac = "+hex(self.cmac)
+
+ #Human Friendly Identifier
+ # Maximus simulator HFID by default :
+ hfid = "SPiDCOM MAXIMUS SIMULATOR HUMAN FRIENDLY IDENTIFIER : " + maxAddress #pack('Q',maxAddress)[0:6]
+ hfidField = hfid
+ while len(hfidField)<64:
+ hfidField = hfidField + pack('B',0)
+ def createHfid(self, myHfid=None):
+ if myHfid!=None:
+ self.hfid=myHfid
+ self.hfidField = self.hfid
+ while len(self.hfidField)<64:
+ self.hfidField = self.hfidField + pack('B',0)
+ print "hfid = "+self.hfid
+
+ #CCo Capability
+ ccoCapability = 0 #level 0 by default
+ ccoCapabilityField = pack('B',ccoCapability)
+ def createCcoCapability(self, myCcoCapability=None):
+ if myCcoCapability!=None:
+ try:
+ self.ccoCapability=myCcoCapability
+ self.ccoCapabilityField = pack('B',self.ccoCapability)
+ except:
+ self.ccoCapabilityField=myCcoCapability
+ self.ccoCapability = unpack('B',self.ccoCapabilityField[0])[0]
+ print "ccoCapability = "+hex(self.ccoCapability)
+
+ #Proxy Networking Capability
+ proxyNetworkingCapability = 0 #not supported by default
+ proxyNetworkingCapabilityField = pack('B',proxyNetworkingCapability)
+ def createProxyNetworkingCapability(self, myProxyNetworkingCapability=None):
+ if myProxyNetworkingCapability!=None:
+ try:
+ self.proxyNetworkingCapability=myProxyNetworkingCapability
+ self.proxyNetworkingCapabilityField = pack('B',self.proxyNetworkingCapability)
+ except:
+ self.proxyNetworkingCapabilityField=myProxyNetworkingCapability
+ self.proxyNetworkingCapability = unpack('B',self.proxyNetworkingCapabilityField[0])[0]
+ print "proxyNetworkingCapability = "+hex(self.proxyNetworkingCapability)
+
+ #SNID
+ snid = 0xA
+ access = 0 #in home by default
+ snidAccess = int(snid + access*pow(2,4))
+ snidAccessField = pack('B',snidAccess)
+ def createSnidAccess(self, mySnid=None, myAccess=None, mySnidAccess=None):
+ if mySnidAccess!=None:
+ try:
+ self.snidAccess=mySnidAccess
+ self.snidAccessField = pack('B',self.snidAccess)
+ except:
+ self.snidAccessField=mySnidAccess
+ self.snidAccess = unpack('B',self.snidAccessField[0])[0]
+ print "snidAccess = "+hex(self.snidAccess)
+ else:
+ if mySnid!=None:
+ self.snid=mySnid
+ if myAccess!=None:
+ self.access=myAccess
+ self.snidAccess = int(self.snid + self.access*pow(2,4))
+ self.snidAccessField = pack('B',self.snidAccess)
+ print "snid = "+hex(self.snid)
+ print "access = "+hex(self.access)
+ print "snidAccess = "+hex(self.snidAccess)
+
+ #TEI assigned to the station
+ staTei = 0 #no backupCco by default
+ staTeiField = pack('B',staTei)
+ def createStaTei(self, myStaTei=None):
+ if myStaTei!=None:
+ try:
+ self.staTei=myStaTei
+ self.staTeiField = pack('B',self.staTei)
+ except:
+ self.staTeiField=myStaTei
+ self.staTei = unpack('B',self.staTeiField[0])[0]
+ print "staTei = "+hex(self.staTei)
+
+ #Lease Time
+ leaseTime = 0x000F #15min by default
+ leaseTimeField = pack('H',leaseTime)
+ def createLeaseTime(self, myLeaseTime=None):
+ if myLeaseTime!=None:
+ try:
+ self.leaseTime=myLeaseTime
+ self.leaseTimeField = pack('H',self.leaseTime)
+ except:
+ self.leaseTimeField=myLeaseTime
+ self.leaseTime = unpack('H',self.leaseTimeField[0:2])[0]
+ print "leaseTime = "+hex(self.leaseTime)
+
+ #Mode
+ mode = 0 #Update by default
+ modeField = pack('B',mode)
+ def createMode(self, myMode=None):
+ if myMode!=None:
+ try:
+ self.mode=myMode
+ self.modeField = pack('B',self.mode)
+ except:
+ self.modeField=myMode
+ self.mode = unpack('B',self.modeField[0])[0]
+ print "mode = "+hex(self.mode)
+
+ #TEIs
+ teis = []
+ teisField = []
+ i = 0
+ while i < num:
+ teis.append(i)
+ teisField.append(pack('B',teis[i]))
+ i=i+1
+ def createTeis(self, myNum=None, myTei=None):
+ print "teis :"
+ self.createNum(myNum)
+ try:
+ self.i = 0
+ while self.i < self.num:
+ if myTei!=None:
+ self.teis[self.i]=int((myTei+self.i)%pow(2,8))
+ self.teisField[self.i]=pack('B',self.teis[self.i])
+ #print "teis["+str(self.i)+"] = "+hex(self.teis[self.i])
+ self.i = self.i + 1
+ except:
+ if myTei!=None:
+ self.i = 0
+ while self.i < self.num:
+ self.teisField[self.i]=myTei[self.i*8]
+ self.teis[self.i]=unpack('B',self.teisField[self.i])[0]
+ #print "teis["+str(self.i)+"] = "+hex(self.teis[self.i])
+ self.i = self.i + 1
+
+ #MAC Addresses
+ addrs = []
+ addrsField = []
+ i = 0
+ while i < num:
+ addrs.append(i+0x123456)
+ addrsField.append(pack('Q',addrs[i])[0:6])
+ i=i+1
+ def createAddrs(self, myNum=None, myAddr=None):
+ print "addrs : "
+ self.createNum(myNum)
+ try:
+ self.i = 0
+ while self.i < self.num:
+ if myAddr!=None:
+ self.addrs[self.i]=int((myAddr+self.i)%pow(2,48))
+ self.addrsField[self.i]=pack('Q',self.addrs[self.i])[0:6]
+ #print "addrs["+str(self.i)+"] = "+hex(self.addrs[self.i])
+ self.i = self.i + 1
+ except:
+ if myAddr!=None:
+ self.i = 0
+ while self.i < self.num:
+ self.addrsField[self.i]=myAddr[self.i*8:(self.i*8)+6]
+ self.addrs[self.i]=unpack('Q',self.addrsField[self.i]+"\x00\x00")[0]
+ #print "addrs["+str(self.i)+"] = "+hex(self.addrs[self.i])
+ self.i = self.i + 1
+
+ #Statuses
+ statuses = []
+ statusesField = []
+ i = 0
+ while i < num:
+ statuses.append(0) #associated by default
+ statusesField.append(pack('B',statuses[i]))
+ i=i+1
+ def createStatuses(self, myNum=None, myStatus=None):
+ print "statuses :"
+ self.createNum(myNum)
+ try:
+ self.i = 0
+ while self.i < self.num:
+ if myStatus!=None:
+ self.statuses[self.i]=myStatus
+ self.statusesField[self.i]=pack('B',self.statuses[self.i])
+ #print "statuses["+str(self.i)+"] = "+hex(self.statuses[self.i])
+ self.i = self.i + 1
+ except:
+ if myStatus!=None:
+ self.i = 0
+ while self.i < self.num:
+ self.statusesField[self.i]=myStatus[self.i*8]
+ self.statuses[self.i]=unpack('B',self.statusesField[self.i])[0]
+ #print "statuses["+str(self.i)+"] = "+hex(self.statuses[self.i])
+ self.i = self.i + 1
+
+ #TEIs + MAC Addresses + Statuses
+ teisAddrsStatuses = []
+ i = 0
+ while i < num:
+ teisAddrsStatuses.append(teisField[i]+addrsField[i]+statusesField[i])
+ i=i+1
+ def createTeisAddrsStatuses(self, myNum=None, myTei=None, myAddr=None, myStatus=None):
+ print "teisAddrsStatuses :"
+ self.createTeis(myNum, myTei)
+ self.createAddrs(self.num, myAddr)
+ self.createStatuses(self.num, myStatus)
+ self.i = 0
+ while self.i < self.num:
+ self.teisAddrsStatuses[self.i]=self.teisField[self.i]+self.addrsField[self.i]+self.statusesField[self.i]
+ self.i = self.i + 1
+
+ #Final STA MAC Address
+ fda = 0x43414D414446 #="FDAMAC"
+ fdaField = pack('Q',fda)[0:6]
+ def createFda(self, myFda=None):
+ if myFda!=None:
+ self.fda=myFda
+ self.fdaField = pack('Q',self.fda)[0:6]
+ print "fda = "+hex(self.fda)
+
+ #Final STA TEI
+ fTei = 0 #no backupCco by default
+ fTeiField = pack('B',fTei)
+ def createFTei(self, myFTei=None):
+ if myFTei!=None:
+ self.fTei=myFTei
+ self.fTeiField = pack('B',self.fTei)
+ print "fTei = "+hex(self.fTei)
+
+ #Payload
+ payload = "MME"
+ def createPayload(self, myPayload=None):
+ if myPayload!=None:
+ self.payload = myPayload
+ print "payload = "+payload
+
+ #Length of payload
+ length = len(payload)
+ lengthField = pack('H',length)
+ def createLength(self):
+ self.length = len(self.payload)
+ self.lengthField = pack('H',self.length)
+ print "length = "+hex(self.length)
+
+ #Original STA MAC Address
+ oda = 0x43414D41444F #="ODAMAC"
+ odaField = pack('Q',oda)[0:6]
+ def createOda(self, myOda=None):
+ if myOda!=None:
+ self.oda=myOda
+ self.odaField = pack('Q',self.oda)[0:6]
+ print "oda = "+hex(self.oda)
+
+ #Original STA TEI
+ oTei = 0 #no backupCco by default
+ oTeiField = pack('B',oTei)
+ def createOTei(self, myOTei=None):
+ if myOTei!=None:
+ self.oTei=myOTei
+ self.oTeiField = pack('B',self.oTei)
+ print "oTei = "+hex(self.oTei)
+
+ #Number of Beacon Periods
+ nbp = 0
+ nbpField = pack('H',nbp)
+ def createNbp(self, myNbp=None):
+ if myNbp!=None:
+ self.nbp=myNbp
+ self.nbpField = pack('H',self.nbp)
+ print "nbp = "+hex(self.nbp)
+
+ #Number of Missed Beacons
+ nmb = 0
+ nmbField = pack('H',nmb)
+ def createNmb(self, myNmb=None):
+ if myNmb!=None:
+ self.nmb=myNmb
+ self.nmbField = pack('H',self.nmb)
+ print "nmb = "+hex(self.nmb)
+
+ #STEI
+ stei = 0
+ steiField = pack('B',stei)
+ def createStei(self, myStei=None):
+ if myStei!=None:
+ self.stei=myStei
+ self.steiField = pack('B',self.stei)
+ print "stei = "+hex(self.stei)
+
+ #DTEI
+ dtei = 0
+ dteiField = pack('B',dtei)
+ def createDtei(self, myDtei=None):
+ if myDtei!=None:
+ self.dtei=myDtei
+ self.dteiField = pack('B',self.dtei)
+ print "dtei = "+hex(self.dtei)
+
+ #DAddr
+ dAddr = 0x644143414D44 #="DMACAd"
+ dAddrField = pack('Q',dAddr)[0:6]
+ def createDAddr(self, myDAddr=None):
+ if myDAddr!=None:
+ self.dAddr=myDAddr
+ self.dAddrField = pack('Q',self.dAddr)[0:6]
+ print "dAddr = "+hex(self.dAddr)
+
+ #LLID
+ llid = 0
+ llidField = pack('B',llid)
+ def createLlid(self, myLlid=None):
+ if myLlid!=None:
+ self.llid=myLlid
+ self.llidField = pack('B',self.llid)
+ print "llid = "+hex(self.llid)
+
+ #Bit Loading Estimates
+ ble = Ble()
+ bleField=ble.ble
+ def createBle(self, myNum=None, myEndTime=None, myIntBle=None, myInterval=None):
+ print "ble : "
+ self.createNum(myNum)
+ self.ble.createBle(self.num, myEndTime, myIntBle, myInterval)
+ self.bleField=self.ble.ble
+
+ #GCID-F
+ gcidF = 0xFF #Local CSMA allocation by default
+ gcidFField = pack('B',gcidF)
+ def createGcidF(self, myGcidF=None):
+ if myGcidF!=None:
+ self.gcidF=myGcidF
+ self.gcidFField = pack('B',self.gcidF)
+ print "gcidF = "+hex(self.gcidF)
+
+ #GCID-R
+ gcidR = 0xFF #Local CSMA allocation by default
+ gcidRField = pack('B',gcidR)
+ def createGcidR(self, myGcidR=None):
+ if myGcidR!=None:
+ self.gcidR=myGcidR
+ self.gcidRField = pack('B',self.gcidR)
+ print "gcidR = "+hex(self.gcidR)
+
+ #ChanEstF
+ chanEstF = 0
+ chanEstFField = pack('B',chanEstF)
+ def createChanEstF(self, myChanEstF=None):
+ if myChanEstF!=None:
+ self.chanEstF=myChanEstF
+ self.chanEstFField = pack('B',self.chanEstF)
+ print "chanEstF = "+hex(self.chanEstF)
+
+ #ChanEstR
+ chanEstR = 0
+ chanEstRField = pack('B',chanEstR)
+ def createChanEstR(self, myChanEstR=None):
+ if myChanEstR!=None:
+ self.chanEstR=myChanEstR
+ self.chanEstRField = pack('B',self.chanEstR)
+ print "chanEstR = "+hex(self.chanEstR)
+
+ #Bit Loading Estimates Forward
+ bleF = Ble()
+ bleFField=bleF.ble
+ def createBleF(self, myNum=None, myEndTime=None, myIntBle=None, myInterval=None):
+ print "bleF : "
+ self.createNum(myNum)
+ self.bleF.createBle(self.num, myEndTime, myIntBle, myInterval)
+ self.bleFField=self.bleF.ble
+
+ #Bit Loading Estimates Reverse
+ bleR = Ble()
+ bleRField=bleR.ble
+ def createBleR(self, myNum=None, myEndTime=None, myIntBle=None, myInterval=None):
+ print "bleR : "
+ self.createNum(myNum)
+ self.bleR.createBle(self.num, myEndTime, myIntBle, myInterval)
+ self.bleRField=self.bleR.ble
+
+ #Cause
+ cause = 0
+ causeField = pack('B',cause)
+ def createCause(self):
+ self.causeField = pack('B',self.cause)
+ print "cause = "+hex(self.cause)
+
+ #DCPPC
+ dcppc = 0
+ dcppcField = pack('B',dcppc)
+ def createDcppc(self, myDcppc=None):
+ if myDcppc!=None:
+ self.dcppc=myDcppc
+ self.dcppcField = pack('B',self.dcppc)
+ print "dcppc = "+hex(self.dcppc)
+
+ #Number of HomePlug 1.0.1 transmission detected
+ nhp10 = 0
+ nhp10Field = pack('H',nhp10)
+ def createNhp10(self, myNhp10=None):
+ if myNhp10!=None:
+ self.nhp10=myNhp10
+ self.nhp10Field = pack('H',self.nhp10)
+ print "nhp10 = "+hex(self.nhp10)
+
+ #Number of HomePlug 1.1 transmission detected
+ nhp11 = 0
+ nhp11Field = pack('H',nhp11)
+ def createNhp11(self, myNhp11=None):
+ if myNhp11!=None:
+ self.nhp11=myNhp11
+ self.nhp11Field = pack('H',self.nhp11)
+ print "nhp11 = "+hex(self.nhp11)
+
+ #Payload Encryption Key Select
+ peks = 0x0F #Not encripted by default
+ peksField = pack('B',peks)
+ def createPeks(self, myPeks=None):
+ try:
+ if myPeks!=None:
+ self.peks=myPeks
+ self.peksField = pack('B',self.peks)
+ except:
+ if myPeks!=None:
+ self.peksField=myPeks
+ self.peks = unpack('B',self.peksField[0])[0]
+ print "peks = "+hex(self.peks)
+
+ #AVLN Status
+ avlnStatus = 0
+ avlnStatusField = pack('B',avlnStatus)
+ def createAvlnStatus(self, myAvlnStatus=None):
+ try:
+ if myAvlnStatus!=None:
+ self.avlnStatus=myAvlnStatus
+ self.avlnStatusField = pack('B',self.avlnStatus)
+ except:
+ if myAvlnStatus!=None:
+ self.avlnStatusField=myAvlnStatus
+ self.avlnStatus = unpack('B',self.avlnStatusField[0])[0]
+ print "avlnStatus = "+hex(self.avlnStatus)
+
+ #Protocol ID
+ pid = 0
+ pidField = pack('B',pid)
+ def createPid(self, myPid=None):
+ try:
+ if myPid!=None:
+ self.pid=myPid
+ self.pidField = pack('B',self.pid)
+ except:
+ if myPid!=None:
+ self.pidField=myPid
+ self.pid = unpack('B',self.pidField[0])[0]
+ print "pid = "+hex(self.pid)
+
+ #Protocol Run Number
+ prn = randrange(0,pow(2,16)-1,1)
+ prnField = pack('H',prn)
+ def createPrn(self, myPrn=None):
+ try:
+ if myPrn!=None:
+ self.prn=myPrn
+ else:
+ self.prn=randrange(0,pow(2,16)-1,1)
+ self.prnField = pack('H',self.prn)
+ except:
+ if myPrn!=None:
+ self.prnField=myPrn
+ else:
+ self.prnField=pack('H',randrange(0,pow(2,16)-1,1))
+ self.prn = unpack('H',self.prnField[:2])[0]
+ print "prn = "+hex(self.prn)
+
+ #Protocol Message Number
+ pmn = 0
+ pmnField = pack('B',pmn)
+ def createPmn(self, myPmn=None, reset=False):
+ try:
+ if myPmn!=None:
+ self.pmn=myPmn
+ elif reset==True:
+ self.pmn=0
+ else:
+ self.pmn=self.pmn + 1
+ self.pmnField = pack('B',self.pmn)
+ except:
+ if myPmn!=None:
+ self.pmnField=myPmn
+ elif reset==True:
+ self.pmnField=pack('B',0)
+ else:
+ self.pmnField=pack('B',self.pmn + 1)
+ self.pmn = unpack('B',self.pmnField[0])[0]
+ print "pmn = "+hex(self.pmn)
+
+ #Key Type
+ keyType = 5 #No key by default
+ keyTypeField = pack('B',keyType)
+ def createKeyType(self, myKeyType=None):
+ try:
+ if myKeyType!=None:
+ self.keyType=myKeyType
+ self.keyTypeField = pack('B',self.keyType)
+ except:
+ if myKeyType!=None:
+ self.keyTypeField=myKeyType
+ self.keyType = unpack('B',self.keyTypeField[0])[0]
+ print "keyType = "+hex(self.keyType)
+
+ #My Nonce
+ myNonce = randrange(0,pow(2,32)-1,1)
+ myNonceField = pack('I',myNonce)
+ def createMyNonce(self, myMyNonce=None):
+ if myMyNonce!=None:
+ try:
+ self.myNonceField=myMyNonce
+ self.myNonce = unpack('I',self.myNonceField[:4])[0]
+ except:
+ self.myNonce=myMyNonce
+ self.myNonceField = pack('I',self.myNonce)
+ else:
+ self.myNonce=randrange(0,pow(2,32)-1,1)
+ self.myNonceField = pack('I',self.myNonce)
+ print "myNonce = "+hex(self.myNonce)
+
+ #Your Nonce
+ yourNonce = 0
+ yourNonceField = pack('I',yourNonce)
+ def createYourNonce(self, myYourNonce=None):
+ if myYourNonce!=None:
+ try:
+ self.yourNonceField=myYourNonce
+ self.yourNonce = unpack('I',self.yourNonceField[:4])[0]
+ except:
+ self.yourNonce=myYourNonce
+ self.yourNonceField = pack('I',self.yourNonce)
+ else:
+ self.yourNonceField = pack('I',self.yourNonce)
+ print "yourNonce = "+hex(self.yourNonce)
+
+ #New Encryption Key Select or Payload Encryption Key Select
+ newEks = 0x0F #Not encripted by default
+ newEksField = pack('B',newEks)
+ def createNewEks(self, myNewEks=None):
+ try:
+ if myNewEks!=None:
+ self.newEks=myNewEks
+ self.newEksField = pack('B',self.newEks)
+ except:
+ if myNewEks!=None:
+ self.newEksField=myNewEks
+ self.newEks = unpack('B',self.newEksField[0])[0]
+ print "newEks = "+hex(self.newEks)
+
+ #New Key
+ newKey = 0x4142434445464748494A4B4C4D4E4F50
+ newKeyField = pack('Q',newKey%pow_2_64)+pack('Q',newKey/pow_2_64)
+ def createNewKey(self, myNewKey=None):
+ try:
+ if myNewKey!=None:
+ self.newKey=myNewKey
+ self.newKeyField = pack('Q',self.newKey%pow_2_64)+pack('Q',self.newKey/pow_2_64)
+ except:
+ if myNewKey!=None:
+ self.newKeyField=myNewKey
+ self.newKey = unpack('QQ',self.newKeyField[:16])[0] + unpack('QQ',self.newKeyField[:16])[1]*pow_2_64
+ print "newKey = "+hex(self.newKey)
+
+ #Request Type
+ requestType = 0 #Direct by default
+ requestTypeField = pack('B',requestType)
+ def createRequestType(self, myRequestType=None):
+ try:
+ if myRequestType!=None:
+ self.requestType=myRequestType
+ self.requestTypeField = pack('B',self.requestType)
+ except:
+ if myRequestType!=None:
+ self.requestTypeField=myRequestType
+ self.requestType = unpack('B',self.requestTypeField[0])[0]
+ print "requestType = "+hex(self.requestType)
+
+ #Requested Key Type
+ requestedKeyType = 5 #No key by default
+ requestedKeyTypeField = pack('B',requestedKeyType)
+ def createRequestedKeyType(self, myRequestedKeyType=None):
+ try:
+ if myRequestedKeyType!=None:
+ self.requestedKeyType=myRequestedKeyType
+ self.requestedKeyTypeField = pack('B',self.requestedKeyType)
+ except:
+ if myRequestedKeyType!=None:
+ self.requestedKeyTypeField=myRequestedKeyType
+ self.requestedKeyType = unpack('B',self.requestedKeyTypeField[0])[0]
+ print "requestedKeyType = "+hex(self.requestedKeyType)
+
+ #HASH KEY
+ hashKey = []
+ i=0
+ hashKeyField = ""
+ while i<48:
+ hashKey.append(randrange(0,pow_2_64-1,1))
+ hashKeyField = hashKeyField + pack('Q',hashKey[i])
+ i=i+1
+ def createHashKey(self, myHashKey=None):
+ print "hashKeyField = "
+ if myHashKey!=None:
+ try:
+ self.hashKey=myHashKey
+ self.hashKeyField = ""
+ self.i=0
+ while self.i<48:
+ self.hashKeyField = self.hashKeyField + pack('Q',self.hashKey[self.i])
+ print hex(self.hashKey[self.i])
+ self.i=self.i+1
+ except:
+ self.hashKeyField=myHashKey
+ self.hashKey = []
+ self.i=0
+ while self.i<48*8:
+ self.hashKey.append(unpack('Q',self.hashKeyField[self.i:self.i+8])[0])
+ print hex(self.hashKey[int(self.i/8)])
+ self.i=self.i+8
+ else:
+ self.hashKeyField = ""
+ self.i=0
+ while self.i<48:
+ self.hashKey[self.i]=randrange(0,pow_2_64-1,1)
+ self.hashKeyField = self.hashKeyField + pack('Q',self.hashKey[self.i])
+ print hex(self.hashKey[self.i])
+ self.i=self.i+1
+
+ #Key
+ key = 0x4142434445464748494A4B4C4D4E4F50
+ keyField = pack('Q',newKey%pow_2_64)+pack('Q',newKey/pow_2_64)
+ def createKey(self, myKey=None):
+ try:
+ if myKey!=None:
+ self.key=myKey
+ self.keyField = pack('Q',self.key%pow_2_64)+pack('Q',self.key/pow_2_64)
+ except:
+ if myKey!=None:
+ self.keyField=myKey
+ self.key = unpack('QQ',self.keyField[:16])[0]+unpack('QQ',self.keyField[:16])[1]*pow_2_64
+ print "key = "+hex(self.key)
+
+ #Statuses and Capabilities : AVLN Status - CCo Capability - Proxy Network Capability - Backup CCo Capability - CCo Status - PCo Status - Backup CCo Status
+ avlnStatus = 0 #Not authenticated with an AVLN by default
+ ccoCapability = 0 #does not support QoS and TDMA by default
+ proxyNetworkCapability = 0 #STA does not support Proxy Networking by default
+ backupCcoCapability = 0 #STA does not support the Backup CCo function by default
+ ccoStatus = 0 #STA is not the CCo by default
+ pcoStatus = 0 #STA is not a PCo by default
+ backupCcoStatus = 0 #STA is not a Backup CCo by default
+ statusesNCapabilities = int(avlnStatus + ccoCapability*pow(2,1) + proxyNetworkCapability*pow(2,3) + backupCcoCapability*pow(2,4) + ccoStatus*pow(2,5) + pcoStatus*pow(2,6) + backupCcoStatus*pow(2,7))
+ statusesNCapabilitiesField = pack('B',statusesNCapabilities)
+ def createStatusesNCapabilities(self, myAvlnStatus=None, myCcoCapability=None, myProxyNetworkCapability=None, myBackupCcoCapability=None, myCcoStatus=None, myPcoStatus=None, myBackupCcoStatus=None, myStatusesNCapabilities=None):
+ if myAvlnStatus!=None:
+ self.avlnStatus=myAvlnStatus
+ if myCcoCapability!=None:
+ self.ccoCapability=myCcoCapability
+ if myProxyNetworkCapability!=None:
+ self.proxyNetworkCapability=myProxyNetworkCapability
+ if myBackupCcoCapability!=None:
+ self.backupCcoCapability=myBackupCcoCapability
+ if myCcoStatus!=None:
+ self.ccoStatus=myCcoStatus
+ if myPcoStatus!=None:
+ self.pcoStatus=myPcoStatus
+ if myBackupCcoStatus!=None:
+ self.backupCcoStatus=myBackupCcoStatus
+ if myStatusesNCapabilities!=None:
+ self.statusesNCapabilities=myStatusesNCapabilities
+ else:
+ self.statusesNCapabilities = int(self.avlnStatus + self.ccoCapability*pow(2,1) + self.proxyNetworkCapability*pow(2,3) + self.backupCcoCapability*pow(2,4) + self.ccoStatus*pow(2,5) + self.pcoStatus*pow(2,6) + self.backupCcoStatus*pow(2,7))
+ self.statusesNCapabilitiesField = pack('B',self.statusesNCapabilities)
+ print "statusesNCapabilitiesField = "+hex(self.statusesNCapabilitiesField)
+
+ #Encryption Key Select or Payload Encryption Key Select
+ eks = 0x0F #Not encripted by default
+ eksField = pack('B',eks)
+ def createEks(self, myEks=None):
+ try:
+ if myEks!=None:
+ self.eks=myEks
+ self.eksField = pack('B',self.eks)
+ except:
+ if myEks!=None:
+ self.eksField=myEks
+ self.eks = unpack('B',self.eksField[0])[0]
+ print "eks = "+hex(self.eks)
+
+ #Response Type
+ responseType = 0
+ responseTypeField = pack('B',responseType)
+ def createResponseType(self, myResponseType=None):
+ if myResponseType!=None:
+ self.responseType=myResponseType
+ self.responseTypeField = pack('B',self.responseType)
+ print "responseType = "+hex(self.responseType)
+
+ #Bridging Station Flag
+ bsf = 0x0F #Does not perform bridging functions by default
+ bsfField = pack('B',bsf)
+ def createBsf(self, myBsf=None):
+ if myBsf!=None:
+ self.bsf=myBsf
+ self.bsfField = pack('B',self.bsf)
+ print "bsf = "+hex(self.bsf)
+
+ #STEI of the Bridge
+ btei = 0
+ bteiField = pack('B',btei)
+ def createBtei(self, myBtei=None):
+ if myBtei!=None:
+ self.btei=myBtei
+ self.bteiField = pack('B',self.btei)
+ print "btei = "+hex(self.btei)
+
+ #Nbdaber of Bridged destinations
+ nbda = 255
+ nbdaField = pack('B',nbda)
+ def createNbda(self, myNbda=None):
+ if myNbda!=None:
+ self.nbda=myNbda
+ self.nbdaField = pack('B',self.nbda)
+ print "nbda = "+hex(self.nbda)
+
+ #Bridged Destination Addresses
+ bdas = []
+ bdasField = []
+ i = 0
+ while i < nbda:
+ bdas.append(i+0x414442000000)
+ bdasField.append(pack('Q',bdas[i])[0:6])
+ i=i+1
+ def createBdas(self, myNbda=None, myBda=None):
+ print "bdas : "
+ self.createNbda(myNbda)
+ self.i = 0
+ while self.i < self.nbda:
+ if myBda!=None:
+ self.bdas[self.i]=int((myBda+self.i)%pow(2,48))
+ self.bdasField[self.i]=pack('Q',self.bdas[self.i])[0:6]
+ print "bdas["+str(self.i)+"] = "+hex(self.bdas[self.i])
+ self.i = self.i + 1
+
+ #Classifier Rule Set :
+ # - Classifier Rule Set Version
+ # - Number of Classifier Rules
+ # - Classifier Rule Identifier - Classifier Rule Length - Classifier Rule -* Number of Classifier Rules-
+ classifierRuleSetVersion = 0 #Current version by default
+ classifierRuleSetVersionField = pack('B',classifierRuleSetVersion)
+ def createClassifierRuleSetVersion(self, myClassifierRuleSetVersion=None):
+ if myClassifierRuleSetVersion!=None:
+ self.classifierRuleSetVersion=myClassifierRuleSetVersion
+ self.classifierRuleSetVersionField = pack('B',self.classifierRuleSetVersion)
+ print "classifierRuleSetVersion = "+hex(self.classifierRuleSetVersion)
+ numberofClassifierRules = 255 #Max number by default
+ numberofClassifierRulesField = pack('B',numberofClassifierRules)
+ def createNumberofClassifierRules(self, myNumberofClassifierRules=None):
+ if myNumberofClassifierRules!=None:
+ self.numberofClassifierRules=myNumberofClassifierRules
+ self.numberofClassifierRulesField = pack('B',self.numberofClassifierRules)
+ print "numberofClassifierRules = "+hex(self.numberofClassifierRules)
+ classifierRuleIdentifiers = [] #Ethernet_Destination_Address_Identifier by default
+ classifierRuleLengths = [] #Ethernet_Destination_Address_Identifier Length by default
+ i=0
+ classifierRuleIdentifiersField = []
+ classifierRuleLengthsField = []
+ while i<numberofClassifierRules:
+ classifierRuleIdentifiers.append(Ethernet_Destination_Address_Identifier)
+ classifierRuleIdentifiersField.append(pack('B',classifierRuleIdentifiers[i]))
+ classifierRuleLengths.append(classifierRuleSize[classifierRuleIdentifiers[i]])
+ classifierRuleLengthsField.append(pack('B',classifierRuleLengths[i]))
+ i=i+1
+ def createClassifierRuleIdentifiersNLengths(self, myNumberofClassifierRules=None, myClassifierRuleIdentifier=None):
+ print "classifierRuleIdentifiers and classifierRuleLengths :"
+ self.createNumberofClassifierRules(myNumberofClassifierRules)
+ self.i = 0
+ while self.i < self.numberofClassifierRules:
+ if myClassifierRuleIdentifier!=None:
+ self.classifierRuleIdentifiers[self.i]=myClassifierRuleIdentifier
+ self.classifierRuleIdentifiersField[self.i]=pack('B',self.classifierRuleIdentifiers[self.i])
+ print "classifierRuleIdentifiers["+str(self.i)+"] = "+hex(self.classifierRuleIdentifiers[self.i])
+ self.classifierRuleLengths[self.i]=classifierRuleSize[self.classifierRuleIdentifiers[self.i]]
+ self.classifierRuleLengthsField[self.i]=pack('B',self.classifierRuleLengths[self.i])
+ print "classifierRuleLengths["+str(self.i)+"] = "+hex(self.classifierRuleLengths[self.i])
+ self.i = self.i + 1
+ classifierRules = [] #Ethernet_Destination_Address_Identifier Rule by default
+ i=0
+ classifierRulesField = []
+ while i<numberofClassifierRules:
+ classifierRules.append(0x644168744500+i)
+ if classifierRuleSize[classifierRuleIdentifiers[i]] <= 8:
+ classifierRulesField.append(pack('Q',classifierRules[i])[0:classifierRuleSize[classifierRuleIdentifiers[i]]])
+ elif classifierRuleSize[classifierRuleIdentifiers[i]] <= 16:
+ classifierRulesField.append(pack('Q',classifierRules[i]%pow_2_64)+pack('Q',classifierRules[i]/pow_2_64)[0:classifierRuleSize[classifierRuleIdentifiers[i]]-8])
+ i=i+1
+ def createClassifierRules(self, myClassifierRules=None):
+ self.i=0
+ while self.i<self.numberofClassifierRules:
+ if myClassifierRules!=None:
+ self.classifierRules[self.i]=myClassifierRules
+ if classifierRuleSize[self.classifierRuleIdentifiers[self.i]] <= 8:
+ self.classifierRulesField[self.i]=pack('Q',self.classifierRules[self.i])[0:classifierRuleSize[self.classifierRuleIdentifiers[self.i]]]
+ elif classifierRuleSize[self.classifierRuleIdentifiers[self.i]] <= 16:
+ self.classifierRulesField[self.i]=pack('Q',self.classifierRules[self.i]%pow_2_64)+pack('Q',self.classifierRules[self.i]/pow_2_64)[0:classifierRuleSize[self.classifierRuleIdentifiers[self.i]]-8]
+ print "classifierRules["+str(self.i)+"] = "+hex(self.classifierRules[self.i])
+ self.i=self.i+1
+ classifierRuleSetField = classifierRuleSetVersionField + numberofClassifierRulesField
+ i=0
+ while i<numberofClassifierRules:
+ classifierRuleSetField = classifierRuleSetField + classifierRuleIdentifiersField[i] + classifierRuleLengthsField[i] + classifierRulesField[i]
+ i=i+1
+ def createClassifierRuleSetField(self, myClassifierRuleSetVersion=None, myNumberofClassifierRules=None, myClassifierRuleIdentifier=None, myClassifierRules=None):
+ print "classifierRuleSetField :"
+ self.createClassifierRuleSetVersion(myClassifierRuleSetVersion)
+ self.createClassifierRuleIdentifiersNLengths(myNumberofClassifierRules, myClassifierRuleIdentifier)
+ self.createClassifierRules(myClassifierRules)
+ self.classifierRuleSetField = self.classifierRuleSetVersionField + self.numberofClassifierRulesField
+ self.i = 0
+ while self.i < self.numberofClassifierRules:
+ self.classifierRuleSetField = self.classifierRuleSetField + self.classifierRuleIdentifiersField[self.i] + self.classifierRuleLengthsField[self.i] + self.classifierRulesField[self.i]
+ self.i = self.i + 1
+
+ #Maximum FL_AV in multiples of 1.28µs
+ maxFL_AV = 0x0FFF #5241.6µs by default
+ maxFL_AVField = pack('H',maxFL_AV)
+ def createMaxFL_AV(self, myMaxFL_AV=None):
+ if myMaxFL_AV!=None:
+ self.maxFL_AV=myMaxFL_AV
+ self.maxFL_AVField = pack('H',self.maxFL_AV)
+ print "maxFL_AV = "+hex(self.maxFL_AV)
+
+ #Response Interframe Spacing for MPDUs with one OFDM Symbol
+ rifs_AV_OneSym = 0x18 #30.72µs by default
+ rifs_AV_OneSymField = pack('B',rifs_AV_OneSym)
+ def createRifs_AV_OneSym(self, myRifs_AV_OneSym=None):
+ if myRifs_AV_OneSym!=None:
+ self.rifs_AV_OneSym=myRifs_AV_OneSym
+ self.rifs_AV_OneSymField = pack('B',self.rifs_AV_OneSym)
+ print "rifs_AV_OneSym = "+hex(self.rifs_AV_OneSym)
+
+ #Response Interframe Spacing for MPDUs with two OFDM Symbols
+ rifs_AV_TwoSym = 0x18 #30.72µs by default
+ rifs_AV_TwoSymField = pack('B',rifs_AV_TwoSym)
+ def createRifs_AV_TwoSym(self, myRifs_AV_TwoSym=None):
+ if myRifs_AV_TwoSym!=None:
+ self.rifs_AV_TwoSym=myRifs_AV_TwoSym
+ self.rifs_AV_TwoSymField = pack('B',self.rifs_AV_TwoSym)
+ print "rifs_AV_TwoSym = "+hex(self.rifs_AV_TwoSym)
+
+ #Response Interframe Spacing for MPDUs with more than two OFDM Symbols
+ rifs_AV_G2Sym = 0x18 #30.72µs by default
+ rifs_AV_G2SymField = pack('B',rifs_AV_G2Sym)
+ def createRifs_AV_G2Sym(self, myRifs_AV_G2Sym=None):
+ if myRifs_AV_G2Sym!=None:
+ self.rifs_AV_G2Sym=myRifs_AV_G2Sym
+ self.rifs_AV_G2SymField = pack('B',self.rifs_AV_G2Sym)
+ print "rifs_AV_G2Sym = "+hex(self.rifs_AV_G2Sym)
+
+ #Response Type
+ respt = 0 #Default Tone Map by default
+ resptField = pack('B',respt)
+ def createRespt(self, myRespt=None):
+ if myRespt!=None:
+ self.respt=myRespt
+ self.resptField = pack('B',self.respt)
+ print "respt = "+hex(self.respt)
+
+ #Maximum number of Tone Map that the receiver can support
+ maxtm = 0x1F #31 Tone Map (equal to max possible) by default
+ maxtmField = pack('B',maxtm)
+ def createMaxtm(self, myMaxtm=None):
+ if myMaxtm!=None:
+ self.maxtm=myMaxtm
+ self.maxtmField = pack('B',self.maxtm)
+ print "maxtm = "+hex(self.maxtm)
+
+ #TMI_AV of the default Tone Map
+ cp_TMI_AV = 0 #MODE ROBO by default
+ cp_TMI_AVField = pack('B',cp_TMI_AV)
+ def createCp_TMI_AV(self, myCp_TMI_AV=None):
+ if myCp_TMI_AV!=None:
+ self.cp_TMI_AV=myCp_TMI_AV
+ self.cp_TMI_AVField = pack('B',self.cp_TMI_AV)
+ print "cp_TMI_AV = "+hex(self.cp_TMI_AV)
+
+ #Sound Control During Contention Period
+ scl_CP = 0 #Without adapted Tone Map by default
+ scl_CPField = pack('B',scl_CP)
+ def createScl_CP(self, myScl_CP=None):
+ if myScl_CP!=None:
+ self.scl_CP=myScl_CP
+ self.scl_CPField = pack('B',self.scl_CP)
+ print "scl_CP = "+hex(self.scl_CP)
+
+ #Sound Control During Contention Free Period
+ scl_CFP = 0 #Without adapted Tone Map by default
+ scl_CFPField = pack('B',scl_CFP)
+ def createScl_CFP(self, myScl_CFP=None):
+ if myScl_CFP!=None:
+ self.scl_CFP=myScl_CFP
+ self.scl_CFPField = pack('B',self.scl_CFP)
+ print "scl_CFP = "+hex(self.scl_CFP)
+
+ #Number of entries in the valid TMI_AV List
+ ntmi_AV = min(maxtm,MAX_TONE_MAPS) #Max 7 by default
+ ntmi_AVField = pack('B',ntmi_AV)
+ def createNtmi_AV(self, myNtmi_AV=None):
+ if myNtmi_AV!=None:
+ self.ntmi_AV=min(self.maxtm,MAX_TONE_MAPS,myNtmi_AV)
+ self.ntmi_AVField = pack('B',self.ntmi_AV)
+ print "ntmi_AV = "+hex(self.ntmi_AV)
+
+ #TMI_AV
+ tmi_AVs = []
+ tmi_AVsField = []
+ i = 0
+ while i < ntmi_AV:
+ tmi_AVs.append(0) #MODE ROBO by default
+ tmi_AVsField.append(pack('B',tmi_AVs[i]))
+ i=i+1
+ def createTmi_AV(self, myNtmi_AV=None, myTmi_AV=None):
+ print "tmi_AVs : "
+ self.createNtmi_AV(myNtmi_AV)
+ self.i = 0
+ while self.i < self.ntmi_AV:
+ if myTmi_AV!=None:
+ self.tmi_AVs[self.i]=myTmi_AV
+ self.tmi_AVsField[self.i]=pack('B',self.tmi_AVs[self.i])
+ print "tmi_AVs["+str(self.i)+"] = "+hex(self.tmi_AVs[self.i])
+ self.i = self.i + 1
+
+ #Number of Intervals
+ nint = 32 #Max 32 by default
+ nintField = pack('B',nint)
+ def createNint(self, myNint=None):
+ if myNint!=None:
+ self.nint=min(self.maxtm,MAX_TONE_MAPS,myNint)
+ self.nintField = pack('B',self.nint)
+ print "nint = "+hex(self.nint)
+
+ #End Time and TMI_AV of the AC Line
+ ets = []
+ etsField = []
+ int_TMI_AVs = []
+ int_TMI_AVsField = []
+ i = 0
+ ets.append(int(randrange(0,3906/(nint-i),1)))
+ i=i+1
+ while i < nint-1:
+ ets.append(int(randrange(ets[i-1],((3906-ets[i-1])/(nint-i))+ets[i-1],1))) #Random End Time by default
+ i=i+1
+ ets.append(3907)
+ i=i+1
+ i=0
+ while i < nint:
+ etsField.append(pack('H',ets[i]))
+ i=i+1
+ i=0
+ while i < nint:
+ int_TMI_AVs.append(randrange(0,maxtm,1)) #Random MODE by default
+ int_TMI_AVsField.append(pack('B',int_TMI_AVs[i]))
+ i=i+1
+
+ def createEtNInt_TMI_AV(self, myNint=None, myRandomEt=False, myInt_TMI_AV=None, myRandomInt_TMI_AV=False):
+ self.createNint(myNint)
+ print "ets : "
+ if myRandomEt==True:
+ self.i=0
+ self.ets[self.i]=int(randrange(0,3906/(self.nint-self.i),1))
+ self.i=self.i+1
+ while self.i < self.nint-1:
+ self.ets[self.i]=int(randrange(self.ets[self.i-1],((3906-self.ets[self.i-1])/(self.nint-self.i))+self.ets[self.i-1],1)) #Random End Time by default
+ self.i=self.i+1
+ self.ets[self.i]=3907
+ self.i=self.i+1
+ self.i=0
+ while self.i < self.nint:
+ self.etsField[self.i]=pack('H',self.ets[self.i])
+ print "ets["+str(self.i)+"] = "+hex(self.ets[self.i])
+ self.i=self.i+1
+ print "int_TMI_AVs : "
+ self.i=0
+ while self.i < self.nint:
+ if myInt_TMI_AV!=None:
+ self.int_TMI_AVs[self.i]=min(0x1F,myInt_TMI_AV)
+ elif myRandomInt_TMI_AV==True:
+ self.int_TMI_AVs[self.i]=randrange(0,self.maxtm,1) #Random MODE by default
+ self.int_TMI_AVsField[self.i]=pack('B',self.int_TMI_AVs[self.i])
+ print "int_TMI_AVs["+str(self.i)+"] = "+hex(self.int_TMI_AVs[self.i])
+ self.i=self.i+1
+
+ #TMI_AV of the attached Tone Map
+ newTMI_AV = 0 #MODE ROBO by default
+ newTMI_AVField = pack('B',newTMI_AV)
+ def createNewTMI_AV(self, myNewTMI_AV=None):
+ if myNewTMI_AV!=None:
+ self.newTMI_AV=myNewTMI_AV
+ self.newTMI_AVField = pack('B',self.newTMI_AV)
+ print "newTMI_AV = "+hex(self.newTMI_AV)
+
+ #CP Flag for the new Tone Map
+ cpf = 0 #Shall not be applied by default
+ cpfField = pack('B',cpf)
+ def createCpf(self, myCpf=None):
+ if myCpf!=None:
+ self.cpf=myCpf
+ self.cpfField = pack('B',self.cpf)
+ print "cpf = "+hex(self.cpf)
+
+ #FEC Type/Code Rate
+ fecType = 0 #1/2 rate Turbo Convolution Encoder by default
+ fecTypeField = pack('B',fecType)
+ def createFecType(self, myFecType=None):
+ if myFecType!=None:
+ self.fecType=myFecType
+ self.fecTypeField = pack('B',self.fecType)
+ print "fecType = "+hex(self.fecType)
+
+ #Guard Interval Length
+ gil = 0 #GI 417 by default
+ gilField = pack('B',gil)
+ def createGil(self, myGil=None):
+ if myGil!=None:
+ self.gil=myGil
+ self.gilField = pack('B',self.gil)
+ print "gil = "+hex(self.gil)
+
+ #Carrier Bit Loading Data Encoding
+ cbd_Enc = 0 #Carrier Bit Loading Data With Binary Encoding by default
+ cbd_EncField = pack('B',cbd_Enc)
+ def createCbd_Enc(self, myCbd_Enc=None):
+ if myCbd_Enc!=None:
+ self.cbd_Enc=myCbd_Enc
+ self.cbd_EncField = pack('B',self.cbd_Enc)
+ print "cbd_Enc = "+hex(self.cbd_Enc)
+
+ #Number of Carrier Bit Loading Data Entries
+ cbd_Len = 1155 #Maximum Number of carrier by default
+ cbd_LenField = pack('H',cbd_Len)
+ def createCbd_Len(self, myCbd_Len=None):
+ if myCbd_Len!=None:
+ self.cbd_Len=myCbd_Len
+ self.cbd_LenField = pack('H',self.cbd_Len)
+ print "cbd_Len = "+hex(self.cbd_Len)
+
+ #Carrier Bit Loading Data
+ cbds = []
+ cbdsField = []
+ i = 0
+ while i < cbd_Len:
+ cbds.append(1) #BPSK by default
+ i=i+1
+ cbds.append(0) #PAD (in case cbd_Len is an odd number)
+ i = 0
+ while i < cbd_Len + (cbd_Len % 2):
+ cbdsField.append(pack('B',cbds[i] + cbds[i+1]*pow(2,4)))
+ i=i+2
+ def createCbd(self, myCbd_Len=None, myCbd=None):
+ self.createCbd_Len(myCbd_Len)
+ print "cbds : "
+ if myCbd!=None:
+ self.i = 0
+ while self.i < self.cbd_Len + (self.cbd_Len % 2):
+ self.cbds[self.i]=myCbd
+ self.cbds[self.i+1]=myCbd
+ self.i=self.i+2
+ self.cbds[self.cbd_Len]=0
+ self.i = 0
+ while self.i < self.cbd_Len + (self.cbd_Len % 2):
+ self.cbdsField[self.i/2] = pack('B',self.cbds[self.i]+(self.cbds[self.i+1]*pow(2,4)))
+ print "cbds["+str(self.i)+"] = "+hex(self.cbds[self.i])
+ print "cbds["+str(self.i+1)+"] = "+hex(self.cbds[self.i+1])
+ self.i = self.i + 2
+
+ #TMI_AV of the Tone Map to update
+ oldTMI_AV = 0 #MODE ROBO by default
+ oldTMI_AVField = pack('B',oldTMI_AV)
+ def createOldTMI_AV(self, myOldTMI_AV=None):
+ if myOldTMI_AV!=None:
+ self.oldTMI_AV=myOldTMI_AV
+ self.oldTMI_AVField = pack('B',self.oldTMI_AV)
+ print "oldTMI_AV = "+hex(self.oldTMI_AV)
+
+ #Number of Carrier Bit Loading Update Data Entries
+ cbud_Len = 1155 #Maximum Number of carrier by default
+ cbud_LenField = pack('H',cbud_Len)
+ def createCbud_Len(self, myCbud_Len=None):
+ if myCbud_Len!=None:
+ self.cbud_Len=myCbud_Len
+ self.cbud_LenField = pack('H',self.cbud_Len)
+ print "cbud_Len = "+hex(self.cbud_Len)
+
+ #Carrier Bit Loading Update Data
+ cbuds = []
+ cbudsIndex = []
+ cbudsModulation = []
+ cbudsField = []
+ i = 0
+ while i < cbud_Len:
+ cbudsIndex.append(i)
+ cbudsModulation.append(1) #BPSK by default
+ cbuds.append(cbudsIndex[i]+cbudsModulation[i]*pow(2,12))
+ cbudsField.append(pack('H',cbuds[i]))
+ i=i+1
+ def createCbud(self, myCbud_Len=None, myCbudModulation=None):
+ self.createCbud_Len(myCbud_Len)
+ print "cbuds : "
+ if myCbudModulation!=None:
+ self.i = 0
+ while self.i < self.cbud_Len:
+ self.cbudsModulation[self.i]=myCbudModulation
+ self.i=self.i+1
+ self.i = 0
+ while self.i < self.cbud_Len:
+ self.cbuds[self.i] = int(self.cbudsIndex[self.i]+self.cbudsModulation[self.i]*pow(2,12))
+ self.cbudsField[self.i] = pack('H',self.cbuds[self.i])
+ print "cbuds["+str(self.i)+"] = "+hex(self.cbuds[self.i])
+ self.i = self.i + 1
+
+ #AES Encryption Initialization Vector
+ iv = randrange(0,pow(2,128)-1,1) #Random by default
+ ivField = pack('Q',iv%pow_2_64)+pack('Q',iv/pow_2_64)
+ def createIv(self, myIv=None, myRandomIv=False):
+ try:
+ if myIv!=None:
+ self.iv=myIv
+ elif myRandomIv==True :
+ self.iv=randrange(0,pow(2,16*8)-1,1)
+ self.ivField = pack('Q',self.iv%pow_2_64)+pack('Q',self.iv/pow_2_64)
+ except:
+ if myIv!=None:
+ self.ivField=myIv
+ self.iv = unpack('QQ',self.ivField[:16])[0]+unpack('QQ',self.ivField[:16])[1]*pow_2_64
+ print "iv = "+hex(self.iv)
+
+ #Universaly Unique Identifier
+ uuid = randrange(0,pow(2,16*8)-1,1) #Random by default
+ uuidField = pack('Q',uuid%pow_2_64)+pack('Q',uuid/pow_2_64)
+ def createUuid(self, myUuid=None, myRandomUuid=False):
+ try:
+ if myUuid!=None:
+ self.uuid=myUuid
+ elif myRandomUuid==True :
+ self.uuid=randrange(0,pow(2,16*8)-1,1)
+ self.uuidField = pack('Q',self.uuid%pow_2_64)+pack('Q',self.uuid/pow_2_64)
+ except:
+ if myUuid!=None:
+ self.uuidField=myUuid
+ elif myRandomUuid==True :
+ self.uuidFied = pack('Q',randrange(0,pow(2,8*8)-1,1))+pack('Q',randrange(0,pow(2,8*8)-1,1))
+ randrange(0,pow(2,16*8)-1,1)
+ self.uuid = unpack('QQ',self.uuidField[:16])[0] + unpack('QQ',self.uuidField[:16])[1]*pow_2_64
+ #int(unpack('QQ',self.uuidField)[0]+unpack('QQ',self.uuidField)[1]*pow(2,8*8))
+ print "uuid = "+hex(self.uuid)
+
+ #Length of the Random Filler
+ rfLenEncrypted = 1
+ rfLenEncryptedField = pack('B',rfLenEncrypted)
+ def createRfLenEncrypted(self, myRfLenEncrypted=None):
+ try:
+ if myRfLenEncrypted!=None:
+ self.rfLenEncrypted = myRfLenEncrypted
+ else:
+ self.rfLenEncrypted = randrange(0,15,1)
+ self.rfLenEncryptedField = pack('B',self.rfLenEncrypted)
+ except:
+ if myRfLenEncrypted!=None:
+ self.rfLenEncryptedField = myRfLenEncrypted
+ self.rfLenEncrypted = unpack('B',self.rfLenEncrypted[0])[0]
+ print "rfLenEncrypted = "+hex(self.rfLenEncrypted)
+
+ #Encrypted Random Filler
+ randomFillerEncrypted = 0x41
+ randomFillerEncryptedField = ""
+ def createRandomFillerEncrypted(self, myRfLenEncrypted=None, myRandomFillerEncrypted=None):
+ self.createRfLenEncrypted(myRfLenEncrypted)
+ try:
+ if myRandomFillerEncrypted!=None:
+ self.randomFillerEncrypted=myRandomFillerEncrypted
+ elif self.rfLenEncrypted != 0:
+ self.randomFillerEncrypted=randrange(0,pow(2,self.rfLenEncrypted*8)-1,1)
+ if self.rfLenEncrypted == 0:
+ self.randomFillerEncryptedField = ""
+ self.randomFillerEncrypted=None
+ print "randomFillerEncrypted = None"
+ elif self.rfLenEncrypted <= 8:
+ self.randomFillerEncryptedField=pack('Q',self.randomFillerEncrypted)[0:self.rfLenEncrypted]
+ print "randomFillerEncrypted = "+hex(self.randomFillerEncrypted)
+ elif self.rfLenEncrypted <= 15:
+ self.randomFillerEncryptedField=pack('Q',self.randomFillerEncrypted%pow_2_64)+pack('Q',self.randomFillerEncrypted/pow_2_64)[0:self.rfLenEncrypted-8]
+ print "randomFillerEncrypted = "+hex(self.randomFillerEncrypted)
+ except:
+ if myRandomFillerEncrypted!=None:
+ self.randomFillerEncryptedField=myRandomFillerEncrypted
+ if self.rfLenEncrypted == 0:
+ self.randomFillerEncrypted = None
+ print "randomFillerEncrypted = None"
+ elif self.rfLenEncrypted <= 8:
+ self.randomFillerEncrypted=unpack('QQ',self.randomFillerEncryptedField[:self.rfLenEncrypted]+"\x00"*(16-self.rfLenEncrypted))[0]
+ print "randomFillerEncrypted = "+hex(self.randomFillerEncrypted)
+ elif self.rfLenEncrypted <= 15:
+ self.randomFillerEncrypted = unpack('QQ',self.randomFillerEncryptedField[:self.rfLenEncrypted]+"\x00"*(16-self.rfLenEncrypted))[0]+unpack('QQ',self.randomFillerEncryptedField[:self.rfLenEncrypted]+"\x00"*(16-self.rfLenEncrypted))[1]*pow_2_64
+ print "randomFillerEncrypted = "+hex(self.randomFillerEncrypted)
+
+ #Encrypted MM or HLE Payload
+ mmOrHlePayloadEncryptedField = ""
+ def createMmOrHlePayloadEncrypted(self, myPid=None, myOda=None, myOsa=None, myVlanTag=None, myMtype=None, myMmv=None, myMmtype=None, myNfmi=None, myFnMi=None, myFmsn=None, myMmentry=None, myEncapsulatedMmEntry=None, myMmOrHlePayloadEncrypted=None):
+ if myMmentry==None:
+ myMmentry = self.mmentry
+ if myMtype==None:
+ myMtype = self.mmtype
+ if myPid==4:
+ self.mmOrHlePayloadEncryptedField = myMmOrHlePayloadEncrypted
+ else:
+ self.mmOrHlePayloadEncryptedField = myEncapsulatedMme.createEncapsulatedMmEntry(myOda, myOsa, myVlanTag, myMtype, myMmv, myMmtype, myNfmi, myFnMi, myFmsn, myMmentry, myEncapsulatedMmEntry)
+ #print "mmOrHlePayloadEncrypted = "+self.mmOrHlePayloadEncryptedField
+
+ #Length of Encrypted MM or HLE Payload
+ lengthForEncryption = len(mmOrHlePayloadEncryptedField)
+ lengthForEncryptionField = pack('H',lengthForEncryption)
+ def createLengthForEncryption(self, myLengthForEncryption=None):
+ if myLengthForEncryption!=None:
+ try:
+ self.lengthForEncryption = myLengthForEncryption
+ self.lengthForEncryptionField = pack('H',self.lengthForEncryption)
+ except:
+ self.lengthForEncryptionField = myLengthForEncryption
+ self.lengthForEncryption = unpack('H',self.lengthForEncryptionField[:2])[0]
+ else:
+ self.lengthForEncryption = len(self.mmOrHlePayloadEncryptedField)
+ self.lengthForEncryptionField = pack('H',self.lengthForEncryption)
+ print "lengthForEncryption = "+hex(self.lengthForEncryption)
+
+ #Encrypted CRC of the MM or HLE Payload
+ crcEncrypted = 0x41424344
+ crcEncryptedField = pack('I',crcEncrypted)
+ def createCrcEncrypted(self, myCrcEncrypted=None):
+ if myCrcEncrypted!=None:
+ try:
+ self.crcEncryptedField = myCrcEncrypted
+ self.crcEncrypted = unpack('I',self.crcEncryptedField[:4])[0]
+ except:
+ self.crcEncrypted = myCrcEncrypted
+ self.crcEncryptedField = pack('I',self.crcEncrypted)
+ else:
+ self.crcEncrypted = unpack('I',pack('i',crc32(self.mmOrHlePayloadEncryptedField)))[0]
+ self.crcEncryptedField = pack('I',self.crcEncrypted)
+ print "crcEncrypted = "+hex(self.crcEncrypted)
+
+ #Encrypted PRN
+ prnEncrypted = 0x4142
+ prnEncryptedField = pack('H',prnEncrypted)
+ def createPrnEncrypted(self, myPrnEncrypted=None, myRandomPrn=None):
+ if myPrnEncrypted!=None:
+ try:
+ self.prnEncrypted = myPrnEncrypted
+ self.prnEncryptedField = pack('H',self.prnEncrypted)
+ except:
+ self.prnEncryptedField = myPrnEncrypted
+ self.prnEncrypted = unpack('H',self.prnEncryptedField[:2])[0]
+ elif myRandomPrn == True:
+ self.prnEncrypted = randrange(0,pow(2,16)-1,1)
+ self.prnEncryptedField = pack('H',self.prnEncrypted)
+ else:
+ self.prnEncryptedField = pack('H',self.prnEncrypted)
+ print "prnEncrypted = "+hex(self.prnEncrypted)
+
+ #Encrypted PMN
+ pmnEncrypted = 0x00
+ pmnEncryptedField = pack('B',pmnEncrypted)
+ def createPmnEncrypted(self, myPmnEncrypted=None):
+ if myPmnEncrypted!=None:
+ try:
+ self.pmnEncryptedField = myPmnEncrypted
+ self.pmnEncrypted = unpack('B',self.pmnEncryptedField[0])[0]
+ except:
+ self.pmnEncrypted = myPmnEncrypted
+ self.pmnEncryptedField = pack('B',self.pmnEncrypted)
+ else:
+ self.pmnEncryptedField = pack('B',self.pmnEncrypted)
+ print "pmnEncrypted = "+hex(self.pmnEncrypted)
+
+ #Encrypted Padding
+ paddingEncrypted = 0
+ paddingEncryptedSize = (16 - (len(randomFillerEncryptedField + mmOrHlePayloadEncryptedField + crcEncryptedField + pidField + prnEncryptedField + pmnEncryptedField + rfLenEncryptedField)%16))%16
+ if paddingEncryptedSize <= 8:
+ paddingEncryptedField=pack('Q',paddingEncrypted)[0:paddingEncryptedSize]
+ elif paddingEncryptedSize <= 15:
+ paddingEncryptedField = pack('Q',paddingEncrypted%pow_2_64) + pack('Q',paddingEncrypted/pow_2_64)[0:paddingEncryptedSize-8]
+ def createPaddingEncrypted(self, myPaddingEncrypted=None):
+ self.paddingEncryptedSize = (16 - (len(self.randomFillerEncryptedField + self.mmOrHlePayloadEncryptedField + self.crcEncryptedField + self.pidField + self.prnEncryptedField + self.pmnEncryptedField + self.rfLenEncryptedField)%16))%16
+ if myPaddingEncrypted!=None:
+ try:
+ self.paddingEncryptedSize = len(myPaddingEncrypted)
+ self.paddingEncryptedField = myPaddingEncrypted
+ if self.paddingEncryptedSize == 0:
+ self.paddingEncrypted=None
+ elif self.paddingEncryptedSize <= 8:
+ self.paddingEncrypted=unpack('QQ',self.paddingEncryptedField[:len(self.paddingEncryptedField)]+"\x00"*(16-len(self.paddingEncryptedField)))[0]
+ elif self.paddingEncryptedSize <= 15:
+ self.paddingEncrypted = unpack('QQ',self.paddingEncryptedField[:len(self.paddingEncryptedField)]+"\x00"*(16-len(self.paddingEncryptedField)))[0] + unpack('QQ',self.paddingEncryptedField[:len(self.paddingEncryptedField)]+"\x00"*(16-len(self.paddingEncryptedField)))[1] * pow_2_64
+ except:
+ self.paddingEncrypted = myPaddingEncrypted
+ self.paddingEncryptedField=""
+ while myPaddingEncrypted > 0:
+ self.paddingEncryptedField = self.paddingEncryptedField + pack('B',myPaddingEncrypted%256)
+ myPaddingEncrypted = int(myPaddingEncrypted / 256)
+ self.paddingEncryptedSize = len(self.paddingEncryptedField)
+ elif self.paddingEncryptedSize != 0:
+ self.paddingEncrypted = randrange(0,pow(2,self.paddingEncryptedSize*8)-1,1)
+ if self.paddingEncryptedSize == 0:
+ self.paddingEncryptedField=""
+ print "paddingEncrypted = None"
+ elif self.paddingEncryptedSize <= 8:
+ self.paddingEncryptedField=pack('Q',self.paddingEncrypted)[0:self.paddingEncryptedSize]
+ print "paddingEncrypted = "+hex(self.paddingEncrypted)
+ elif self.paddingEncryptedSize <= 15:
+ self.paddingEncryptedField = pack('Q',self.paddingEncrypted%pow_2_64) + pack('Q',self.paddingEncrypted/pow_2_64)[0:self.paddingEncryptedSize-8]
+ print "paddingEncrypted = "+hex(self.paddingEncrypted)
+
+ #Reason Code
+ reasonCode = 0 #MME not supported by default
+ reasonCodeField = pack('B',reasonCode)
+ def createReasonCode(self, myReasonCode=None):
+ if myReasonCode!=None:
+ try:
+ self.reasonCode=myReasonCode
+ self.reasonCodeField = pack('B',self.reasonCode)
+ except:
+ self.reasonCodeField=myReasonCode
+ self.reasonCode = unpack('B',self.reasonCodeField[0])[0]
+ print "reasonCode = "+hex(self.reasonCode)
+
+ #Management Message Version of the received MME
+ rx_MMV = 0 #1.0 by default
+ rx_MMVField = pack('B',rx_MMV)
+ def createRx_MMV(self, myRx_MMV=None):
+ if myRx_MMV!=None:
+ try:
+ self.rx_MMV=myRx_MMV
+ self.rx_MMVField = pack('B',self.rx_MMV)
+ except:
+ self.rx_MMVField=myRx_MMV
+ self.rx_MMV = unpack('B',self.rx_MMVField[0])[0]
+ print "rx_MMV = "+hex(self.rx_MMV)
+
+ #Management Message Type of the received MME
+ rx_MMTYPE = 0 #1.0 by default
+ rx_MMTYPEField = pack('H',rx_MMTYPE)
+ def createRx_MMTYPE(self, myRx_MMTYPE=None):
+ if myRx_MMTYPE!=None:
+ try:
+ self.rx_MMTYPE=myRx_MMTYPE
+ self.rx_MMTYPEField = pack('H',self.rx_MMTYPE)
+ except:
+ self.rx_MMTYPEField=myRx_MMTYPE
+ self.rx_MMTYPE = unpack('H',self.rx_MMTYPEField[:2])[0]
+ print "rx_MMTYPE = "+hex(self.rx_MMTYPE)
+
+ #Byte offset of first or only invalid field in MME
+ invalidByteOffset = 0 #First octet by default
+ invalidByteOffsetField = pack('H',invalidByteOffset)
+ def createInvalidByteOffset(self, myInvalidByteOffset=None):
+ if myInvalidByteOffset!=None:
+ try:
+ self.invalidByteOffset=myInvalidByteOffset
+ self.invalidByteOffsetField = pack('H',self.invalidByteOffset)
+ except:
+ self.invalidByteOffsetField=myInvalidByteOffset
+ self.invalidByteOffset = unpack('H',self.invalidByteOffsetField[:2])[0]
+ print "invalidByteOffset = "+hex(self.invalidByteOffset)
+
+ #LLID-R
+ llidR = 0
+ llidRField = pack('B',llidR)
+ def createLlidR(self, myLlidR=None):
+ if myLlidR!=None:
+ self.llidR=myLlidR
+ self.llidFieldR = pack('B',self.llidR)
+ print "llidR = "+hex(self.llidR)
+
+ #Number of connection
+ numConn = 255
+ numConnField = pack('B',numConn)
+ def createNumConn(self, myNumConn=None):
+ if myNumConn!=None:
+ self.numConn=myNumConn
+ self.numConnField = pack('B',self.numConn)
+ print "numConn = "+hex(self.numConn)
+
+ #Connection Informations
+ connInfos = []
+ i = 0
+ while i < numConn:
+ connInfos.append(ConnInfo())
+ i=i+1
+ def createConnInfos(self, myNumConn=None, myTei=None, myLlidF=None, myStei=None, myDtei=None, myLidF=None, myLidR=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ self.createNumConn(myNumConn)
+ self.i = 0
+ while self.i < self.numConn:
+ print "connInfos["+str(self.i)+"] :"
+ self.connInfos[self.i].createConnInfo(myTei, myLlidF, myStei, myDtei, myLidF, myLidR, myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.i = self.i + 1
+
+ #HomePlug AV Version
+ avVersion = 0 #Current and only version by default
+ avVersionField = pack('B',avVersion)
+ def createAvVersion(self, myAvVersion=None):
+ if myAvVersion!=None:
+ self.avVersion=myAvVersion
+ self.avVersionField = pack('B',self.avVersion)
+ print "avVersion = "+hex(self.avVersion)
+
+ #Organizationnaly Unique Identifier
+ oui = 0x49554F
+ ouiField = pack('I',oui)[0:3]
+ def createOui(self, myOui=None):
+ if myOui!=None:
+ self.oui = myOui
+ self.ouiField = pack('I',self.oui)[0:3]
+ print "oui = "+hex(self.oui)
+
+ #Auto Connect Capability
+ autoConnect = 0 #Not supported by default
+ autoConnectField = pack('B',autoConnect)
+ def createAutoConnect(self, myAutoConnect=None):
+ if myAutoConnect!=None:
+ self.autoConnect=myAutoConnect
+ self.autoConnectField = pack('B',self.autoConnect)
+ print "autoConnect = "+hex(self.autoConnect)
+
+ #Smoothing Capability
+ smoothing = 0 #Not supported by default
+ smoothingField = pack('B',smoothing)
+ def createSmoothing(self, mySmoothing=None):
+ if mySmoothing!=None:
+ self.smoothing=mySmoothing
+ self.smoothingField = pack('B',self.smoothing)
+ print "smoothing = "+hex(self.smoothing)
+
+ #Proxy Capability
+ proxyCapable = 0 #Not capable by default
+ proxyCapableField = pack('B',proxyCapable)
+ def createProxyCapable(self, myProxyCapable=None):
+ if myProxyCapable!=None:
+ self.proxyCapable=myProxyCapable
+ self.proxyCapableField = pack('B',self.proxyCapable)
+ print "proxyCapable = "+hex(self.proxyCapable)
+
+ #Backup CCo-capable
+ backupCcoCapable = 0 #Not supported by default
+ backupCcoCapableField = pack('B',backupCcoCapable)
+ def createBackupCcoCapable(self, myBackupCcoCapable=None):
+ if myBackupCcoCapable!=None:
+ self.backupCcoCapable=myBackupCcoCapable
+ self.backupCcoCapableField = pack('B',self.backupCcoCapable)
+ print "backupCcoCapable = "+hex(self.backupCcoCapable)
+
+ #Soft Hand Over Support
+ softHandOver = 0 #Not supported by default
+ softHandOverField = pack('B',softHandOver)
+ def createSoftHandOver(self, mySoftHandOver=None):
+ if mySoftHandOver!=None:
+ self.softHandOver=mySoftHandOver
+ self.softHandOverField = pack('B',self.softHandOver)
+ print "softHandOver = "+hex(self.softHandOver)
+
+ #Two Symbol Frame Control
+ twoSymFc = 0 #Not supported by default
+ twoSymFcField = pack('B',twoSymFc)
+ def createTwoSymFc(self, myTwoSymFc=None):
+ if myTwoSymFc!=None:
+ self.twoSymFc=myTwoSymFc
+ self.twoSymFcField = pack('B',self.twoSymFc)
+ print "twoSymFc = "+hex(self.twoSymFc)
+
+ #Ability to support Enhanced Coexistance with HomePlug 1.1
+ homePlug11Cap = 0 #Not capable by default
+ homePlug11CapField = pack('B',homePlug11Cap)
+ def createHomePlug11Cap(self, myHomePlug11Cap=None):
+ if myHomePlug11Cap!=None:
+ self.homePlug11Cap=myHomePlug11Cap
+ self.homePlug11CapField = pack('B',self.homePlug11Cap)
+ print "homePlug11Cap = "+hex(self.homePlug11Cap)
+
+ #HomePlug 1.0.1 Interoperability
+ homePlug10Interop = 0 #Not capable by default
+ homePlug10InteropField = pack('B',homePlug10Interop)
+ def createHomePlug10Interop(self, myHomePlug10Interop=None):
+ if myHomePlug10Interop!=None:
+ self.homePlug10Interop=myHomePlug10Interop
+ self.homePlug10InteropField = pack('B',self.homePlug10Interop)
+ print "homePlug10Interop = "+hex(self.homePlug10Interop)
+
+ #Capability of Operating in Various Regulatory Domains
+ regulatoryCap = 0 #North America Only
+ regulatoryCapField = pack('B',regulatoryCap)
+ def createRegulatoryCap(self, myRegulatoryCap=None):
+ if myRegulatoryCap!=None:
+ self.regulatoryCap=myRegulatoryCap
+ self.regulatoryCapField = pack('B',self.regulatoryCap)
+ print "regulatoryCap = "+hex(self.regulatoryCap)
+
+ #Bidirectional Bursting Capability
+ bidirectionalBursting = 0 #Not capable by default
+ bidirectionalBurstingField = pack('B',bidirectionalBursting)
+ def createBidirectionalBursting(self, myBidirectionalBursting=None):
+ if myBidirectionalBursting!=None:
+ self.bidirectionalBursting=myBidirectionalBursting
+ self.bidirectionalBurstingField = pack('B',self.bidirectionalBursting)
+ print "bidirectionalBursting = "+hex(self.bidirectionalBursting)
+
+ #Implementation Version
+ implementationVer = 0 #0 by default
+ implementationVerField = pack('H',implementationVer)
+ def createImplementationVer(self, myImplementationVer=None):
+ if myImplementationVer!=None:
+ self.implementationVer=myImplementationVer
+ self.implementationVerField = pack('H',self.implementationVer)
+ print "implementationVer = "+hex(self.implementationVer)
+
+ #MAC Addresse of the STAs
+ das = []
+ dasField = []
+ i = 0
+ while i < numSta:
+ das.append(i+0x123456789000)
+ dasField.append(pack('Q',das[i])[0:6])
+ i=i+1
+ def createDas(self, myNumSta=None, myDa=None):
+ print "das : "
+ self.createNumSta(myNumSta)
+ self.i = 0
+ while self.i < self.numSta:
+ if myDa!=None:
+ self.das[self.i]=int((myDa+self.i)%pow(2,48))
+ self.dasField[self.i]=pack('Q',self.das[self.i])[0:6]
+ print "das["+str(self.i)+"] = "+hex(self.das[self.i])
+ self.i = self.i + 1
+
+ #Average PHY Data Rate Transmission
+ avgPhyDR_Tx = []
+ avgPhyDR_TxField = []
+ i = 0
+ while i < numSta:
+ avgPhyDR_Tx.append(255-i)
+ avgPhyDR_TxField.append(pack('B',avgPhyDR_Tx[i]))
+ i=i+1
+ def createAvgPhyDR_Tx(self, myNumSta=None, myAvgPhyDR_Tx=None):
+ print "avgPhyDR_Tx : "
+ self.createNumSta(myNumSta)
+ self.i = 0
+ while self.i < self.numSta:
+ if myAvgPhyDR_Tx!=None:
+ self.avgPhyDR_Tx[self.i]=int((myAvgPhyDR_Tx+self.i)%pow(2,48))
+ self.avgPhyDR_TxField[self.i]=pack('B',self.avgPhyDR_Tx[self.i])
+ print "avgPhyDR_Tx["+str(self.i)+"] = "+hex(self.avgPhyDR_Tx[self.i])
+ self.i = self.i + 1
+
+ #Average PHY Data Rate Reception
+ avgPhyDR_Rx = []
+ avgPhyDR_RxField = []
+ i = 0
+ while i < numSta:
+ avgPhyDR_Rx.append(i)
+ avgPhyDR_RxField.append(pack('B',avgPhyDR_Rx[i]))
+ i=i+1
+ def createAvgPhyDR_Rx(self, myNumSta=None, myAvgPhyDR_Rx=None):
+ print "avgPhyDR_Rx : "
+ self.createNumSta(myNumSta)
+ self.i = 0
+ while self.i < self.numSta:
+ if myAvgPhyDR_Rx!=None:
+ self.avgPhyDR_Rx[self.i]=int((myAvgPhyDR_Rx+self.i)%pow(2,48))
+ self.avgPhyDR_RxField[self.i]=pack('B',self.avgPhyDR_Rx[self.i])
+ print "avgPhyDR_Rx["+str(self.i)+"] = "+hex(self.avgPhyDR_Rx[self.i])
+ self.i = self.i + 1
+
+ #das + avgPhyDR_Tx + avgPhyDR_Rx
+ dasAvgPhyDR_TxAvgPhyDR_Rx = []
+ i = 0
+ while i < numSta:
+ dasAvgPhyDR_TxAvgPhyDR_Rx.append(dasField[i]+avgPhyDR_TxField[i]+avgPhyDR_RxField[i])
+ i=i+1
+ def createDasAvgPhyDR_TxAvgPhyDR_Rx(self, myNumSta=None, myDa=None, myAvgPhyDR_Tx=None, myAvgPhyDR_Rx=None):
+ print "dasAvgPhyDR_TxAvgPhyDR_Rx :"
+ #self.createNumSta(myNumSta)
+ self.createDas(myNumSta, myDa)
+ self.createAvgPhyDR_Tx(self.numSta, myAvgPhyDR_Tx)
+ self.createAvgPhyDR_Rx(self.numSta, myAvgPhyDR_Rx)
+ self.i = 0
+ while self.i < self.numSta:
+ self.dasAvgPhyDR_TxAvgPhyDR_Rx[self.i]=self.dasField[self.i]+self.avgPhyDR_TxField[self.i]+self.avgPhyDR_RxField[self.i]
+ self.i = self.i + 1
+
+ #LID
+ lid = 0
+ lidField = pack('B',lid)
+ def createLid(self, myLid=None):
+ if myLid!=None:
+ self.lid=myLid
+ self.lidField = pack('B',self.lid)
+ print "lid = "+hex(self.lid)
+
+ #Transmit Link Flag
+ tlFlag = 0 #Transmit Link by default
+ tlFlagField = pack('B',tlFlag)
+ def createTlFlag(self, myTlFlag=None):
+ if myTlFlag!=None:
+ self.tlFlag=myTlFlag
+ self.tlFlagField = pack('B',self.tlFlag)
+ print "tlFlag = "+hex(self.tlFlag)
+
+ #Management Link Flag
+ mgmt_Flag = 0 #Transmit Link by default
+ mgmt_FlagField = pack('B',mgmt_Flag)
+ def createMgmt_Flag(self, myMgmt_Flag=None):
+ if myMgmt_Flag!=None:
+ self.mgmt_Flag=myMgmt_Flag
+ self.mgmt_FlagField = pack('B',self.mgmt_Flag)
+ print "mgmt_Flag = "+hex(self.mgmt_Flag)
+
+ #Destination or Source MAC Address
+ daSa = 0x4153726F4144 #="DAorSA"
+ daSaField = pack('Q',daSa)[0:6]
+ def createDaSa(self, myDaSa=None):
+ if myDaSa!=None:
+ self.daSa=myDaSa
+ self.daSaField = pack('Q',self.daSa)[0:6]
+ print "daSa = "+hex(self.daSa)
+
+ #Beacon Period Counter
+ beaconPeriodCnt = 0 #0 by default
+ beaconPeriodCntField = pack('H',beaconPeriodCnt)
+ def createBeaconPeriodCnt(self, myBeaconPeriodCnt=None):
+ if myBeaconPeriodCnt!=None:
+ self.beaconPeriodCnt=myBeaconPeriodCnt
+ self.beaconPeriodCntField = pack('H',self.beaconPeriodCnt)
+ print "beaconPeriodCnt = "+hex(self.beaconPeriodCnt)
+
+ #Number of MSDU
+ numMsdus = 0 #0 by default
+ numMsdusField = pack('I',numMsdus)
+ def createNumMsdus(self, myNumMsdus=None):
+ if myNumMsdus!=None:
+ self.numMsdus=myNumMsdus
+ self.numMsdusField = pack('I',self.numMsdus)
+ print "numMsdus = "+hex(self.numMsdus)
+
+ #Number of MSDU Payload octets
+ octets = 0 #0 by default
+ octetsField = pack('I',octets)
+ def createOctets(self, myOctets=None):
+ if myOctets!=None:
+ self.octets=myOctets
+ self.octetsField = pack('I',self.octets)
+ print "octets = "+hex(self.octets)
+
+ #Number of generated segments
+ numSegs = 0 #0 by default
+ numSegsField = pack('I',numSegs)
+ def createNumSegs(self, myNumSegs=None):
+ if myNumSegs!=None:
+ self.numSegs=myNumSegs
+ self.numSegsField = pack('I',self.numSegs)
+ print "numSegs = "+hex(self.numSegs)
+
+ #Number of segments
+ numSeg_Suc = 0 #0 by default
+ numSeg_SucField = pack('I',numSeg_Suc)
+ def createNumSeg_Suc(self, myNumSeg_Suc=None):
+ if myNumSeg_Suc!=None:
+ self.numSeg_Suc=myNumSeg_Suc
+ self.numSeg_SucField = pack('I',self.numSeg_Suc)
+ print "numSeg_Suc = "+hex(self.numSeg_Suc)
+
+ #Number of Dropped segments
+ numSeg_Dropped = 0 #0 by default
+ numSeg_DroppedField = pack('I',numSeg_Dropped)
+ def createNumSeg_Dropped(self, myNumSeg_Dropped=None):
+ if myNumSeg_Dropped!=None:
+ self.numSeg_Dropped=myNumSeg_Dropped
+ self.numSeg_DroppedField = pack('I',self.numSeg_Dropped)
+ print "numSeg_Dropped = "+hex(self.numSeg_Dropped)
+
+ #Number of Missed segments
+ numSeg_Missed = 0 #0 by default
+ numSeg_MissedField = pack('I',numSeg_Missed)
+ def createNumSeg_Missed(self, myNumSeg_Missed=None):
+ if myNumSeg_Missed!=None:
+ self.numSeg_Missed=myNumSeg_Missed
+ self.numSeg_MissedField = pack('I',self.numSeg_Missed)
+ print "numSeg_Missed = "+hex(self.numSeg_Missed)
+
+ #Number of Handed Over PBs
+ numPbs = 0 #0 by default
+ numPbsField = pack('I',numPbs)
+ def createNumPbs(self, myNumPbs=None):
+ if myNumPbs!=None:
+ self.numPbs=myNumPbs
+ self.numPbsField = pack('I',self.numPbs)
+ print "numPbs = "+hex(self.numPbs)
+
+ #number of MPDUs
+ numMpdus = 0 #0 by default
+ numMpdusField = pack('I',numMpdus)
+ def createNumMpdus(self, myNumMpdus=None):
+ if myNumMpdus!=None:
+ self.numMpdus=myNumMpdus
+ self.numMpdusField = pack('I',self.numMpdus)
+ print "numMpdus = "+hex(self.numMpdus)
+
+ #Number of Bursts
+ numBursts = 0 #0 by default
+ numBurstsField = pack('I',numBursts)
+ def createNumBursts(self, myNumBursts=None):
+ if myNumBursts!=None:
+ self.numBursts=myNumBursts
+ self.numBurstsField = pack('I',self.numBursts)
+ print "numBursts = "+hex(self.numBursts)
+
+ #Number of Successfully Acknoledged MPDUs
+ numSacks = 0 #0 by default
+ numSacksField = pack('I',numSacks)
+ def createNumSacks(self, myNumSacks=None):
+ if myNumSacks!=None:
+ self.numSacks=myNumSacks
+ self.numSacksField = pack('I',self.numSacks)
+ print "numSacks = "+hex(self.numSacks)
+
+ #Number of Collected Latency Information Bins
+ numLatBins = 255
+ numLatBinsField = pack('B',numLatBins)
+ def createNumLatBins(self, myNumLatBins=None):
+ if myNumLatBins!=None:
+ self.numLatBins=myNumLatBins
+ self.numLatBinsField = pack('B',self.numLatBins)
+ print "numLatBins = "+hex(self.numLatBins)
+
+ #Number of Failed ICV MAC Frame
+ numIcvFails = 255
+ numIcvFailsField = pack('B',numIcvFails)
+ def createNumIcvFails(self, myNumIcvFails=None):
+ if myNumIcvFails!=None:
+ self.numIcvFails=myNumIcvFails
+ self.numIcvFailsField = pack('B',self.numIcvFails)
+ print "numIcvFails = "+hex(self.numIcvFails)
+
+ #Latency Bin Granularity ( 0 = 1 Beacon Period, 1 and more in milliseconds )
+ latBinGran = 0 #One Beacon Period by default
+ latBinGranField = pack('B',latBinGran)
+ def createLatBinGran(self, myLatBinGran=None):
+ if myLatBinGran!=None:
+ self.latBinGran=myLatBinGran
+ self.latBinGranField = pack('B',self.latBinGran)
+ print "latBinGran = "+hex(self.latBinGran)
+
+ #Number of successfully transmitted PBs with ranged latency
+ latBin = []
+ latBinField = []
+ i = 0
+ while i < numLatBins:
+ latBin.append(i)
+ latBinField.append(pack('I',latBin[i]))
+ i=i+1
+ def createLatBin(self, myNumLatBins=None, myLatBin=None, myRandomLatBin=False):
+ print "latBin : "
+ self.createNumLatBins(myNumLatBins)
+ self.i = 0
+ while self.i < self.numLatBins:
+ if myLatBin!=None:
+ self.latBin[self.i]=int((myLatBin+self.i)%pow(2,32))
+ elif myRandomLatBin==True:
+ self.latBin[self.i]=randrange(0,pow(2,4*8)-1,1)
+ self.latBinField[self.i]=pack('I',self.latBin[self.i])
+ print "latBin["+str(self.i)+"] = "+hex(self.latBin[self.i])
+ self.i = self.i + 1
+
+ #Receive MFS LinkStats
+ receiveMfsLinkStats = beaconPeriodCntField + numMsdusField + octetsField + numSeg_SucField + numSeg_MissedField + numPbsField + numBurstsField + numMpdusField + numIcvFailsField
+ def createReceiveMfsLinkStats(self, myBeaconPeriodCnt=None, myNumMsdus=None, myOctets=None, myNumSeg_Suc=None, myNumSeg_Missed=None, myNumPbs=None, myNumBursts=None, myNumMpdus=None, myNumIcvFails=None):
+ print "receiveMfsLinkStats :"
+ self.createBeaconPeriodCnt(myBeaconPeriodCnt)
+ self.createNumMsdus(myNumMsdus)
+ self.createOctets(myOctets)
+ self.createNumSeg_Suc(myNumSeg_Suc)
+ self.createNumSeg_Missed(myNumSeg_Missed)
+ self.createNumPbs(myNumPbs)
+ self.createNumBursts(myNumBursts)
+ self.createNumMpdus(myNumMpdus)
+ self.createNumIcvFails(myNumIcvFails)
+ self.receiveMfsLinkStats = self.beaconPeriodCntField + self.numMsdusField + self.octetsField + self.numSeg_SucField + self.numSeg_MissedField + self.numPbsField + self.numBurstsField + self.numMpdusField + self.numIcvFailsField
+
+ #Transmit MFS LinkStats
+ transmitMfsLinkStats = beaconPeriodCntField + numMsdusField + octetsField + numSegsField + numSeg_SucField + numSeg_DroppedField + numPbsField + numMpdusField + numBurstsField + numSacksField + numLatBinsField + latBinGranField
+ i = 0
+ while i < numLatBins:
+ transmitMfsLinkStats = transmitMfsLinkStats + latBinField[i]
+ i=i+1
+ def createTransmitMfsLinkStats(self, myBeaconPeriodCnt=None, myNumMsdus=None, myOctets=None, myNumSegs=None, myNumSeg_Suc=None, myNumSeg_Dropped=None, myNumPbs=None, myNumMpdus=None, myNumBursts=None, myNumSacks=None, myNumLatBins=None, myLatBinGran=None, myLatBin=None, myRandomLatBin=False):
+ print "transmitMfsLinkStats :"
+ self.createBeaconPeriodCnt(myBeaconPeriodCnt)
+ self.createNumMsdus(myNumMsdus)
+ self.createOctets(myOctets)
+ self.createNumSegs(myNumSegs)
+ self.createNumSeg_Suc(myNumSeg_Suc)
+ self.createNumSeg_Dropped(myNumSeg_Dropped)
+ self.createNumPbs(myNumPbs)
+ self.createNumMpdus(myNumMpdus)
+ self.createNumBursts(myNumBursts)
+ self.createNumSacks(myNumSacks)
+ self.createLatBinGran(myLatBinGran)
+ self.createLatBin(myNumLatBins,myLatBin,myRandomLatBin)
+ self.transmitMfsLinkStats = self.beaconPeriodCntField + self.numMsdusField + self.octetsField + self.numSegsField + self.numSeg_SucField + self.numSeg_DroppedField + self.numPbsField + self.numMpdusField + self.numBurstsField + self.numSacksField + self.numLatBinsField + self.latBinGranField
+ self.i = 0
+ while self.i < self.numLatBins:
+ self.transmitMfsLinkStats = self.transmitMfsLinkStats + self.latBinField[self.i]
+ self.i = self.i + 1
+
+ hm = 0 #AV Only Mode by default
+ securityLevel = 0 #Simple connect by default
+ nidOffset = 0x0f0e0d0c
+ nid = int(nidOffset + securityLevel*pow(2,52))
+ nidHm = int(nid + hm*pow(2,54))
+ nidHmField = pack('Q',nidHm)[0:7]
+ def createNidHm(self, mySecurityLevel=None, myNidOffset=None, myNid=None, myHm=None, myNidHm=None):
+ if mySecurityLevel!=None or myNidOffset!=None:
+ if mySecurityLevel!=None:
+ self.securityLevel=mySecurityLevel
+ if myNidOffset!=None:
+ self.nidOffset=myNidOffset
+ self.nid = int(self.nidOffset + self.securityLevel*pow(2,52))
+ if myNid!=None:
+ self.nid=myNid
+ if myHm!=None:
+ self.Hm=myHm
+ self.nidHm = int(self.nid + self.hm*pow(2,54))
+ if myNidHm!=None:
+ self.nidHm=myNidHm
+ print "nidHm = "+hex(self.nidHm)
+ else:
+ print "nid = "+hex(self.nid)
+ print "hm = "+hex(self.hm)
+ self.nidHmField = pack('Q',self.nidHm)[0:7]
+
+ bt = 0 #Central beacon by default
+ ncnr = 0 #not reported by default
+ npsm = 0 #not active by default
+ numSlot = 0 #1 beacon slot by default
+ btNcnrNpsmNumSlot = int(bt + ncnr*pow(2,3) + npsm*pow(2,4) + numSlot*pow(2,5))
+ btNcnrNpsmNumSlotField = pack('B',btNcnrNpsmNumSlot)
+ def createBtNcnrNpsmNumSlot(self, myBt=None, myNcnr=None, myNpsm=None, myNumSlot=None, myBtNcnrNpsmNumSlot=None):
+ if myBt!=None or myNcnr!=None or myNpsm!=None or myNumSlot!=None:
+ if myBt!=None:
+ self.bt=myBt
+ if myNcnr!=None:
+ self.ncnr=myNcnr
+ if myNpsm!=None:
+ self.npsm=myNpsm
+ if myNumSlot!=None:
+ self.numSlot=myNumSlot
+ self.btNcnrNpsmNumSlot = int(self.bt + self.ncnr*pow(2,3) + self.npsm*pow(2,4) + self.numSlot*pow(2,5))
+ if myBtNcnrNpsmNumSlot!=None:
+ self.btNcnrNpsmNumSlot = myBtNcnrNpsmNumSlot
+ print "btNcnrNpsmNumSlot = "+hex(self.btNcnrNpsmNumSlot)
+ else:
+ print "bt = "+hex(self.bt)
+ print "ncnr = "+hex(self.ncnr)
+ print "npsm = "+hex(self.npsm)
+ print "numSlot = "+hex(self.numSlot)
+ self.btNcnrNpsmNumSlotField = pack('B',self.btNcnrNpsmNumSlot)
+
+ #Beacon Slot Usage
+ slotUsage = 0 #All slot free by default
+ slotUsageField = pack('B',slotUsage)
+ def createSlotUsage(self, mySlotUsage=None):
+ if mySlotUsage!=None:
+ self.slotUsage=mySlotUsage
+ self.slotUsageField = pack('B',self.slotUsage)
+ print "slotUsage = "+hex(self.slotUsage)
+
+ slotId = 0 #First beacon slot by default
+ aclss = 0 #0 by default
+ hoip = 0 #Hand Over Not in Progress by default
+ rtsbf = 0 #0 by default
+ slotIdAclssHoipRtsbf = int(slotId + aclss*pow(2,3) + hoip*pow(2,6) + rtsbf*pow(2,7))
+ slotIdAclssHoipRtsbfField = pack('B',slotIdAclssHoipRtsbf)
+ def createSlotIdAclssHoipRtsbf(self, mySlotId=None, myAclss=None, myHoip=None, myRtsbf=None, mySlotIdAclssHoipRtsbf=None):
+ if mySlotId!=None or myAclss!=None or myHoip!=None or myRtsbf!=None:
+ if mySlotId!=None:
+ self.slotId=mySlotId
+ if myAclss!=None:
+ self.aclss=myAclss
+ if myHoip!=None:
+ self.hoip=myHoip
+ if myRtsbf!=None:
+ self.rtsbf=myRtsbf
+ self.slotIdAclssHoipRtsbf = int(self.slotId + self.aclss*pow(2,3) + self.hoip*pow(2,6) + self.rtsbf*pow(2,7))
+ if mySlotIdAclssHoipRtsbf!=None:
+ self.slotIdAclssHoipRtsbf = mySlotIdAclssHoipRtsbf
+ print "slotIdAclssHoipRtsbf = "+hex(self.slotIdAclssHoipRtsbf)
+ else:
+ print "slotId = "+hex(self.slotId)
+ print "aclss = "+hex(self.aclss)
+ print "hoip = "+hex(self.hoip)
+ print "rtsbf = "+hex(self.rtsbf)
+ self.slotIdAclssHoipRtsbfField = pack('B',self.slotIdAclssHoipRtsbf)
+
+ nm = 0 #Uncoordinated Mode by default
+ ccoCap = 0 #Level 0 by default
+ rsvd = 0 #reserved = 0 by default
+ nmCcoCapRsvd = int(nm + ccoCap*pow(2,2) + rsvd*pow(2,4))
+ nmCcoCapRsvdField = pack('B',nmCcoCapRsvd)
+ def createNmCcoCaptsbf(self, myNm=None, myCcoCap=None, myNmCcoCapRsvd=None):
+ if myNm!=None or myCcoCap!=None:
+ if myNm!=None:
+ self.nm=myNm
+ if myCcoCap!=None:
+ self.ccoCap=myCcoCap
+ self.nmCcoCapRsvd = int(self.nm + self.ccoCap*pow(2,2))
+ if myNmCcoCapRsvd!=None:
+ self.nmCcoCapRsvd = myNmCcoCapRsvd
+ print "nmCcoCapRsvd = "+hex(self.nmCcoCapRsvd)
+ else:
+ print "nm = "+hex(self.nm)
+ print "ccoCap = "+hex(self.ccoCap)
+ self.nmCcoCapRsvdField = pack('B',self.nmCcoCapRsvd)
+
+ #Number of Beacon Entries
+ nbe = 255
+ nbeField = pack('B',nbe)
+ def createNbe(self, myNbe=None):
+ if myNbe!=None:
+ self.nbe=myNbe
+ self.nbeField = pack('B',self.nbe)
+ print "nbe = "+hex(self.nbe)
+
+ #Beacon Entry Headers
+ behdr = []
+ behdrField = []
+ i = 0
+ while i < nbe:
+ behdr.append(i%0x0E)
+ behdrField.append(pack('B',behdr[i]))
+ i=i+1
+ def createBehdr(self, myNbe=None, myBehdr=None, myRandomBehdr=False):
+ self.createNbe(myNbe)
+ self.i = 0
+ while self.i < self.nbe:
+ if myBehdr!=None:
+ self.behdr[self.i]=int((myBehdr+self.i)%0x0E)
+ elif myRandomBehdr==True:
+ self.behdr[self.i]=randrange(0,0x0D,1)
+ self.behdrField[self.i]=pack('B',self.behdr[self.i])
+ print "behdr["+str(self.i)+"] = "+BMI[self.behdr[self.i]]
+ print "bentryField["+str(self.i)+"] = "#+self.bentryField[self.i]
+ self.bentryField[self.i] = self.bentry.dico[self.behdr[self.i]]()
+ self.i = self.i + 1
+
+ #Becon Management information Field
+ bentry = BmiMethod()
+ bentryField = []
+ i = 0
+ while i < nbe:
+ bentryField.append(bentry.dico[behdr[i]]())
+ i=i+1
+ def createBentry(self, myBmiNumber=0, myBehdr=None, param1=None, param2=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myBehdr==None:
+ myBehdr=self.behdr[myBmiNumber]
+ self.behdr[myBmiNumber]=myBehdr
+ print "behdr["+str(myBmiNumber)+"] = "+BMI[self.behdr[myBmiNumber]]
+ print "bentryField["+str(myBmiNumber)+"] = "#+self.bentryField[self.i]
+ self.bentryField[myBmiNumber] = self.bentry.dico[myBehdr](param1, param2, param3, param4, param5, param6, param7, param8, param9, paramA, paramB)
+
+ #Beacon Management Information
+ bmiField = nbeField
+ i = 0
+ while i < nbe:
+ bmiField = bmiField + behdrField[i] + bentryField[i]
+ i=i+1
+ def createBmi(self, myNbe=None, myRandomBehdr=False, myBmiNumber=None, myBehdr=None, param1=None, param2=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ if myBmiNumber!=None:
+ self.createBentry(myBmiNumber, myBehdr, param1, param2, param3, param4, param5, param6, param7, param8, param9, paramA, paramB)
+ print "bmi :"
+ self.createBehdr(myNbe, None, False)
+ else:
+ print "bmi :"
+ self.createBehdr(myNbe, myBehdr, myRandomBehdr)
+ self.bmiField = self.nbeField
+ self.i = 0
+ while self.i < self.nbe:
+ self.bmiField = self.bmiField + self.behdrField[self.i] + self.bentryField[self.i]
+ self.i = self.i + 1
+
+ #MAC Frame Length = MFL
+ mmeMfl = 59 #MFL = 59 by default
+ def createMmeMfl(self, myMmentry=""):
+ self.mmeMfl = len(myMmentry) + 26 #len(mmHeaderWithVLanTag)+len(confunder)-1
+ #In Maximus VLanTag is always present
+ if self.mmeMfl < 59:
+ self.mmeMfl = 59
+ print "mmeMfl = "+hex(self.mmeMfl)
+
+ #AES cryption
+ encryptedFields = ""
+ myEncryption=new(keyField,2,ivField)
+ def createEncryptedFields(self, myIvOrUuid=None, myIvOrUuidRandom=False, myRandomFillerEncrypted=None, myOda=None, myOsa=None, myVlanTag=None, myMtype=None, myMmv=None, myMmtype=None, myNfmi=None, myFnMi=None, myFmsn=None, myMmentry=None, myEncapsulatedMmEntry=None, myMmOrHlePayloadEncrypted=None, myCrcEncrypted=None, myPidEncrypted=None, myPrnEncrypted=None, myRandomPrn=None, myPmnEncrypted=None, myPaddingEncrypted=None, myRfLenEncrypted=None, myKey=None, myEncryptedFields=None):
+ self.myEncryption = new(self.keyField,2,self.ivField)
+ if myEncryptedFields == None:
+ self.createIv(myIvOrUuid, myIvOrUuidRandom)
+ self.createRandomFillerEncrypted(myRfLenEncrypted, myRandomFillerEncrypted)
+ self.createMmOrHlePayloadEncrypted(self.pid, myOda, myOsa, myVlanTag, myMtype, myMmv, myMmtype, myNfmi, myFnMi, myFmsn, myMmentry, myEncapsulatedMmEntry, myMmOrHlePayloadEncrypted)
+ self.createLengthForEncryption()
+ self.createCrcEncrypted(myCrcEncrypted)
+ self.createPrnEncrypted(myPrnEncrypted, myRandomPrn)
+ self.createPmnEncrypted(myPmnEncrypted)
+ self.createPaddingEncrypted(myPaddingEncrypted)
+ self.createKey(myKey)
+ self.encryptedFields = self.randomFillerEncryptedField + self.mmOrHlePayloadEncryptedField + self.crcEncryptedField + self.pidField + self.prnEncryptedField + self.pmnEncryptedField + self.paddingEncryptedField + self.rfLenEncryptedField
+ if self.peks != 0x0F:
+ self.encryptedFields=self.myEncryption.encrypt(self.encryptedFields)
+ return self.ivField + self.lengthForEncryptionField + self.encryptedFields
+ else:
+ self.createKey(myKey)
+ self.encryptedFields = myEncryptedFields
+ self.createIv(myIv = self.encryptedFields[0:16])
+ self.createLengthForEncryption(myLengthForEncryption = self.encryptedFields[16:18])
+ self.encryptedFields=self.encryptedFields[18:]
+ if self.peks != 0x0F:
+ self.myEncryption = new(self.keyField,2,self.ivField)
+ self.encryptedFields=self.myEncryption.decrypt(self.encryptedFields)
+ self.createRandomFillerEncrypted(myRfLenEncrypted = self.encryptedFields[len(self.encryptedFields)-1:], myRandomFillerEncrypted = self.encryptedFields[0:unpack('B',self.encryptedFields[len(self.encryptedFields)-1:])[0]])
+ self.createMmOrHlePayloadEncrypted( myEncapsulatedMmEntry = self.encryptedFields[self.rfLenEncrypted:self.rfLenEncrypted+self.lengthForEncryption] )
+ self.createCrcEncrypted( myCrcEncrypted = self.encryptedFields[self.rfLenEncrypted+self.lengthForEncryption:self.rfLenEncrypted+self.lengthForEncryption+4] )
+ self.createPid( myPid = self.encryptedFields[self.rfLenEncrypted+self.lengthForEncryption+4:self.rfLenEncrypted+self.lengthForEncryption+4+1] )
+ self.createPrnEncrypted( myPrnEncrypted = self.encryptedFields[self.rfLenEncrypted+self.lengthForEncryption+4+1:self.rfLenEncrypted+self.lengthForEncryption+4+1+2] )
+ self.createPmnEncrypted( myPmnEncrypted = self.encryptedFields[self.rfLenEncrypted+self.lengthForEncryption+4+1+2:self.rfLenEncrypted+self.lengthForEncryption+4+1+2+1] )
+ self.createPaddingEncrypted( myPaddingEncrypted = self.encryptedFields[self.rfLenEncrypted+self.lengthForEncryption+4+1+2+1:len(self.encryptedFields)-1] )
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cesar/maximus/python/lib/mmentry/mmentryMethod.py b/cesar/maximus/python/lib/mmentry/mmentryMethod.py
new file mode 100644
index 0000000000..d936202a41
--- /dev/null
+++ b/cesar/maximus/python/lib/mmentry/mmentryMethod.py
@@ -0,0 +1,2089 @@
+# -*- coding:Utf-8 -*-
+#MMENTRY Methods
+
+from mmentry import *
+from mmentryFields import *
+
+#MmentryMethod can create every MMENTRY of MME
+# from MMENTRY format and MMENTRY fields
+class MmentryMethod():
+
+ mmentry = Mmentry() #Creates MMENTRY format
+ mmentryFields = MmentryFields() #Creates MMENTRY fields
+
+
+
+ #----- Station - Central Coordination -----
+
+
+
+ #createCC_CCO_APPOINT_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_CCO_APPOINT.REQ MME
+ def createCC_CCO_APPOINT_REQ_MMENTRY(self, myReqType=None, myMacAddress=None, myMmentry=None):
+ print "CC_CCO_APPOINT.REQ ="
+ #CC_CCO_APPOINT_REQ_MMENTRY is composed by 2 fields :
+ # - ReqType
+ # - macAddress
+ if myMmentry == None:
+ self.mmentryFields.createReqType(myReqType)
+ #MAC Address field is not present when ReqType = 0x01
+ if self.mmentryFields.reqType == 0x01:
+ self.mmentryFields.macAddress = 0
+ self.mmentryFields.createMacAddress(myMacAddress)
+ self.mmentry.CC_CCO_APPOINT_REQ = self.mmentryFields.reqTypeField + self.mmentryFields.macAddressField
+ self.mmentryFields.mmentry = self.mmentry.CC_CCO_APPOINT_REQ
+ self.mmentryFields.mmtype = CC_CCO_APPOINT_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createReqType(myMmentry[0])
+ if self.mmentryFields.reqType != 0x01:
+ self.mmentryFields.createMacAddress(myMmentry[1:])
+ else:
+ self.mmentryFields.createMacAddress(0)
+
+
+ #createCC_CCO_APPOINT_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_CCO_APPOINT.CNF MME
+ def createCC_CCO_APPOINT_CNF_MMENTRY(self, myResult=None):
+ print "CC_CCO_APPOINT.CNF ="
+ #CC_CCO_APPOINT_CNF_MMENTRY is composed by 1 field :
+ # - Result
+ self.mmentryFields.createResult(myResult)
+ self.mmentry.CC_CCO_APPOINT_CNF = self.mmentryFields.resultField
+ self.mmentryFields.mmentry = self.mmentry.CC_CCO_APPOINT_CNF
+ self.mmentryFields.mmtype = CC_CCO_APPOINT_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_BACKUP_APPOINT_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_BACKUP_APPOINT.REQ MME
+ def createCC_BACKUP_APPOINT_REQ_MMENTRY(self, myAppointRelease=None):
+ print "CC_BACKUP_APPOINT.REQ ="
+ #CC_BACKUP_APPOINT_REQ_MMENTRY is composed by 1 field :
+ # - AppointRelease
+ self.mmentryFields.createAppointRelease(myAppointRelease)
+ self.mmentry.CC_BACKUP_APPOINT_REQ = self.mmentryFields.appointReleaseField
+ self.mmentryFields.mmentry = self.mmentry.CC_BACKUP_APPOINT_REQ
+ self.mmentryFields.mmtype = CC_BACKUP_APPOINT_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_BACKUP_APPOINT_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_BACKUP_APPOINT.CNF MME
+ def createCC_BACKUP_APPOINT_CNF_MMENTRY(self, myResult=None):
+ print "CC_BACKUP_APPOINT.CNF ="
+ #CC_BACKUP_APPOINT_CNF_MMENTRY is composed by 1 field :
+ # - Result
+ self.mmentryFields.createResult(myResult)
+ self.mmentry.CC_BACKUP_APPOINT_CNF = self.mmentryFields.resultField
+ self.mmentryFields.mmentry = self.mmentry.CC_BACKUP_APPOINT_CNF
+ self.mmentryFields.mmtype = CC_BACKUP_APPOINT_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_LINK_INFO.REQ has no MMENTRY
+ def createCC_LINK_INFO_REQ_MMENTRY(self):
+ print "CC_LINK_INFO.REQ ="
+ #CC_LINK_INFO_REQ_MMENTRY is composed by 0 field :
+ self.mmentry.CC_LINK_INFO_REQ = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_INFO_REQ
+ self.mmentryFields.mmtype = CC_LINK_INFO_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_INFO_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_INFO.CNF MME
+ def createCC_LINK_INFO_CNF_MMENTRY(self, myNum=0, myTei=None, myLlidF=None, myStei=None, myDtei=None, myLidF=None, myLidR=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None, myNumF=None, myEndTimeL=None, myIntBleL=None, myIntervalL=None, myNumR=None, myEndTimeR=None, myIntBleR=None, myIntervalR=None):
+ print "CC_LINK_INFO.CNF ="
+ #CC_LINK_INFO_CNF_MMENTRY is composed by 2 fields :
+ # - Num
+ # - GlobalLinkInfo -* Num-
+ #self.mmentryFields.createNum(myNum)
+ self.mmentryFields.createGlobalLinks(myNum, myTei, myLlidF, myStei, myDtei, myLidF, myLidR, myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R, myNumF, myEndTimeL, myIntBleL, myIntervalL, myNumR, myEndTimeR, myIntBleR, myIntervalR)
+ self.mmentry.CC_LINK_INFO_CNF = self.mmentryFields.numField
+ self.i=0
+ while self.i<self.mmentryFields.num:
+ self.mmentry.CC_LINK_INFO_CNF = self.mmentry.CC_LINK_INFO_CNF + self.mmentryFields.globalLinks[self.i].globalLinkInfo
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_INFO_CNF
+ self.mmentryFields.mmtype = CC_LINK_INFO_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_INFO_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_INFO.IND MME
+ def createCC_LINK_INFO_IND_MMENTRY(self, myNum=0, myTei=None, myLlidF=None, myStei=None, myDtei=None, myLidF=None, myLidR=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None, myNumF=None, myEndTimeL=None, myIntBleL=None, myIntervalL=None, myNumR=None, myEndTimeR=None, myIntBleR=None, myIntervalR=None):
+ print "CC_LINK_INFO.IND ="
+ #CC_LINK_INFO_IND_MMENTRY is composed by 2 fields :
+ # - Num
+ # - GlobalLinkInfo -* Num-
+ #self.mmentryFields.createNum(myNum)
+ self.mmentryFields.createGlobalLinks(myNum, myTei, myLlidF, myStei, myDtei, myLidF, myLidR, myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R, myNumF, myEndTimeL, myIntBleL, myIntervalL, myNumR, myEndTimeR, myIntBleR, myIntervalR)
+ self.mmentry.CC_LINK_INFO_IND = self.mmentryFields.numField
+ self.i=0
+ while self.i<self.mmentryFields.num:
+ self.mmentry.CC_LINK_INFO_IND = self.mmentry.CC_LINK_INFO_IND + self.mmentryFields.globalLinks[self.i].globalLinkInfo
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_INFO_IND
+ self.mmentryFields.mmtype = CC_LINK_INFO_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_LINK_INFO.RSP has no MMENTRY
+ def createCC_LINK_INFO_RSP_MMENTRY(self):
+ print "CC_LINK_INFO.RSP ="
+ #CC_LINK_INFO_RSP_MMENTRY is composed by 0 field :
+ self.mmentry.CC_LINK_INFO_RSP = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_INFO_RSP
+ self.mmentryFields.mmtype = CC_LINK_INFO_RSP
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_HANDOVER_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_HANDOVER.REQ MME
+ def createCC_HANDOVER_REQ_MMENTRY(self, mySoftHard=None, myReason=None):
+ print "CC_HANDOVER.REQ ="
+ #CC_HANDOVER_REQ_MMENTRY is composed by 2 fields :
+ # - Soft/Hard
+ # - Reason
+ self.mmentryFields.createSoftHard(mySoftHard)
+ self.mmentryFields.createReason(myReason)
+ self.mmentry.CC_HANDOVER_REQ = self.mmentryFields.softHardField + self.mmentryFields.reasonField
+ self.mmentryFields.mmentry = self.mmentry.CC_HANDOVER_REQ
+ self.mmentryFields.mmtype = CC_HANDOVER_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_HANDOVER_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_HANDOVER.CNF MME
+ def createCC_HANDOVER_CNF_MMENTRY(self, myResult=None):
+ print "CC_HANDOVER.CNF ="
+ #CC_HANDOVER_CNF_MMENTRY is composed by 1 field :
+ # - Result
+ self.mmentryFields.createResult(myResult)
+ self.mmentry.CC_HANDOVER_CNF = self.mmentryFields.resultField
+ self.mmentryFields.mmentry = self.mmentry.CC_HANDOVER_CNF
+ self.mmentryFields.mmtype = CC_HANDOVER_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_HANDOVER_INFO_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_HANDOVER_INFO.IND MME
+ def createCC_HANDOVER_INFO_IND_MMENTRY(self, myRsc=None,myBackupCco=None,myNum=0):
+ print "CC_HANDOVER_INFO.IND ="
+ #CC_HANDOVER_INFO_IND_MMENTRY is composed by 4 field :
+ # - RSC
+ # - BackupCCo
+ # - Num
+ # - STA_Info -*Num-
+ self.mmentryFields.createRsc(myRsc)
+ self.mmentryFields.createBackupCco(myBackupCco)
+ self.mmentryFields.createNum(myNum)
+ self.mmentry.CC_HANDOVER_INFO_IND = self.mmentryFields.rscField + self.mmentryFields.backupCcoField + self.mmentryFields.numField
+ self.i=0
+ while self.i<self.mmentryFields.num:
+ self.mmentry.CC_HANDOVER_INFO_IND = self.mmentry.CC_HANDOVER_INFO_IND + self.mmentryFields.stasInfo[self.i].staInfo
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CC_HANDOVER_INFO_IND
+ self.mmentryFields.mmtype = CC_HANDOVER_INFO_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_HANDOVER_INFO.RSP has no MMENTRY
+ def createCC_HANDOVER_INFO_RSP_MMENTRY(self):
+ print "CC_HANDOVER_INFO.RSP ="
+ #CC_HANDOVER_INFO_RSP_MMENTRY is composed by 0 field :
+ self.mmentry.CC_HANDOVER_INFO_RSP = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_HANDOVER_INFO_RSP
+ self.mmentryFields.mmtype = CC_HANDOVER_INFO_RSP
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_DISCOVER_LIST.REQ has no MMENTRY
+ def createCC_DISCOVER_LIST_REQ_MMENTRY(self):
+ print "CC_DISCOVER_LIST.REQ ="
+ #CC_DISCOVER_LIST_REQ_MMENTRY is composed by 0 field :
+ self.mmentry.CC_DISCOVER_LIST_REQ = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_DISCOVER_LIST_REQ
+ self.mmentryFields.mmtype = CC_DISCOVER_LIST_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_DISCOVER_LIST_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_DISCOVER_LIST.CNF MME
+ def createCC_DISCOVER_LIST_CNF_MMENTRY(self, myNumSta=0, myMacAddress=None, myTei=None, mySameNetwork=None, mySnidStation=None, myAccessStation=None, mySnidAccessStation=None, myCcoCapability=None, myProxyNetworkCapability=None, myBackupCcoCapability=None, myCcoStatus=None, myPcoStatus=None, myBackupCcoStatus=None, myNinthOctet=None, mySignalLevel=None, myEndTime=None, myIntBle=None, myNumNet=0, mySecurityLevel=None, myNidOffset=None, myNid=None, mySnidNetwork=None, myAccessNetwork=None, mySnidAccessNetwork=None, myHm=None, myNumSlot=None, myCoordonatingStatus=None, myOffset=None):
+ print "CC_DISCOVER_LIST.CNF ="
+ #CC_DISCOVER_LIST_CNF_MMENTRY is composed by 4 field :
+ # - NumStation
+ # - StationInfo -*NumStation-
+ # - NumNetwork
+ # - NetworkInfo -*NumNetwork-
+ self.mmentryFields.createStationsInfo(myNumSta, myMacAddress, myTei, mySameNetwork, mySnidStation, myAccessStation, mySnidAccessStation, myCcoCapability, myProxyNetworkCapability, myBackupCcoCapability, myCcoStatus, myPcoStatus, myBackupCcoStatus, myNinthOctet, mySignalLevel, myEndTime, myIntBle)
+ self.mmentry.CC_DISCOVER_LIST_CNF = self.mmentryFields.numStaField
+ self.i=0
+ while self.i<self.mmentryFields.numSta:
+ self.mmentry.CC_DISCOVER_LIST_CNF = self.mmentry.CC_DISCOVER_LIST_CNF + self.mmentryFields.stationsInfo[self.i].stationInfo
+ self.i=self.i+1
+ self.mmentryFields.createNetworksInfo(myNumNet, mySecurityLevel, myNidOffset, myNid, mySnidNetwork, myAccessNetwork, mySnidAccessNetwork, myHm, myNumSlot, myCoordonatingStatus, myOffset)
+ self.mmentry.CC_DISCOVER_LIST_CNF = self.mmentry.CC_DISCOVER_LIST_CNF + self.mmentryFields.numNetField
+ self.i=0
+ while self.i<self.mmentryFields.numNet:
+ self.mmentry.CC_DISCOVER_LIST_CNF = self.mmentry.CC_DISCOVER_LIST_CNF + self.mmentryFields.networksInfo[self.i].networkInfo
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CC_DISCOVER_LIST_CNF
+ self.mmentryFields.mmtype = CC_DISCOVER_LIST_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_DISCOVER_LIST_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_DISCOVER_LIST.IND MME
+ def createCC_DISCOVER_LIST_IND_MMENTRY(self, myNumSta=0, myMacAddress=None, myTei=None, mySameNetwork=None, mySnidStation=None, myAccessStation=None, mySnidAccessStation=None, myCcoCapability=None, myProxyNetworkCapability=None, myBackupCcoCapability=None, myCcoStatus=None, myPcoStatus=None, myBackupCcoStatus=None, myNinthOctet=None, mySignalLevel=None, myEndTime=None, myIntBle=None, myNumNet=0, mySecurityLevel=None, myNidOffset=None, myNid=None, mySnidNetwork=None, myAccessNetwork=None, mySnidAccessNetwork=None, myHm=None, myNumSlot=None, myCoordonatingStatus=None, myOffset=None):
+ print "CC_DISCOVER_LIST.IND ="
+ #CC_DISCOVER_LIST_IND_MMENTRY is composed by 4 field :
+ # - NumStation
+ # - StationInfo -*NumStation-
+ # - NumNetwork
+ # - NetworkInfo -*NumNetwork-
+ self.mmentryFields.createStationsInfo(myNumSta, myMacAddress, myTei, mySameNetwork, mySnidStation, myAccessStation, mySnidAccessStation, myCcoCapability, myProxyNetworkCapability, myBackupCcoCapability, myCcoStatus, myPcoStatus, myBackupCcoStatus, myNinthOctet, mySignalLevel, myEndTime, myIntBle)
+ self.mmentry.CC_DISCOVER_LIST_IND = self.mmentryFields.numStaField
+ self.i=0
+ while self.i<self.mmentryFields.numSta:
+ self.mmentry.CC_DISCOVER_LIST_IND = self.mmentry.CC_DISCOVER_LIST_IND + self.mmentryFields.stationsInfo[self.i].stationInfo
+ self.i=self.i+1
+ self.mmentryFields.createNetworksInfo(myNumNet, mySecurityLevel, myNidOffset, myNid, mySnidNetwork, myAccessNetwork, mySnidAccessNetwork, myHm, myNumSlot, myCoordonatingStatus, myOffset)
+ self.mmentry.CC_DISCOVER_LIST_IND = self.mmentry.CC_DISCOVER_LIST_IND + self.mmentryFields.numNetField
+ self.i=0
+ while self.i<self.mmentryFields.numNet:
+ self.mmentry.CC_DISCOVER_LIST_IND = self.mmentry.CC_DISCOVER_LIST_IND + self.mmentryFields.networksInfo[self.i].networkInfo
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CC_DISCOVER_LIST_IND
+ self.mmentryFields.mmtype = CC_DISCOVER_LIST_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_NEW_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_NEW.REQ MME
+ def createCC_LINK_NEW_REQ_MMENTRY(self, myInitMacAddress=None, myTermMacAddress=None, myTei=None, myLlidF=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None, myNumF=None, myEndTimeF=None, myIntBleF=None, myNumR=None, myEndTimeR=None, myIntBleR=None):
+ print "CC_LINK_NEW.REQ ="
+ #CC_LINK_NEW_REQ_MMENTRY is composed by 6 fields :
+ # - Init MAC Address
+ # - Term MAC Address
+ # - CID
+ # - CSPEC
+ # - Forward Link Bit Loading Estimates
+ # - Reverse Link Bit Loading Estimates
+ self.mmentryFields.createInitMacAddress(myInitMacAddress)
+ self.mmentryFields.createTermMacAddress(myTermMacAddress)
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentryFields.createForwardLinkBle(myNumF, myEndTimeF, myIntBleF)
+ self.mmentryFields.createReverseLinkBle(myNumR, myEndTimeR, myIntBleR)
+ self.mmentry.CC_LINK_NEW_REQ = self.mmentryFields.initMacAddressField + self.mmentryFields.termMacAddressField + self.mmentryFields.cidField + self.mmentryFields.cspecField + self.mmentryFields.forwardLinkBle.ble + self.mmentryFields.reverseLinkBle.ble
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_NEW_REQ
+ self.mmentryFields.mmtype = CC_LINK_NEW_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_NEW_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_NEW.CNF MME
+ def createCC_LINK_NEW_CNF_MMENTRY(self, myTei=None, myLlidF=None, myGlidF=None, myGlidR=None, myResult=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CC_LINK_NEW.CNF ="
+ #CC_LINK_NEW_CNF_MMENTRY is composed by 5 fields :
+ # - CID
+ # - GLID-F
+ # - GLID-R
+ # - Result
+ # - Proposed CSPEC
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createGlidF(myGlidF=None)
+ self.mmentryFields.createGlidR(myGlidR=None)
+ self.mmentryFields.createResult(myResult)
+ self.mmentry.CC_LINK_NEW_CNF = self.mmentryFields.cidField + self.mmentryFields.glidFField + self.mmentryFields.glidRField + self.mmentryFields.resultField
+ if self.mmentryFields.result == 1 :
+ self.mmentryFields.createProposedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CC_LINK_NEW_CNF = self.mmentry.CC_LINK_NEW_CNF + self.mmentryFields.proposedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_NEW_CNF
+ self.mmentryFields.mmtype = CC_LINK_NEW_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_MOD_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_MOD.REQ MME
+ def createCC_LINK_MOD_REQ_MMENTRY(self, myTei=None, myLlidF=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None, myNumF=None, myEndTimeF=None, myIntBleF=None, myNumR=None, myEndTimesR=None, myIntBleR=None):
+ print "CC_LINK_MOD.REQ ="
+ #CC_LINK_MOD_REQ_MMENTRY is composed by 4 fields :
+ # - CID
+ # - Modified CSPEC
+ # - Forward Link Bit Loading Estimates
+ # - Reverse Link Bit Loading Estimates
+ #CAREFUL : this MME requires the GLID-F and the GLID-R to be fulfilled
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createModifiedCspec(self, myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CC_LINK_MOD_REQ = self.mmentryFields.cidField + self.mmentryFields.modifiedCspecField
+ if self.mmentryFields.glidF in globalId:
+ self.mmentryFields.createForwardLinkBle(myNumF, myEndTimeF, myIntBleF)
+ self.mmentry.CC_LINK_MOD_REQ = self.mmentry.CC_LINK_MOD_REQ + self.mmentryFields.forwardLinkBleField
+ if self.mmentryFields.glidR in globalId:
+ self.mmentryFields.createReverseLinkBle(myNumR, myEndTimeR, myIntBleR)
+ self.mmentry.CC_LINK_MOD_REQ = self.mmentry.CC_LINK_MOD_REQ + self.mmentryFields.reverseLinkBleField
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_MOD_REQ
+ self.mmentryFields.mmtype = CC_LINK_MOD_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_MOD_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_MOD.CNF MME
+ def createCC_LINK_MOD_CNF_MMENTRY(self, myTei=None, myLlidF=None, myResult=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CC_LINK_MOD.CNF ="
+ #CC_LINK_MOD_CNF_MMENTRY is composed by 3 fields :
+ # - CID
+ # - Result
+ # - Proposed CSPEC
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createResult(myResult)
+ self.mmentry.CC_LINK_MOD_CNF = self.mmentryFields.cidField + self.mmentryFields.resultField
+ if self.mmentryFields.result == 1 :
+ self.mmentryFields.createProposedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CC_LINK_MOD_CNF = self.mmentry.CC_LINK_MOD_CNF + self.mmentryFields.proposedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_MOD_CNF
+ self.mmentryFields.mmtype = CC_LINK_MOD_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_SQZ_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_SQZ.REQ MME
+ def createCC_LINK_SQZ_REQ_MMENTRY(self, myTei=None, myLlidF=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CC_LINK_SQZ.REQ ="
+ #CC_LINK_SQZ_REQ_MMENTRY is composed by 2 fields :
+ # - CID
+ # - Modified CSPEC
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createModifiedCspec(self, myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CC_LINK_SQZ_REQ = self.mmentryFields.cidField + self.mmentryFields.modifiedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_SQZ_REQ
+ self.mmentryFields.mmtype = CC_LINK_SQZ_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_SQZ_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_SQZ.CNF MME
+ def createCC_LINK_SQZ_CNF_MMENTRY(self, myTei=None, myLlidF=None, myResult=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CC_LINK_SQZ.CNF ="
+ #CC_LINK_SQZ_CNF_MMENTRY is composed by 3 fields :
+ # - CID
+ # - Result
+ # - Proposed CSPEC
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createResult(myResult)
+ self.mmentry.CC_LINK_SQZ_CNF = self.mmentryFields.cidField + self.mmentryFields.resultField
+ if self.mmentryFields.result == 1 :
+ self.mmentryFields.createProposedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CC_LINK_SQZ_CNF = self.mmentry.CC_LINK_SQZ_CNF + self.mmentryFields.proposedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_SQZ_CNF
+ self.mmentryFields.mmtype = CC_LINK_SQZ_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_REL_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_REL.REQ MME
+ def createCC_LINK_REL_REQ_MMENTRY(self, myCidTei=None, myLlidF=None, myTei=None, myRsc=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CC_LINK_REL.REQ ="
+ #CC_LINK_REL_REQ_MMENTRY is composed by 4 fields :
+ # - CID
+ # - TEI
+ # - Reason Code
+ # - Violated CSPEC
+ self.mmentryFields.createCid(myCidTei, myLlidF)
+ self.mmentryFields.createTei(myTei)
+ self.mmentryFields.createRsc(myRsc)
+ self.mmentry.CC_LINK_REL_REQ = self.mmentryFields.cidField + self.mmentryFields.teiField + self.mmentryFields.rscField
+ if self.mmentryFields.rsc == 1 :
+ self.mmentryFields.createViolatedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CC_LINK_REL_REQ = self.mmentry.CC_LINK_REL_REQ + self.mmentryFields.violatedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_REL_REQ
+ self.mmentryFields.mmtype = CC_LINK_REL_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LINK_REL_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_LINK_REL.IND MME
+ def createCC_LINK_REL_IND_MMENTRY(self, myTei=None, myLlidF=None, myReleasingStationMacAddress=None, myRsc=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CC_LINK_REL.IND ="
+ #CC_LINK_REL_IND_MMENTRY is composed by 4 fields :
+ # - CID
+ # - Releasing Station Mac Address
+ # - Reason Code
+ # - Proposed CSPEC or Violated CSPEC
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createReleasingStationMacAddress(myReleasingStationMacAddress)
+ self.mmentryFields.createRsc(myRsc)
+ self.mmentry.CC_LINK_REL_IND = self.mmentryFields.cidField + self.mmentryFields.releasingStationMacAddressField + self.mmentryFields.rscField
+ if self.mmentryFields.rsc == 1 :
+ self.mmentryFields.createProposedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CC_LINK_REL_IND = self.mmentry.CC_LINK_REL_IND + self.mmentryFields.proposedCspecField
+ elif self.mmentryFields.rsc == 2 :
+ self.mmentryFields.createViolatedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CC_LINK_REL_IND = self.mmentry.CC_LINK_REL_IND + self.mmentryFields.violatedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_REL_IND
+ self.mmentryFields.mmtype = CC_LINK_REL_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_DETECT_REPORT_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_DETECT_REPORT.REQ MME
+ def createCC_DETECT_REPORT_REQ_MMENTRY(self, myDuration=None, myNumGlid=0, myGlids=None):
+ print "CC_DETECT_REPORT.REQ ="
+ #CC_DETECT_REPORT_REQ_MMENTRY is composed by 3 fields :
+ # - Duration
+ # - Number of GLID
+ # - GLID -* NumGlid-
+ self.mmentryFields.createDuration(myDuration)
+ self.mmentryFields.createNumGlid(myNumGlid)
+ self.mmentry.CC_DETECT_REPORT_REQ = self.mmentryFields.durationField + self.mmentryFields.numGlidField
+ self.mmentryFields.createGlids(self.mmentryFields.numGlid, myGlids)
+ self.i=0
+ while self.i<self.mmentryFields.numGlid:
+ self.mmentry.CC_DETECT_REPORT_REQ = self.mmentry.CC_DETECT_REPORT_REQ + self.mmentryFields.glids.glidsField[self.i]
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CC_DETECT_REPORT_REQ
+ self.mmentryFields.mmtype = CC_DETECT_REPORT_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_DETECT_REPORT_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_DETECT_REPORT.CNF MME
+ def createCC_DETECT_REPORT_CNF_MMENTRY(self, myNumGlid=0, myCfDetecteds=None, myCsmaDetecteds=None, myHp1Detecteds=None, myOthersDetecteds=None, mySignalLevels=None, myEndTime=None, myIntBle=None):
+ print "CC_DETECT_REPORT.CNF ="
+ #CC_DETECT_REPORT_CNF_MMENTRY is composed by 2 fields :
+ # - Number of GLID
+ # - GLID Info -* NumGlid-
+ self.mmentryFields.createNumGlid(myNumGlid)
+ self.mmentry.CC_DETECT_REPORT_CNF = self.mmentryFields.numGlidField
+ self.mmentryFields.createGlidsInfo(self.mmentryFields.numGlid, myCfDetecteds, myCsmaDetecteds, myHp1Detecteds, myOthersDetecteds, mySignalLevels, myEndTime, myIntBle)
+ self.i=0
+ while self.i<self.mmentryFields.numGlid:
+ self.mmentry.CC_DETECT_REPORT_CNF = self.mmentry.CC_DETECT_REPORT_CNF + self.mmentryFields.glidsInfo.glidsInfo[self.i]
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CC_DETECT_REPORT_CNF
+ self.mmentryFields.mmtype = CC_DETECT_REPORT_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_WHO_RU_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_WHO_RU.REQ MME
+ def createCC_WHO_RU_REQ_MMENTRY(self, mySecurityLevel=None, myNidOffset=None, myNid=None):
+ print "CC_WHO_RU.REQ ="
+ #CC_WHO_RU_REQ_MMENTRY is composed by 1 fields :
+ # - NID
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentry.CC_WHO_RU_REQ = self.mmentryFields.nidField
+ self.mmentryFields.mmentry = self.mmentry.CC_WHO_RU_REQ
+ self.mmentryFields.mmtype = CC_WHO_RU_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_WHO_RU_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_WHO_RU.CNF MME
+ def createCC_WHO_RU_CNF_MMENTRY(self, mySecurityLevel=None, myNidOffset=None, myNid=None, myCmac=None, myHfid=None):
+ print "CC_WHO_RU.CNF ="
+ #CC_WHO_RU_CNF_MMENTRY is composed by 3 fields :
+ # - NID
+ # - CMAC
+ # - HFID
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createCmac(myCmac)
+ self.mmentryFields.createHfid(myHfid)
+ self.mmentry.CC_WHO_RU_CNF = self.mmentryFields.nidField + self.mmentryFields.cmacField + self.mmentryFields.hfidField
+ self.mmentryFields.mmentry = self.mmentry.CC_WHO_RU_CNF
+ self.mmentryFields.mmtype = CC_WHO_RU_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_ASSOC_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_ASSOC.REQ MME
+ def createCC_ASSOC_REQ_MMENTRY(self, myReqType=None, mySecurityLevel=None, myNidOffset=None, myNid=None, myCcoCapability=None, myProxyNetworkingCapability=None, myMmentry=None):
+ print "CC_ASSOC.REQ ="
+ #CC_ASSOC_REQ_MMENTRY is composed by 4 fields :
+ # - ReqType
+ # - NID
+ # - CCo Capability
+ # - Proxy Networking Capability
+ if myMmentry==None:
+ self.mmentryFields.createReqType(myReqType)
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createCcoCapability(myCcoCapability)
+ self.mmentryFields.createProxyNetworkingCapability(myProxyNetworkingCapability)
+ self.mmentry.CC_ASSOC_REQ = self.mmentryFields.reqTypeField + self.mmentryFields.nidField + self.mmentryFields.ccoCapabilityField + self.mmentryFields.proxyNetworkingCapabilityField
+ self.mmentryFields.mmentry = self.mmentry.CC_ASSOC_REQ
+ self.mmentryFields.mmtype = CC_ASSOC_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createReqType(myReqType=myMmentry[0])
+ self.mmentryFields.createNid(myNid=myMmentry[1:8])
+ self.mmentryFields.createCcoCapability(myCcoCapability=myMmentry[8])
+ self.mmentryFields.createProxyNetworkingCapability(myProxyNetworkingCapability=myMmentry[9:])
+
+
+ #createCC_ASSOC_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_ASSOC.CNF MME
+ def createCC_ASSOC_CNF_MMENTRY(self, myResult=None, mySecurityLevel=None, myNidOffset=None, myNid=None, mySnid=None, myAccess=None, mySnidAccess=None, myStaTei=None, myLeaseTime=None, myMmentry=None):
+ print "CC_ASSOC.CNF ="
+ #CC_ASSOC_CNF_MMENTRY is composed by 5 fields :
+ # - Result
+ # - NID
+ # - SNID
+ # - STA TEI
+ # - Lease Time
+ if myMmentry==None:
+ self.mmentryFields.createResult(myResult)
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createSnidAccess(mySnid, myAccess, mySnidAccess)
+ self.mmentryFields.createStaTei(myStaTei)
+ self.mmentryFields.createLeaseTime(myLeaseTime)
+ self.mmentry.CC_ASSOC_CNF = self.mmentryFields.resultField + self.mmentryFields.nidField + self.mmentryFields.snidAccessField + self.mmentryFields.staTeiField + self.mmentryFields.leaseTimeField
+ self.mmentryFields.mmentry = self.mmentry.CC_ASSOC_CNF
+ self.mmentryFields.mmtype = CC_ASSOC_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createResult(myResult=myMmentry[0])
+ self.mmentryFields.createNid(myNid=myMmentry[1:8])
+ self.mmentryFields.createSnidAccess(mySnidAccess=myMmentry[8])
+ self.mmentryFields.createStaTei(myStaTei=myMmentry[9])
+ self.mmentryFields.createLeaseTime(myLeaseTime=myMmentry[10:])
+
+
+ #createCC_LEAVE_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_LEAVE.REQ MME
+ def createCC_LEAVE_REQ_MMENTRY(self, myReason=None):
+ print "CC_LEAVE.REQ ="
+ #CC_LEAVE_REQ_MMENTRY is composed by 1 fields :
+ # - Reason
+ self.mmentryFields.createReason(myReason)
+ self.mmentry.CC_LEAVE_REQ = self.mmentryFields.reasonField
+ self.mmentryFields.mmentry = self.mmentry.CC_LEAVE_REQ
+ self.mmentryFields.mmtype = CC_LEAVE_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_LEAVE.CNF has no MMENTRY
+ def createCC_LEAVE_CNF_MMENTRY(self):
+ print "CC_LEAVE.CNF ="
+ #CC_LEAVE_CNF_MMENTRY is composed by 0 field :
+ self.mmentry.CC_LEAVE_CNF = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_LEAVE_CNF
+ self.mmentryFields.mmtype = CC_LEAVE_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_LEAVE_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_LEAVE.IND MME
+ def createCC_LEAVE_IND_MMENTRY(self, myReason=None, mySecurityLevel=None, myNidOffset=None, myNid=None):
+ print "CC_LEAVE.IND ="
+ #CC_LEAVE_IND_MMENTRY is composed by 2 fields :
+ # - Reason
+ # - NID
+ self.mmentryFields.createReason(myReason)
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentry.CC_LEAVE_IND = self.mmentryFields.reasonField + self.mmentryFields.nidField
+ self.mmentryFields.mmentry = self.mmentry.CC_LEAVE_IND
+ self.mmentryFields.mmtype = CC_LEAVE_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_LEAVE.RSP has no MMENTRY
+ def createCC_LEAVE_RSP_MMENTRY(self):
+ print "CC_LEAVE.RSP ="
+ #CC_LEAVE_RSP_MMENTRY is composed by 0 field :
+ self.mmentry.CC_LEAVE_RSP = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_LEAVE_RSP
+ self.mmentryFields.mmtype = CC_LEAVE_RSP
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_SET_TEI_MAP.REQ has no MMENTRY
+ def createCC_SET_TEI_REQ_MMENTRY(self):
+ print "CC_SET_TEI.REQ ="
+ #CC_SET_TEI_REQ_MMENTRY is composed by 0 field :
+ self.mmentry.CC_SET_TEI_REQ = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_SET_TEI_REQ
+ self.mmentryFields.mmtype = CC_SET_TEI_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_SET_TEI_MAP_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_SET_TEI_MAP.IND MME
+ def createCC_SET_TEI_MAP_IND_MMENTRY(self, myMode=None, myNum=0, myTei=None, myAddr=None, myStatus=None, myMmentry=None):
+ print "CC_SET_TEI_MAP.IND ="
+ #CC_SET_TEI_MAP_IND_MMENTRY is composed by 3 fields :
+ # - Mode
+ # - Num
+ # - TEI + MAC Address + Status -*Num-
+ if myMmentry==None:
+ self.mmentryFields.createMode(myMode)
+ self.mmentryFields.createTeisAddrsStatuses(myNum, myTei, myAddr, myStatus)
+ self.mmentry.CC_SET_TEI_MAP_IND = self.mmentryFields.modeField + self.mmentryFields.numField
+ self.i=0
+ while self.i<self.mmentryFields.num:
+ self.mmentry.CC_SET_TEI_MAP_IND = self.mmentry.CC_SET_TEI_MAP_IND + self.mmentryFields.teisAddrsStatuses[self.i]
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CC_SET_TEI_MAP_IND
+ self.mmentryFields.mmtype = CC_SET_TEI_MAP_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createMode(myMode=myMmentry[0])
+ self.mmentryFields.createTeisAddrsStatuses(myNum=myMmentry[1], myTei=myMmentry[2:], myAddr=myMmentry[3:], myStatus=myMmentry[9:])
+
+
+ #createCC_RELAY_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_RELAY.REQ MME
+ def createCC_RELAY_REQ_MMENTRY(self, myFda=None, myFTei=None, myPayload=None):
+ print "CC_RELAY.REQ ="
+ #CC_RELAY_REQ_MMENTRY is composed by 4 fields :
+ # - FDA
+ # - FTEI
+ # - Length
+ # - Payload
+ self.mmentryFields.createFda(myFda)
+ self.mmentryFields.createFTei(myFTei)
+ self.mmentryFields.createPayload(myPayload)
+ self.mmentryFields.createLength()
+ self.mmentry.CC_RELAY_REQ = self.mmentryFields.fdaField + self.mmentryFields.fTeiField + self.mmentryFields.lengthField + self.mmentryFields.payload
+ self.mmentryFields.mmentry = self.mmentry.CC_RELAY_REQ
+ self.mmentryFields.mmtype = CC_RELAY_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_RELAY_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_RELAY.IND MME
+ def createCC_RELAY_IND_MMENTRY(self, myOda=None, myOTei=None, myPayload=None):
+ print "CC_RELAY.IND ="
+ #CC_RELAY_IND_MMENTRY is composed by 4 fields :
+ # - ODA
+ # - OTEI
+ # - Length
+ # - Payload
+ self.mmentryFields.createOda(myOda)
+ self.mmentryFields.createOTei(myOTei)
+ self.mmentryFields.createPayload(myPayload)
+ self.mmentryFields.createLength()
+ self.mmentry.CC_RELAY_IND = self.mmentryFields.odaField + self.mmentryFields.oTeiField + self.mmentryFields.lengthField + self.mmentryFields.payload
+ self.mmentryFields.mmentry = self.mmentry.CC_RELAY_IND
+ self.mmentryFields.mmtype = CC_RELAY_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_BEACON_RELIABILITY.REQ has no MMENTRY
+ def createCC_BEACON_RELIABILITY_REQ_MMENTRY(self):
+ print "CC_BEACON_RELIABILITY.REQ ="
+ #CC_BEACON_RELIABILITY_REQ_MMENTRY is composed by 0 field :
+ self.mmentry.CC_BEACON_RELIABILITY_REQ = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_BEACON_RELIABILITY_REQ
+ self.mmentryFields.mmtype = CC_BEACON_RELIABILITY_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_BEACON_RELIABILITY_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_BEACON_RELIABILITY.CNF MME
+ def createCC_BEACON_RELIABILITY_CNF_MMENTRY(self, myNbp=None, myNmb=None):
+ print "CC_BEACON_RELIABILITY.CNF ="
+ #CC_BEACON_RELIABILITY_CNF_MMENTRY is composed by 2 fields :
+ # - Number of beacon periods
+ # - Number of missed beacons
+ self.mmentryFields.createNbp(myNbp)
+ self.mmentryFields.createNmb(myNmb)
+ self.mmentry.CC_BEACON_RELIABILITY_CNF = self.mmentryFields.nbpField + self.mmentryFields.nmbField
+ self.mmentryFields.mmentry = self.mmentry.CC_BEACON_RELIABILITY_CNF
+ self.mmentryFields.mmtype = CC_BEACON_RELIABILITY_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_ALLOC_MOVE_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_ALLOC_MOVE.REQ MME
+ def createCC_ALLOC_MOVE_REQ_MMENTRY(self, myTei=None, myLlidF=None, myGlidF=None, myGlidR=None, myNumF=None, myEndTimeF=None, myIntBleF=None, myNumR=None, myEndTimeR=None, myIntBleR=None):
+ print "CC_ALLOC_MOVE.REQ ="
+ #CC_ALLOC_MOVE_REQ_MMENTRY is composed by 5 fields :
+ # - CID
+ # - GLID-F
+ # - GLID-R
+ # - Forward Link Bit Loading Estimates
+ # - Reverse Link Bit Loading Estimates
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createGlidF(myGlidF=None)
+ self.mmentryFields.createGlidR(myGlidR=None)
+ self.mmentry.CC_ALLOC_MOVE_REQ = self.mmentryFields.cidField + self.mmentryFields.glidFField + self.mmentryFields.glidRField
+ if self.mmentryFields.glidF in globalId:
+ self.mmentryFields.createForwardLinkBle(myNumF, myEndTimeF, myIntBleF)
+ self.mmentry.CC_ALLOC_MOVE_REQ = self.mmentry.CC_ALLOC_MOVE_REQ + self.mmentryFields.forwardLinkBle.ble
+ if self.mmentryFields.glidR in globalId:
+ self.mmentryFields.createReverseLinkBle(myNumR, myEndTimeR, myIntBleR)
+ self.mmentry.CC_ALLOC_MOVE_REQ = self.mmentry.CC_ALLOC_MOVE_REQ + self.mmentryFields.reverseLinkBle.ble
+ self.mmentryFields.mmentry = self.mmentry.CC_ALLOC_MOVE_REQ
+ self.mmentryFields.mmtype = CC_ALLOC_MOVE_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC__ALLOC_MOVE_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC__ALLOC_MOVE.CNF MME
+ def createCC_ALLOC_MOVE_CNF_MMENTRY(self, myTei=None, myLlidF=None, myResult=None):
+ print "CC__ALLOC_MOVE.CNF ="
+ #CC__ALLOC_MOVE_CNF_MMENTRY is composed by 2 fields :
+ # - CID
+ # - Result
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createResult(myResult)
+ self.mmentry.CC_LINK_SQZ_CNF = self.mmentryFields.cidField + self.mmentryFields.resultField
+ self.mmentryFields.mmentry = self.mmentry.CC_LINK_SQZ_CNF
+ self.mmentryFields.mmtype = CC_LINK_SQZ_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_ACCESS_NEW_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_ACCESS_NEW.REQ MME
+ def createCC_ACCESS_NEW_REQ_MMENTRY(self, myStei=None, myDtei=None, myDAddr=None, myLlid=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None, myNum=None, myEndTime=None, myIntBle=None):
+ print "CC_ACCESS_NEW.REQ ="
+ #CC_ACCESS_NEW_REQ_MMENTRY is composed by 6 fields :
+ # - STEI
+ # - DTEI
+ # - DAddr
+ # - LLID
+ # - CSPEC
+ # - Bit Loading Estimates
+ self.mmentryFields.createStei(myStei)
+ self.mmentryFields.createDtei(myDtei)
+ self.mmentryFields.createDAddr(myDAddr)
+ self.mmentryFields.createLlid(myLlid)
+ self.mmentryFields.createCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentryFields.createBle(myNum, myEndTime, myIntBle)
+ self.mmentry.CC_ACCESS_NEW_REQ = self.mmentryFields.steiField + self.mmentryFields.dteiField + self.mmentryFields.dAddrField + self.mmentryFields.llidField + self.mmentryFields.cspecField + self.mmentryFields.bleField
+ self.mmentryFields.mmentry = self.mmentry.CC_ACCESS_NEW_REQ
+ self.mmentryFields.mmtype = CC_ACCESS_NEW_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+ #createCC_ACCESS_NEW_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_ACCESS_NEW.CNF MME
+ def createCC_ACCESS_NEW_CNF_MMENTRY(self, myResult=None, myLlid=None, myGcidF=None, myChanEstF=None, myGcidR=None, myChanEstR=None):
+ print "CC_ACCESS_NEW.CNF ="
+ #CC_ACCESS_NEW_CNF_MMENTRY is composed by 6 fields :
+ # - Result
+ # - LLID
+ # - GCID-F
+ # - ChanEstF
+ # - GCID-R
+ # - ChanEstR
+ self.mmentryFields.createResult(myResult)
+ self.mmentryFields.createLlid(myLlid)
+ self.mmentryFields.createGcidF(myGcidF)
+ self.mmentryFields.createChanEstF(myChanEstF)
+ self.mmentryFields.createGcidR(myGcidR)
+ self.mmentryFields.createChanEstR(myChanEstR)
+ self.mmentry.CC_ACCESS_NEW_CNF = self.mmentryFields.resultField + self.mmentryFields.llidField + self.mmentryFields.gcidFField + self.mmentryFields.chanEstFField + self.mmentryFields.gcidRField + self.mmentryFields.chanEstRField
+ self.mmentryFields.mmentry = self.mmentry.CC_ACCESS_NEW_CNF
+ self.mmentryFields.mmtype = CC_ACCESS_NEW_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_ACCESS_NEW_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_ACCESS_NEW.IND MME
+ def createCC_ACCESS_NEW_IND_MMENTRY(self, myResult=None, myLlid=None, myGcidF=None, myChanEstF=None, myGcidR=None, myChanEstR=None, mySecurityLevel=None, myNidOffset=None, myNid=None):
+ print "CC_ACCESS_NEW.IND ="
+ #CC_ACCESS_NEW_IND_MMENTRY is composed by 6 fields :
+ # - Result
+ # - LLID
+ # - GCID-F
+ # - ChanEstF
+ # - GCID-R
+ # - ChanEstR
+ # - NID
+ self.mmentryFields.createResult(myResult)
+ self.mmentryFields.createLlid(myLlid)
+ self.mmentryFields.createGcidF(myGcidF)
+ self.mmentryFields.createChanEstF(myChanEstF)
+ self.mmentryFields.createGcidR(myGcidR)
+ self.mmentryFields.createChanEstR(myChanEstR)
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentry.CC_ACCESS_NEW_IND = self.mmentryFields.resultField + self.mmentryFields.llidField + self.mmentryFields.gcidFField + self.mmentryFields.chanEstFField + self.mmentryFields.gcidRField + self.mmentryFields.chanEstRField + self.mmentryFields.nidField
+ self.mmentryFields.mmentry = self.mmentry.CC_ACCESS_NEW_IND
+ self.mmentryFields.mmtype = CC_ACCESS_NEW_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_ACCESS_NEW_RSP_MMENTRY creates
+ # the MMENTRY Field of the CC_ACCESS_NEW.RSP MME
+ def createCC_ACCESS_NEW_RSP_MMENTRY(self, myResult=None, myLlid=None, myGcidF=None, myGcidR=None, myNumF=None, myEndTimeF=None, myIntBleF=None, myNumR=None, myEndTimeR=None, myIntBleR=None):
+ print "CC_ACCESS_NEW.RSP ="
+ #CC_ACCESS_NEW_RSP_MMENTRY is composed by 6 fields :
+ # - Result
+ # - LLID
+ # - GCID-F
+ # - GCID-R
+ # - BLE-F
+ # - BLE-R
+ self.mmentryFields.createResult(myResult)
+ self.mmentryFields.createLlid(myLlid)
+ self.mmentryFields.createGcidF(myGcidF)
+ self.mmentryFields.createGcidR(myGcidR)
+ self.mmentryFields.createBleF(myNumF, myEndTimeF, myIntBleF)
+ self.mmentryFields.createBleR(myNumR, myEndTimeR, myIntBleR)
+ self.mmentry.CC_ACCESS_NEW_RSP = self.mmentryFields.resultField + self.mmentryFields.llidField + self.mmentryFields.gcidFField + self.mmentryFields.gcidRField + self.mmentryFields.bleFField + self.mmentryFields.bleRField
+ self.mmentryFields.mmentry = self.mmentry.CC_ACCESS_NEW_RSP
+ self.mmentryFields.mmtype = CC_ACCESS_NEW_RSP
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_ACCESS_REL_REQ_MMENTRY creates
+ # the MMENTRY Field of the CC_ACCESS_REL.REQ MME
+ def createCC_ACCESS_REL_REQ_MMENTRY(self, myGcidF=None, myGcidR=None):
+ print "CC_ACCESS_REL.REQ ="
+ #CC_ACCESS_REL_REQ_MMENTRY is composed by 3 fields :
+ # - Cause
+ # - GCID-F
+ # - GCID-R
+ self.mmentryFields.createCause()
+ self.mmentryFields.createGcidF(myGcidF)
+ self.mmentryFields.createGcidR(myGcidR)
+ self.mmentry.CC_ACCESS_REL_REQ = self.mmentryFields.causeField + self.mmentryFields.gcidFField + self.mmentryFields.gcidRField
+ self.mmentryFields.mmentry = self.mmentry.CC_ACCESS_REL_REQ
+ self.mmentryFields.mmtype = CC_ACCESS_REL_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_ACCESS_REL_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_ACCESS_REL.CNF MME
+ def createCC_ACCESS_REL_CNF_MMENTRY(self, myResult=None, myGcidF=None, myGcidR=None):
+ print "CC_ACCESS_REL.CNF ="
+ #CC_ACCESS_REL_CNF_MMENTRY is composed by 3 fields :
+ # - Result
+ # - GCID-F
+ # - GCID-R
+ self.mmentryFields.createResult(myResult)
+ self.mmentryFields.createGcidF(myGcidF)
+ self.mmentryFields.createGcidR(myGcidR)
+ self.mmentry.CC_ACCESS_REL_CNF = self.mmentryFields.resultField + self.mmentryFields.gcidFField + self.mmentryFields.gcidRField
+ self.mmentryFields.mmentry = self.mmentry.CC_ACCESS_REL_CNF
+ self.mmentryFields.mmtype = CC_ACCESS_REL_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_ACCESS_REL_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_ACCESS_REL.IND MME
+ def createCC_ACCESS_REL_IND_MMENTRY(self, myGcidF=None, myGcidR=None):
+ print "CC_ACCESS_REL.IND ="
+ #CC_ACCESS_REL_IND_MMENTRY is composed by 3 fields :
+ # - Cause
+ # - GCID-F
+ # - GCID-R
+ self.mmentryFields.createCause()
+ self.mmentryFields.createGcidF(myGcidF)
+ self.mmentryFields.createGcidR(myGcidR)
+ self.mmentry.CC_ACCESS_REL_IND = self.mmentryFields.causeField + self.mmentryFields.gcidFField + self.mmentryFields.gcidRField
+ self.mmentryFields.mmentry = self.mmentry.CC_ACCESS_REL_IND
+ self.mmentryFields.mmtype = CC_ACCESS_REL_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_ACCESS_REL_RSP_MMENTRY creates
+ # the MMENTRY Field of the CC_ACCESS_REL.RSP MME
+ def createCC_ACCESS_REL_RSP_MMENTRY(self, myResult=None, myGcidF=None, myGcidR=None):
+ print "CC_ACCESS_REL.RSP ="
+ #CC_ACCESS_REL_RSP_MMENTRY is composed by 3 fields :
+ # - Result
+ # - GCID-F
+ # - GCID-R
+ self.mmentryFields.createResult(myResult)
+ self.mmentryFields.createGcidF(myGcidF)
+ self.mmentryFields.createGcidR(myGcidR)
+ self.mmentry.CC_ACCESS_REL_RSP = self.mmentryFields.resultField + self.mmentryFields.gcidFField + self.mmentryFields.gcidRField
+ self.mmentryFields.mmentry = self.mmentry.CC_ACCESS_REL_RSP
+ self.mmentryFields.mmtype = CC_ACCESS_REL_RSP
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_DCPPC_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_DCPPC.IND MME
+ def createCC_DCPPC_IND_MMENTRY(self, myDcppc=None):
+ print "CC_DCPPC.IND ="
+ #CC_DCPPC_IND_MMENTRY is composed by 1 fields :
+ # - DCPPC
+ self.mmentryFields.createDcppc(myDcppc)
+ self.mmentry.CC_DCPPC_IND = self.mmentryFields.dcppcField
+ self.mmentryFields.mmentry = self.mmentry.CC_DCPPC_IND
+ self.mmentryFields.mmtype = CC_DCPPC_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_DCPPC.RSP has no MMENTRY
+ def createCC_DCPPC_RSP_MMENTRY(self):
+ print "CC_DCPPC.RSP ="
+ #CC_DCPPC_RSP_MMENTRY is composed by 0 field :
+ self.mmentry.CC_DCPPC_RSP = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_DCPPC_RSP
+ self.mmentryFields.mmtype = CC_DCPPC_RSP
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CC_HP1_DET.REQ has no MMENTRY
+ def createCC_HP1_DET_REQ_MMENTRY(self):
+ print "CC_HP1_DET.REQ ="
+ #CC_HP1_DET_REQ_MMENTRY is composed by 0 field :
+ self.mmentry.CC_HP1_DET_REQ = ""
+ self.mmentryFields.mmentry = self.mmentry.CC_HP1_DET_REQ
+ self.mmentryFields.mmtype = CC_HP1_DET_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_HP1_DET_CNF_MMENTRY creates
+ # the MMENTRY Field of the CC_HP1_DET.CNF MME
+ def createCC_HP1_DET_CNF_MMENTRY(self, myNbp=None, myNhp10=None, myNhp11=None):
+ print "CC_HP1_DET.CNF ="
+ #CC_HP1_DET_CNF_MMENTRY is composed by 3 fields :
+ # - NBP
+ # - NHP1.0
+ # - NHP1.1
+ self.mmentryFields.createNbp(myNbp)
+ self.mmentryFields.createNhp10(myNhp10)
+ self.mmentryFields.createNhp11(myNhp11)
+ self.mmentry.CC_HP1_DET_CNF = self.mmentryFields.nbpField + self.mmentryFields.nhp10Field + self.mmentryFields.nhp11Field
+ self.mmentryFields.mmentry = self.mmentry.CC_HP1_DET_CNF
+ self.mmentryFields.mmtype = CC_HP1_DET_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCC_BLE_UPDATE_IND_MMENTRY creates
+ # the MMENTRY Field of the CC_BLE_UPDATE.IND MME
+ def createCC_BLE_UPDATE_IND_MMENTRY(self, myGlids=None, myNum=None, myEndTime=None, myIntBle=None):
+ print "CC_BLE_UPDATE.IND ="
+ #CC_BLE_UPDATE_IND_MMENTRY is composed by 2 fields :
+ # - GLID
+ # - Bit Loading Estimates
+ myNumGlid=1
+ self.mmentryFields.createGlids(myNumGlid, myGlids)
+ self.mmentryFields.createBle(self, myNum, myEndTime, myIntBle)
+ self.mmentry.CC_BLE_UPDATE_IND = self.mmentryFields.glids.glidsField[0] + self.mmentryFields.bleField
+ self.mmentryFields.mmentry = self.mmentry.CC_BLE_UPDATE_IND
+ self.mmentryFields.mmtype = CC_BLE_UPDATE_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+
+ #----- Station - Station -----
+
+
+
+ #createCM_UNASSOCIATED_STA_IND_MMENTRY creates
+ # the MMENTRY Field of the CM_UNASSOCIATED_STA.IND MME
+ def createCM_UNASSOCIATED_STA_IND_MMENTRY(self, mySecurityLevel=None, myNidOffset=None, myNid=None, myCcoCapability=None, myMmentry=None):
+ print "CM_UNASSOCIATED_STA.IND ="
+ #CM_UNASSOCIATED_STA_IND_MMENTRY is composed by 2 fields :
+ # - NID
+ # - CCo Capability
+ if myMmentry==None:
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createCcoCapability(myCcoCapability)
+ self.mmentry.CM_UNASSOCIATED_STA_IND = self.mmentryFields.nidField + self.mmentryFields.ccoCapabilityField
+ self.mmentryFields.mmentry = self.mmentry.CM_UNASSOCIATED_STA_IND
+ self.mmentryFields.mmtype = CM_UNASSOCIATED_STA_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createNid(myNid = myMmentry[0:7])
+ self.mmentryFields.createCcoCapability(myCcoCapability = myMmentry[7:])
+
+
+ #createCM_ENCRYPTED_PAYLOAD_RSP_MMENTRY creates
+ # the MMENTRY Field of the CM_ENCRYPTED_PAYLOAD.RSP MME
+ def createCM_ENCRYPTED_PAYLOAD_RSP_MMENTRY(self, myResult=None, myPid=None, myPrn=None, myMmentry=None):
+ print "CM_ENCRYPTED_PAYLOAD.RSP ="
+ #CM_ENCRYPTED_PAYLOAD_RSP_MMENTRY is composed by 3 fields :
+ # - Result
+ # - PID
+ # - PRN
+ if myMmentry==None:
+ self.mmentryFields.createResult(myResult)
+ self.mmentryFields.createPid(myPid)
+ self.mmentryFields.createPrn(myPrn)
+ self.mmentry.CM_ENCRYPTED_PAYLOAD_RSP = self.mmentryFields.resultField + self.mmentryFields.pidField + self.mmentryFields.prnField
+ self.mmentryFields.mmentry = self.mmentry.CM_ENCRYPTED_PAYLOAD_RSP
+ self.mmentryFields.mmtype = CM_ENCRYPTED_PAYLOAD_RSP
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createResult(myResult=myMmentry[0])
+ self.mmentryFields.createPid(myPid=myMmentry[1])
+ self.mmentryFields.createPrn(myPrn=myMmentry[2:])
+
+ #createCM_SET_KEY_REQ_MMENTRY creates
+ # the MMENTRY Field of the CM_SET_KEY.REQ MME
+ def createCM_SET_KEY_REQ_MMENTRY(self, myKeyType=None, myMyNonce=None, myYourNonce=None, myPid=None, myPrn=None, myPmn=None, myPmnReset=False, myCcoCapability=None, mySecurityLevel=None, myNidOffset=None, myNid=None, myNewEks=None, myNewKey=None, myMmentry=None):
+ print "CM_SET_KEY.REQ ="
+ #CM_SET_KEY_REQ_MMENTRY is composed by 10 fields :
+ # - Key Type
+ # - My Nonce
+ # - Your Nonce
+ # - PID
+ # - PRN
+ # - PMN
+ # - CCo Capability
+ # - NID
+ # - New EKS
+ # - New KEY
+ if myMmentry==None:
+ self.mmentryFields.createKeyType(myKeyType)
+ self.mmentryFields.createMyNonce(myMyNonce)
+ self.mmentryFields.createYourNonce(myYourNonce)
+ self.mmentryFields.createPid(myPid)
+ self.mmentryFields.createPrn(myPrn)
+ self.mmentryFields.createPmn(myPmn, myPmnReset)
+ self.mmentryFields.createCcoCapability(myCcoCapability)
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createNewEks(myNewEks)
+ self.mmentryFields.createNewKey(myNewKey)
+ self.mmentry.CM_SET_KEY_REQ = self.mmentryFields.keyTypeField + self.mmentryFields.myNonceField + self.mmentryFields.yourNonceField + self.mmentryFields.pidField + self.mmentryFields.prnField + self.mmentryFields.pmnField + self.mmentryFields.ccoCapabilityField + self.mmentryFields.nidField + self.mmentryFields.newEksField + self.mmentryFields.newKeyField
+ self.mmentryFields.mmentry = self.mmentry.CM_SET_KEY_REQ
+ self.mmentryFields.mmtype = CM_SET_KEY_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createKeyType(myKeyType=myMmentry[0])
+ self.mmentryFields.createMyNonce(myMyNonce=myMmentry[1:5])
+ self.mmentryFields.createYourNonce(myYourNonce=myMmentry[5:9])
+ self.mmentryFields.createPid(myPid=myMmentry[9])
+ self.mmentryFields.createPrn(myPrn=myMmentry[10:12])
+ self.mmentryFields.createPmn(myPmn=myMmentry[12])
+ self.mmentryFields.createCcoCapability(myCcoCapability=myMmentry[13])
+ self.mmentryFields.createNid(myNid=myMmentry[14:21])
+ self.mmentryFields.createNewEks(myNewEks=myMmentry[21])
+ self.mmentryFields.createNewKey(myNewKey=myMmentry[22:])
+
+
+ #createCM_SET_KEY_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_SET_KEY.CNF MME
+ def createCM_SET_KEY_CNF_MMENTRY(self, myResult=None, myMyNonce=None, myYourNonce=None, myPid=None, myPrn=None, myPmn=None, myPmnReset=False, myCcoCapability=None, myMmentry=None):
+ print "CM_SET_KEY.CNF ="
+ #CM_SET_KEY_CNF_MMENTRY is composed by 7 fields :
+ # - Result
+ # - My Nonce
+ # - Your Nonce
+ # - PID
+ # - PRN
+ # - PMN
+ # - CCo Capability
+ if myMmentry==None:
+ self.mmentryFields.createResult(myResult)
+ self.mmentryFields.createMyNonce(myMyNonce)
+ self.mmentryFields.createYourNonce(myYourNonce)
+ self.mmentryFields.createPid(myPid)
+ self.mmentryFields.createPrn(myPrn)
+ self.mmentryFields.createPmn(myPmn, myPmnReset)
+ self.mmentryFields.createCcoCapability(myCcoCapability)
+ self.mmentry.CM_SET_KEY_CNF = self.mmentryFields.resultField + self.mmentryFields.myNonceField + self.mmentryFields.yourNonceField + self.mmentryFields.pidField + self.mmentryFields.prnField + self.mmentryFields.pmnField + self.mmentryFields.ccoCapabilityField
+ self.mmentryFields.mmentry = self.mmentry.CM_SET_KEY_CNF
+ self.mmentryFields.mmtype = CM_SET_KEY_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createResult(myResult=myMmentry[0])
+ self.mmentryFields.createMyNonce(myMyNonce=myMmentry[1:5])
+ self.mmentryFields.createYourNonce(myYourNonce=myMmentry[5:9])
+ self.mmentryFields.createPid(myPid=myMmentry[9])
+ self.mmentryFields.createPrn(myPrn=myMmentry[10:12])
+ self.mmentryFields.createPmn(myPmn=myMmentry[12])
+ self.mmentryFields.createCcoCapability(myCcoCapability=myMmentry[13:])
+
+
+ #createCM_GET_KEY_REQ_MMENTRY creates
+ # the MMENTRY Field of the CM_GET_KEY.REQ MME
+ def createCM_GET_KEY_REQ_MMENTRY(self, myRequestType=None, myRequestedKeyType=None, mySecurityLevel=None, myNidOffset=None, myNid=None, myMyNonce=None, myPid=None, myPrn=None, myPmn=None, myPmnReset=False, myHashKey=None, myMmentry=None):
+ print "CM_GET_KEY.REQ ="
+ #CM_GET_KEY_REQ_MMENTRY is composed by 8 fields :
+ # - Request Type
+ # - Requested Key Type
+ # - NID
+ # - My Nonce
+ # - PID
+ # - PRN
+ # - PMN
+ # - HASH KEY
+ if myMmentry==None:
+ self.mmentryFields.createRequestType(myRequestType)
+ self.mmentryFields.createRequestedKeyType(myRequestedKeyType)
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createMyNonce(myMyNonce)
+ self.mmentryFields.createPid(myPid)
+ self.mmentryFields.createPrn(myPrn)
+ self.mmentryFields.createPmn(myPmn, myPmnReset)
+ self.mmentry.CM_GET_KEY_REQ = self.mmentryFields.requestTypeField + self.mmentryFields.requestedKeyTypeField + self.mmentryFields.nidField + self.mmentryFields.myNonceField + self.mmentryFields.pidField + self.mmentryFields.prnField + self.mmentryFields.pmnField
+ if self.mmentryFields.requestedKeyType == 4:
+ self.mmentryFields.createHashKey(myHashKey)
+ self.mmentry.CM_GET_KEY_REQ = self.mmentry.CM_GET_KEY_REQ + self.mmentryFields.hashKeyField
+ self.mmentryFields.mmentry = self.mmentry.CM_GET_KEY_REQ
+ self.mmentryFields.mmtype = CM_GET_KEY_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createRequestType(myRequestType=myMmentry[0])
+ self.mmentryFields.createRequestedKeyType(myRequestedKeyType=myMmentry[1])
+ self.mmentryFields.createNid(myNid=myMmentry[2:9])
+ self.mmentryFields.createMyNonce(myMyNonce=myMmentry[9:13])
+ self.mmentryFields.createPid(myPid=myMmentry[13])
+ self.mmentryFields.createPrn(myPrn=myMmentry[14:16])
+ self.mmentryFields.createPmn(myPmn=myMmentry[16])
+ if self.mmentryFields.requestedKeyType == 4:
+ self.mmentryFields.createHashKey(myHashKey=myMmentry[17:])
+
+
+ #createCM_GET_KEY_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_GET_KEY.CNF MME
+ def createCM_GET_KEY_CNF_MMENTRY(self, myResult=None, myRequestedKeyType=None, myMyNonce=None, myYourNonce=None, mySecurityLevel=None, myNidOffset=None, myNid=None, myEks=None, myPid=None, myPrn=None, myPmn=None, myPmnReset=False, myKey=None, myHashKey=None, myMmentry=None):
+ print "CM_GET_KEY.CNF ="
+ #CM_GET_KEY_CNF_MMENTRY is composed by 10 fields :
+ # - Result
+ # - Requested Key Type
+ # - My Nonce
+ # - Your Nonce
+ # - NID
+ # - EKS
+ # - PID
+ # - PRN
+ # - PMN
+ # - Key
+ if myMmentry==None:
+ self.mmentryFields.createResult(myResult)
+ self.mmentryFields.createRequestedKeyType(myRequestedKeyType)
+ self.mmentryFields.createMyNonce(myMyNonce)
+ self.mmentryFields.createYourNonce(myYourNonce)
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createEks(myEks)
+ self.mmentryFields.createPid(myPid)
+ self.mmentryFields.createPrn(myPrn)
+ self.mmentryFields.createPmn(myPmn, myPmnReset)
+ self.mmentry.CM_GET_KEY_CNF = self.mmentryFields.resultField + self.mmentryFields.requestedKeyTypeField + self.mmentryFields.myNonceField + self.mmentryFields.yourNonceField + self.mmentryFields.nidField + self.mmentryFields.eksField + self.mmentryFields.pidField + self.mmentryFields.prnField + self.mmentryFields.pmnField
+ if self.mmentryFields.requestedKeyType == 4:
+ self.mmentryFields.createHashKey(myHashKey)
+ self.mmentry.CM_GET_KEY_CNF = self.mmentry.CM_GET_KEY_CNF + self.mmentryFields.hashKeyField
+ elif self.mmentryFields.requestedKeyType < 4:
+ self.mmentryFields.createKey(myKey)
+ self.mmentry.CM_GET_KEY_CNF = self.mmentry.CM_GET_KEY_CNF + self.mmentryFields.keyField
+ self.mmentryFields.mmentry = self.mmentry.CM_GET_KEY_CNF
+ self.mmentryFields.mmtype = CM_GET_KEY_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createResult(myResult=myMmentry[0])
+ self.mmentryFields.createRequestedKeyType(myRequestedKeyType=myMmentry[1])
+ self.mmentryFields.createMyNonce(myMyNonce=myMmentry[2:6])
+ self.mmentryFields.createYourNonce(myYourNonce=myMmentry[6:10])
+ self.mmentryFields.createNid(myNid=myMmentry[10:17])
+ self.mmentryFields.createEks(myEks=myMmentry[17])
+ self.mmentryFields.createPid(myPid=myMmentry[18])
+ self.mmentryFields.createPrn(myPrn=myMmentry[19:21])
+ self.mmentryFields.createPmn(myPmn=myMmentry[21])
+ if self.mmentryFields.requestedKeyType == 4:
+ self.mmentryFields.createHashKey(myHashKey=myMmentry[22:])
+ elif self.mmentryFields.requestedKeyType < 4:
+ self.mmentryFields.createKey(myKey=myMmentry[22:])
+
+
+ #createCM_SC_JOIN_REQ_MMENTRY creates
+ # the MMENTRY Field of the CM_SC_JOIN.REQ MME
+ def createCM_SC_JOIN_REQ_MMENTRY(self, myCcoCapability=None, myMmentry=None):
+ print "CM_SC_JOIN.REQ ="
+ #CM_SC_JOIN_REQ_MMENTRY is composed by 1 fields :
+ # - CCo Capability
+ if myMmentry==None:
+ self.mmentryFields.createCcoCapability(myCcoCapability)
+ self.mmentry.CM_SC_JOIN_REQ = self.mmentryFields.ccoCapabilityField
+ self.mmentryFields.mmentry = self.mmentry.CM_SC_JOIN_REQ
+ self.mmentryFields.mmtype = CM_SC_JOIN_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createCcoCapability(myCcoCapability=myMmentry)
+
+
+ #createCM_SC_JOIN_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_SC_JOIN.CNF MME
+ def createCM_SC_JOIN_CNF_MMENTRY(self, mySecurityLevel=None, myNidOffset=None, myNid=None, myAvlnStatus=None, myCcoCapability=None, myProxyNetworkCapability=None, myBackupCcoCapability=None, myCcoStatus=None, myPcoStatus=None, myBackupCcoStatus=None, myStatusesNCapabilities=None):
+ print "CM_SC_JOIN.CNF ="
+ #CM_SC_JOIN_CNF_MMENTRY is composed by 2 fields :
+ # - NID
+ # - Statuses and Capabilities
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createStatusesNCapabilities(myAvlnStatus, myCcoCapability, myProxyNetworkCapability, myBackupCcoCapability, myCcoStatus, myPcoStatus, myBackupCcoStatus, myStatusesNCapabilities)
+ self.mmentry.CM_SC_JOIN_CNF = self.mmentryFields.nidField + self.mmentryFields.statusesNCapabilitiesField
+ self.mmentryFields.mmentry = self.mmentry.CM_SC_JOIN_CNF
+ self.mmentryFields.mmtype = CM_SC_JOIN_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_AMP_MAP_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_AMP_MAP.CNF MME
+ def createCM_AMP_MAP_CNF_MMENTRY(self, myResType=None):
+ print "CM_AMP_MAP.CNF ="
+ #CM_AMP_MAP_CNF_MMENTRY is composed by 1 field :
+ # - ResType
+ self.mmentryFields.createResType(myResType)
+ self.mmentry.CM_AMP_MAP_CNF = self.mmentryFields.resTypeField
+ self.mmentryFields.mmentry = self.mmentry.CM_AMP_MAP_CNF
+ self.mmentryFields.mmtype = CM_AMP_MAP_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CM_BRG_INFO.REQ has no MMENTRY
+ def createCM_BRG_INFO_REQ_MMENTRY(self):
+ print "CM_BRG_INFO.REQ ="
+ #CM_BRG_INFO_REQ_MMENTRY is composed by 0 field :
+ self.mmentry.CM_BRG_INFO_REQ = ""
+ self.mmentryFields.mmentry = self.mmentry.CM_BRG_INFO_REQ
+ self.mmentryFields.mmtype = CM_BRG_INFO_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_BRG_INFO_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_BRG_INFO.CNF MME
+ def createCM_BRG_INFO_CNF_MMENTRY(self, myBsf=None, myBtei=None, myNbda=0, myBda=None):
+ print "CM_BRG_INFO.CNF ="
+ #CM_BRG_INFO_CNF_MMENTRY is composed by 4 fields :
+ # - BSF
+ # - BIVF :
+ # - BTEI
+ # - NBDA
+ # - BAD -*NBDA-
+ self.mmentryFields.createBsf(myBsf)
+ self.mmentryFields.createBtei(myBtei)
+ self.mmentryFields.createNbda(myNbda)
+ self.mmentry.CM_BRG_INFO_CNF = self.mmentryFields.bsfField + self.mmentryFields.bteiField + self.mmentryFields.nbdaField
+ self.mmentryFields.createBdas(self.mmentryFields.nbda, myBda)
+ self.i=0
+ while self.i<self.mmentryFields.nbda:
+ self.mmentry.CM_BRG_INFO_CNF = self.mmentry.CM_BRG_INFO_CNF + self.mmentryFields.bdasField[self.i]
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CM_BRG_INFO_CNF
+ self.mmentryFields.mmtype = CM_BRG_INFO_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_CONN_NEW_REQ_MMENTRY creates
+ # the MMENTRY Field of the CM_CONN_NEW.REQ MME
+ def createCM_CONN_NEW_REQ_MMENTRY(self, myTei=None, myLlidF=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None, myClassifierRuleSetVersion=None, myNumberofClassifierRules=None, myClassifierRuleIdentifier=None, myClassifierRules=None):
+ print "CM_CONN_NEW.REQ ="
+ #CM_CONN_NEW_REQ_MMENTRY is composed by 6 fields :
+ # - CID
+ # - CSPEC
+ # - Classifier Rule Set
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentryFields.createClassifierRuleSetField(myClassifierRuleSetVersion, myNumberofClassifierRules, myClassifierRuleIdentifier, myClassifierRules)
+ self.mmentry.CM_CONN_NEW_REQ = self.mmentryFields.cidField + self.mmentryFields.cspecField + self.mmentryFields.classifierRuleSetField
+ self.mmentryFields.mmentry = self.mmentry.CM_CONN_NEW_REQ
+ self.mmentryFields.mmtype = CM_CONN_NEW_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_CHAN_EST_IND_MMENTRY creates
+ # the MMENTRY Field of the CM_CHAN_EST.IND MME
+ def createCM_CHAN_EST_IND_MMENTRY(self, myMaxFL_AV=None, myRifs_AV_OneSym=None, myRifs_AV_TwoSym=None, myRifs_AV_G2Sym=None, myRespt=None, myMaxtm=None, myCp_TMI_AV=None, myScl_CP=None, myScl_CFP=None, myNtmi_AV=None, myTmi_AV=None, myNint=None, myRandomEt=False, myInt_TMI_AV=None, myRandomInt_TMI_AV=False, myNewTMI_AV=None, myCpf=None, myFecType=None, myGil=None, myCbd_Enc=None, myCbd_Len=None, myCbd=None):
+ print "CM_CHAN_EST.IND ="
+ #CM_CHAN_EST_IND_MMENTRY is composed by 22 fields :
+ # - MaxFL_AV
+ # - Rifs_AV_OneSym
+ # - Rifs_AV_TwoSym
+ # - Rifs_AV_G2Sym
+ # - Respt
+ # - Maxtm
+ # - Cp_TMI_AV
+ # - Scl_CP
+ # - Scl_CFP
+ # - Ntmi_AV
+ # - Tmi_AV - *Ntmi_AV -
+ # - Nint
+ # - Et - Int_TMI_AV - *Nint -
+ # - NewTMI_AV
+ # - Cpf
+ # - FecType
+ # - Gil
+ # - Cbd_Enc
+ # - Cbd_Len
+ # - Cbd_Len
+ # - Cbd - *Cbd_Len -
+ self.mmentryFields.createMaxFL_AV(myMaxFL_AV)
+ self.mmentryFields.createRifs_AV_OneSym(myRifs_AV_OneSym)
+ self.mmentryFields.createRifs_AV_TwoSym(myRifs_AV_TwoSym)
+ self.mmentryFields.createRifs_AV_G2Sym(myRifs_AV_G2Sym)
+ self.mmentryFields.createRespt(myRespt)
+ self.mmentryFields.createMaxtm(myMaxtm)
+ self.mmentryFields.createCp_TMI_AV(myCp_TMI_AV)
+ self.mmentryFields.createScl_CP(myScl_CP)
+ self.mmentryFields.createScl_CFP(myScl_CFP)
+ self.mmentryFields.createTmi_AV(myNtmi_AV, myTmi_AV)
+ self.mmentryFields.createEtNInt_TMI_AV(myNint, myRandomEt, myInt_TMI_AV, myRandomInt_TMI_AV)
+ self.mmentryFields.createNewTMI_AV(myNewTMI_AV)
+ self.mmentryFields.createCpf(myCpf)
+ self.mmentryFields.createFecType(myFecType)
+ self.mmentryFields.createGil(myGil)
+ self.mmentryFields.createCbd_Enc(myCbd_Enc)
+ self.mmentryFields.createCbd(myCbd_Len, myCbd)
+ self.mmentry.CM_CHAN_EST_IND = self.mmentryFields.maxFL_AVField + self.mmentryFields.rifs_AV_OneSymField + self.mmentryFields.rifs_AV_TwoSymField + self.mmentryFields.rifs_AV_G2SymField + self.mmentryFields.resptField + self.mmentryFields.maxtmField + self.mmentryFields.cp_TMI_AVField + self.mmentryFields.scl_CPField + self.mmentryFields.scl_CFPField + self.mmentryFields.ntmi_AVField
+ self.i=0
+ while self.i<self.mmentryFields.ntmi_AV:
+ self.mmentry.CM_CHAN_EST_IND = self.mmentry.CM_CHAN_EST_IND + self.mmentryFields.tmi_AVsField[self.i]
+ self.i=self.i+1
+ self.mmentry.CM_CHAN_EST_IND = self.mmentry.CM_CHAN_EST_IND + self.mmentryFields.nintField
+ self.i=0
+ while self.i<self.mmentryFields.nint:
+ self.mmentry.CM_CHAN_EST_IND = self.mmentry.CM_CHAN_EST_IND + self.mmentryFields.etsField[self.i] + self.mmentryFields.int_TMI_AVsField[self.i]
+ self.i=self.i+1
+ self.mmentry.CM_CHAN_EST_IND = self.mmentry.CM_CHAN_EST_IND + self.mmentryFields.newTMI_AVField + self.mmentryFields.cpfField + self.mmentryFields.fecTypeField + self.mmentryFields.gilField + self.mmentryFields.cbd_EncField + self.mmentryFields.cbd_LenField
+ self.i=0
+ while self.i<(self.mmentryFields.cbd_Len + (self.mmentryFields.cbd_Len % 2))/2:
+ self.mmentry.CM_CHAN_EST_IND = self.mmentry.CM_CHAN_EST_IND + self.mmentryFields.cbdsField[self.i]
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CM_CHAN_EST_IND
+ self.mmentryFields.mmtype = CM_CHAN_EST_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+ #createCM_TM_UPDATE_IND_MMENTRY creates
+ # the MMENTRY Field of the CM_TM_UPDATE.IND MME
+ def createCM_TM_UPDATE_IND_MMENTRY(self, myCp_TMI_AV=None, myNtmi_AV=None, myTmi_AV=None, myNint=None, myRandomEt=False, myInt_TMI_AV=None, myRandomInt_TMI_AV=False, myOldTMI_AV=None, myNewTMI_AV=None, myCpf=None, myFecType=None, myGil=None, myCbud_Len=None, myCbudModulation=None):
+ print "CM_TM_UPDATE.IND ="
+ #CM_TM_UPDATE_IND_MMENTRY is composed by 13 fields :
+ # - Cp_TMI_AV
+ # - Ntmi_AV
+ # - Tmi_AV - *Ntmi_AV -
+ # - Nint
+ # - Et - Int_TMI_AV - *Nint -
+ # - OldTMI_AV
+ # - NewTMI_AV
+ # - Cpf
+ # - FecType
+ # - Gil
+ # - Cbud_Len
+ # - Cbud - *Cbud_Len -
+ self.mmentryFields.createCp_TMI_AV(myCp_TMI_AV)
+ self.mmentryFields.createTmi_AV(myNtmi_AV, myTmi_AV)
+ self.mmentryFields.createEtNInt_TMI_AV(myNint, myRandomEt, myInt_TMI_AV, myRandomInt_TMI_AV)
+ self.mmentryFields.createOldTMI_AV(myOldTMI_AV)
+ self.mmentryFields.createNewTMI_AV(myNewTMI_AV)
+ self.mmentryFields.createCpf(myCpf)
+ self.mmentryFields.createFecType(myFecType)
+ self.mmentryFields.createGil(myGil)
+ self.mmentryFields.createCbud(myCbud_Len, myCbudModulation)
+ self.mmentry.CM_TM_UPDATE_IND = self.mmentryFields.cp_TMI_AVField + self.mmentryFields.ntmi_AVField
+ self.i=0
+ while self.i<self.mmentryFields.ntmi_AV:
+ self.mmentry.CM_TM_UPDATE_IND = self.mmentry.CM_TM_UPDATE_IND + self.mmentryFields.tmi_AVsField[self.i]
+ self.i=self.i+1
+ self.mmentry.CM_TM_UPDATE_IND = self.mmentry.CM_TM_UPDATE_IND + self.mmentryFields.nintField
+ self.i=0
+ while self.i<self.mmentryFields.nint:
+ self.mmentry.CM_TM_UPDATE_IND = self.mmentry.CM_TM_UPDATE_IND + self.mmentryFields.etsField[self.i] + self.mmentryFields.int_TMI_AVsField[self.i]
+ self.i=self.i+1
+ self.mmentry.CM_TM_UPDATE_IND = self.mmentry.CM_TM_UPDATE_IND + self.mmentryFields.oldTMI_AVField + self.mmentryFields.newTMI_AVField + self.mmentryFields.cpfField + self.mmentryFields.fecTypeField + self.mmentryFields.gilField + self.mmentryFields.cbud_LenField
+ self.i=0
+ while self.i<self.mmentryFields.cbud_Len:
+ self.mmentry.CM_TM_UPDATE_IND = self.mmentry.CM_TM_UPDATE_IND + self.mmentryFields.cbudsField[self.i]
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CM_TM_UPDATE_IND
+ self.mmentryFields.mmtype = CM_TM_UPDATE_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY creates
+ # the MMENTRY Field of the CM_ENCRYPTED_PAYLOAD.IND MME
+ def createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(self, myPeks=None, myAvlnStatus=None, myPid=None, myPrn=None, myPmn=None, myIvOrUuid=None, myIvOrUuidRandom=False, myRandomFillerEncrypted=None, myOda=None, myOsa=None, myVlanTag=None, myMtype=None, myMmv=None, myMmtype=None, myNfmi=None, myFnMi=None, myFmsn=None, myMmentry=None, myEncapsulatedMmEntry="ToEncrypt", myMmOrHlePayloadEncrypted=None, myCrcEncrypted=None, myPidEncrypted=None, myPrnEncrypted=None, myRandomPrn=None, myPmnEncrypted=None, myPaddingEncrypted=None, myRfLenEncrypted=None, myKey=None, myEncryptedFields=None):
+ print "CM_ENCRYPTED_PAYLOAD.IND ="
+ #CM_ENCRYPTED_PAYLOAD_IND_MMENTRY is composed by 15 fields :
+ # - Peks
+ # - AvlnStatus
+ # - Pid
+ # - Prn
+ # - Pmn
+ # - IV or UUID
+ # - LengthForEncryption
+ # - RandomFillerEncrypted
+ # - MmOrHlePayloadEncrypted
+ # - CrcEncrypted
+ # - PidEncrypted
+ # - PrnEncrypted
+ # - PmnEncrypted
+ # - PaddingEncrypted
+ # - RfLenEncrypted
+ if myEncryptedFields == None:
+ self.mmentryFields.createPeks(myPeks)
+ self.mmentryFields.createAvlnStatus(myAvlnStatus)
+ self.mmentryFields.createPid(myPid)
+ self.mmentryFields.createPrn(myPrn)
+ self.mmentryFields.createPmn(myPmn)
+ self.mmentry.CM_ENCRYPTED_PAYLOAD_IND = self.mmentryFields.peksField + self.mmentryFields.avlnStatusField + self.mmentryFields.pidField + self.mmentryFields.prnField + self.mmentryFields.pmnField
+ if self.mmentryFields.pid==4:
+ self.mmentryFields.createUuid(myIvOrUuid, myIvOrUuidRandom)
+ self.mmentryFields.createMmOrHlePayloadEncrypted(self.mmentryFields.pid, myMmOrHlePayloadEncrypted)
+ self.mmentryFields.createLengthForEncryption()
+ self.mmentry.CM_ENCRYPTED_PAYLOAD_IND = self.mmentry.CM_ENCRYPTED_PAYLOAD_IND + self.mmentryFields.uuidField + self.mmentryFields.lengthForEncryptionField + self.mmentryFields.mmOrHlePayloadEncryptedField
+ else:
+ self.mmentry.CM_ENCRYPTED_PAYLOAD_IND = self.mmentry.CM_ENCRYPTED_PAYLOAD_IND + self.mmentryFields.createEncryptedFields(myIvOrUuid, myIvOrUuidRandom, myRandomFillerEncrypted, myOda, myOsa, myVlanTag, myMtype, myMmv, myMmtype, myNfmi, myFnMi, myFmsn, myMmentry, myEncapsulatedMmEntry, myMmOrHlePayloadEncrypted, myCrcEncrypted, myPidEncrypted, myPrnEncrypted, myRandomPrn, myPmnEncrypted, myPaddingEncrypted, myRfLenEncrypted, myKey, myEncryptedFields)
+ self.mmentryFields.mmentry = self.mmentry.CM_ENCRYPTED_PAYLOAD_IND
+ self.mmentryFields.mmtype = CM_ENCRYPTED_PAYLOAD_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createPeks(myEncryptedFields[0])
+ self.mmentryFields.createAvlnStatus(myEncryptedFields[1])
+ self.mmentryFields.createPid(myEncryptedFields[2])
+ self.mmentryFields.createPrn(myEncryptedFields[3:5])
+ self.mmentryFields.createPmn(myEncryptedFields[5])
+ if self.mmentryFields.pid==4:
+ self.mmentryFields.createUuid(myEncryptedFields[6:22])
+ self.mmentryFields.createLengthForEncryption(myEncryptedFields[22:24])
+ self.mmentryFields.createMmOrHlePayloadEncrypted(myEncryptedFields[24:])
+ else:
+ self.mmentryFields.createEncryptedFields(myKey=myKey,myEncryptedFields=myEncryptedFields[6:])
+
+
+ #createCM_MME_ERROR_IND_MMENTRY creates
+ # the MMENTRY Field of the CM_MME_ERROR.IND MME
+ def createCM_MME_ERROR_IND_MMENTRY(self, myReasonCode=None, myRx_MMV=None, myRx_MMTYPE=None, myInvalidByteOffset=None, myMmentry=None):
+ print "CM_MME_ERROR.IND ="
+ #CM_MME_ERROR_IND_MMENTRY is composed by 4 fields :
+ # - ReasonCode
+ # - Rx_MMV
+ # - Rx_MMTYPE
+ # - InvalidByteOffset
+ if myMmentry==None:
+ self.mmentryFields.createReasonCode(myReasonCode)
+ self.mmentryFields.createRx_MMV(myRx_MMV)
+ self.mmentryFields.createRx_MMTYPE(myRx_MMTYPE)
+ self.mmentryFields.createInvalidByteOffset(myInvalidByteOffset)
+ self.mmentry.CM_MME_ERROR_IND = self.mmentryFields.reasonCodeField + self.mmentryFields.rx_MMVField + self.mmentryFields.rx_MMTYPEField + self.mmentryFields.invalidByteOffsetField
+ self.mmentryFields.mmentry = self.mmentry.CM_MME_ERROR_IND
+ self.mmentryFields.mmtype = CM_MME_ERROR_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+ else:
+ self.mmentryFields.createReasonCode(myReasonCode=myMmentry[0])
+ self.mmentryFields.createRx_MMV(myRx_MMV=myMmentry[1])
+ self.mmentryFields.createRx_MMTYPE(myRx_MMTYPE=myMmentry[2:4])
+ self.mmentryFields.createInvalidByteOffset(myInvalidByteOffset=myMmentry[4:])
+
+
+ #createCM_CONN_NEW_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_CONN_NEW.CNF MME
+ def createCM_CONN_NEW_CNF_MMENTRY(self, myTei=None, myLlidF=None, myLlidR=None, myResult=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CM_CONN_NEW.CNF ="
+ #CM_CONN_NEW_CNF_MMENTRY is composed by 4 fields :
+ # - CID
+ # - LLID-R
+ # - Result
+ # - Proposed CSPEC
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createLlidR(myLlidR)
+ self.mmentryFields.createResult(myResult)
+ self.mmentry.CM_CONN_NEW_CNF = self.mmentryFields.cidField + self.mmentryFields.llidRField + self.mmentryFields.resultField
+ if self.mmentryFields.result == 4 :
+ self.mmentryFields.createProposedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CM_CONN_NEW_CNF = self.mmentry.CM_CONN_NEW_CNF + self.mmentryFields.proposedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CM_CONN_NEW_CNF
+ self.mmentryFields.mmtype = CM_CONN_NEW_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_CONN_REL_IND_MMENTRY creates
+ # the MMENTRY Field of the CM_CONN_REL.IND MME
+ def createCM_CONN_REL_IND_MMENTRY(self, myTei=None, myLlidF=None, myReasonCode=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CM_CONN_REL.IND ="
+ #CM_CONN_REL_IND_MMENTRY is composed by 3 fields :
+ # - CID
+ # - Reason Code
+ # - Violated CSPEC
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createReasonCode(myReasonCode)
+ self.mmentry.CM_CONN_REL_IND = self.mmentryFields.cidField + self.mmentryFields.reasonCodeField
+ if self.mmentryFields.reasonCode == 1 :
+ self.mmentryFields.createViolatedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CM_CONN_REL_IND = self.mmentry.CM_CONN_REL_IND + self.mmentryFields.violatedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CM_CONN_REL_IND
+ self.mmentryFields.mmtype = CM_CONN_REL_IND
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_CONN_REL_RSP_MMENTRY creates
+ # the MMENTRY Field of the CM_CONN_REL.RSP MME
+ def createCM_CONN_REL_RSP_MMENTRY(self, myTei=None, myLlidF=None):
+ print "CM_CONN_REL.RSP ="
+ #CM_CONN_REL_RSP_MMENTRY is composed by 1 fields :
+ # - CID
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentry.CM_CONN_REL_RSP = self.mmentryFields.cidField
+ self.mmentryFields.mmentry = self.mmentry.CM_CONN_REL_RSP
+ self.mmentryFields.mmtype = CM_CONN_REL_RSP
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_CONN_MOD_REQ_MMENTRY creates
+ # the MMENTRY Field of the CM_CONN_MOD.REQ MME
+ def createCM_CONN_MOD_REQ_MMENTRY(self, myTei=None, myLlidF=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CM_CONN_MOD.REQ ="
+ #CM_CONN_MOD_REQ_MMENTRY is composed by 2 fields :
+ # - CID
+ # - Modified CSPEC
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createModifiedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CM_CONN_MOD_REQ = self.mmentryFields.cidField + self.mmentryFields.modifiedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CM_CONN_MOD_REQ
+ self.mmentryFields.mmtype = CM_CONN_MOD_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_CONN_MOD_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_CONN_MOD.CNF MME
+ def createCM_CONN_MOD_CNF_MMENTRY(self, myTei=None, myLlidF=None, myResult=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CM_CONN_MOD.CNF ="
+ #CM_CONN_MOD_CNF_MMENTRY is composed by 3 fields :
+ # - CID
+ # - Result
+ # - Proposed CSPEC
+ self.mmentryFields.createCid(myTei, myLlidF)
+ self.mmentryFields.createResult(myResult)
+ self.mmentry.CM_CONN_MOD_CNF = self.mmentryFields.cidField + self.mmentryFields.resultField
+ if self.mmentryFields.result == 1 :
+ self.mmentryFields.createProposedCspec(myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CM_CONN_MOD_CNF = self.mmentry.CM_CONN_MOD_CNF + self.mmentryFields.proposedCspecField
+ self.mmentryFields.mmentry = self.mmentry.CM_CONN_MOD_CNF
+ self.mmentryFields.mmtype = CM_CONN_MOD_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_CONN_INFO_REQ_MMENTRY creates
+ # the MMENTRY Field of the CM_CONN_INFO.REQ MME
+ def createCM_CONN_INFO_REQ_MMENTRY(self, myReqType=None, myTei=None, myLlidF=None, myGlids=None):
+ print "CM_CONN_INFO.REQ ="
+ #CM_CONN_INFO_REQ_MMENTRY is composed by 3 fields :
+ # - ReqType
+ # - CID
+ # - GLID
+ self.mmentryFields.createReqType(myReqType)
+ self.mmentryFields.createCid(myTei, myLlidF)
+ myNumGlid=1
+ self.mmentryFields.createGlids(myNumGlid, myGlids)
+ self.mmentry.CM_CONN_INFO_REQ = self.mmentryFields.reqTypeField + self.mmentryFields.cidField + self.mmentryFields.glids.glidsField[0]
+ self.mmentryFields.mmentry = self.mmentry.CM_CONN_INFO_REQ
+ self.mmentryFields.mmtype = CM_CONN_INFO_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_CONN_INFO_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_CONN_INFO.CNF MME
+ def createCM_CONN_INFO_CNF_MMENTRY(self, myNumConn=0, myTei=None, myLlidF=None, myStei=None, myDtei=None, myLidF=None, myLidR=None, myCsepcLen=None, myValidF=None, myMacServiceTypeF=None, myUserPriorityF=None, myAtsF=None, mySmoothingF=None, myValidR=None, myMacServiceTypeR=None, myUserPriorityR=None, myAtsR=None, mySmoothingR=None, myFRF=None, myFidF=None, qmpParam1F=None, qmpParam2F=None, qmpParam3F=None, qmpParam4F=None, qmpParam5F=None, qmpParam6F=None, myFRR=None, myFidR=None, qmpParam1R=None, qmpParam2R=None, qmpParam3R=None, qmpParam4R=None, qmpParam5R=None, qmpParam6R=None):
+ print "CM_CONN_INFO.CNF ="
+ #CM_CONN_INFO_CNF_MMENTRY is composed by 2 fields :
+ # - NumConn
+ # - Connection Informations -* NumConn-
+ self.mmentryFields.createConnInfos(myNumConn, myTei, myLlidF, myStei, myDtei, myLidF, myLidR, myCsepcLen, myValidF, myMacServiceTypeF, myUserPriorityF, myAtsF, mySmoothingF, myValidR, myMacServiceTypeR, myUserPriorityR, myAtsR, mySmoothingR, myFRF, myFidF, qmpParam1F, qmpParam2F, qmpParam3F, qmpParam4F, qmpParam5F, qmpParam6F, myFRR, myFidR, qmpParam1R, qmpParam2R, qmpParam3R, qmpParam4R, qmpParam5R, qmpParam6R)
+ self.mmentry.CM_CONN_INFO_CNF = self.mmentryFields.numConnField
+ self.i=0
+ while self.i<self.mmentryFields.numConn:
+ self.mmentry.CM_CONN_INFO_CNF = self.mmentry.CM_CONN_INFO_CNF + self.mmentryFields.connInfos[self.i].ConnInfo
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CM_CONN_INFO_CNF
+ self.mmentryFields.mmtype = CM_CONN_INFO_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CM_STA_CAP.REQ has no MMENTRY
+ def createCM_STA_CAP_REQ_MMENTRY(self):
+ print "CM_STA_CAP.REQ ="
+ #CM_STA_CAP_REQ_MMENTRY is composed by 0 field :
+ self.mmentry.CM_STA_CAP_REQ = ""
+ self.mmentryFields.mmentry = self.mmentry.CM_STA_CAP_REQ
+ self.mmentryFields.mmtype = CM_STA_CAP_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_STA_CAP_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_STA_CAP.CNF MME
+ def createCM_STA_CAP_CNF_MMENTRY(self, myAvVersion=None, myMacAddress=None, myOui=None, myAutoConnect=None, mySmoothing=None, myCcoCapability=None, myProxyCapable=None, myBackupCcoCapable=None, mySoftHandOver=None, myTwoSymFc=None, myMaxFL_AV=None, myHomePlug11Cap=None, myHomePlug10Interop=None, myRegulatoryCap=None, myBidirectionalBursting=None, myImplementationVer=None):
+ print "CM_STA_CAP.CNF ="
+ #CM_STA_CAP_CNF_MMENTRY is composed by 4 fields :
+ # - avVersion
+ # - MacAddress
+ # - Oui
+ # - AutoConnect
+ # - Smoothing
+ self.mmentryFields.createAvVersion(myAvVersion)
+ self.mmentryFields.createMacAddress(myMacAddress)
+ self.mmentryFields.createOui(myOui)
+ self.mmentryFields.createAutoConnect(myAutoConnect)
+ self.mmentryFields.createSmoothing(mySmoothing)
+ self.mmentryFields.createCcoCapability(myCcoCapability)
+ self.mmentryFields.createProxyCapable(myProxyCapable)
+ self.mmentryFields.createBackupCcoCapable(myBackupCcoCapable)
+ self.mmentryFields.createSoftHandOver(mySoftHandOver)
+ self.mmentryFields.createTwoSymFc(myTwoSymFc)
+ self.mmentryFields.createMaxFL_AV(myMaxFL_AV)
+ self.mmentryFields.createHomePlug11Cap(myHomePlug11Cap)
+ self.mmentryFields.createHomePlug10Interop(myHomePlug10Interop)
+ self.mmentryFields.createRegulatoryCap(myRegulatoryCap)
+ self.mmentryFields.createBidirectionalBursting(myBidirectionalBursting)
+ self.mmentryFields.createImplementationVer(myImplementationVer)
+ self.mmentry.CM_STA_CAP_CNF = self.mmentryFields.reasonCodeField + self.mmentryFields.macAddressField + self.mmentryFields.ouiField + self.mmentryFields.autoConnectField + self.mmentryFields.smoothingField + self.mmentryFields.ccoCapabilityField + self.mmentryFields.proxyCapableField + self.mmentryFields.backupCcoCapableField + self.mmentryFields.softHandOverField + self.mmentryFields.twoSymFcField + self.mmentryFields.maxFL_AVField + self.mmentryFields.homePlug11CapField + self.mmentryFields.homePlug10InteropField + self.mmentryFields.regulatoryCapField + self.mmentryFields.bidirectionalBurstingField + self.mmentryFields.implementationVerField
+ self.mmentryFields.mmentry = self.mmentry.CM_STA_CAP_CNF
+ self.mmentryFields.mmtype = CM_STA_CAP_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CM_NW_INFO.REQ has no MMENTRY
+ def createCM_NW_INFO_REQ_MMENTRY(self):
+ print "CM_NW_INFO.REQ ="
+ #CM_NW_INFO_REQ_MMENTRY is composed by 0 field :
+ self.mmentry.CM_NW_INFO_REQ = ""
+ self.mmentryFields.mmentry = self.mmentry.CM_NW_INFO_REQ
+ self.mmentryFields.mmtype = CM_NW_INFO_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_NW_INFO_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_NW_INFO.CNF MME
+ def createCM_NW_INFO_CNF_MMENTRY(self, myNumNws=None, mySecurityLevel=None, myNidOffset=None, myNid=None, mySnid=None, myTei=None, myStationRole=None, myCco_MacAddress=None, myAccess=None, myNumCordNws=None):
+ print "CM_NW_INFO.CNF ="
+ #CM_NW_INFO_CNF_MMENTRY is composed by 2 field :
+ # - NumNws
+ # - NwsInfo -*NumNws-
+ self.mmentryFields.createNwsInfo(myNumNws, mySecurityLevel, myNidOffset, myNid, mySnid, myTei, myStationRole, myCco_MacAddress, myAccess, myNumCordNws)
+ self.mmentry.CM_NW_INFO_CNF = self.mmentry.CM_NW_INFO_CNF + self.mmentryFields.numNwsField
+ self.i=0
+ while self.i<self.mmentryFields.numNws:
+ self.mmentry.CM_NW_INFO_CNF = self.mmentry.CM_NW_INFO_CNF + self.mmentryFields.nwsInfo[self.i].nwInfo
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CM_NW_INFO_CNF
+ self.mmentryFields.mmtype = CM_NW_INFO_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_GET_BEACON_REQ_MMENTRY creates
+ # the MMENTRY Field of the CM_GET_BEACON.REQ MME
+ def createCM_GET_BEACON_REQ_MMENTRY(self, mySecurityLevel=None, myNidOffset=None, myNid=None):
+ print "CM_GET_BEACON.REQ ="
+ #CM_GET_BEACON_REQ_MMENTRY is composed by 1 fields :
+ # - NID
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentry.CM_GET_BEACON_REQ = self.mmentryFields.nidField
+ self.mmentryFields.mmentry = self.mmentry.CM_GET_BEACON_REQ
+ self.mmentryFields.mmtype = CM_GET_BEACON_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_HFID_REQ_MMENTRY creates
+ # the MMENTRY Field of the CM_HFID.REQ MME
+ def createCM_HFID_REQ_MMENTRY(self, myReqType=None, mySecurityLevel=None, myNidOffset=None, myNid=None, myHfid=None):
+ print "CM_HFID.REQ ="
+ #CM_HFID_REQ_MMENTRY is composed by 3 fields :
+ # - ReqType
+ # - NID
+ # - HFID
+ self.mmentryFields.createReqType(myReqType)
+ self.mmentry.CM_HFID_REQ = self.mmentryFields.reqTypeField
+ if self.mmentryFields.reqType == 2 :
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentry.CM_HFID_REQ = self.mmentry.CM_HFID_REQ + self.mmentryFields.nidField
+ elif self.mmentryFields.reqType == 3 :
+ self.mmentryFields.createHfid(myHfid)
+ self.mmentry.CM_HFID_REQ = self.mmentry.CM_HFID_REQ + self.mmentryFields.hfidField
+ elif self.mmentryFields.reqType == 4 :
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createHfid(myHfid)
+ self.mmentry.CM_HFID_REQ = self.mmentry.CM_HFID_REQ + self.mmentryFields.nidField + self.mmentryFields.hfidField
+ self.mmentryFields.mmentry = self.mmentry.CM_HFID_REQ
+ self.mmentryFields.mmtype = CM_HFID_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_HFID_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_HFID.CNF MME
+ def createCM_HFID_CNF_MMENTRY(self, myResType=None, myHfid=None):
+ print "CM_HFID.CNF ="
+ #CM_HFID_CNF_MMENTRY is composed by 2 fields :
+ # - ResType
+ # - HFID
+ self.mmentryFields.createResType(myResType)
+ self.mmentryFields.createHfid(myHfid)
+ self.mmentry.CM_HFID_CNF = self.mmentryFields.resTypeField + self.mmentryFields.hfidField
+ self.mmentryFields.mmentry = self.mmentry.CM_HFID_CNF
+ self.mmentryFields.mmtype = CM_HFID_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #CM_NW_STATS.REQ has no MMENTRY
+ def createCM_NW_STATS_REQ_MMENTRY(self):
+ print "CM_NW_STATS.REQ ="
+ #CM_NW_STATS_REQ_MMENTRY is composed by 0 field :
+ self.mmentry.CM_NW_STATS_REQ = ""
+ self.mmentryFields.mmentry = self.mmentry.CM_NW_STATS_REQ
+ self.mmentryFields.mmtype = CM_NW_STATS_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_NW_STATS_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_NW_STATS.CNF MME
+ def createCM_NW_STATS_CNF_MMENTRY(self, myNumSta=0, myDa=None, myAvgPhyDR_Tx=None, myAvgPhyDR_Rx=None):
+ print "CM_NW_STATS.CNF ="
+ #CM_NW_STATS_CNF_MMENTRY is composed by 2 fields :
+ # - NumSta
+ # - TEI + AvgPhyDR_Tx + AvgPhyDR_Rx -*NumSta-
+ #self.mmentryFields.createNumSta(myNumSta)
+ self.mmentryFields.createDasAvgPhyDR_TxAvgPhyDR_Rx(myNumSta, myDa, myAvgPhyDR_Tx, myAvgPhyDR_Rx)
+ self.mmentry.CM_NW_STATS_CNF = self.mmentryFields.numStaField
+ self.i=0
+ while self.i<self.mmentryFields.numSta:
+ self.mmentry.CM_NW_STATS_CNF = self.mmentry.CM_NW_STATS_CNF + self.mmentryFields.dasAvgPhyDR_TxAvgPhyDR_Rx[self.i]
+ self.i=self.i+1
+ self.mmentryFields.mmentry = self.mmentry.CM_NW_STATS_CNF
+ self.mmentryFields.mmtype = CM_NW_STATS_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_LINK_STATS_REQ_MMENTRY creates
+ # the MMENTRY Field of the CM_LINK_STATS.REQ MME
+ def createCM_LINK_STATS_REQ_MMENTRY(self, myReqType=None, myReqId=None, mySecurityLevel=None, myNidOffset=None, myNid=None, myLid=None, myTlFlag=None, myMgmt_Flag=None, myDaSa=None):
+ print "CM_LINK_STATS.REQ ="
+ #CM_LINK_STATS_REQ_MMENTRY is composed by 7 fields :
+ # - ReqType
+ # - ReqId
+ # - NID
+ # - LID
+ # - TlFlag
+ # - Mgmt_Flag
+ # - DaSa
+ self.mmentryFields.createReqType(myReqType)
+ self.mmentryFields.createReqId(myReqId)
+ self.mmentryFields.createNid(mySecurityLevel, myNidOffset, myNid)
+ self.mmentryFields.createLid(myLid)
+ self.mmentryFields.createTlFlag(myTlFlag)
+ self.mmentryFields.createMgmt_Flag(myMgmt_Flag)
+ self.mmentryFields.createDaSa(myDaSa)
+ self.mmentry.CM_LINK_STATS_REQ = self.mmentryFields.reqTypeField + self.mmentryFields.reqIdField + self.mmentryFields.nidField + self.mmentryFields.lidField + self.mmentryFields.tlFlagField + self.mmentryFields.mgmt_FlagField + self.mmentryFields.daSaField
+ self.mmentryFields.mmentry = self.mmentry.CM_LINK_STATS_REQ
+ self.mmentryFields.mmtype = CM_LINK_STATS_REQ
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_LINK_STATS_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_LINK_STATS.CNF MME
+ def createCM_LINK_STATS_CNF_MMENTRY(self, myReqId=None, myResType=None, myRxTx=False, myBeaconPeriodCnt=None, myNumMsdus=None, myOctets=None, myNumSegs=None, myNumSeg_Suc=None, myNumSeg_Dropped=None, myNumSeg_Missed=None, myNumPbs=None, myNumMpdus=None, myNumBursts=None, myNumSacks=None, myNumIcvFails=None, myNumLatBins=0, myLatBinGran=None, myLatBin=None, myRandomLatBin=False): #Tx by default
+ print "CM_LINK_STATS.CNF ="
+ #CM_LINK_STATS_CNF_MMENTRY is composed by 3 fields :
+ # - ReqId
+ # - ResType
+ # - Tx or Rx MFS LinkStats
+ self.mmentryFields.createReqId(myReqId)
+ self.mmentryFields.createResType(myResType)
+ self.mmentry.CM_LINK_STATS_CNF = self.mmentryFields.resTypeField + self.mmentryFields.reqIdField
+ if myRxTx: #Rx
+ self.mmentryFields.createReceiveMfsLinkStats(myBeaconPeriodCnt, myNumMsdus, myOctets, myNumSeg_Suc, myNumSeg_Missed, myNumPbs, myNumBursts, myNumMpdus, myNumIcvFails)
+ self.mmentry.CM_LINK_STATS_CNF = self.mmentry.CM_LINK_STATS_CNF + self.mmentryFields.receiveMfsLinkStats
+ else: #Tx
+ self.mmentryFields.createTransmitMfsLinkStats(myBeaconPeriodCnt, myNumMsdus, myOctets, myNumSegs, myNumSeg_Suc, myNumSeg_Dropped, myNumPbs, myNumMpdus, myNumBursts, myNumSacks, myNumLatBins, myLatBinGran, myLatBin, myRandomLatBin)
+ self.mmentry.CM_LINK_STATS_CNF = self.mmentry.CM_LINK_STATS_CNF + self.mmentryFields.transmitMfsLinkStats
+ self.mmentryFields.mmentry = self.mmentry.CM_LINK_STATS_CNF
+ self.mmentryFields.mmtype = CM_LINK_STATS_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+ #createCM_GET_BEACON_CNF_MMENTRY creates
+ # the MMENTRY Field of the CM_GET_BEACON.CNF MME
+ def createCM_GET_BEACON_CNF_MMENTRY(self, mySecurityLevel=None, myNidOffset=None, myNid=None, myHm=None, myStei=None, myBt=None, myNcnr=None, myNpsm=None, myNumSlot=None, mySlotUsage=None, mySlotId=None, myAclss=None, myHoip=None, myRtsbf=None, myNm=None, myCcoCap=None, myNbe=None, myRandomBehdr=False, myBmiNumber=None, myBehdr=None, param1=None, param2=None, param3=None, param4=None, param5=None, param6=None, param7=None, param8=None, param9=None, paramA=None, paramB=None):
+ print "CM_GET_BEACON.CNF ="
+ #CM_GET_BEACON_CNF_MMENTRY is composed by 15... fields :
+ # - Nid
+ # - SecurityLevel
+ # - NidOffset
+ # - Hm
+ # - Stei
+ # - Bt
+ # - Ncnr
+ # - Npsm
+ # - NumSlot
+ # - SlotUsage
+ # - SlotId
+ # - Aclss
+ # - Hoip
+ # - Rtsbf
+ # - Nm
+ # - CcoCap
+ # - BMI :
+ # - Nbe
+ # - Behdr - * Nbe -
+ # - Bentry - * Nbe -
+ self.mmentryFields.createNidHm(mySecurityLevel, myNidOffset, myNid, myHm, myNidHm=None)
+ self.mmentryFields.createStei(myStei)
+ self.mmentryFields.createBtNcnrNpsmNumSlot(myBt, myNcnr, myNpsm, myNumSlot, myBtNcnrNpsmNumSlot=None)
+ self.mmentryFields.createSlotUsage(mySlotUsage)
+ self.mmentryFields.createSlotIdAclssHoipRtsbf(mySlotId, myAclss, myHoip, myRtsbf, mySlotIdAclssHoipRtsbf=None)
+ self.mmentryFields.createNmCcoCaptsbf(myNm, myCcoCap, myNmCcoCapRsvd=None)
+ self.mmentryFields.createBmi(myNbe, myRandomBehdr, myBmiNumber, myBehdr, param1, param2, param3, param4, param5, param6, param7, param8, param9, paramA, paramB)
+ self.mmentry.CM_GET_BEACON_CNF = self.mmentryFields.nidHmField + self.mmentryFields.steiField + self.mmentryFields.btNcnrNpsmNumSlotField + self.mmentryFields.slotUsageField + self.mmentryFields.slotIdAclssHoipRtsbfField + self.mmentryFields.nmCcoCapRsvdField + self.mmentryFields.bmiField
+ self.mmentryFields.mmentry = self.mmentry.CM_GET_BEACON_CNF
+ self.mmentryFields.mmtype = CM_GET_BEACON_CNF
+ self.mmentryFields.createMmeMfl(self.mmentryFields.mmentry)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cesar/maximus/python/lib/proto/fcall.py b/cesar/maximus/python/lib/proto/fcall.py
new file mode 100644
index 0000000000..8b87c3d07d
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/fcall.py
@@ -0,0 +1,349 @@
+#! usr/bin/env python
+
+#print __name__
+
+SERIAL = 'PYSERIAL'
+#SERIAL = 'USPP'
+
+import sys
+base = '../../../../'
+utils = 'maximus/python/maximus/utils'
+path = __file__[:__file__.find(".py") - len(__name__)] + base + utils
+sys.path.append(path)
+if SERIAL == 'PYSERIAL':
+ serial = 'maximus/python/lib/proto/pyserial'
+elif SERIAL == 'USPP':
+ serial = 'maximus/python/lib/proto/uspp'
+path = __file__[:__file__.find(".py") - len(__name__)] + base + serial
+sys.path.append(path)
+
+from exception import *
+from format import *
+if SERIAL == 'PYSERIAL':
+ import serial
+elif SERIAL == 'USPP':
+ from uspp import *
+
+# Constants from 'maximus/common/types/sci_types.h'
+SCI_MSG_MAGIC = 'MAXI'
+SCI_MSG_VERSION = 0x03
+SCI_MSG_ID_STATION = 0x8000
+SCI_MSG_TYPE_FUNCTION_CALL = 0x02
+SCI_MSG_TYPE_STATION_LOG = 0x06
+SCI_MSG_FLAG_RESP = 0x0001
+SIZE_OF_SCI_MSG_HEADER = 24 # in octets
+
+# Constants from 'maximus/common/types/functioncall_types.h'
+FUNCTION_CALL_VERSION = 0x03
+FUNCTION_CALL_FLAG_FAILED = 0x01
+FUNCTION_CALL_TYPE_REQ = 0x01
+FUNCTION_CALL_TYPE_RSP = 0x02
+SIZE_OF_FUNCTION_CALL_HEADER = 8 # in octets
+
+class Param:
+
+ def __init__(self, name, length, value):
+ self.__name = name
+ self.__length = hton16(length)
+ self.__value = value
+
+ def get_name(self):
+ return self.__name
+
+ def get_value(self):
+ return self.__value
+
+ def get(self):
+ return self.__name + '\0' + self.__length + self.__value
+
+class Fcall:
+ __msg_id = 1
+
+ tty = None
+ for i in range (1, len(sys.argv)):
+ if sys.argv[i] == '-r' or sys.argv[i] == '--rs-232':
+ if i+1 < len(sys.argv):
+ tty = sys.argv[i+1]
+ break
+
+ if SERIAL == 'PYSERIAL':
+ if tty is None:
+ # Open port 0 at "9600,8,N,1", 1s timeout
+ __tty = serial.Serial(0, timeout=1) # open first serial port
+ # Check which port was really used
+ print "Using port:", __tty.portstr
+ else:
+ # Open named port at "9600,8,N,1", 1s timeout
+ __tty = serial.Serial(tty, timeout=1)
+ if not __tty.isOpen():
+ raise Error("Cannot open serial port!")
+ elif SERIAL == 'USPP':
+ if tty is None:
+ tty = '/dev/ttyS0'
+ # Opens RS-232 at 9600 bps and with a read timeout of 1 second
+ __tty = SerialPort(tty, 1000, 9600)
+
+ def __init__(self, name):
+ self.__name = name
+ self.__param_list = []
+ self.__user_cb = None
+
+ def add_param(self, name, value=None):
+ if value is None:
+ value = ''
+ self.__param_list.append(Param(name, len(value), value))
+ return self
+
+ def add_param_bool(self, name, value):
+ self.__param_list.append(Param(name, SIZE_OF_U8, hton8(value)))
+ return self
+
+ def add_param_uchar(self, name, value):
+ self.__param_list.append(Param(name, SIZE_OF_U8, hton8(value)))
+ return self
+
+ def add_param_ushort(self, name, value):
+ self.__param_list.append(Param(name, SIZE_OF_U16, hton16(value)))
+ return self
+
+ def add_param_ulong(self, name, value):
+ self.__param_list.append(Param(name, SIZE_OF_U32, hton32(value)))
+ return self
+
+ def add_param_n_u8(self, name, tuple):
+ value = ''
+ for t in tuple:
+ value += hton8(t)
+ self.__param_list.append(Param(name, SIZE_OF_U8 * len(value), value))
+ return self
+
+ def add_param_n_u16(self, name, tuple):
+ value = ''
+ for t in tuple:
+ value += hton16(t)
+ self.__param_list.append(Param(name, SIZE_OF_U16 * len(value), value))
+ return self
+
+ def add_param_n_u32(self, name, tuple):
+ value = ''
+ for t in tuple:
+ value += hton32(t)
+ self.__param_list.append(Param(name, SIZE_OF_U32 * len(value), value))
+ return self
+
+ def remove_param(self, name):
+ for i in range (0, len(self.__param_list)):
+ if self.__param_list[i].get_name() == name:
+ self.__param_list.pop(i)
+ break
+ return self
+
+ def set_cb(self, user_cb):
+ self.__user_cb = user_cb
+ return self
+
+ def remove_cb(self):
+ self.__user_cb = None
+ return self
+
+ def set_sta(self, sta):
+ return self
+
+ def send_async(self, sta=None):
+ self.__write()
+ self.__read()
+ if self.__user_cb is not None:
+ self.__user_cb(self)
+
+ def send(self, sta=None):
+ self.__write()
+ return self.__read()
+
+ def is_param(self, name):
+ found = False
+ for l in self.__param_list:
+ if l.get_name() == name:
+ found = True
+ return found
+
+ def bind_param(self, name):
+ param = None
+ for l in self.__param_list:
+ if l.get_name() == name:
+ param = l.get_value()
+ break
+ return param
+
+ def bind_param_string(self, name):
+ param = None
+ for l in self.__param_list:
+ if l.get_name() == name:
+ param = l.get_value()
+ if param[len(param)-1] == '\0':
+ param = param[:-1]
+ break
+ return param
+
+ def bind_param_bool(self, name):
+ param = None
+ for l in self.__param_list:
+ if l.get_name() == name:
+ param = ntoh8(l.get_value())
+ break
+ return param
+
+ def bind_param_ushort(self, name):
+ param = None
+ for l in self.__param_list:
+ if l.get_name() == name:
+ param = ntoh16(l.get_value())
+ break
+ return param
+
+ def bind_param_ulong(self, name):
+ param = None
+ for l in self.__param_list:
+ if l.get_name() == name:
+ param = ntoh32(l.get_value())
+ break
+ return param
+
+ def __get(self):
+ if self.__class__.__msg_id < 0x7FFF:
+ self.__class__.__msg_id += 1
+ else:
+ self.__class__.__msg_id = 0x0001
+
+ # FCALL data
+ fcall_data = self.__name + '\0'
+ for l in self.__param_list:
+ fcall_data += l.get()
+
+ # FCALL header
+ # uint8_t version
+ # uint8_t type
+ # uint16_t msg_id
+ # uint8_t param_nb
+ # uint8_t flags
+ # uint16_t reserved
+ fcall_hdr = hton8(FUNCTION_CALL_VERSION)\
+ + hton8(FUNCTION_CALL_TYPE_REQ)\
+ + hton16(self.__class__.__msg_id)\
+ + hton8(len(self.__param_list))\
+ + hton8(0)\
+ + hton16(0)
+
+ # SCI header
+ # uint32_t magic_id
+ # uint8_t version
+ # uint8_t type
+ # uint16_t length
+ # uint16_t station_id
+ # uint16_t msg_id
+ # uint32_t netclock_high
+ # uint32_t netclock_low
+ # uint16_t flags
+ # uint16_t reserved
+ sci_hdr = SCI_MSG_MAGIC\
+ + hton8(SCI_MSG_VERSION)\
+ + hton8(SCI_MSG_TYPE_FUNCTION_CALL)\
+ + hton16(len(fcall_hdr + fcall_data))\
+ + hton16(0)\
+ + hton16(self.__class__.__msg_id)\
+ + hton32(0)\
+ + hton32(0)\
+ + hton16(0)\
+ + hton16(0)
+
+ return sci_hdr + fcall_hdr + fcall_data
+
+ def __write(self):
+ # Writes a string to the RS-232 port
+ self.__class__.__tty.write(self.__get())
+
+ def __read(self):
+ fcall = None
+
+ # SCI header
+ sci_hdr = self.__class__.__tty.read(SIZE_OF_SCI_MSG_HEADER) # read up to 24 bytes (timeout)
+ if sci_hdr[0:4] != SCI_MSG_MAGIC: # uint32_t magic_id
+ print "SCI header:"
+ print "magic id =", hex(ntoh32(sci_hdr[0:4]))
+ print "version =", hex(ntoh8(sci_hdr[4]))
+ print "type =", hex(ntoh8(sci_hdr[5]))
+ print "length =", hex(ntoh16(sci_hdr[6:8]))
+ print "station id =", hex(ntoh16(sci_hdr[8:10]))
+ print "msg id =", hex(ntoh16(sci_hdr[10:12]))
+ print "netclock high =", hex(ntoh32(sci_hdr[12:16]))
+ print "netclock low =", hex(ntoh32(sci_hdr[16:20]))
+ print "flags =", hex(ntoh16(sci_hdr[20:22]))
+ print "reserved =", hex(ntoh16(sci_hdr[22:24]))
+ raise Error("SCI header: bad magic id! (" + sci_hdr[0:4] + ")")
+ if ntoh8(sci_hdr[4]) != SCI_MSG_VERSION: # uint8_t version
+ raise Error("SCI header: bad version! (" + hex(ntoh8(sci_hdr[4])) + ")")
+ if ntoh8(sci_hdr[5]) == SCI_MSG_TYPE_FUNCTION_CALL: # uint8_t type
+ length = ntoh16(sci_hdr[6:8]) # uint16_t length
+
+ # FCALL header
+ fcall_hdr = self.__class__.__tty.read(SIZE_OF_FUNCTION_CALL_HEADER) # read up to 8 bytes (timeout)
+ if ntoh8(fcall_hdr[0]) != FUNCTION_CALL_VERSION: # uint8_t version
+ raise Error("FCALL header: bad version! (" + hex(ntoh8(fcall_hdr[0])) + ")")
+ if ntoh8(fcall_hdr[1]) != FUNCTION_CALL_TYPE_RSP: # uint8_t type
+ raise Error("FCALL header: bad type! (" + hex(ntoh8(fcall_hdr[1])) + ")")
+ ntoh16(fcall_hdr[2:4]) # uint16_t msg_id
+ param_nb = ntoh8(fcall_hdr[4]) # uint8_t param_nb
+ if ntoh8(fcall_hdr[5]) >= FUNCTION_CALL_FLAG_FAILED: # uint8_t flags
+ raise Error("FCALL header: flag failed! (" + hex(ntoh8(fcall_hdr[5])) + ")")
+ length -= SIZE_OF_FUNCTION_CALL_HEADER
+
+ # FCALL data
+ name = self.__read_name()
+ fcall = Fcall(name)
+ length -= len(name) + 1
+ for n in range(0, param_nb):
+ param_name = self.__read_param_name()
+ param_length = self.__read_param_length()
+ param_value = self.__read_param_value(param_length)
+ fcall.__param_list.append(Param(param_name, param_length, param_value))
+ length -= len(param_name) + 1 + SIZE_OF_U16 + param_length
+
+ if length != 0:
+ raise Error("length = " + str(length))
+
+ elif ntoh8(sci_hdr[5]) == SCI_MSG_TYPE_STATION_LOG: # uint8_t type
+ print self.__class__.__tty.readline() # read a '\n' terminated line
+ else:
+ raise Error("SCI header: bad type! (" + hex(ntoh8(sci_hdr[5])) + ")")
+
+ ntoh16(sci_hdr[8:10]) # uint16_t station_id
+ if ntoh16(sci_hdr[10:12]) < SCI_MSG_ID_STATION: # uint16_t msg_id
+ raise Error("SCI header: bad msg id! (" + hex(ntoh16(sci_hdr[10:12])) + ")")
+ ntoh32(sci_hdr[12:16]) # uint32_t netclock_high
+ ntoh32(sci_hdr[16:20]) # uint32_t netclock_low
+ if ntoh16(sci_hdr[20:22]) != SCI_MSG_FLAG_RESP: # uint16_t flags
+ raise Error("SCI header: bad flags! (" + hex(ntoh16(sci_hdr[20:22])) + ")")
+
+ return fcall
+
+ def __read_name(self):
+ name = ''
+ c = self.__class__.__tty.read() # read one byte
+ while c != '\0':
+ name += c
+ c = self.__class__.__tty.read() # read one byte
+ return name
+
+ def __read_param_name(self):
+ return self.__read_name()
+
+ def __read_param_length(self):
+ return ntoh16(self.__class__.__tty.read(2))
+
+ def __read_param_value(self, length):
+ return self.__class__.__tty.read(length)
+
+def create_fcall(name):
+ return Fcall(name)
+
+def create_probe():
+ return Fcall('probe')
diff --git a/cesar/maximus/python/lib/proto/pyserial/CHANGES.txt b/cesar/maximus/python/lib/proto/pyserial/CHANGES.txt
new file mode 100644
index 0000000000..cc2c0faace
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/CHANGES.txt
@@ -0,0 +1,171 @@
+Version 1.0 13 Feb 2002
+ First public release.
+ Split from the pybsl application (see mspgcc.sourceforge.net)
+
+ New Features:
+ - Added Jython support
+
+Version 1.1 14 Feb 2002
+ Bugfixes:
+ - Win32, when not specifying a timeout
+ - Typos in the Docs
+
+ New Features:
+ - added serialutil which provides a base class for the Serial
+ objects.
+
+ - readline, readlines, writelines and flush are now supported
+ see README.txt for deatils.
+
+Version 1.11 14 Feb 2002
+ Same as 1.1 but added missing files.
+
+Version 1.12 18 Feb 2002
+ Removed unneded constants to fix RH7.x problems.
+
+Version 1.13 09 Apr 2002
+ Added alternate way for enabling rtscts (CNEW_RTSCTS is tried too)
+ If port opening fails, a SerialException is raised on all platforms
+
+Version 1.14 29 May 2002
+ Added examples to archive
+ Added non-blocking mode for timeout=0 (tnx Mat Martineau)
+
+ Bugfixes:
+ - win32 does now return the remaining characters on timeout
+
+Version 1.15 04 Jun 2002
+ Bugfixes (win32):
+ - removed debug messages
+ - compatibility to win9x improved
+
+Version 1.16 02 Jul 2002
+ Added implementation of RI and corrected RTS/CTS on Win32
+
+Version 1.17 03 Jul 2002
+ Silly mix of two versions in win32 code corrected
+
+Version 1.18 06 Dec 2002
+ Bugfixes (general):
+ - remove the mapping of flush to the destructive flushOutput as
+ this is not the expected behaviour.
+ - readline: EOL character for lines can be chosen idea by
+ John Florian.
+ Bugfixes (posix):
+ - cygwin port numbering fixed
+ - test each and every constant for it's existence in termios module,
+ use default if not existent (fix for Bug item #640214)
+ - wrong exception on nonexitstent ports with /dev file. bug report
+ by Louis Cordier
+ Bugfixes (win32):
+ - RTS/CTS handling as sugested in Bug #635072
+ - bugfix of timeouts brought up by Markus Hoffrogge
+
+Version 1.19 19 Mar 2003
+ Bugfixes (posix):
+ - removed dgux entry which actualy had a wrong comment and is
+ probably not in use anywhere.
+ Bugfixes (win32):
+ - added int() conversion, [Bug 702120]
+ - remove code to set control lines in close methond of win32
+ version. [Bug 669625]
+
+Version 1.20 28 Aug 2003
+ Added serial.device() for all platforms
+ Bugfixes (win32):
+ - don't recreate opverlaped structures and events on each
+ read/write.
+ - don't set unneded event masks.
+ - dont use DOS device names for ports > 9.
+ - remove send timeout (its not used in the linux impl. anyway).
+
+
+Version 1.21 30 sep 2003
+ Bugfixes (win32):
+ - name for COM10 was not built correctly, found by Norm Davis.
+ Bugfixes (examples):
+ - small change in miniterm.py that should mage it run on cygwin,
+ [Bug 809904] submitted by Rolf Campbell.
+
+Version 2.0b1 1 Oct 2003
+ Transition to the 2.0 series:
+ - New implementation only supports Python 2.2+, backwards compatibility
+ should be maintained almost everywhere.
+ The OS handles (like the hComPort or fd attribute) were prefixed with an
+ underscore. The different names stay, as anyone that uses one of these
+ has to write platform specific code anyway.
+ - Common base class serialutil.SerialBase for all implementations.
+ - PARITY_NONE, PARITY_EVEN, PARITY_ODD constants changed and all these
+ constants moved to serialutil.py (still available as serial.PARITY_NONE
+ etc. and they should be used that way)
+ - Added serial.PARITY_NAMES (implemented in serialutil.PARITY_NAMES).
+ This dictionary can be used to convert parity constants to meaningful
+ strings.
+ - Each Serial class and instance has a list of supported values:
+ BAUDRATES, BYTESIZES, PARITIES, STOPBITS
+ (i.e. serial.Serial.BAUDRATES or s = serial.Serial; s.BAUDRATES)
+ these values can be used to fill in value sin GUI dialogs etc.
+ - Creating a Serial() object without port spec returns an unconfigured,
+ closed port. Useful if a GUI dialog should take a port and configure
+ it.
+ - New methods for serial.Serial instances: open(), isOpen()
+ - A port can be opened and closed as many times as desired.
+ - Instances of serial.Serial have baudrate, bytesize, timeout etc.
+ attributes implemented as properties, all can be set while the port is
+ opened. It will then be reconfigured.
+ - Improved __doc__'s.
+ - New test_advanced.py for the property setting/getting testing.
+ - Small bugfix on posix with get* methods (return value should be true a
+ boolean).
+ - added a __repr__ that returns a meaningful string will all the serial
+ setting, easy for debugging.
+ - The serialposix module does not throw an exception on unsupported
+ platforms, the message is still printed. The idea that it may still
+ work even if the platform itself s not known, it simply tries to do
+ the posix stuff anyway (It's likely that opening ports by number
+ fails, but by name it should work).
+
+Version 2.0b2 4 Oct 2003
+ - Added serial port configuration dialog for wxPython to the examples.
+ - Added terminal application for wxPython with wxGlade design file
+ to the examples.
+ - Jython support is currenty broken as Jython does not have a Python 2.2
+ compatible release out yet
+
+Version 2.0 6 Nov 2003
+ - Fixes setup.py for older distutils
+
+Version 2.1 28 Jul 2004
+ Bugfixes:
+ - Fix XON/XOFF values [Bug 975250]
+ Bugfixes (posix):
+ - fd == 0 fix from Vsevolod Lobko
+ - netbsd fixes from Erik Lindgren
+ - Dynamicaly lookup baudrates and some cleanups
+ Bugfixes (examples):
+ - CRLF handling of miniterm.py should be more consistent on Win32
+ and others. Added LF only command line option
+ - Mutithreading fixes to wxTerminal.py (helps with wxGTK)
+ - Small change for wxPython 2.5 in wxSerialConfigDialog.py [Bug 994856]
+
+ New Features:
+ - Implement write timeouts ('writeTimeout' parameter)
+
+
+Version 2.2 31 Jul 2005
+ Bugfixes:
+ - [Bug 1014227]: property <del> broken
+ - [Bug 1105687]: serial_tcp_example.py: --localport option
+ - [Bug 1106313]: device (port) strings cannot be unicode
+ Bugfixes (posix):
+ - [Patch 1043436] Fix for [Bug 1043420] (OSError: EAGAIN)
+ - [Patch 1102700] fileno() added
+ - ensure disbaled PARMRK
+ Bugfixes (win32):
+ - [Patch 983106]: keep RTS/CTS state on port setting changes
+
+ New Features:
+ - dsrdtr setting to enable/disable DSR/DTR flow control independently
+ from the rtscts setting. (Currenly Win32 only, ignored on other
+ platforms)
+
diff --git a/cesar/maximus/python/lib/proto/pyserial/LICENSE.txt b/cesar/maximus/python/lib/proto/pyserial/LICENSE.txt
new file mode 100644
index 0000000000..694e98a79d
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/LICENSE.txt
@@ -0,0 +1,61 @@
+Copyright (c) 2001-2004 Chris Liechti <cliechti@gmx.net>;
+All Rights Reserved.
+
+This is the Python license. In short, you can use this product in
+commercial and non-commercial applications, modify it, redistribute it.
+A notification to the author when you use and/or modify it is welcome.
+
+
+TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING THIS SOFTWARE
+===================================================================
+
+LICENSE AGREEMENT
+-----------------
+
+1. This LICENSE AGREEMENT is between the copyright holder of this
+product, and the Individual or Organization ("Licensee") accessing
+and otherwise using this product in source or binary form and its
+associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement,
+the copyright holder hereby grants Licensee a nonexclusive,
+royalty-free, world-wide license to reproduce, analyze, test,
+perform and/or display publicly, prepare derivative works, distribute,
+and otherwise use this product alone or in any derivative version,
+provided, however, that copyright holders License Agreement and
+copyright holders notice of copyright are retained in this product
+alone or in any derivative version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates this product or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to this product.
+
+4. The copyright holder is making this product available to Licensee on
+an "AS IS" basis. THE COPYRIGHT HOLDER MAKES NO REPRESENTATIONS OR
+WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION,
+THE COPYRIGHT HOLDER MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
+WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR
+THAT THE USE OF THIS PRODUCT WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. THE COPYRIGHT HOLDER SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER
+USERS OF THIS PRODUCT FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL
+DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE
+USING THIS PRODUCT, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE
+POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between the
+copyright holder and Licensee. This License Agreement does not grant
+permission to use trademarks or trade names from the copyright holder
+in a trademark sense to endorse or promote products or services of
+Licensee, or any third party.
+
+8. By copying, installing or otherwise using this product, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
diff --git a/cesar/maximus/python/lib/proto/pyserial/PKG-INFO b/cesar/maximus/python/lib/proto/pyserial/PKG-INFO
new file mode 100644
index 0000000000..575389e3e7
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/PKG-INFO
@@ -0,0 +1,21 @@
+Metadata-Version: 1.0
+Name: pyserial
+Version: 2.2
+Summary: Python Serial Port Extension
+Home-page: http://pyserial.sourceforge.net/
+Author: Chris Liechti
+Author-email: cliechti@gmx.net
+License: Python
+Description: Python Serial Port Extension for Win32, Linux, BSD, Jython
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: End Users/Desktop
+Classifier: License :: OSI Approved :: Python Software Foundation License
+Classifier: Natural Language :: English
+Classifier: Operating System :: POSIX
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Programming Language :: Python
+Classifier: Topic :: Communications
+Classifier: Topic :: Software Development :: Libraries
+Classifier: Topic :: Terminals :: Serial
diff --git a/cesar/maximus/python/lib/proto/pyserial/README.txt b/cesar/maximus/python/lib/proto/pyserial/README.txt
new file mode 100644
index 0000000000..2dfa443ba7
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/README.txt
@@ -0,0 +1,244 @@
+pySerial
+--------
+This module capsulates the access for the serial port. It provides backends
+for standard Python running on Windows, Linux, BSD (possibly any POSIX
+compilant system) and Jython. The module named "serial" automaticaly selects
+the appropriate backend.
+
+It is released under a free software license, see LICENSE.txt for more
+details.
+
+Project Homepage: pyserial.sourceforge.net
+(C) 2001-2004 Chris Liechti <cliechti@gmx.net>
+
+
+Features
+--------
+- same class based interface on all supported platforms
+- access to the port settings trough Python 2.2 properties
+- port numbering starts at zero, no need to know the platform dependant port
+ name in the user program
+- port name can be specified if access through numbering is inappropriate
+- support for different bytesizes, stopbits, parity and flow control
+ with RTS/CTS and/or Xon/Xoff
+- working with or without receive timeout, blocking or non-blocking
+- file like API with "read" and "write" ("readline" etc. also supported)
+- The files in this package are 100% pure Python.
+ They depend on non standard but common packages on Windows (win32all) and
+ Jython (JavaComm). POSIX (Linux, BSD) uses only modules from the standard
+ Python distribution)
+- The port is set up for binary transmission. No NULL byte stripping, CR-LF
+ translation etc. (which are many times enabled for POSIX.) This makes this
+ module universally useful.
+
+
+Requirements
+------------
+- Python 2.2 or newer
+- win32all extensions on Windows
+- "Java Communications" (JavaComm) extension for Java/Jython
+
+
+Installation
+------------
+Extract files from the archive, open a shell/console in that directory and
+let Distutils do the rest: "python setup.py install"
+
+The files get installed in the "Lib/site-packages" directory.
+
+There is also a Windows installer, but for developers it may be interesting
+to get the source archive anyway, because it contains examples and the readme.
+
+Do also have a look at the example files in the examples directory in the
+source distribution or online in CVS repository.
+
+Serial to USB adapters
+----------------------
+Such adapters are reported to work under Mac OSX and Windows. They are
+mapped to a normal COM port under Windows, but on Mac OSX and other platforms
+they have special device names.
+
+Mac OSX: "/dev/[cu|tty].USA<adaptername><USB-part>P<serial-port>.1"
+ e.g. "/dev/cu.USA19QW11P1.1"
+
+Linux: "/dev/usb/ttyUSB[n]" or "/dev/ttyUSB[n]"
+ first for for RedHat, second form for Debian.
+ e.g. "/dev/usb/ttyUSB0"
+
+Either use these names for the serial ports or create a link to the common device
+names like "ln -s /dev/cu.USA19QW11P1.1 /dev/cuaa0" or "ln -s /dev/usb/ttyUSB0
+/dev/ttyS4" etc.
+
+But be aware that the (USB) device file disappears as soon as you unplug the USB
+adapter.
+
+
+Short introduction
+------------------
+Open port 0 at "9600,8,N,1", no timeout
+>>> import serial
+>>> ser = serial.Serial(0) #open first serial port
+>>> print ser.portstr #check which port was realy used
+>>> ser.write("hello") #write a string
+>>> ser.close() #close port
+
+Open named port at "19200,8,N,1", 1s timeout
+>>> ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)
+>>> x = ser.read() #read one byte
+>>> s = ser.read(10) #read up to ten bytes (timeout)
+>>> line = ser.readline() #read a '\n' terminated line
+>>> ser.close()
+
+Open second port at "38400,8,E,1", non blocking HW handshaking
+>>> ser = serial.Serial(1, 38400, timeout=0,
+... parity=serial.PARITY_EVEN, rtscts=1)
+>>> s = ser.read(100) #read up to one hunded bytes
+... #or as much is in the buffer
+
+Get a Serial instance and configure/open it later
+>>> ser = serial.Serial()
+>>> ser.baudrate = 19200
+>>> ser.port = 0
+>>> ser
+Serial<id=0xa81c10, open=False>(port='COM1', baudrate=19200, bytesize=8,
+parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0)
+>>> ser.open()
+>>> ser.isOpen()
+True
+>>> ser.close()
+>>> ser.isOpen()
+False
+
+Be carefully when using "readline". Do specify a timeout when
+opening the serial port otherwise it could block forever if
+no newline character is received. Also note that "readlines" only
+works with a timeout. "readlines" depends on having a timeout
+and interprets that as EOF (end of file). It raises an exception
+if the port is not opened correctly.
+
+
+Parameters for the Serial class
+-------------------------------
+ser = serial.Serial(
+ port=None, #number of device, numbering starts at
+ #zero. if everything fails, the user
+ #can specify a device string, note
+ #that this isn't portable anymore
+ #if no port is specified an unconfigured
+ #an closed serial port object is created
+ baudrate=9600, #baudrate
+ bytesize=EIGHTBITS, #number of databits
+ parity=PARITY_NONE, #enable parity checking
+ stopbits=STOPBITS_ONE, #number of stopbits
+ timeout=None, #set a timeout value, None to wait forever
+ xonxoff=0, #enable software flow control
+ rtscts=0, #enable RTS/CTS flow control
+ writeTimeout=None, #set a timeout for writes
+)
+
+The port is immediately opened on object creation, if a port is given.
+It is not opened if port is None.
+
+Options for read timeout:
+timeout=None #wait forever
+timeout=0 #non-blocking mode (return immediately on read)
+timeout=x #set timeout to x seconds (float allowed)
+
+Options for write timeout:
+writeTimeout=x #will rise a SerialTimeoutException if the data
+ #cannot be sent in x seconds
+
+Methods of Serial instances
+---------------------------
+open() #open port
+close() #close port immediately
+setBaudrate(baudrate) #change baudarte on an open port
+inWaiting() #return the number of chars in the receive buffer
+read(size=1) #read "size" characters
+write(s) #write the string s to the port
+flushInput() #flush input buffer, discarding all it's contents
+flushOutput() #flush output buffer, abort output
+sendBreak() #send break condition
+setRTS(level=1) #set RTS line to specified logic level
+setDTR(level=1) #set DTR line to specified logic level
+getCTS() #return the state of the CTS line
+getDSR() #return the state of the DSR line
+getRI() #return the state of the RI line
+getCD() #return the state of the CD line
+
+Attributes of Serial instances
+------------------------------
+Read Only:
+portstr #device name
+BAUDRATES #list of valid baudrates
+BYTESIZES #list of valid byte sizes
+PARITIES #list of valid parities
+STOPBITS #list of valid stop bit widths
+
+New values can be assigned to the following attribues, the port
+will be reconfigured, even if it's opened at that time (port will be
+closed and reopened to apply the changes):
+port #port name/number as set by the user
+baudrate #current baudrate setting
+bytesize #bytesize in bits
+parity #parity setting
+stopbits #stop bit with (1,2)
+timeout #read timeout setting
+xonxoff #if Xon/Xoff flow control is enabled
+rtscts #if hardware flow control is enabled
+writeTimeout #write timeout setting
+
+These attribues also have corresponding getX and setXX methods.
+
+Exceptions
+----------
+serial.SerialException
+
+Constants
+---------
+parity:
+ serial.PARITY_NONE
+ serial.PARITY_EVEN
+ serial.PARITY_ODD
+stopbits:
+ serial.STOPBITS_ONE
+ serial.STOPBITS_TWO
+bytesize:
+ serial.FIVEBITS
+ serial.SIXBITS
+ serial.SEVENBITS
+ serial.EIGHTBITS
+
+Xon/Xoff characters:
+ serial.XON
+ serial.XOFF
+
+Tips & Tricks
+-------------
+- Some protocols need CR LF ("\r\n") as line terminator, not just LF ("\n").
+ Telephone modems with the AT command set are an example of this behaviour.
+
+- Scanning for available serial ports is possible with more or less success on
+ some platforms. Look at the tools from Roger Binns:
+ http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/bitpim/comscan/
+
+- When packaging a project with py2exe, it will likely print a warning about
+ missing modules 'javax.comm'. This warning is uncritical as the module is
+ used in the Jython implementation that is not used but packaged.
+
+ It can be avoided with:
+ setup(...
+ options = {'py2exe': {'excludes': ['javax.comm']}})
+
+ See also setup_demo.py in the examples.
+
+
+References
+----------
+- Python: http://www.python.org
+- Jython: http://www.jython.org
+- win32all: http://starship.python.net/crew/mhammond/
+ and http://www.activestate.com/Products/ActivePython/win32all.html
+- Java@IBM http://www-106.ibm.com/developerworks/java/jdk/
+ (JavaComm links are on the download page for the respective platform jdk)
+- Java@SUN http://java.sun.com/products/
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/enhancedserial.py b/cesar/maximus/python/lib/proto/pyserial/examples/enhancedserial.py
new file mode 100644
index 0000000000..7ca8b6f40e
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/enhancedserial.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+"""Enhanced Serial Port class
+part of pyserial (http://pyserial.sf.net) (C)2002 cliechti@gmx.net
+
+another implementation of the readline and readlines method.
+this one should be more efficient because a bunch of characters are read
+on each access, but the drawback is that a timeout must be specified to
+make it work (enforced by the class __init__).
+
+this class could be enhanced with a read_until() method and more
+like found in the telnetlib.
+"""
+
+from serial import Serial
+
+class EnhancedSerial(Serial):
+ def __init__(self, *args, **kwargs):
+ #ensure that a reasonable timeout is set
+ timeout = kwargs.get('timeout',0.1)
+ if timeout < 0.01: timeout = 0.1
+ kwargs['timeout'] = timeout
+ Serial.__init__(self, *args, **kwargs)
+ self.buf = ''
+
+ def readline(self, maxsize=None, timeout=1):
+ """maxsize is ignored, timeout in seconds is the max time that is way for a complete line"""
+ tries = 0
+ while 1:
+ self.buf += self.read(512)
+ pos = self.buf.find('\n')
+ if pos >= 0:
+ line, self.buf = self.buf[:pos+1], self.buf[pos+1:]
+ return line
+ tries += 1
+ if tries * self.timeout > timeout:
+ break
+ line, self.buf = self.buf, ''
+ return line
+
+ def readlines(self, sizehint=None, timeout=1):
+ """read all lines that are available. abort after timout
+ when no more data arrives."""
+ lines = []
+ while 1:
+ line = self.readline(timeout=timeout)
+ if line:
+ lines.append(line)
+ if not line or line[-1:] != '\n':
+ break
+ return lines
+
+if __name__=='__main__':
+ #do some simple tests with a Loopback HW (see test.py for details)
+ PORT = 0
+ #test, only with Loopback HW (shortcut RX/TX pins (3+4 on DSUB 9 and 25) )
+ s = EnhancedSerial(PORT)
+ #write out some test data lines
+ s.write('\n'.join("hello how are you".split()))
+ #and read them back
+ print s.readlines()
+ #this one should print an empty list
+ print s.readlines(timeout=0.4)
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/miniterm.py b/cesar/maximus/python/lib/proto/pyserial/examples/miniterm.py
new file mode 100644
index 0000000000..345c0c42e3
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/miniterm.py
@@ -0,0 +1,165 @@
+#!/usr/bin/env python
+
+# Very simple serial terminal
+# (C)2002-2004 Chris Liechti <cliecht@gmx.net>
+
+# Input characters are sent directly (only LF -> CR/LF/CRLF translation is
+# done), received characters are displayed as is (or as trough pythons
+# repr, useful for debug purposes)
+# Baudrate and echo configuartion is done through globals
+
+
+import sys, os, serial, threading, getopt
+
+EXITCHARCTER = '\x04' #ctrl+D
+
+#first choose a platform dependant way to read single characters from the console
+if os.name == 'nt':
+ import msvcrt
+ def getkey():
+ while 1:
+ if echo:
+ z = msvcrt.getche()
+ else:
+ z = msvcrt.getch()
+ if z == '\0' or z == '\xe0': #functions keys
+ msvcrt.getch()
+ else:
+ if z == '\r':
+ return '\n'
+ return z
+
+elif os.name == 'posix':
+ import termios, sys, os
+ fd = sys.stdin.fileno()
+ old = termios.tcgetattr(fd)
+ new = termios.tcgetattr(fd)
+ new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
+ new[6][termios.VMIN] = 1
+ new[6][termios.VTIME] = 0
+ termios.tcsetattr(fd, termios.TCSANOW, new)
+ s = '' # We'll save the characters typed and add them to the pool.
+ def getkey():
+ c = os.read(fd, 1)
+ #~ c = sys.stdin.read(1)
+ if echo: sys.stdout.write(c); sys.stdout.flush()
+ return c
+ def clenaup_console():
+ termios.tcsetattr(fd, termios.TCSAFLUSH, old)
+ sys.exitfunc = clenaup_console #terminal modes have to be restored on exit...
+
+else:
+ raise "Sorry no implementation for your platform (%s) available." % sys.platform
+
+CONVERT_CRLF = 2
+CONVERT_CR = 1
+CONVERT_LF = 0
+
+def reader():
+ """loop forever and copy serial->console"""
+ while 1:
+ data = s.read()
+ if repr_mode:
+ sys.stdout.write(repr(data)[1:-1])
+ else:
+ sys.stdout.write(data)
+ sys.stdout.flush()
+
+def writer():
+ """loop and copy console->serial until EOF character is found"""
+ while 1:
+ c = getkey()
+ if c == EXITCHARCTER:
+ break #exit app
+ elif c == '\n':
+ if convert_outgoing == CONVERT_CRLF:
+ s.write('\r\n') #make it a CR+LF
+ elif convert_outgoing == CONVERT_CR:
+ s.write('\r') #make it a CR
+ elif convert_outgoing == CONVERT_LF:
+ s.write('\n') #make it a LF
+ else:
+ s.write(c) #send character
+
+
+#print a short help message
+def usage():
+ sys.stderr.write("""USAGE: %s [options]
+ Miniterm - A simple terminal program for the serial port.
+
+ options:
+ -p, --port=PORT: port, a number, default = 0 or a device name
+ -b, --baud=BAUD: baudrate, default 9600
+ -r, --rtscts: enable RTS/CTS flow control (default off)
+ -x, --xonxoff: enable software flow control (default off)
+ -e, --echo: enable local echo (default off)
+ -c, --cr: do not send CR+LF, send CR only
+ -n, --newline: do not send CR+LF, send LF only
+ -D, --debug: debug received data (escape nonprintable chars)
+
+""" % (sys.argv[0], ))
+
+if __name__ == '__main__':
+ #initialize with defaults
+ port = 0
+ baudrate = 9600
+ echo = 0
+ convert_outgoing = CONVERT_CRLF
+ rtscts = 0
+ xonxoff = 0
+ repr_mode = 0
+
+ #parse command line options
+ try:
+ opts, args = getopt.getopt(sys.argv[1:],
+ "hp:b:rxecnD",
+ ["help", "port=", "baud=", "rtscts", "xonxoff", "echo",
+ "cr", "newline", "debug"]
+ )
+ except getopt.GetoptError:
+ # print help information and exit:
+ usage()
+ sys.exit(2)
+
+ for o, a in opts:
+ if o in ("-h", "--help"): #help text
+ usage()
+ sys.exit()
+ elif o in ("-p", "--port"): #specified port
+ try:
+ port = int(a)
+ except ValueError:
+ port = a
+ elif o in ("-b", "--baud"): #specified baudrate
+ try:
+ baudrate = int(a)
+ except ValueError:
+ raise ValueError, "Baudrate must be a integer number, not %r" % a
+ elif o in ("-r", "--rtscts"):
+ rtscts = 1
+ elif o in ("-x", "--xonxoff"):
+ xonxoff = 1
+ elif o in ("-e", "--echo"):
+ echo = 1
+ elif o in ("-c", "--cr"):
+ convert_outgoing = CONVERT_CR
+ elif o in ("-n", "--newline"):
+ convert_outgoing = CONVERT_LF
+ elif o in ("-D", "--debug"):
+ repr_mode = 1
+
+ #open the port
+ try:
+ s = serial.Serial(port, baudrate, rtscts=rtscts, xonxoff=xonxoff)
+ except:
+ sys.stderr.write("Could not open port\n")
+ sys.exit(1)
+ sys.stderr.write("--- Miniterm --- type Ctrl-D to quit\n")
+ #start serial->console thread
+ r = threading.Thread(target=reader)
+ r.setDaemon(1)
+ r.start()
+ #and enter console->serial loop
+ writer()
+
+ sys.stderr.write("\n--- exit ---\n")
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/scan.py b/cesar/maximus/python/lib/proto/pyserial/examples/scan.py
new file mode 100644
index 0000000000..ee0b92a337
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/scan.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+"""Scan for serial ports.
+Part of pySerial (http://pyserial.sf.net) (C)2002-2003 <cliechti@gmx.net>
+
+The scan function of this module tries to open each port number
+from 0 to 255 and it builds a list of those ports where this was
+successful.
+"""
+
+import serial
+
+def scan():
+ """scan for available ports. return a list of tuples (num, name)"""
+ available = []
+ for i in range(256):
+ try:
+ s = serial.Serial(i)
+ available.append( (i, s.portstr))
+ s.close() #explicit close 'cause of delayed GC in java
+ except serial.SerialException:
+ pass
+ return available
+
+if __name__=='__main__':
+ print "Found ports:"
+ for n,s in scan():
+ print "(%d) %s" % (n,s)
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/setup_demo.py b/cesar/maximus/python/lib/proto/pyserial/examples/setup_demo.py
new file mode 100644
index 0000000000..34c8c122e0
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/setup_demo.py
@@ -0,0 +1,35 @@
+# This is a setup.py example script for the use with py2exe
+from distutils.core import setup
+import py2exe
+import sys, os
+
+#this script is only useful for py2exe so just run that distutils command.
+#that allows to run it with a simple double click.
+sys.argv.append('py2exe')
+
+#get an icon from somewhere.. the python installation should have one:
+icon = os.path.join(os.path.dirname(sys.executable), 'py.ico')
+
+setup(
+ options = {'py2exe': {
+ 'excludes': ['javax.comm'],
+ 'optimize': 2,
+ 'dist_dir': 'dist',
+ }
+ },
+
+ name = "wxTerminal",
+ windows = [
+ {
+ 'script': "wxTerminal.py",
+ 'icon_resources': [(0x0004, icon)]
+ },
+ ],
+ zipfile = "stuff.lib",
+
+ description = "Simple serial terminal application",
+ version = "0.1",
+ author = "Chris Liechti",
+ author_email = "cliechti@gmx.net",
+ url = "http://pyserial.sf.net",
+)
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/tcp_serial_redirect.py b/cesar/maximus/python/lib/proto/pyserial/examples/tcp_serial_redirect.py
new file mode 100644
index 0000000000..771f3c268e
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/tcp_serial_redirect.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+
+#(C)2002-2003 Chris Liechti <cliechti@gmx.net>
+#redirect data from a TCP/IP connection to a serial port and vice versa
+#requires Python 2.2 'cause socket.sendall is used
+
+"""USAGE: tcp_serial_redirect.py [options]
+Simple Serial to Network (TCP/IP) redirector.
+
+Options:
+ -p, --port=PORT serial port, a number, defualt = 0 or a device name
+ -b, --baud=BAUD baudrate, default 9600
+ -r, --rtscts enable RTS/CTS flow control (default off)
+ -x, --xonxoff enable software flow control (default off)
+ -P, --localport TCP/IP port on which to run the server (default 7777)
+
+Note: no security measures are implemeted. Anyone can remotely connect
+to this service over the network.
+Only one connection at once is supported. If the connection is terminaed
+it waits for the next connect.
+"""
+
+import sys, os, serial, threading, getopt, socket
+
+try:
+ True
+except NameError:
+ True = 1
+ False = 0
+
+class Redirector:
+ def __init__(self, serial, socket):
+ self.serial = serial
+ self.socket = socket
+
+ def shortcut(self):
+ """connect the serial port to the tcp port by copying everything
+ from one side to the other"""
+ self.alive = True
+ self.thread_read = threading.Thread(target=self.reader)
+ self.thread_read.setDaemon(1)
+ self.thread_read.start()
+ self.writer()
+
+ def reader(self):
+ """loop forever and copy serial->socket"""
+ while self.alive:
+ try:
+ data = self.serial.read(1) #read one, blocking
+ n = self.serial.inWaiting() #look if there is more
+ if n:
+ data = data + self.serial.read(n) #and get as much as possible
+ if data:
+ self.socket.sendall(data) #send it over TCP
+ except socket.error, msg:
+ print msg
+ #probably got disconnected
+ break
+ self.alive = False
+
+ def writer(self):
+ """loop forever and copy socket->serial"""
+ while self.alive:
+ try:
+ data = self.socket.recv(1024)
+ if not data:
+ break
+ self.serial.write(data) #get a bunch of bytes and send them
+ except socket.error, msg:
+ print msg
+ #probably got disconnected
+ break
+ self.alive = False
+ self.thread_read.join()
+
+ def stop(self):
+ """Stop copying"""
+ if self.alive:
+ self.alive = False
+ self.thread_read.join()
+
+if __name__ == '__main__':
+ ser = serial.Serial()
+
+ #parse command line options
+ try:
+ opts, args = getopt.getopt(sys.argv[1:],
+ "hp:b:rxP",
+ ["help", "port=", "baud=", "rtscts", "xonxoff", "localport="])
+ except getopt.GetoptError:
+ # print help information and exit:
+ print >>sys.stderr, __doc__
+ sys.exit(2)
+
+ ser.port = 0
+ ser.baudrate = 9600
+ ser.rtscts = False
+ ser.xonxoff = False
+ ser.timeout = 1 #required so that the reader thread can exit
+
+ localport = 7777
+ for o, a in opts:
+ if o in ("-h", "--help"): #help text
+ usage()
+ sys.exit()
+ elif o in ("-p", "--port"): #specified port
+ try:
+ ser.port = int(a)
+ except ValueError:
+ ser.port = a
+ elif o in ("-b", "--baud"): #specified baudrate
+ try:
+ ser.baudrate = int(a)
+ except ValueError:
+ raise ValueError, "Baudrate must be a integer number"
+ elif o in ("-r", "--rtscts"):
+ ser.rtscts = True
+ elif o in ("-x", "--xonxoff"):
+ ser.xonxoff = True
+ elif o in ("-P", "--localport"):
+ try:
+ localport = int(a)
+ except ValueError:
+ raise ValueError, "Local port must be an integer number"
+
+ print "--- TCP/IP to Serial redirector --- type Ctrl-C / BREAK to quit"
+
+ try:
+ ser.open()
+ except serial.SerialException, e:
+ print "Could not open serial port %s: %s" % (ser.portstr, e)
+ sys.exit(1)
+
+ srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ srv.bind( ('', localport) )
+ srv.listen(1)
+ while 1:
+ try:
+ print "Waiting for connection..."
+ connection, addr = srv.accept()
+ print 'Connected by', addr
+ #enter console->serial loop
+ r = Redirector(ser, connection)
+ r.shortcut()
+ print 'Disconnected'
+ connection.close()
+ except socket.error, msg:
+ print msg
+
+ print "\n--- exit ---"
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/test.py b/cesar/maximus/python/lib/proto/pyserial/examples/test.py
new file mode 100644
index 0000000000..ab3f830b52
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/test.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#see __init__.py
+#
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+"""Some tests for the serial module.
+Part of pyserial (http://pyserial.sf.net) (C)2002-2003 cliechti@gmx.net
+
+Intended to be run on different platforms, to ensure portability of
+the code.
+
+For all these tests a simple hardware is required.
+Loopback HW adapter:
+Shortcut these pin pairs:
+ TX <-> RX
+ RTS <-> CTS
+ DTR <-> DSR
+
+On a 9 pole DSUB these are the pins (2-3) (4-6) (7-8)
+"""
+
+import unittest, threading, time
+import serial
+
+#on which port should the tests be performed:
+PORT=0
+
+
+class Test4_Nonblocking(unittest.TestCase):
+ """Test with timeouts"""
+ timeout=0
+ def setUp(self):
+ self.s = serial.Serial(PORT,timeout=self.timeout)
+ def tearDown(self):
+ self.s.close()
+
+ def test0_Messy(self):
+ """NonBlocking (timeout=0)"""
+ #this is only here to write out the message in verbose mode
+ #because Test3 and Test4 print the same messages
+
+ def test1_ReadEmpty(self):
+ """timeout: After port open, the input buffer must be empty"""
+ self.failUnless(self.s.read(1)=='', "expected empty buffer")
+ def test2_Loopback(self):
+ """timeout: each sent character should return (binary test).
+ this is also a test for the binary capability of a port."""
+ for c in map(chr,range(256)):
+ self.s.write(c)
+ time.sleep(0.02) #there might be a small delay until the character is ready (especialy on win32)
+ self.failUnless(self.s.inWaiting()==1, "expected exactly one character for inWainting()")
+ self.failUnless(self.s.read(1)==c, "expected a '%s' which was written before" % c)
+ self.failUnless(self.s.read(1)=='', "expected empty buffer after all sent chars are read")
+ def test2_LoopbackTimeout(self):
+ """timeout: test the timeout/immediate return.
+ partial results should be returned."""
+ self.s.write("HELLO")
+ time.sleep(0.02) #there might be a small delay until the character is ready (especialy on win32)
+ #read more characters as are available to run in the timeout
+ self.failUnless(self.s.read(10)=='HELLO', "expected an 'HELLO' which was written before")
+ self.failUnless(self.s.read(1)=='', "expected empty buffer after all sent chars are read")
+
+
+class Test3_Timeout(Test4_Nonblocking):
+ """Same tests as the NonBlocking ones but this time with timeout"""
+ timeout=1
+ def test0_Messy(self):
+ """Blocking (timeout=1)"""
+ #this is only here to write out the message in verbose mode
+ #because Test3 and Test4 print the same messages
+
+class SendEvent(threading.Thread):
+ def __init__(self, serial, delay=1):
+ threading.Thread.__init__(self)
+ self.serial = serial
+ self.delay = delay
+ self.x = threading.Event()
+ self.stopped = 0
+ self.start()
+ def run(self):
+ time.sleep(self.delay)
+ if not self.stopped:
+ self.serial.write("E")
+ self.x.set()
+ def isSet(self):
+ return self.x.isSet()
+ def stop(self):
+ self.stopped = 1
+ self.x.wait()
+
+class Test1_Forever(unittest.TestCase):
+ """Tests a port with no timeout. These tests require that a
+ character is sent after some time to stop the test, this is done
+ through the SendEvent class and the Loopback HW."""
+ def setUp(self):
+ self.s = serial.Serial(PORT, timeout=None)
+ self.event = SendEvent(self.s)
+ def tearDown(self):
+ self.event.stop()
+ self.s.close()
+
+ def test2_ReadEmpty(self):
+ """no timeout: after port open, the input buffer must be empty (read).
+ a character is sent after some time to terminate the test (SendEvent)."""
+ c = self.s.read(1)
+ if not (self.event.isSet() and c == 'E'):
+ self.fail("expected marker")
+
+class Test2_Forever(unittest.TestCase):
+ """Tests a port with no timeout"""
+ def setUp(self):
+ self.s = serial.Serial(PORT,timeout=None)
+ def tearDown(self):
+ self.s.close()
+
+ def test1_inWaitingEmpty(self):
+ """no timeout: after port open, the input buffer must be empty (inWaiting)"""
+ self.failUnless(self.s.inWaiting()==0, "expected empty buffer")
+
+ def test2_Loopback(self):
+ """no timeout: each sent character should return (binary test).
+ this is also a test for the binary capability of a port."""
+ for c in map(chr,range(256)):
+ self.s.write(c)
+ time.sleep(0.02) #there might be a small delay until the character is ready (especialy on win32)
+ self.failUnless(self.s.inWaiting()==1, "expected exactly one character for inWainting()")
+ self.failUnless(self.s.read(1)==c, "expected an '%s' which was written before" % c)
+ self.failUnless(self.s.inWaiting()==0, "expected empty buffer after all sent chars are read")
+
+
+class Test0_DataWires(unittest.TestCase):
+ """Test modem control lines"""
+ def setUp(self):
+ self.s = serial.Serial(PORT)
+ def tearDown(self):
+ self.s.close()
+
+ def test1_RTS(self):
+ """Test RTS/CTS"""
+ self.s.setRTS(0)
+ self.failUnless(self.s.getCTS()==0, "CTS -> 0")
+ self.s.setRTS(1)
+ self.failUnless(self.s.getCTS()==1, "CTS -> 1")
+
+ def test2_DTR(self):
+ """Test DTR/DSR"""
+ self.s.setDTR(0)
+ self.failUnless(self.s.getDSR()==0, "DSR -> 0")
+ self.s.setDTR(1)
+ self.failUnless(self.s.getDSR()==1, "DSR -> 1")
+
+ def test3_RI(self):
+ """Test RI"""
+ self.failUnless(self.s.getRI()==0, "RI -> 0")
+
+class Test_MoreTimeouts(unittest.TestCase):
+ """Test with timeouts"""
+ def setUp(self):
+ self.s = serial.Serial() #create an closed serial port
+
+ def tearDown(self):
+ self.s.close()
+
+ def test_WriteTimeout(self):
+ """Test write() timeout."""
+ #use xonxoff setting and the loopback adapter to switch traffic on hold
+ self.s.port = PORT
+ self.s.writeTimeout = 1
+ self.s.xonxoff = 1
+ self.s.open()
+ self.s.write(serial.XOFF)
+ time.sleep(0.1) #some systems need a little delay so that they can react on XOFF
+ t1 = time.time()
+ self.failUnlessRaises(serial.SerialTimeoutException, self.s.write, "timeout please"*100)
+ t2 = time.time()
+ self.failUnless( 1 <= (t2-t1) < 2, "Timeout not in the given intervall (%s)" % (t2-t1))
+
+if __name__ == '__main__':
+ import sys
+ print __doc__
+ print "Testing port", PORT
+ sys.argv.append('-v')
+ # When this module is executed from the command-line, it runs all its tests
+ unittest.main()
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/test_advanced.py b/cesar/maximus/python/lib/proto/pyserial/examples/test_advanced.py
new file mode 100644
index 0000000000..980d29005f
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/test_advanced.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+#needs at least python 2.2.3
+
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#see __init__.py
+#
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+"""Some tests for the serial module.
+Part of pyserial (http://pyserial.sf.net) (C)2002 cliechti@gmx.net
+
+Intended to be run on different platforms, to ensure portability of
+the code.
+
+These tests open a serial port and change all the settings on the fly.
+If the port is realy correctly configured cannot be determined - that
+would require external hardware or a nullmodem cable and an other
+serial port library... Thus it mainly tests that all features are
+correctly implemented and that the interface does what it should.
+"""
+
+import unittest
+import serial
+
+#on which port should the tests be performed:
+PORT=0
+
+class Test_ChangeAttributes(unittest.TestCase):
+ """Test with timeouts"""
+
+ def setUp(self):
+ self.s = serial.Serial() #create an closed serial port
+
+ def tearDown(self):
+ self.s.close()
+
+ def test_PortSetting(self):
+ self.s.port = PORT
+ #portstr has to be set
+ self.failUnlessEqual(self.s.portstr, serial.device(PORT))
+ #test internals
+ self.failUnlessEqual(self.s._port, PORT)
+ #test on the fly change
+ self.s.open()
+ self.failUnless(self.s.isOpen())
+ self.s.port = 0
+ self.failUnless(self.s.isOpen())
+ self.failUnlessEqual(self.s.port, 0)
+ self.failUnlessEqual(self.s.portstr, serial.device(0))
+ try:
+ self.s.port = 1
+ except serial.SerialException: #port not available on system
+ pass #cant test on this machine...
+ else:
+ self.failUnless(self.s.isOpen())
+ self.failUnlessEqual(self.s.port, 1)
+ self.failUnlessEqual(self.s.portstr, serial.device(1))
+
+ def test_BaudrateSetting(self):
+ self.s.port = PORT
+ self.s.open()
+ for baudrate in (300, 9600, 19200, 115200):
+ self.s.baudrate = baudrate
+ #test get method
+ self.failUnlessEqual(self.s.baudrate, baudrate)
+ #test internals
+ self.failUnlessEqual(self.s._baudrate, baudrate)
+ #test illegal values
+ for illegal_value in (-300, -1, 'a', None):
+ self.failUnlessRaises(ValueError, self.s.setBaudrate, illegal_value)
+
+ def test_BaudrateSetting2(self):
+ #test illegal values, depending on machine/port some of these may be valid...
+ self.s.port = PORT
+ self.s.open()
+ for illegal_value in (500000,576000,921600,92160):
+ self.failUnlessRaises(ValueError, self.s.setBaudrate, illegal_value)
+
+ def test_BytesizeSetting(self):
+ for bytesize in (5,6,7,8):
+ self.s.bytesize = bytesize
+ #test get method
+ self.failUnlessEqual(self.s.bytesize, bytesize)
+ #test internals
+ self.failUnlessEqual(self.s._bytesize, bytesize)
+ #test illegal values
+ for illegal_value in (0, 1, 3, 4, 9, 10, 'a', None):
+ self.failUnlessRaises(ValueError, self.s.setByteSize, illegal_value)
+
+ def test_ParitySetting(self):
+ for parity in (serial.PARITY_NONE, serial.PARITY_EVEN, serial.PARITY_ODD):
+ self.s.parity = parity
+ #test get method
+ self.failUnlessEqual(self.s.parity, parity)
+ #test internals
+ self.failUnlessEqual(self.s._parity, parity)
+ #test illegal values
+ for illegal_value in (0, 57, 'a', None):
+ self.failUnlessRaises(ValueError, self.s.setParity, illegal_value)
+
+ def test_StopbitsSetting(self):
+ for stopbits in (1, 2):
+ self.s.stopbits = stopbits
+ #test get method
+ self.failUnlessEqual(self.s.stopbits, stopbits)
+ #test internals
+ self.failUnlessEqual(self.s._stopbits, stopbits)
+ #test illegal values
+ for illegal_value in (0, 3, 1.5, 57, 'a', None):
+ self.failUnlessRaises(ValueError, self.s.setStopbits, illegal_value)
+
+ def test_TimeoutSetting(self):
+ for timeout in (None, 0, 1, 3.14159, 10, 1000, 3600):
+ self.s.timeout = timeout
+ #test get method
+ self.failUnlessEqual(self.s.timeout, timeout)
+ #test internals
+ self.failUnlessEqual(self.s._timeout, timeout)
+ #test illegal values
+ for illegal_value in (-1, 'a'):
+ self.failUnlessRaises(ValueError, self.s.setTimeout, illegal_value)
+
+ def test_XonXoffSetting(self):
+ for xonxoff in (True, False):
+ self.s.xonxoff = xonxoff
+ #test get method
+ self.failUnlessEqual(self.s.xonxoff, xonxoff)
+ #test internals
+ self.failUnlessEqual(self.s._xonxoff, xonxoff)
+ #no illegal values here, normal rules for the boolean value of an
+ #object are used thus all objects have a truth value.
+
+ def test_RtsCtsSetting(self):
+ for rtscts in (True, False):
+ self.s.rtscts = rtscts
+ #test get method
+ self.failUnlessEqual(self.s.rtscts, rtscts)
+ #test internals
+ self.failUnlessEqual(self.s._rtscts, rtscts)
+ #no illegal values here, normal rules for the boolean value of an
+ #object are used thus all objects have a truth value.
+
+ def test_UnconfiguredPort(self):
+ #an unconfigured port cannot be opened
+ self.failUnlessRaises(serial.SerialException, self.s.open)
+
+ def test_PortOpenClose(self):
+ self.s.port = PORT
+ for i in range(3):
+ #open the port and check flag
+ self.failUnless(not self.s.isOpen())
+ self.s.open()
+ self.failUnless(self.s.isOpen())
+ self.s.close()
+ self.failUnless(not self.s.isOpen())
+
+if __name__ == '__main__':
+ import sys
+ print __doc__
+ print "Testing port", PORT
+ sys.argv.append('-v')
+ # When this module is executed from the command-line, it runs all its tests
+ unittest.main()
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/test_high_load.py b/cesar/maximus/python/lib/proto/pyserial/examples/test_high_load.py
new file mode 100644
index 0000000000..ce884b32b3
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/test_high_load.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#see __init__.py
+#
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+"""Some tests for the serial module.
+Part of pyserial (http://pyserial.sf.net) (C)2002-2003 cliechti@gmx.net
+
+Intended to be run on different platforms, to ensure portability of
+the code.
+
+For all these tests a simple hardware is required.
+Loopback HW adapter:
+Shortcut these pin pairs:
+ TX <-> RX
+ RTS <-> CTS
+ DTR <-> DSR
+
+On a 9 pole DSUB these are the pins (2-3) (4-6) (7-8)
+"""
+
+import unittest, threading, time
+import serial
+
+#on which port should the tests be performed:
+PORT=0
+BAUDRATE=115200
+#~ BAUDRATE=9600
+
+
+class TestHighLoad(unittest.TestCase):
+ """Test sending and receiving large amount of data"""
+
+ N = 16
+ #~ N = 1
+
+ def setUp(self):
+ self.s = serial.Serial(PORT,BAUDRATE, timeout=10)
+ def tearDown(self):
+ self.s.close()
+
+ def test0_WriteReadLoopback(self):
+ """Send big strings, write/read order."""
+ for i in range(self.N):
+ q = ''.join(map(chr,range(256)))
+ self.s.write(q)
+ self.failUnless(self.s.read(len(q))==q, "expected a '%s' which was written before" % q)
+ self.failUnless(self.s.inWaiting()==0, "expected empty buffer after all sent chars are read")
+
+ def test1_WriteWriteReadLoopback(self):
+ """Send big strings, multiple write one read."""
+ q = ''.join(map(chr,range(256)))
+ for i in range(self.N):
+ self.s.write(q)
+ read = self.s.read(len(q)*self.N)
+ self.failUnless(read==q*self.N, "expected what was written before. got %d bytes, expected %d" % (len(read), self.N*len(q)))
+ self.failUnless(self.s.inWaiting()==0, "expected empty buffer after all sent chars are read")
+
+if __name__ == '__main__':
+ import sys
+ print __doc__
+ print "Testing port", PORT
+ sys.argv.append('-v')
+ # When this module is executed from the command-line, it runs all its tests
+ unittest.main()
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/wxSerialConfigDialog.py b/cesar/maximus/python/lib/proto/pyserial/examples/wxSerialConfigDialog.py
new file mode 100644
index 0000000000..57436ceae2
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/wxSerialConfigDialog.py
@@ -0,0 +1,259 @@
+#!/usr/bin/env python
+# generated by wxGlade 0.3.1 on Thu Oct 02 23:25:44 2003
+
+from wxPython.wx import *
+import serial
+
+SHOW_BAUDRATE = 1<<0
+SHOW_FORMAT = 1<<1
+SHOW_FLOW = 1<<2
+SHOW_TIMEOUT = 1<<3
+SHOW_ALL = SHOW_BAUDRATE|SHOW_FORMAT|SHOW_FLOW|SHOW_TIMEOUT
+
+try:
+ enumerate
+except NameError:
+ def enumerate(sequence):
+ return zip(range(len(sequence)), sequence)
+
+class SerialConfigDialog(wxDialog):
+ """Serial Port confiuration dialog, to be used with pyserial 2.0+
+ When instantiating a class of this dialog, then the "serial" keyword
+ argument is mandatory. It is a reference to a serial.Serial instance.
+ the optional "show" keyword argument can be used to show/hide different
+ settings. The default is SHOW_ALL which coresponds to
+ SHOW_BAUDRATE|SHOW_FORMAT|SHOW_FLOW|SHOW_TIMEOUT. All constants can be
+ found in ths module (not the class)."""
+
+ def __init__(self, *args, **kwds):
+ #grab the serial keyword and remove it from the dict
+ self.serial = kwds['serial']
+ del kwds['serial']
+ self.show = SHOW_ALL
+ if kwds.has_key('show'):
+ self.show = kwds['show']
+ del kwds['show']
+ # begin wxGlade: SerialConfigDialog.__init__
+ # end wxGlade
+ kwds["style"] = wxDEFAULT_DIALOG_STYLE
+ wxDialog.__init__(self, *args, **kwds)
+ self.label_2 = wxStaticText(self, -1, "Port")
+ self.combo_box_port = wxComboBox(self, -1, choices=["dummy1", "dummy2", "dummy3", "dummy4", "dummy5"], style=wxCB_DROPDOWN)
+ if self.show & SHOW_BAUDRATE:
+ self.label_1 = wxStaticText(self, -1, "Baudrate")
+ self.choice_baudrate = wxChoice(self, -1, choices=["choice 1"])
+ if self.show & SHOW_FORMAT:
+ self.label_3 = wxStaticText(self, -1, "Data Bits")
+ self.choice_databits = wxChoice(self, -1, choices=["choice 1"])
+ self.label_4 = wxStaticText(self, -1, "Stop Bits")
+ self.choice_stopbits = wxChoice(self, -1, choices=["choice 1"])
+ self.label_5 = wxStaticText(self, -1, "Parity")
+ self.choice_parity = wxChoice(self, -1, choices=["choice 1"])
+ if self.show & SHOW_TIMEOUT:
+ self.checkbox_timeout = wxCheckBox(self, -1, "Use Timeout")
+ self.text_ctrl_timeout = wxTextCtrl(self, -1, "")
+ self.label_6 = wxStaticText(self, -1, "seconds")
+ if self.show & SHOW_FLOW:
+ self.checkbox_rtscts = wxCheckBox(self, -1, "RTS/CTS")
+ self.checkbox_xonxoff = wxCheckBox(self, -1, "Xon/Xoff")
+ self.button_ok = wxButton(self, -1, "OK")
+ self.button_cancel = wxButton(self, -1, "Cancel")
+
+ self.__set_properties()
+ self.__do_layout()
+ #fill in ports and select current setting
+ index = 0
+ self.combo_box_port.Clear()
+ for n in range(4):
+ portname = serial.device(n)
+ self.combo_box_port.Append(portname)
+ if self.serial.portstr == portname:
+ index = n
+ if self.serial.portstr is not None:
+ self.combo_box_port.SetValue(str(self.serial.portstr))
+ else:
+ self.combo_box_port.SetSelection(index)
+ if self.show & SHOW_BAUDRATE:
+ #fill in badrates and select current setting
+ self.choice_baudrate.Clear()
+ for n, baudrate in enumerate(self.serial.BAUDRATES):
+ self.choice_baudrate.Append(str(baudrate))
+ if self.serial.baudrate == baudrate:
+ index = n
+ self.choice_baudrate.SetSelection(index)
+ if self.show & SHOW_FORMAT:
+ #fill in databits and select current setting
+ self.choice_databits.Clear()
+ for n, bytesize in enumerate(self.serial.BYTESIZES):
+ self.choice_databits.Append(str(bytesize))
+ if self.serial.bytesize == bytesize:
+ index = n
+ self.choice_databits.SetSelection(index)
+ #fill in stopbits and select current setting
+ self.choice_stopbits.Clear()
+ for n, stopbits in enumerate(self.serial.STOPBITS):
+ self.choice_stopbits.Append(str(stopbits))
+ if self.serial.stopbits == stopbits:
+ index = n
+ self.choice_stopbits.SetSelection(index)
+ #fill in parities and select current setting
+ self.choice_parity.Clear()
+ for n, parity in enumerate(self.serial.PARITIES):
+ self.choice_parity.Append(str(serial.PARITY_NAMES[parity]))
+ if self.serial.parity == parity:
+ index = n
+ self.choice_parity.SetSelection(index)
+ if self.show & SHOW_TIMEOUT:
+ #set the timeout mode and value
+ if self.serial.timeout is None:
+ self.checkbox_timeout.SetValue(False)
+ self.text_ctrl_timeout.Enable(False)
+ else:
+ self.checkbox_timeout.SetValue(True)
+ self.text_ctrl_timeout.Enable(True)
+ self.text_ctrl_timeout.SetValue(str(self.serial.timeout))
+ if self.show & SHOW_FLOW:
+ #set the rtscts mode
+ self.checkbox_rtscts.SetValue(self.serial.rtscts)
+ #set the rtscts mode
+ self.checkbox_xonxoff.SetValue(self.serial.xonxoff)
+ #attach the event handlers
+ self.__attach_events()
+
+ def __set_properties(self):
+ # begin wxGlade: SerialConfigDialog.__set_properties
+ # end wxGlade
+ self.SetTitle("Serial Port Configuration")
+ if self.show & SHOW_TIMEOUT:
+ self.text_ctrl_timeout.Enable(0)
+ self.button_ok.SetDefault()
+
+ def __do_layout(self):
+ # begin wxGlade: SerialConfigDialog.__do_layout
+ # end wxGlade
+ sizer_2 = wxBoxSizer(wxVERTICAL)
+ sizer_3 = wxBoxSizer(wxHORIZONTAL)
+ sizer_basics = wxStaticBoxSizer(wxStaticBox(self, -1, "Basics"), wxVERTICAL)
+ sizer_5 = wxBoxSizer(wxHORIZONTAL)
+ sizer_5.Add(self.label_2, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
+ sizer_5.Add(self.combo_box_port, 1, 0, 0)
+ sizer_basics.Add(sizer_5, 0, wxRIGHT|wxEXPAND, 0)
+ if self.show & SHOW_BAUDRATE:
+ sizer_baudrate = wxBoxSizer(wxHORIZONTAL)
+ sizer_baudrate.Add(self.label_1, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
+ sizer_baudrate.Add(self.choice_baudrate, 1, wxALIGN_RIGHT, 0)
+ sizer_basics.Add(sizer_baudrate, 0, wxEXPAND, 0)
+ sizer_2.Add(sizer_basics, 0, wxEXPAND, 0)
+ if self.show & SHOW_FORMAT:
+ sizer_8 = wxBoxSizer(wxHORIZONTAL)
+ sizer_7 = wxBoxSizer(wxHORIZONTAL)
+ sizer_6 = wxBoxSizer(wxHORIZONTAL)
+ sizer_format = wxStaticBoxSizer(wxStaticBox(self, -1, "Data Format"), wxVERTICAL)
+ sizer_6.Add(self.label_3, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
+ sizer_6.Add(self.choice_databits, 1, wxALIGN_RIGHT, 0)
+ sizer_format.Add(sizer_6, 0, wxEXPAND, 0)
+ sizer_7.Add(self.label_4, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
+ sizer_7.Add(self.choice_stopbits, 1, wxALIGN_RIGHT, 0)
+ sizer_format.Add(sizer_7, 0, wxEXPAND, 0)
+ sizer_8.Add(self.label_5, 1, wxALL|wxALIGN_CENTER_VERTICAL, 4)
+ sizer_8.Add(self.choice_parity, 1, wxALIGN_RIGHT, 0)
+ sizer_format.Add(sizer_8, 0, wxEXPAND, 0)
+ sizer_2.Add(sizer_format, 0, wxEXPAND, 0)
+ if self.show & SHOW_TIMEOUT:
+ sizer_timeout = wxStaticBoxSizer(wxStaticBox(self, -1, "Timeout"), wxHORIZONTAL)
+ sizer_timeout.Add(self.checkbox_timeout, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
+ sizer_timeout.Add(self.text_ctrl_timeout, 0, 0, 0)
+ sizer_timeout.Add(self.label_6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
+ sizer_2.Add(sizer_timeout, 0, 0, 0)
+ if self.show & SHOW_FLOW:
+ sizer_flow = wxStaticBoxSizer(wxStaticBox(self, -1, "Flow Control"), wxHORIZONTAL)
+ sizer_flow.Add(self.checkbox_rtscts, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
+ sizer_flow.Add(self.checkbox_xonxoff, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
+ sizer_flow.Add((10,10), 1, wxEXPAND, 0)
+ sizer_2.Add(sizer_flow, 0, wxEXPAND, 0)
+ sizer_3.Add(self.button_ok, 0, 0, 0)
+ sizer_3.Add(self.button_cancel, 0, 0, 0)
+ sizer_2.Add(sizer_3, 0, wxALL|wxALIGN_RIGHT, 4)
+ self.SetAutoLayout(1)
+ self.SetSizer(sizer_2)
+ sizer_2.Fit(self)
+ sizer_2.SetSizeHints(self)
+ self.Layout()
+
+ def __attach_events(self):
+ EVT_BUTTON(self, self.button_ok.GetId(), self.OnOK)
+ EVT_BUTTON(self, self.button_cancel.GetId(), self.OnCancel)
+ if self.show & SHOW_TIMEOUT:
+ EVT_CHECKBOX(self, self.checkbox_timeout.GetId(), self.OnTimeout)
+
+ def OnOK(self, events):
+ success = True
+ self.serial.port = str(self.combo_box_port.GetValue())
+ if self.show & SHOW_BAUDRATE:
+ self.serial.baudrate = self.serial.BAUDRATES[self.choice_baudrate.GetSelection()]
+ if self.show & SHOW_FORMAT:
+ self.serial.bytesize = self.serial.BYTESIZES[self.choice_databits.GetSelection()]
+ self.serial.stopbits = self.serial.STOPBITS[self.choice_stopbits.GetSelection()]
+ self.serial.parity = self.serial.PARITIES[self.choice_parity.GetSelection()]
+ if self.show & SHOW_FLOW:
+ self.serial.rtscts = self.checkbox_rtscts.GetValue()
+ self.serial.xonxoff = self.checkbox_xonxoff.GetValue()
+ if self.show & SHOW_TIMEOUT:
+ if self.checkbox_timeout.GetValue():
+ try:
+ self.serial.timeout = float(self.text_ctrl_timeout.GetValue())
+ except ValueError:
+ dlg = wxMessageDialog(self, 'Timeout must be a numeric value',
+ 'Value Error', wxOK | wxICON_ERROR)
+ dlg.ShowModal()
+ dlg.Destroy()
+ success = False
+ else:
+ self.serial.timeout = None
+ if success:
+ self.EndModal(wxID_OK)
+
+ def OnCancel(self, events):
+ self.EndModal(wxID_CANCEL)
+
+ def OnTimeout(self, events):
+ if self.checkbox_timeout.GetValue():
+ self.text_ctrl_timeout.Enable(True)
+ else:
+ self.text_ctrl_timeout.Enable(False)
+
+# end of class SerialConfigDialog
+
+
+class MyApp(wxApp):
+ """Test code"""
+ def OnInit(self):
+ wxInitAllImageHandlers()
+
+ ser = serial.Serial()
+ print ser
+ #loop until cancel is pressed, old values are used as start for the next run
+ #show the different views, one after the other
+ #value are kept.
+ for flags in (SHOW_BAUDRATE, SHOW_FLOW, SHOW_FORMAT, SHOW_TIMEOUT, SHOW_ALL):
+ dialog_serial_cfg = SerialConfigDialog(None, -1, "", serial=ser, show=flags)
+ self.SetTopWindow(dialog_serial_cfg)
+ result = dialog_serial_cfg.ShowModal()
+ print ser
+ if result != wxID_OK:
+ break
+ #the user can play around with the values, CANCEL aborts the loop
+ while 1:
+ dialog_serial_cfg = SerialConfigDialog(None, -1, "", serial=ser)
+ self.SetTopWindow(dialog_serial_cfg)
+ result = dialog_serial_cfg.ShowModal()
+ print ser
+ if result != wxID_OK:
+ break
+ return 0
+
+# end of class MyApp
+
+if __name__ == "__main__":
+ app = MyApp(0)
+ app.MainLoop()
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/wxSerialConfigDialog.wxg b/cesar/maximus/python/lib/proto/pyserial/examples/wxSerialConfigDialog.wxg
new file mode 100644
index 0000000000..8888611195
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/wxSerialConfigDialog.wxg
@@ -0,0 +1,262 @@
+<?xml version="1.0"?>
+<!-- generated by wxGlade 0.3.1 on Fri Oct 03 01:53:04 2003 -->
+
+<application path="D:\prog\python\pyserial_sf\pyserial\examples\wxSerialConfigDialog.py" name="app" class="MyApp" option="0" language="python" top_window="dialog_serial_cfg" encoding="ISO-8859-1" use_gettext="0" overwrite="0">
+ <object class="SerialConfigDialog" name="dialog_serial_cfg" base="EditDialog">
+ <style>wxDEFAULT_DIALOG_STYLE</style>
+ <title>Serial Port Configuration</title>
+ <object class="wxBoxSizer" name="sizer_2" base="EditBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>0</option>
+ <object class="wxStaticBoxSizer" name="sizer_basics" base="EditStaticBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <label>Basics</label>
+ <object class="sizeritem">
+ <flag>wxRIGHT|wxEXPAND</flag>
+ <border>0</border>
+ <option>0</option>
+ <object class="wxBoxSizer" name="sizer_5" base="EditBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>
+ <border>4</border>
+ <option>1</option>
+ <object class="wxStaticText" name="label_2" base="EditStaticText">
+ <attribute>1</attribute>
+ <label>Port</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <border>0</border>
+ <option>1</option>
+ <object class="wxComboBox" name="combo_box_port" base="EditComboBox">
+ <selection>0</selection>
+ <choices>
+ <choice>dummy1</choice>
+ <choice>dummy2</choice>
+ <choice>dummy3</choice>
+ <choice>dummy4</choice>
+ <choice>dummy5</choice>
+ </choices>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>0</option>
+ <object class="wxBoxSizer" name="sizer_baudrate" base="EditBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>
+ <border>4</border>
+ <option>1</option>
+ <object class="wxStaticText" name="label_1" base="EditStaticText">
+ <attribute>1</attribute>
+ <label>Baudrate</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALIGN_RIGHT</flag>
+ <border>0</border>
+ <option>1</option>
+ <object class="wxChoice" name="choice_baudrate" base="EditChoice">
+ <selection>0</selection>
+ <choices>
+ <choice>choice 1</choice>
+ </choices>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>0</option>
+ <object class="wxStaticBoxSizer" name="sizer_format" base="EditStaticBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <label>Data Format</label>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>0</option>
+ <object class="wxBoxSizer" name="sizer_6" base="EditBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>
+ <border>4</border>
+ <option>1</option>
+ <object class="wxStaticText" name="label_3" base="EditStaticText">
+ <attribute>1</attribute>
+ <label>Data Bits</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALIGN_RIGHT</flag>
+ <border>0</border>
+ <option>1</option>
+ <object class="wxChoice" name="choice_databits" base="EditChoice">
+ <selection>0</selection>
+ <choices>
+ <choice>choice 1</choice>
+ </choices>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>0</option>
+ <object class="wxBoxSizer" name="sizer_7" base="EditBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>
+ <border>4</border>
+ <option>1</option>
+ <object class="wxStaticText" name="label_4" base="EditStaticText">
+ <attribute>1</attribute>
+ <label>Stop Bits</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALIGN_RIGHT</flag>
+ <border>0</border>
+ <option>1</option>
+ <object class="wxChoice" name="choice_stopbits" base="EditChoice">
+ <selection>0</selection>
+ <choices>
+ <choice>choice 1</choice>
+ </choices>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>0</option>
+ <object class="wxBoxSizer" name="sizer_8" base="EditBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>
+ <border>4</border>
+ <option>1</option>
+ <object class="wxStaticText" name="label_5" base="EditStaticText">
+ <attribute>1</attribute>
+ <label>Parity</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALIGN_RIGHT</flag>
+ <border>0</border>
+ <option>1</option>
+ <object class="wxChoice" name="choice_parity" base="EditChoice">
+ <selection>0</selection>
+ <choices>
+ <choice>choice 1</choice>
+ </choices>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <border>0</border>
+ <option>0</option>
+ <object class="wxStaticBoxSizer" name="sizer_timeout" base="EditStaticBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <label>Timeout</label>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>
+ <border>4</border>
+ <option>0</option>
+ <object class="wxCheckBox" name="checkbox_timeout" base="EditCheckBox">
+ <label>Use Timeout</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <border>0</border>
+ <option>0</option>
+ <object class="wxTextCtrl" name="text_ctrl_timeout" base="EditTextCtrl">
+ <disabled>1</disabled>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>
+ <border>4</border>
+ <option>0</option>
+ <object class="wxStaticText" name="label_6" base="EditStaticText">
+ <attribute>1</attribute>
+ <label>seconds</label>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>0</option>
+ <object class="wxStaticBoxSizer" name="sizer_flow" base="EditStaticBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <label>Flow Control</label>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>
+ <border>4</border>
+ <option>0</option>
+ <object class="wxCheckBox" name="checkbox_rtscts" base="EditCheckBox">
+ <label>RTS/CTS</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>
+ <border>4</border>
+ <option>0</option>
+ <object class="wxCheckBox" name="checkbox_xonxoff" base="EditCheckBox">
+ <label>Xon/Xoff</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>1</option>
+ <object class="spacer" name="spacer" base="EditSpacer">
+ <height>10</height>
+ <width>10</width>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_RIGHT</flag>
+ <border>4</border>
+ <option>0</option>
+ <object class="wxBoxSizer" name="sizer_3" base="EditBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <border>0</border>
+ <option>0</option>
+ <object class="wxButton" name="button_ok" base="EditButton">
+ <default>1</default>
+ <label>OK</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <border>0</border>
+ <option>0</option>
+ <object class="wxButton" name="button_cancel" base="EditButton">
+ <label>Cancel</label>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</application>
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/wxTerminal.py b/cesar/maximus/python/lib/proto/pyserial/examples/wxTerminal.py
new file mode 100644
index 0000000000..fcac57195a
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/wxTerminal.py
@@ -0,0 +1,332 @@
+#!/usr/bin/env python
+# generated by wxGlade 0.3.1 on Fri Oct 03 23:23:45 2003
+
+from wxPython.wx import *
+import wxSerialConfigDialog
+import serial
+import threading
+
+#----------------------------------------------------------------------
+# Create an own event type, so that GUI updates can be delegated
+# this is required as on some platforms only the main thread can
+# access the GUI without crashing. wxMutexGuiEnter/wxMutexGuiLeave
+# could be used too, but an event is more elegant.
+
+SERIALRX = wxNewEventType()
+# bind to serial data receive events
+EVT_SERIALRX = wxPyEventBinder(SERIALRX, 0)
+
+class SerialRxEvent(wxPyCommandEvent):
+ eventType = SERIALRX
+ def __init__(self, windowID, data):
+ wxPyCommandEvent.__init__(self, self.eventType, windowID)
+ self.data = data
+
+ def Clone(self):
+ self.__class__(self.GetId(), self.data)
+
+#----------------------------------------------------------------------
+
+ID_CLEAR = wxNewId()
+ID_SAVEAS = wxNewId()
+ID_SETTINGS = wxNewId()
+ID_TERM = wxNewId()
+ID_EXIT = wxNewId()
+
+NEWLINE_CR = 0
+NEWLINE_LF = 1
+NEWLINE_CRLF = 2
+
+class TerminalSetup:
+ """Placeholder for various terminal settings. Used to pass the
+ options to the TerminalSettingsDialog."""
+ def __init__(self):
+ self.echo = False
+ self.unprintable = False
+ self.newline = NEWLINE_CRLF
+
+class TerminalSettingsDialog(wxDialog):
+ """Simple dialog with common terminal settings like echo, newline mode."""
+
+ def __init__(self, *args, **kwds):
+ self.settings = kwds['settings']
+ del kwds['settings']
+ # begin wxGlade: TerminalSettingsDialog.__init__
+ kwds["style"] = wxDEFAULT_DIALOG_STYLE
+ wxDialog.__init__(self, *args, **kwds)
+ self.checkbox_echo = wxCheckBox(self, -1, "Local Echo")
+ self.checkbox_unprintable = wxCheckBox(self, -1, "Show unprintable characters")
+ self.radio_box_newline = wxRadioBox(self, -1, "Newline Handling", choices=["CR only", "LF only", "CR+LF"], majorDimension=0, style=wxRA_SPECIFY_ROWS)
+ self.button_ok = wxButton(self, -1, "OK")
+ self.button_cancel = wxButton(self, -1, "Cancel")
+
+ self.__set_properties()
+ self.__do_layout()
+ # end wxGlade
+ self.__attach_events()
+ self.checkbox_echo.SetValue(self.settings.echo)
+ self.checkbox_unprintable.SetValue(self.settings.unprintable)
+ self.radio_box_newline.SetSelection(self.settings.newline)
+
+ def __set_properties(self):
+ # begin wxGlade: TerminalSettingsDialog.__set_properties
+ self.SetTitle("Terminal Settings")
+ self.radio_box_newline.SetSelection(0)
+ self.button_ok.SetDefault()
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: TerminalSettingsDialog.__do_layout
+ sizer_2 = wxBoxSizer(wxVERTICAL)
+ sizer_3 = wxBoxSizer(wxHORIZONTAL)
+ sizer_4 = wxStaticBoxSizer(wxStaticBox(self, -1, "Input/Output"), wxVERTICAL)
+ sizer_4.Add(self.checkbox_echo, 0, wxALL, 4)
+ sizer_4.Add(self.checkbox_unprintable, 0, wxALL, 4)
+ sizer_4.Add(self.radio_box_newline, 0, 0, 0)
+ sizer_2.Add(sizer_4, 0, wxEXPAND, 0)
+ sizer_3.Add(self.button_ok, 0, 0, 0)
+ sizer_3.Add(self.button_cancel, 0, 0, 0)
+ sizer_2.Add(sizer_3, 0, wxALL|wxALIGN_RIGHT, 4)
+ self.SetAutoLayout(1)
+ self.SetSizer(sizer_2)
+ sizer_2.Fit(self)
+ sizer_2.SetSizeHints(self)
+ self.Layout()
+ # end wxGlade
+
+ def __attach_events(self):
+ self.Bind(EVT_BUTTON, self.OnOK, id = self.button_ok.GetId())
+ self.Bind(EVT_BUTTON, self.OnCancel, id = self.button_cancel.GetId())
+
+ def OnOK(self, events):
+ """Update data wil new values and close dialog."""
+ self.settings.echo = self.checkbox_echo.GetValue()
+ self.settings.unprintable = self.checkbox_unprintable.GetValue()
+ self.settings.newline = self.radio_box_newline.GetSelection()
+ self.EndModal(wxID_OK)
+
+ def OnCancel(self, events):
+ """Do not update data but close dialog."""
+ self.EndModal(wxID_CANCEL)
+
+# end of class TerminalSettingsDialog
+
+
+class TerminalFrame(wxFrame):
+ """Simple terminal program for wxPython"""
+
+ def __init__(self, *args, **kwds):
+ self.serial = serial.Serial()
+ self.serial.timeout = 0.5 #make sure that the alive event can be checked from time to time
+ self.settings = TerminalSetup() #placeholder for the settings
+ self.thread = None
+ self.alive = threading.Event()
+ # begin wxGlade: TerminalFrame.__init__
+ kwds["style"] = wxDEFAULT_FRAME_STYLE
+ wxFrame.__init__(self, *args, **kwds)
+ self.text_ctrl_output = wxTextCtrl(self, -1, "", style=wxTE_MULTILINE|wxTE_READONLY)
+
+ # Menu Bar
+ self.frame_terminal_menubar = wxMenuBar()
+ self.SetMenuBar(self.frame_terminal_menubar)
+ wxglade_tmp_menu = wxMenu()
+ wxglade_tmp_menu.Append(ID_CLEAR, "&Clear", "", wxITEM_NORMAL)
+ wxglade_tmp_menu.Append(ID_SAVEAS, "&Save Text As...", "", wxITEM_NORMAL)
+ wxglade_tmp_menu.AppendSeparator()
+ wxglade_tmp_menu.Append(ID_SETTINGS, "&Port Settings...", "", wxITEM_NORMAL)
+ wxglade_tmp_menu.Append(ID_TERM, "&Terminal Settings...", "", wxITEM_NORMAL)
+ wxglade_tmp_menu.AppendSeparator()
+ wxglade_tmp_menu.Append(ID_EXIT, "&Exit", "", wxITEM_NORMAL)
+ self.frame_terminal_menubar.Append(wxglade_tmp_menu, "&File")
+ # Menu Bar end
+
+ self.__set_properties()
+ self.__do_layout()
+ # end wxGlade
+ self.__attach_events() #register events
+ self.OnPortSettings(None) #call setup dialog on startup, opens port
+ if not self.alive.isSet():
+ self.Close()
+
+ def StartThread(self):
+ """Start the receiver thread"""
+ self.thread = threading.Thread(target=self.ComPortThread)
+ self.thread.setDaemon(1)
+ self.thread.start()
+ self.alive.set()
+
+ def StopThread(self):
+ """Stop the receiver thread, wait util it's finished."""
+ if self.thread is not None:
+ self.alive.clear() #clear alive event for thread
+ self.thread.join() #wait until thread has finished
+ self.thread = None
+
+ def __set_properties(self):
+ # begin wxGlade: TerminalFrame.__set_properties
+ self.SetTitle("Serial Terminal")
+ self.SetSize((546, 383))
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: TerminalFrame.__do_layout
+ sizer_1 = wxBoxSizer(wxVERTICAL)
+ sizer_1.Add(self.text_ctrl_output, 1, wxEXPAND, 0)
+ self.SetAutoLayout(1)
+ self.SetSizer(sizer_1)
+ self.Layout()
+ # end wxGlade
+
+ def __attach_events(self):
+ #register events at the controls
+ self.Bind(EVT_MENU, self.OnClear, id = ID_CLEAR)
+ self.Bind(EVT_MENU, self.OnSaveAs, id = ID_SAVEAS)
+ self.Bind(EVT_MENU, self.OnExit, id = ID_EXIT)
+ self.Bind(EVT_MENU, self.OnPortSettings, id = ID_SETTINGS)
+ self.Bind(EVT_MENU, self.OnTermSettings, id = ID_TERM)
+ self.text_ctrl_output.Bind(EVT_CHAR, self.OnKey)
+ self.Bind(EVT_SERIALRX, self.OnSerialRead)
+ self.Bind(EVT_CLOSE, self.OnClose)
+
+ def OnExit(self, event):
+ """Menu point Exit"""
+ self.Close()
+
+ def OnClose(self, event):
+ """Called on application shutdown."""
+ self.StopThread() #stop reader thread
+ self.serial.close() #cleanup
+ self.Destroy() #close windows, exit app
+
+ def OnSaveAs(self, event):
+ """Save contents of output window."""
+ filename = None
+ dlg = wxFileDialog(None, "Save Text As...", ".", "", "Text File|*.txt|All Files|*", wxSAVE)
+ if dlg.ShowModal() == wxID_OK:
+ filename = dlg.GetPath()
+ dlg.Destroy()
+
+ if filename is not None:
+ f = file(filename, 'w')
+ text = self.text_ctrl_output.GetValue()
+ if type(text) == unicode:
+ text = text.encode("latin1") #hm, is that a good asumption?
+ f.write(text)
+ f.close()
+
+ def OnClear(self, event):
+ """Clear contents of output window."""
+ self.text_ctrl_output.Clear()
+
+ def OnPortSettings(self, event=None):
+ """Show the portsettings dialog. The reader thread is stopped for the
+ settings change."""
+ if event is not None: #will be none when called on startup
+ self.StopThread()
+ self.serial.close()
+ ok = False
+ while not ok:
+ dialog_serial_cfg = wxSerialConfigDialog.SerialConfigDialog(None, -1, "",
+ show=wxSerialConfigDialog.SHOW_BAUDRATE|wxSerialConfigDialog.SHOW_FORMAT|wxSerialConfigDialog.SHOW_FLOW,
+ serial=self.serial
+ )
+ result = dialog_serial_cfg.ShowModal()
+ dialog_serial_cfg.Destroy()
+ #open port if not called on startup, open it on startup and OK too
+ if result == wxID_OK or event is not None:
+ try:
+ self.serial.open()
+ except serial.SerialException, e:
+ dlg = wxMessageDialog(None, str(e), "Serial Port Error", wxOK | wxICON_ERROR)
+ dlg.ShowModal()
+ dlg.Destroy()
+ else:
+ self.StartThread()
+ self.SetTitle("Serial Terminal on %s [%s, %s%s%s%s%s]" % (
+ self.serial.portstr,
+ self.serial.baudrate,
+ self.serial.bytesize,
+ self.serial.parity,
+ self.serial.stopbits,
+ self.serial.rtscts and ' RTS/CTS' or '',
+ self.serial.xonxoff and ' Xon/Xoff' or '',
+ )
+ )
+ ok = True
+ else:
+ #on startup, dialog aborted
+ self.alive.clear()
+ ok = True
+
+ def OnTermSettings(self, event):
+ """Menu point Terminal Settings. Show the settings dialog
+ with the current terminal settings"""
+ dialog = TerminalSettingsDialog(None, -1, "", settings=self.settings)
+ result = dialog.ShowModal()
+ dialog.Destroy()
+
+ def OnKey(self, event):
+ """Key event handler. if the key is in the ASCII range, write it to the serial port.
+ Newline handling and local echo is also done here."""
+ code = event.GetKeyCode()
+ if code < 256: #is it printable?
+ if code == 13: #is it a newline? (check for CR which is the RETURN key)
+ if self.settings.echo: #do echo if needed
+ self.text_ctrl_output.AppendText('\n')
+ if self.settings.newline == NEWLINE_CR:
+ self.serial.write('\r') #send CR
+ elif self.settings.newline == NEWLINE_LF:
+ self.serial.write('\n') #send LF
+ elif self.settings.newline == NEWLINE_CRLF:
+ self.serial.write('\r\n') #send CR+LF
+ else:
+ char = chr(code)
+ if self.settings.echo: #do echo if needed
+ self.text_ctrl_output.WriteText(char)
+ self.serial.write(char) #send the charcater
+ else:
+ print "Extra Key:", code
+
+ def OnSerialRead(self, event):
+ """Handle input from the serial port."""
+ text = event.data
+ if self.settings.unprintable:
+ text = ''.join([(c >= ' ') and c or '<%d>' % ord(c) for c in text])
+ self.text_ctrl_output.AppendText(text)
+
+ def ComPortThread(self):
+ """Thread that handles the incomming traffic. Does the basic input
+ transformation (newlines) and generates an SerialRxEvent"""
+ while self.alive.isSet(): #loop while alive event is true
+ text = self.serial.read(1) #read one, with timout
+ if text: #check if not timeout
+ n = self.serial.inWaiting() #look if there is more to read
+ if n:
+ text = text + self.serial.read(n) #get it
+ #newline transformation
+ if self.settings.newline == NEWLINE_CR:
+ text = text.replace('\r', '\n')
+ elif self.settings.newline == NEWLINE_LF:
+ pass
+ elif self.settings.newline == NEWLINE_CRLF:
+ text = text.replace('\r\n', '\n')
+ event = SerialRxEvent(self.GetId(), text)
+ self.GetEventHandler().AddPendingEvent(event)
+ #~ self.OnSerialRead(text) #output text in window
+
+# end of class TerminalFrame
+
+
+class MyApp(wxApp):
+ def OnInit(self):
+ wxInitAllImageHandlers()
+ frame_terminal = TerminalFrame(None, -1, "")
+ self.SetTopWindow(frame_terminal)
+ frame_terminal.Show(1)
+ return 1
+
+# end of class MyApp
+
+if __name__ == "__main__":
+ app = MyApp(0)
+ app.MainLoop()
diff --git a/cesar/maximus/python/lib/proto/pyserial/examples/wxTerminal.wxg b/cesar/maximus/python/lib/proto/pyserial/examples/wxTerminal.wxg
new file mode 100644
index 0000000000..1f20511f6b
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/examples/wxTerminal.wxg
@@ -0,0 +1,127 @@
+<?xml version="1.0"?>
+<!-- generated by wxGlade 0.3.1 on Sat Oct 04 02:41:48 2003 -->
+
+<application path="D:\prog\python\pyserial_sf\pyserial\examples\wxTerminal.py" name="app" class="MyApp" option="0" language="python" top_window="frame_terminal" encoding="ISO-8859-1" use_gettext="0" overwrite="0">
+ <object class="TerminalFrame" name="frame_terminal" base="EditFrame">
+ <style>wxDEFAULT_FRAME_STYLE</style>
+ <title>Serial Terminal</title>
+ <menubar>1</menubar>
+ <size>546, 383</size>
+ <object class="wxBoxSizer" name="sizer_1" base="EditBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>1</option>
+ <object class="wxTextCtrl" name="text_ctrl_output" base="EditTextCtrl">
+ <style>wxTE_MULTILINE|wxTE_READONLY</style>
+ </object>
+ </object>
+ </object>
+ <object class="wxMenuBar" name="frame_terminal_menubar" base="EditMenuBar">
+ <menus>
+ <menu name="" label="&amp;File">
+ <item>
+ <label>&amp;Clear</label>
+ <id>ID_CLEAR</id>
+ </item>
+ <item>
+ <label>&amp;Save Text As...</label>
+ <id>ID_SAVEAS</id>
+ </item>
+ <item>
+ <label>---</label>
+ <id>---</id>
+ <name>---</name>
+ </item>
+ <item>
+ <label>&amp;Port Settings...</label>
+ <id>ID_SETTINGS</id>
+ </item>
+ <item>
+ <label>&amp;Terminal Settings...</label>
+ <id>ID_TERM</id>
+ </item>
+ <item>
+ <label>---</label>
+ <name>---</name>
+ </item>
+ <item>
+ <label>&amp;Exit</label>
+ <id>ID_EXIT</id>
+ </item>
+ </menu>
+ </menus>
+ </object>
+ </object>
+ <object class="TerminalSettingsDialog" name="dialog_terminal_Settings" base="EditDialog">
+ <style>wxDEFAULT_DIALOG_STYLE</style>
+ <title>Terminal Settings</title>
+ <object class="wxBoxSizer" name="sizer_2" base="EditBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <flag>wxEXPAND</flag>
+ <border>0</border>
+ <option>0</option>
+ <object class="wxStaticBoxSizer" name="sizer_4" base="EditStaticBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <label>Input/Output</label>
+ <object class="sizeritem">
+ <flag>wxALL</flag>
+ <border>4</border>
+ <option>0</option>
+ <object class="wxCheckBox" name="checkbox_echo" base="EditCheckBox">
+ <label>Local Echo</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALL</flag>
+ <border>4</border>
+ <option>0</option>
+ <object class="wxCheckBox" name="checkbox_unprintable" base="EditCheckBox">
+ <label>Show unprintable characters</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <border>0</border>
+ <option>0</option>
+ <object class="wxRadioBox" name="radio_box_newline" base="EditRadioBox">
+ <style>wxRA_SPECIFY_ROWS</style>
+ <selection>0</selection>
+ <dimension>0</dimension>
+ <label>Newline Handling</label>
+ <choices>
+ <choice>CR only</choice>
+ <choice>LF only</choice>
+ <choice>CR+LF</choice>
+ </choices>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALL|wxALIGN_RIGHT</flag>
+ <border>4</border>
+ <option>0</option>
+ <object class="wxBoxSizer" name="sizer_3" base="EditBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <border>0</border>
+ <option>0</option>
+ <object class="wxButton" name="button_ok" base="EditButton">
+ <default>1</default>
+ <label>OK</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <border>0</border>
+ <option>0</option>
+ <object class="wxButton" name="button_cancel" base="EditButton">
+ <label>Cancel</label>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</application>
diff --git a/cesar/maximus/python/lib/proto/pyserial/serial/__init__.py b/cesar/maximus/python/lib/proto/pyserial/serial/__init__.py
new file mode 100644
index 0000000000..2894b30055
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/serial/__init__.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+#portable serial port access with python
+#this is a wrapper module for different platform implementations
+#
+# (C)2001-2002 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+import sys, os, string
+VERSION = string.split("$Revision: 1.3 $")[1] #extract CVS version
+
+#chose an implementation, depending on os
+if os.name == 'nt': #sys.platform == 'win32':
+ from serialwin32 import *
+elif os.name == 'posix':
+ from serialposix import *
+elif os.name == 'java':
+ from serialjava import *
+else:
+ raise Exception("Sorry: no implementation for your platform ('%s') available" % os.name)
+
diff --git a/cesar/maximus/python/lib/proto/pyserial/serial/serialjava.py b/cesar/maximus/python/lib/proto/pyserial/serial/serialjava.py
new file mode 100644
index 0000000000..f5c84fb99b
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/serial/serialjava.py
@@ -0,0 +1,212 @@
+#!jython
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#module for serial IO for Jython and JavaComm
+#see __init__.py
+#
+#(C) 2002-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+import javax.comm
+from serialutil import *
+
+VERSION = "$Revision: 1.8 $".split()[1] #extract CVS version
+
+
+def device(portnumber):
+ """Turn a port number into a device name"""
+ enum = javax.comm.CommPortIdentifier.getPortIdentifiers()
+ ports = []
+ while enum.hasMoreElements():
+ el = enum.nextElement()
+ if el.getPortType() == javax.comm.CommPortIdentifier.PORT_SERIAL:
+ ports.append(el)
+ return ports[portnumber].getName()
+
+class Serial(SerialBase):
+ """Serial port class, implemented with javax.comm and thus usable with
+ jython and the appropriate java extension."""
+
+ def open(self):
+ """Open port with current settings. This may throw a SerialException
+ if the port cannot be opened."""
+ if self._port is None:
+ raise SerialException("Port must be configured before it can be used.")
+ if type(self._port) == type(''): #strings are taken directly
+ portId = javax.comm.CommPortIdentifier.getPortIdentifier(self._port)
+ else:
+ portId = javax.comm.CommPortIdentifier.getPortIdentifier(device(self._port)) #numbers are transformed to a comportid obj
+ try:
+ self.sPort = portId.open("python serial module", 10)
+ except Exception, msg:
+ self.sPort = None
+ raise SerialException("Could not open port: %s" % msg)
+ self._reconfigurePort()
+ self._instream = self.sPort.getInputStream()
+ self._outstream = self.sPort.getOutputStream()
+ self._isOpen = True
+
+ def _reconfigurePort(self):
+ """Set commuication parameters on opened port."""
+ if not self.sPort:
+ raise SerialException("Can only operate on a valid port handle")
+
+ self.sPort.enableReceiveTimeout(30)
+ if self._bytesize == FIVEBITS:
+ jdatabits = javax.comm.SerialPort.DATABITS_5
+ elif self._bytesize == SIXBITS:
+ jdatabits = javax.comm.SerialPort.DATABITS_6
+ elif self._bytesize == SEVENBITS:
+ jdatabits = javax.comm.SerialPort.DATABITS_7
+ elif self._bytesize == EIGHTBITS:
+ jdatabits = javax.comm.SerialPort.DATABITS_8
+ else:
+ raise ValueError("unsupported bytesize: %r" % self._bytesize)
+
+ if self._stopbits == STOPBITS_ONE:
+ jstopbits = javax.comm.SerialPort.STOPBITS_1
+ elif stopbits == STOPBITS_ONE_HALVE:
+ self._jstopbits = javax.comm.SerialPort.STOPBITS_1_5
+ elif self._stopbits == STOPBITS_TWO:
+ jstopbits = javax.comm.SerialPort.STOPBITS_2
+ else:
+ raise ValueError("unsupported number of stopbits: %r" % self._stopbits)
+
+ if self._parity == PARITY_NONE:
+ jparity = javax.comm.SerialPort.PARITY_NONE
+ elif self._parity == PARITY_EVEN:
+ jparity = javax.comm.SerialPort.PARITY_EVEN
+ elif self._parity == PARITY_ODD:
+ jparity = javax.comm.SerialPort.PARITY_ODD
+ #~ elif self._parity == PARITY_MARK:
+ #~ jparity = javax.comm.SerialPort.PARITY_MARK
+ #~ elif self._parity == PARITY_SPACE:
+ #~ jparity = javax.comm.SerialPort.PARITY_SPACE
+ else:
+ raise ValueError("unsupported parity type: %r" % self._parity)
+
+ jflowin = jflowout = 0
+ if self._rtscts:
+ jflowin |= javax.comm.SerialPort.FLOWCONTROL_RTSCTS_IN
+ jflowout |= javax.comm.SerialPort.FLOWCONTROL_RTSCTS_OUT
+ if self._xonxoff:
+ jflowin |= javax.comm.SerialPort.FLOWCONTROL_XONXOFF_IN
+ jflowout |= javax.comm.SerialPort.FLOWCONTROL_XONXOFF_OUT
+
+ self.sPort.setSerialPortParams(baudrate, jdatabits, jstopbits, jparity)
+ self.sPort.setFlowControlMode(jflowin | jflowout)
+
+ if self._timeout >= 0:
+ self.sPort.enableReceiveTimeout(self._timeout*1000)
+ else:
+ self.sPort.disableReceiveTimeout()
+
+ def close(self):
+ """Close port"""
+ if self._isOpen:
+ if self.sPort:
+ self._instream.close()
+ self._outstream.close()
+ self.sPort.close()
+ self.sPort = None
+ self._isOpen = False
+
+ def makeDeviceName(self, port):
+ return device(port)
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ def inWaiting(self):
+ """Return the number of characters currently in the input buffer."""
+ if not self.sPort: raise portNotOpenError
+ return self._instream.available()
+
+ def read(self, size=1):
+ """Read size bytes from the serial port. If a timeout is set it may
+ return less characters as requested. With no timeout it will block
+ until the requested number of bytes is read."""
+ if not self.sPort: raise portNotOpenError
+ read = ''
+ if size > 0:
+ while len(read) < size:
+ x = self._instream.read()
+ if x == -1:
+ if self.timeout >= 0:
+ break
+ else:
+ read = read + chr(x)
+ return read
+
+ def write(self, data):
+ """Output the given string over the serial port."""
+ if not self.sPort: raise portNotOpenError
+ self._outstream.write(data)
+
+ def flushInput(self):
+ """Clear input buffer, discarding all that is in the buffer."""
+ if not self.sPort: raise portNotOpenError
+ self._instream.skip(self._instream.available())
+
+ def flushOutput(self):
+ """Clear output buffer, aborting the current output and
+ discarding all that is in the buffer."""
+ if not self.sPort: raise portNotOpenError
+ self._outstream.flush()
+
+ def sendBreak(self):
+ """Send break condition."""
+ if not self.sPort: raise portNotOpenError
+ self.sPort.sendBreak()
+
+ def setRTS(self,on=1):
+ """Set terminal status line: Request To Send"""
+ if not self.sPort: raise portNotOpenError
+ self.sPort.setRTS(on)
+
+ def setDTR(self,on=1):
+ """Set terminal status line: Data Terminal Ready"""
+ if not self.sPort: raise portNotOpenError
+ self.sPort.setDTR(on)
+
+ def getCTS(self):
+ """Read terminal status line: Clear To Send"""
+ if not self.sPort: raise portNotOpenError
+ self.sPort.isCTS()
+
+ def getDSR(self):
+ """Read terminal status line: Data Set Ready"""
+ if not self.sPort: raise portNotOpenError
+ self.sPort.isDSR()
+
+ def getRI(self):
+ """Read terminal status line: Ring Indicator"""
+ if not self.sPort: raise portNotOpenError
+ self.sPort.isRI()
+
+ def getCD(self):
+ """Read terminal status line: Carrier Detect"""
+ if not self.sPort: raise portNotOpenError
+ self.sPort.isCD()
+
+
+
+if __name__ == '__main__':
+ s = Serial(0,
+ baudrate=19200, #baudrate
+ bytesize=EIGHTBITS, #number of databits
+ parity=PARITY_EVEN, #enable parity checking
+ stopbits=STOPBITS_ONE, #number of stopbits
+ timeout=3, #set a timeout value, None for waiting forever
+ xonxoff=0, #enable software flow control
+ rtscts=0, #enable RTS/CTS flow control
+ )
+ s.setRTS(1)
+ s.setDTR(1)
+ s.flushInput()
+ s.flushOutput()
+ s.write('hello')
+ print repr(s.read(5))
+ print s.inWaiting()
+ del s
+
+
+
diff --git a/cesar/maximus/python/lib/proto/pyserial/serial/serialposix.py b/cesar/maximus/python/lib/proto/pyserial/serial/serialposix.py
new file mode 100644
index 0000000000..09aef6ca9c
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/serial/serialposix.py
@@ -0,0 +1,406 @@
+#!/usr/bin/env python
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#module for serial IO for POSIX compatible systems, like Linux
+#see __init__.py
+#
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+#
+#parts based on code from Grant B. Edwards <grante@visi.com>:
+# ftp://ftp.visi.com/users/grante/python/PosixSerial.py
+# references: http://www.easysw.com/~mike/serial/serial.html
+
+import sys, os, fcntl, termios, struct, select, errno
+from serialutil import *
+
+VERSION = "$Revision: 1.27 $".split()[1] #extract CVS version
+
+#Do check the Python version as some constants have moved.
+if (sys.hexversion < 0x020100f0):
+ import TERMIOS
+else:
+ TERMIOS = termios
+
+if (sys.hexversion < 0x020200f0):
+ import FCNTL
+else:
+ FCNTL = fcntl
+
+#try to detect the os so that a device can be selected...
+plat = sys.platform.lower()
+
+if plat[:5] == 'linux': #Linux (confirmed)
+ def device(port):
+ return '/dev/ttyS%d' % port
+
+elif plat == 'cygwin': #cywin/win32 (confirmed)
+ def device(port):
+ return '/dev/com%d' % (port + 1)
+
+elif plat == 'openbsd3': #BSD (confirmed)
+ def device(port):
+ return '/dev/ttyp%d' % port
+
+elif plat[:3] == 'bsd' or \
+ plat[:7] == 'freebsd' or \
+ plat[:7] == 'openbsd' or \
+ plat[:6] == 'darwin': #BSD (confirmed for freebsd4: cuaa%d)
+ def device(port):
+ return '/dev/cuaa%d' % port
+
+elif plat[:6] == 'netbsd': #NetBSD 1.6 testing by Erk
+ def device(port):
+ return '/dev/dty%02d' % port
+
+elif plat[:4] == 'irix': #IRIX (not tested)
+ def device(port):
+ return '/dev/ttyf%d' % port
+
+elif plat[:2] == 'hp': #HP-UX (not tested)
+ def device(port):
+ return '/dev/tty%dp0' % (port+1)
+
+elif plat[:5] == 'sunos': #Solaris/SunOS (confirmed)
+ def device(port):
+ return '/dev/tty%c' % (ord('a')+port)
+
+elif plat[:3] == 'aix': #aix
+ def device(port):
+ return '/dev/tty%d' % (port)
+
+else:
+ #platform detection has failed...
+ print """don't know how to number ttys on this system.
+! Use an explicit path (eg /dev/ttyS1) or send this information to
+! the author of this module:
+
+sys.platform = %r
+os.name = %r
+serialposix.py version = %s
+
+also add the device name of the serial port and where the
+counting starts for the first serial port.
+e.g. 'first serial port: /dev/ttyS0'
+and with a bit luck you can get this module running...
+""" % (sys.platform, os.name, VERSION)
+ #no exception, just continue with a brave attempt to build a device name
+ #even if the device name is not correct for the platform it has chances
+ #to work using a string with the real device name as port paramter.
+ def device(portum):
+ return '/dev/ttyS%d' % portnum
+ #~ raise Exception, "this module does not run on this platform, sorry."
+
+#whats up with "aix", "beos", ....
+#they should work, just need to know the device names.
+
+
+#load some constants for later use.
+#try to use values from TERMIOS, use defaults from linux otherwise
+TIOCMGET = hasattr(TERMIOS, 'TIOCMGET') and TERMIOS.TIOCMGET or 0x5415
+TIOCMBIS = hasattr(TERMIOS, 'TIOCMBIS') and TERMIOS.TIOCMBIS or 0x5416
+TIOCMBIC = hasattr(TERMIOS, 'TIOCMBIC') and TERMIOS.TIOCMBIC or 0x5417
+TIOCMSET = hasattr(TERMIOS, 'TIOCMSET') and TERMIOS.TIOCMSET or 0x5418
+
+#TIOCM_LE = hasattr(TERMIOS, 'TIOCM_LE') and TERMIOS.TIOCM_LE or 0x001
+TIOCM_DTR = hasattr(TERMIOS, 'TIOCM_DTR') and TERMIOS.TIOCM_DTR or 0x002
+TIOCM_RTS = hasattr(TERMIOS, 'TIOCM_RTS') and TERMIOS.TIOCM_RTS or 0x004
+#TIOCM_ST = hasattr(TERMIOS, 'TIOCM_ST') and TERMIOS.TIOCM_ST or 0x008
+#TIOCM_SR = hasattr(TERMIOS, 'TIOCM_SR') and TERMIOS.TIOCM_SR or 0x010
+
+TIOCM_CTS = hasattr(TERMIOS, 'TIOCM_CTS') and TERMIOS.TIOCM_CTS or 0x020
+TIOCM_CAR = hasattr(TERMIOS, 'TIOCM_CAR') and TERMIOS.TIOCM_CAR or 0x040
+TIOCM_RNG = hasattr(TERMIOS, 'TIOCM_RNG') and TERMIOS.TIOCM_RNG or 0x080
+TIOCM_DSR = hasattr(TERMIOS, 'TIOCM_DSR') and TERMIOS.TIOCM_DSR or 0x100
+TIOCM_CD = hasattr(TERMIOS, 'TIOCM_CD') and TERMIOS.TIOCM_CD or TIOCM_CAR
+TIOCM_RI = hasattr(TERMIOS, 'TIOCM_RI') and TERMIOS.TIOCM_RI or TIOCM_RNG
+#TIOCM_OUT1 = hasattr(TERMIOS, 'TIOCM_OUT1') and TERMIOS.TIOCM_OUT1 or 0x2000
+#TIOCM_OUT2 = hasattr(TERMIOS, 'TIOCM_OUT2') and TERMIOS.TIOCM_OUT2 or 0x4000
+TIOCINQ = hasattr(TERMIOS, 'FIONREAD') and TERMIOS.FIONREAD or 0x541B
+
+TIOCM_zero_str = struct.pack('I', 0)
+TIOCM_RTS_str = struct.pack('I', TIOCM_RTS)
+TIOCM_DTR_str = struct.pack('I', TIOCM_DTR)
+
+
+class Serial(SerialBase):
+ """Serial port class POSIX implementation. Serial port configuration is
+ done with termios and fcntl. Runs on Linux and many other Un*x like
+ systems."""
+
+ def open(self):
+ """Open port with current settings. This may throw a SerialException
+ if the port cannot be opened."""
+ if self._port is None:
+ raise SerialException("Port must be configured before it can be used.")
+ self.fd = None
+ #open
+ try:
+ self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)
+ except Exception, msg:
+ self.fd = None
+ raise SerialException("Could not open port: %s" % msg)
+ #~ fcntl.fcntl(self.fd, FCNTL.F_SETFL, 0) #set blocking
+
+ self._reconfigurePort()
+ self._isOpen = True
+ #~ self.flushInput()
+
+
+ def _reconfigurePort(self):
+ """Set commuication parameters on opened port."""
+ if self.fd is None:
+ raise SerialException("Can only operate on a valid port handle")
+
+ vmin = vtime = 0 #timeout is done via select
+ try:
+ iflag, oflag, cflag, lflag, ispeed, ospeed, cc = termios.tcgetattr(self.fd)
+ except termios.error, msg: #if a port is nonexistent but has a /dev file, it'll fail here
+ raise SerialException("Could not configure port: %s" % msg)
+ #set up raw mode / no echo / binary
+ cflag |= (TERMIOS.CLOCAL|TERMIOS.CREAD)
+ lflag &= ~(TERMIOS.ICANON|TERMIOS.ECHO|TERMIOS.ECHOE|TERMIOS.ECHOK|TERMIOS.ECHONL|
+ TERMIOS.ISIG|TERMIOS.IEXTEN) #|TERMIOS.ECHOPRT
+ for flag in ('ECHOCTL', 'ECHOKE'): #netbsd workaround for Erk
+ if hasattr(TERMIOS, flag):
+ lflag &= ~getattr(TERMIOS, flag)
+
+ oflag &= ~(TERMIOS.OPOST)
+ iflag &= ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IGNBRK)
+ if hasattr(TERMIOS, 'IUCLC'):
+ iflag &= ~TERMIOS.IUCLC
+ if hasattr(TERMIOS, 'PARMRK'):
+ iflag &= ~TERMIOS.PARMRK
+
+ #setup baudrate
+ try:
+ ispeed = ospeed = getattr(TERMIOS,'B%s' % (self._baudrate))
+ except AttributeError:
+ raise ValueError('Invalid baud rate: %r' % self._baudrate)
+ #setup char len
+ cflag &= ~TERMIOS.CSIZE
+ if self._bytesize == 8:
+ cflag |= TERMIOS.CS8
+ elif self._bytesize == 7:
+ cflag |= TERMIOS.CS7
+ elif self._bytesize == 6:
+ cflag |= TERMIOS.CS6
+ elif self._bytesize == 5:
+ cflag |= TERMIOS.CS5
+ else:
+ raise ValueError('Invalid char len: %r' % self._bytesize)
+ #setup stopbits
+ if self._stopbits == STOPBITS_ONE:
+ cflag &= ~(TERMIOS.CSTOPB)
+ elif self._stopbits == STOPBITS_TWO:
+ cflag |= (TERMIOS.CSTOPB)
+ else:
+ raise ValueError('Invalid stopit specification: %r' % self._stopbits)
+ #setup parity
+ iflag &= ~(TERMIOS.INPCK|TERMIOS.ISTRIP)
+ if self._parity == PARITY_NONE:
+ cflag &= ~(TERMIOS.PARENB|TERMIOS.PARODD)
+ elif self._parity == PARITY_EVEN:
+ cflag &= ~(TERMIOS.PARODD)
+ cflag |= (TERMIOS.PARENB)
+ elif self._parity == PARITY_ODD:
+ cflag |= (TERMIOS.PARENB|TERMIOS.PARODD)
+ else:
+ raise ValueError('Invalid parity: %r' % self._parity)
+ #setup flow control
+ #xonxoff
+ if hasattr(TERMIOS, 'IXANY'):
+ if self._xonxoff:
+ iflag |= (TERMIOS.IXON|TERMIOS.IXOFF) #|TERMIOS.IXANY)
+ else:
+ iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY)
+ else:
+ if self._xonxoff:
+ iflag |= (TERMIOS.IXON|TERMIOS.IXOFF)
+ else:
+ iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF)
+ #rtscts
+ if hasattr(TERMIOS, 'CRTSCTS'):
+ if self._rtscts:
+ cflag |= (TERMIOS.CRTSCTS)
+ else:
+ cflag &= ~(TERMIOS.CRTSCTS)
+ elif hasattr(TERMIOS, 'CNEW_RTSCTS'): #try it with alternate constant name
+ if self._rtscts:
+ cflag |= (TERMIOS.CNEW_RTSCTS)
+ else:
+ cflag &= ~(TERMIOS.CNEW_RTSCTS)
+ #XXX should there be a warning if setting up rtscts (and xonxoff etc) fails??
+
+ #buffer
+ #vmin "minimal number of characters to be read. = for non blocking"
+ if vmin < 0 or vmin > 255:
+ raise ValueError('Invalid vmin: %r ' % vmin)
+ cc[TERMIOS.VMIN] = vmin
+ #vtime
+ if vtime < 0 or vtime > 255:
+ raise ValueError('Invalid vtime: %r' % vtime)
+ cc[TERMIOS.VTIME] = vtime
+ #activate settings
+ termios.tcsetattr(self.fd, TERMIOS.TCSANOW, [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
+
+ def close(self):
+ """Close port"""
+ if self._isOpen:
+ if self.fd is not None:
+ os.close(self.fd)
+ self.fd = None
+ self._isOpen = False
+
+ def makeDeviceName(self, port):
+ return device(port)
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ def inWaiting(self):
+ """Return the number of characters currently in the input buffer."""
+ #~ s = fcntl.ioctl(self.fd, TERMIOS.FIONREAD, TIOCM_zero_str)
+ s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
+ return struct.unpack('I',s)[0]
+
+ def read(self, size=1):
+ """Read size bytes from the serial port. If a timeout is set it may
+ return less characters as requested. With no timeout it will block
+ until the requested number of bytes is read."""
+ if self.fd is None: raise portNotOpenError
+ read = ''
+ inp = None
+ if size > 0:
+ while len(read) < size:
+ #print "\tread(): size",size, "have", len(read) #debug
+ ready,_,_ = select.select([self.fd],[],[], self._timeout)
+ if not ready:
+ break #timeout
+ buf = os.read(self.fd, size-len(read))
+ read = read + buf
+ if self._timeout >= 0 and not buf:
+ break #early abort on timeout
+ return read
+
+ def write(self, data):
+ """Output the given string over the serial port."""
+ if self.fd is None: raise portNotOpenError
+ t = len(data)
+ d = data
+ while t > 0:
+ try:
+ if self._writeTimeout is not None and self._writeTimeout > 0:
+ _,ready,_ = select.select([],[self.fd],[], self._writeTimeout)
+ if not ready:
+ raise writeTimeoutError
+ n = os.write(self.fd, d)
+ if self._writeTimeout is not None and self._writeTimeout > 0:
+ _,ready,_ = select.select([],[self.fd],[], self._writeTimeout)
+ if not ready:
+ raise writeTimeoutError
+ d = d[n:]
+ t = t - n
+ except OSError,v:
+ if v.errno != errno.EAGAIN:
+ raise
+
+ def flush(self):
+ """Flush of file like objects. In this case, wait until all data
+ is written."""
+ self.drainOutput()
+
+ def flushInput(self):
+ """Clear input buffer, discarding all that is in the buffer."""
+ if self.fd is None:
+ raise portNotOpenError
+ termios.tcflush(self.fd, TERMIOS.TCIFLUSH)
+
+ def flushOutput(self):
+ """Clear output buffer, aborting the current output and
+ discarding all that is in the buffer."""
+ if self.fd is None:
+ raise portNotOpenError
+ termios.tcflush(self.fd, TERMIOS.TCOFLUSH)
+
+ def sendBreak(self):
+ """Send break condition."""
+ if self.fd is None:
+ raise portNotOpenError
+ termios.tcsendbreak(self.fd, 0)
+
+ def setRTS(self,on=1):
+ """Set terminal status line: Request To Send"""
+ if self.fd is None: raise portNotOpenError
+ if on:
+ fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str)
+ else:
+ fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str)
+
+ def setDTR(self,on=1):
+ """Set terminal status line: Data Terminal Ready"""
+ if self.fd is None: raise portNotOpenError
+ if on:
+ fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
+ else:
+ fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str)
+
+ def getCTS(self):
+ """Read terminal status line: Clear To Send"""
+ if self.fd is None: raise portNotOpenError
+ s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
+ return struct.unpack('I',s)[0] & TIOCM_CTS != 0
+
+ def getDSR(self):
+ """Read terminal status line: Data Set Ready"""
+ if self.fd is None: raise portNotOpenError
+ s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
+ return struct.unpack('I',s)[0] & TIOCM_DSR != 0
+
+ def getRI(self):
+ """Read terminal status line: Ring Indicator"""
+ if self.fd is None: raise portNotOpenError
+ s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
+ return struct.unpack('I',s)[0] & TIOCM_RI != 0
+
+ def getCD(self):
+ """Read terminal status line: Carrier Detect"""
+ if self.fd is None: raise portNotOpenError
+ s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)
+ return struct.unpack('I',s)[0] & TIOCM_CD != 0
+
+ # - - platform specific - - - -
+
+ def drainOutput(self):
+ """internal - not portable!"""
+ if self.fd is None: raise portNotOpenError
+ termios.tcdrain(self.fd)
+
+ def nonblocking(self):
+ """internal - not portable!"""
+ if self.fd is None:
+ raise portNotOpenError
+ fcntl.fcntl(self.fd, FCNTL.F_SETFL, FCNTL.O_NONBLOCK)
+
+ def fileno(self):
+ """For easier of the serial port instance with select.
+ WARNING: this function is not portable to different platforms!"""
+ if self.fd is None: raise portNotOpenError
+ return self.fd
+
+if __name__ == '__main__':
+ s = Serial(0,
+ baudrate=19200, #baudrate
+ bytesize=EIGHTBITS, #number of databits
+ parity=PARITY_EVEN, #enable parity checking
+ stopbits=STOPBITS_ONE, #number of stopbits
+ timeout=3, #set a timeout value, None for waiting forever
+ xonxoff=0, #enable software flow control
+ rtscts=0, #enable RTS/CTS flow control
+ )
+ s.setRTS(1)
+ s.setDTR(1)
+ s.flushInput()
+ s.flushOutput()
+ s.write('hello')
+ print repr(s.read(5))
+ print s.inWaiting()
+ del s
diff --git a/cesar/maximus/python/lib/proto/pyserial/serial/serialutil.py b/cesar/maximus/python/lib/proto/pyserial/serial/serialutil.py
new file mode 100644
index 0000000000..d58cc53caf
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/serial/serialutil.py
@@ -0,0 +1,366 @@
+#! python
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#see __init__.py
+#
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+PARITY_NONE, PARITY_EVEN, PARITY_ODD = 'N', 'E', 'O'
+STOPBITS_ONE, STOPBITS_TWO = (1, 2)
+FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5,6,7,8)
+
+PARITY_NAMES = {
+ PARITY_NONE: 'None',
+ PARITY_EVEN: 'Even',
+ PARITY_ODD: 'Odd',
+}
+
+XON = chr(17)
+XOFF = chr(19)
+
+#Python < 2.2.3 compatibility
+try:
+ True
+except:
+ True = 1
+ False = not True
+
+class SerialException(Exception):
+ """Base class for serial port related exceptions."""
+
+portNotOpenError = SerialException('Port not open')
+
+class SerialTimeoutException(SerialException):
+ """Write timeouts give an exception"""
+
+writeTimeoutError = SerialTimeoutException("Write timeout")
+
+class FileLike(object):
+ """An abstract file like class.
+
+ This class implements readline and readlines based on read and
+ writelines based on write.
+ This class is used to provide the above functions for to Serial
+ port objects.
+
+ Note that when the serial port was opened with _NO_ timeout that
+ readline blocks until it sees a newline (or the specified size is
+ reached) and that readlines would never return and therefore
+ refuses to work (it raises an exception in this case)!
+ """
+
+ def read(self, size): raise NotImplementedError
+ def write(self, s): raise NotImplementedError
+
+ def readline(self, size=None, eol='\n'):
+ """read a line which is terminated with end-of-line (eol) character
+ ('\n' by default) or until timeout"""
+ line = ''
+ while 1:
+ c = self.read(1)
+ if c:
+ line += c #not very efficient but lines are usually not that long
+ if c == eol:
+ break
+ if size is not None and len(line) >= size:
+ break
+ else:
+ break
+ return line
+
+ def readlines(self, sizehint=None, eol='\n'):
+ """read a list of lines, until timeout
+ sizehint is ignored"""
+ if self.timeout is None:
+ raise ValueError, "Serial port MUST have enabled timeout for this function!"
+ lines = []
+ while 1:
+ line = self.readline(eol=eol)
+ if line:
+ lines.append(line)
+ if line[-1] != eol: #was the line received with a timeout?
+ break
+ else:
+ break
+ return lines
+
+ def xreadlines(self, sizehint=None):
+ """just call readlines - here for compatibility"""
+ return self.readlines()
+
+ def writelines(self, sequence):
+ for line in sequence:
+ self.write(line)
+
+ def flush(self):
+ """flush of file like objects"""
+ pass
+
+class SerialBase(FileLike):
+ """Serial port base class. Provides __init__ function and properties to
+ get/set port settings."""
+
+ #default values, may be overriden in subclasses that do not support all values
+ BAUDRATES = (50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,
+ 19200,38400,57600,115200,230400,460800,500000,576000,921600,
+ 1000000,1152000,1500000,2000000,2500000,3000000,3500000,4000000)
+ BYTESIZES = (FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS)
+ PARITIES = (PARITY_NONE, PARITY_EVEN, PARITY_ODD)
+ STOPBITS = (STOPBITS_ONE, STOPBITS_TWO)
+
+ def __init__(self,
+ port = None, #number of device, numbering starts at
+ #zero. if everything fails, the user
+ #can specify a device string, note
+ #that this isn't portable anymore
+ #port will be opened if one is specified
+ baudrate=9600, #baudrate
+ bytesize=EIGHTBITS, #number of databits
+ parity=PARITY_NONE, #enable parity checking
+ stopbits=STOPBITS_ONE, #number of stopbits
+ timeout=None, #set a timeout value, None to wait forever
+ xonxoff=0, #enable software flow control
+ rtscts=0, #enable RTS/CTS flow control
+ writeTimeout=None, #set a timeout for writes
+ dsrdtr=None, #None: use rtscts setting, dsrdtr override if true or false
+ ):
+ """Initialize comm port object. If a port is given, then the port will be
+ opened immediately. Otherwise a Serial port object in closed state
+ is returned."""
+
+ self._isOpen = False
+ self._port = None #correct value is assigned below trough properties
+ self._baudrate = None #correct value is assigned below trough properties
+ self._bytesize = None #correct value is assigned below trough properties
+ self._parity = None #correct value is assigned below trough properties
+ self._stopbits = None #correct value is assigned below trough properties
+ self._timeout = None #correct value is assigned below trough properties
+ self._writeTimeout = None #correct value is assigned below trough properties
+ self._xonxoff = None #correct value is assigned below trough properties
+ self._rtscts = None #correct value is assigned below trough properties
+ self._dsrdtr = None #correct value is assigned below trough properties
+
+ #assign values using get/set methods using the properties feature
+ self.port = port
+ self.baudrate = baudrate
+ self.bytesize = bytesize
+ self.parity = parity
+ self.stopbits = stopbits
+ self.timeout = timeout
+ self.writeTimeout = writeTimeout
+ self.xonxoff = xonxoff
+ self.rtscts = rtscts
+ self.dsrdtr = dsrdtr
+
+ if port is not None:
+ self.open()
+
+ def isOpen(self):
+ """Check if the port is opened."""
+ return self._isOpen
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ #TODO: these are not realy needed as the is the BAUDRATES etc attribute...
+ #maybe i remove them before the final release...
+
+ def getSupportedBaudrates(self):
+ return [(str(b), b) for b in self.BAUDRATES]
+
+ def getSupportedByteSizes(self):
+ return [(str(b), b) for b in self.BYTESIZES]
+
+ def getSupportedStopbits(self):
+ return [(str(b), b) for b in self.STOPBITS]
+
+ def getSupportedParities(self):
+ return [(PARITY_NAMES[b], b) for b in self.PARITIES]
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ def setPort(self, port):
+ """Change the port. The attribute portstr is set to a string that
+ contains the name of the port."""
+
+ was_open = self._isOpen
+ if was_open: self.close()
+ if port is not None:
+ if type(port) in [type(''), type(u'')]: #strings are taken directly
+ self.portstr = port
+ else:
+ self.portstr = self.makeDeviceName(port)
+ else:
+ self.portstr = None
+ self._port = port
+ if was_open: self.open()
+
+ def getPort(self):
+ """Get the current port setting. The value that was passed on init or using
+ setPort() is passed back. See also the attribute portstr which contains
+ the name of the port as a string."""
+ return self._port
+
+ port = property(getPort, setPort, doc="Port setting")
+
+
+ def setBaudrate(self, baudrate):
+ """Change baudrate. It raises a ValueError if the port is open and the
+ baudrate is not possible. If the port is closed, then tha value is
+ accepted and the exception is raised when the port is opened."""
+ #~ if baudrate not in self.BAUDRATES: raise ValueError("Not a valid baudrate: %r" % baudrate)
+ try:
+ self._baudrate = int(baudrate)
+ except TypeError:
+ raise ValueError("Not a valid baudrate: %r" % baudrate)
+ else:
+ if self._isOpen: self._reconfigurePort()
+
+ def getBaudrate(self):
+ """Get the current baudrate setting."""
+ return self._baudrate
+
+ baudrate = property(getBaudrate, setBaudrate, doc="Baudrate setting")
+
+
+ def setByteSize(self, bytesize):
+ """Change byte size."""
+ if bytesize not in self.BYTESIZES: raise ValueError("Not a valid byte size: %r" % bytesize)
+ self._bytesize = bytesize
+ if self._isOpen: self._reconfigurePort()
+
+ def getByteSize(self):
+ """Get the current byte size setting."""
+ return self._bytesize
+
+ bytesize = property(getByteSize, setByteSize, doc="Byte size setting")
+
+
+ def setParity(self, parity):
+ """Change parity setting."""
+ if parity not in self.PARITIES: raise ValueError("Not a valid parity: %r" % parity)
+ self._parity = parity
+ if self._isOpen: self._reconfigurePort()
+
+ def getParity(self):
+ """Get the current parity setting."""
+ return self._parity
+
+ parity = property(getParity, setParity, doc="Parity setting")
+
+
+ def setStopbits(self, stopbits):
+ """Change stopbits size."""
+ if stopbits not in self.STOPBITS: raise ValueError("Not a valid stopbit size: %r" % stopbits)
+ self._stopbits = stopbits
+ if self._isOpen: self._reconfigurePort()
+
+ def getStopbits(self):
+ """Get the current stopbits setting."""
+ return self._stopbits
+
+ stopbits = property(getStopbits, setStopbits, doc="Stopbits setting")
+
+
+ def setTimeout(self, timeout):
+ """Change timeout setting."""
+ if timeout is not None:
+ if timeout < 0: raise ValueError("Not a valid timeout: %r" % timeout)
+ try:
+ timeout + 1 #test if it's a number, will throw a TypeError if not...
+ except TypeError:
+ raise ValueError("Not a valid timeout: %r" % timeout)
+
+ self._timeout = timeout
+ if self._isOpen: self._reconfigurePort()
+
+ def getTimeout(self):
+ """Get the current timeout setting."""
+ return self._timeout
+
+ timeout = property(getTimeout, setTimeout, doc="Timeout setting for read()")
+
+
+ def setWriteTimeout(self, timeout):
+ """Change timeout setting."""
+ if timeout is not None:
+ if timeout < 0: raise ValueError("Not a valid timeout: %r" % timeout)
+ try:
+ timeout + 1 #test if it's a number, will throw a TypeError if not...
+ except TypeError:
+ raise ValueError("Not a valid timeout: %r" % timeout)
+
+ self._writeTimeout = timeout
+ if self._isOpen: self._reconfigurePort()
+
+ def getWriteTimeout(self):
+ """Get the current timeout setting."""
+ return self._writeTimeout
+
+ writeTimeout = property(getWriteTimeout, setWriteTimeout, doc="Timeout setting for write()")
+
+
+ def setXonXoff(self, xonxoff):
+ """Change XonXoff setting."""
+ self._xonxoff = xonxoff
+ if self._isOpen: self._reconfigurePort()
+
+ def getXonXoff(self):
+ """Get the current XonXoff setting."""
+ return self._xonxoff
+
+ xonxoff = property(getXonXoff, setXonXoff, doc="Xon/Xoff setting")
+
+ def setRtsCts(self, rtscts):
+ """Change RtsCts flow control setting."""
+ self._rtscts = rtscts
+ if self._isOpen: self._reconfigurePort()
+
+ def getRtsCts(self):
+ """Get the current RtsCts flow control setting."""
+ return self._rtscts
+
+ rtscts = property(getRtsCts, setRtsCts, doc="RTS/CTS flow control setting")
+
+ def setDsrDtr(self, dsrdtr=None):
+ """Change DsrDtr flow control setting."""
+ if dsrdtr is None:
+ #if not set, keep backwards compatibility and follow rtscts setting
+ self._dsrdtr = self._rtscts
+ else:
+ #if defined independently, follow its value
+ self._dsrdtr = dsrdtr
+ if self._isOpen: self._reconfigurePort()
+
+ def getDsrDtr(self):
+ """Get the current DsrDtr flow control setting."""
+ return self._dsrdtr
+
+ dsrdtr = property(getDsrDtr, setDsrDtr, "DSR/DTR flow control setting")
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ def __repr__(self):
+ """String representation of the current port settings and its state."""
+ return "%s<id=0x%x, open=%s>(port=%r, baudrate=%r, bytesize=%r, parity=%r, stopbits=%r, timeout=%r, xonxoff=%r, rtscts=%r, dsrdtr=%r)" % (
+ self.__class__.__name__,
+ id(self),
+ self._isOpen,
+ self.portstr,
+ self.baudrate,
+ self.bytesize,
+ self.parity,
+ self.stopbits,
+ self.timeout,
+ self.xonxoff,
+ self.rtscts,
+ self.dsrdtr,
+ )
+
+if __name__ == '__main__':
+ s = SerialBase()
+ print s.portstr
+ print s.getSupportedBaudrates()
+ print s.getSupportedByteSizes()
+ print s.getSupportedParities()
+ print s.getSupportedStopbits()
+ print s
diff --git a/cesar/maximus/python/lib/proto/pyserial/serial/serialwin32.py b/cesar/maximus/python/lib/proto/pyserial/serial/serialwin32.py
new file mode 100644
index 0000000000..1c08c42782
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/serial/serialwin32.py
@@ -0,0 +1,314 @@
+#! python
+#Python Serial Port Extension for Win32, Linux, BSD, Jython
+#serial driver for win32
+#see __init__.py
+#
+#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+import win32file # The base COM port and file IO functions.
+import win32event # We use events and the WaitFor[Single|Multiple]Objects functions.
+import win32con # constants.
+from serialutil import *
+
+VERSION = "$Revision: 1.31 $".split()[1] #extract CVS version
+
+#from winbase.h. these should realy be in win32con
+MS_CTS_ON = 16
+MS_DSR_ON = 32
+MS_RING_ON = 64
+MS_RLSD_ON = 128
+
+def device(portnum):
+ """Turn a port number into a device name"""
+ #the "//./COMx" format is required for devices >= 9
+ #not all versions of windows seem to support this propperly
+ #so that the first few ports are used with the DOS device name
+ if portnum < 9:
+ return 'COM%d' % (portnum+1) #numbers are transformed to a string
+ else:
+ return r'\\.\COM%d' % (portnum+1)
+
+class Serial(SerialBase):
+ """Serial port implemenation for Win32. This implemenatation requires a
+ win32all installation."""
+
+ BAUDRATES = (50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,
+ 19200,38400,57600,115200)
+
+ def open(self):
+ """Open port with current settings. This may throw a SerialException
+ if the port cannot be opened."""
+ if self._port is None:
+ raise SerialException("Port must be configured before it can be used.")
+ self.hComPort = None
+ try:
+ self.hComPort = win32file.CreateFile(self.portstr,
+ win32con.GENERIC_READ | win32con.GENERIC_WRITE,
+ 0, # exclusive access
+ None, # no security
+ win32con.OPEN_EXISTING,
+ win32con.FILE_ATTRIBUTE_NORMAL | win32con.FILE_FLAG_OVERLAPPED,
+ None)
+ except Exception, msg:
+ self.hComPort = None #'cause __del__ is called anyway
+ raise SerialException("could not open port: %s" % msg)
+ # Setup a 4k buffer
+ win32file.SetupComm(self.hComPort, 4096, 4096)
+
+ #Save original timeout values:
+ self._orgTimeouts = win32file.GetCommTimeouts(self.hComPort)
+
+ self._rtsState = win32file.RTS_CONTROL_ENABLE
+ self._dtrState = win32file.RTS_CONTROL_ENABLE
+
+ self._reconfigurePort()
+
+ # Clear buffers:
+ # Remove anything that was there
+ win32file.PurgeComm(self.hComPort,
+ win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT |
+ win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
+
+ self._overlappedRead = win32file.OVERLAPPED()
+ self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None)
+ self._overlappedWrite = win32file.OVERLAPPED()
+ #~ self._overlappedWrite.hEvent = win32event.CreateEvent(None, 1, 0, None)
+ self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None)
+ self._isOpen = True
+
+ def _reconfigurePort(self):
+ """Set commuication parameters on opened port."""
+ if not self.hComPort:
+ raise SerialException("Can only operate on a valid port handle")
+
+ #Set Windows timeout values
+ #timeouts is a tuple with the following items:
+ #(ReadIntervalTimeout,ReadTotalTimeoutMultiplier,
+ # ReadTotalTimeoutConstant,WriteTotalTimeoutMultiplier,
+ # WriteTotalTimeoutConstant)
+ if self._timeout is None:
+ timeouts = (0, 0, 0, 0, 0)
+ elif self._timeout == 0:
+ timeouts = (win32con.MAXDWORD, 0, 0, 0, 0)
+ else:
+ timeouts = (0, 0, int(self._timeout*1000), 0, 0)
+ if self._writeTimeout is None:
+ pass
+ elif self._writeTimeout == 0:
+ timeouts = timeouts[:-2] + (0, win32con.MAXDWORD)
+ else:
+ timeouts = timeouts[:-2] + (0, int(self._writeTimeout*1000))
+ win32file.SetCommTimeouts(self.hComPort, timeouts)
+
+ win32file.SetCommMask(self.hComPort, win32file.EV_ERR)
+
+ # Setup the connection info.
+ # Get state and modify it:
+ comDCB = win32file.GetCommState(self.hComPort)
+ comDCB.BaudRate = self._baudrate
+
+ if self._bytesize == FIVEBITS:
+ comDCB.ByteSize = 5
+ elif self._bytesize == SIXBITS:
+ comDCB.ByteSize = 6
+ elif self._bytesize == SEVENBITS:
+ comDCB.ByteSize = 7
+ elif self._bytesize == EIGHTBITS:
+ comDCB.ByteSize = 8
+ else:
+ raise ValueError("Unsupported number of data bits: %r" % self._bytesize)
+
+ if self._parity == PARITY_NONE:
+ comDCB.Parity = win32file.NOPARITY
+ comDCB.fParity = 0 # Dis/Enable Parity Check
+ elif self._parity == PARITY_EVEN:
+ comDCB.Parity = win32file.EVENPARITY
+ comDCB.fParity = 1 # Dis/Enable Parity Check
+ elif self._parity == PARITY_ODD:
+ comDCB.Parity = win32file.ODDPARITY
+ comDCB.fParity = 1 # Dis/Enable Parity Check
+ else:
+ raise ValueError("Unsupported parity mode: %r" % self._parity)
+
+ if self._stopbits == STOPBITS_ONE:
+ comDCB.StopBits = win32file.ONESTOPBIT
+ elif self._stopbits == STOPBITS_TWO:
+ comDCB.StopBits = win32file.TWOSTOPBITS
+ else:
+ raise ValueError("Unsupported number of stop bits: %r" % self._stopbits)
+
+ comDCB.fBinary = 1 # Enable Binary Transmission
+ # Char. w/ Parity-Err are replaced with 0xff (if fErrorChar is set to TRUE)
+ if self._rtscts:
+ comDCB.fRtsControl = win32file.RTS_CONTROL_HANDSHAKE
+ else:
+ comDCB.fRtsControl = self._rtsState
+ if self._dsrdtr:
+ comDCB.fDtrControl = win32file.DTR_CONTROL_HANDSHAKE
+ else:
+ comDCB.fDtrControl = self._dtrState
+ comDCB.fOutxCtsFlow = self._rtscts
+ comDCB.fOutxDsrFlow = self._dsrdtr
+ comDCB.fOutX = self._xonxoff
+ comDCB.fInX = self._xonxoff
+ comDCB.fNull = 0
+ comDCB.fErrorChar = 0
+ comDCB.fAbortOnError = 0
+ comDCB.XonChar = XON
+ comDCB.XoffChar = XOFF
+
+ try:
+ win32file.SetCommState(self.hComPort, comDCB)
+ except win32file.error, e:
+ raise ValueError("Cannot configure port, some setting was wrong. Original message: %s" % e)
+
+ #~ def __del__(self):
+ #~ self.close()
+
+ def close(self):
+ """Close port"""
+ if self._isOpen:
+ if self.hComPort:
+ #Restore original timeout values:
+ win32file.SetCommTimeouts(self.hComPort, self._orgTimeouts)
+ #Close COM-Port:
+ win32file.CloseHandle(self.hComPort)
+ self.hComPort = None
+ self._isOpen = False
+
+ def makeDeviceName(self, port):
+ return device(port)
+
+ # - - - - - - - - - - - - - - - - - - - - - - - -
+
+ def inWaiting(self):
+ """Return the number of characters currently in the input buffer."""
+ flags, comstat = win32file.ClearCommError(self.hComPort)
+ return comstat.cbInQue
+
+ def read(self, size=1):
+ """Read size bytes from the serial port. If a timeout is set it may
+ return less characters as requested. With no timeout it will block
+ until the requested number of bytes is read."""
+ if not self.hComPort: raise portNotOpenError
+ if size > 0:
+ win32event.ResetEvent(self._overlappedRead.hEvent)
+ flags, comstat = win32file.ClearCommError(self.hComPort)
+ if self.timeout == 0:
+ n = min(comstat.cbInQue, size)
+ if n > 0:
+ rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(n), self._overlappedRead)
+ win32event.WaitForSingleObject(self._overlappedRead.hEvent, win32event.INFINITE)
+ read = str(buf)
+ else:
+ read = ''
+ else:
+ rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(size), self._overlappedRead)
+ n = win32file.GetOverlappedResult(self.hComPort, self._overlappedRead, 1)
+ read = str(buf[:n])
+ else:
+ read = ''
+ return read
+
+ def write(self, s):
+ """Output the given string over the serial port."""
+ if not self.hComPort: raise portNotOpenError
+ #print repr(s),
+ if s:
+ #~ win32event.ResetEvent(self._overlappedWrite.hEvent)
+ err, n = win32file.WriteFile(self.hComPort, s, self._overlappedWrite)
+ if err: #will be ERROR_IO_PENDING:
+ # Wait for the write to complete.
+ #~ win32event.WaitForSingleObject(self._overlappedWrite.hEvent, win32event.INFINITE)
+ n = win32file.GetOverlappedResult(self.hComPort, self._overlappedWrite, 1)
+ if n != len(s):
+ raise writeTimeoutError
+
+
+ def flushInput(self):
+ """Clear input buffer, discarding all that is in the buffer."""
+ if not self.hComPort: raise portNotOpenError
+ win32file.PurgeComm(self.hComPort, win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
+
+ def flushOutput(self):
+ """Clear output buffer, aborting the current output and
+ discarding all that is in the buffer."""
+ if not self.hComPort: raise portNotOpenError
+ win32file.PurgeComm(self.hComPort, win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT)
+
+ def sendBreak(self):
+ """Send break condition."""
+ if not self.hComPort: raise portNotOpenError
+ import time
+ win32file.SetCommBreak(self.hComPort)
+ #TODO: how to set the correct duration??
+ time.sleep(0.020)
+ win32file.ClearCommBreak(self.hComPort)
+
+ def setRTS(self,level=1):
+ """Set terminal status line: Request To Send"""
+ if not self.hComPort: raise portNotOpenError
+ if level:
+ self._rtsState = win32file.RTS_CONTROL_ENABLE
+ win32file.EscapeCommFunction(self.hComPort, win32file.SETRTS)
+ else:
+ self._rtsState = win32file.RTS_CONTROL_DISABLE
+ win32file.EscapeCommFunction(self.hComPort, win32file.CLRRTS)
+
+ def setDTR(self,level=1):
+ """Set terminal status line: Data Terminal Ready"""
+ if not self.hComPort: raise portNotOpenError
+ if level:
+ self._dtrState = win32file.DTR_CONTROL_ENABLE
+ win32file.EscapeCommFunction(self.hComPort, win32file.SETDTR)
+ else:
+ self._dtrState = win32file.DTR_CONTROL_DISABLE
+ win32file.EscapeCommFunction(self.hComPort, win32file.CLRDTR)
+
+ def getCTS(self):
+ """Read terminal status line: Clear To Send"""
+ if not self.hComPort: raise portNotOpenError
+ return MS_CTS_ON & win32file.GetCommModemStatus(self.hComPort) != 0
+
+ def getDSR(self):
+ """Read terminal status line: Data Set Ready"""
+ if not self.hComPort: raise portNotOpenError
+ return MS_DSR_ON & win32file.GetCommModemStatus(self.hComPort) != 0
+
+ def getRI(self):
+ """Read terminal status line: Ring Indicator"""
+ if not self.hComPort: raise portNotOpenError
+ return MS_RING_ON & win32file.GetCommModemStatus(self.hComPort) != 0
+
+ def getCD(self):
+ """Read terminal status line: Carrier Detect"""
+ if not self.hComPort: raise portNotOpenError
+ return MS_RLSD_ON & win32file.GetCommModemStatus(self.hComPort) != 0
+
+ # - - platform specific - - - -
+
+ def setXON(self, level=True):
+ """Platform specific - set flow state."""
+ if not self.hComPort: raise portNotOpenError
+ if level:
+ win32file.EscapeCommFunction(self.hComPort, win32file.SETXON)
+ else:
+ win32file.EscapeCommFunction(self.hComPort, win32file.SETXOFF)
+
+#Nur Testfunktion!!
+if __name__ == '__main__':
+ print __name__
+ s = Serial()
+ print s
+
+ s = Serial(0)
+ print s
+
+ s.baudrate = 19200
+ s.databits = 7
+ s.close()
+ s.port = 3
+ s.open()
+ print s
+
diff --git a/cesar/maximus/python/lib/proto/pyserial/setup.py b/cesar/maximus/python/lib/proto/pyserial/setup.py
new file mode 100644
index 0000000000..b3412f6ff5
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/pyserial/setup.py
@@ -0,0 +1,38 @@
+# setup.py
+from distutils.core import setup
+import sys
+
+#windows installer:
+# python setup.py bdist_wininst
+
+# patch distutils if it can't cope with the "classifiers" or
+# "download_url" keywords
+if sys.version < '2.2.3':
+ from distutils.dist import DistributionMetadata
+ DistributionMetadata.classifiers = None
+ DistributionMetadata.download_url = None
+
+setup(
+ name="pyserial",
+ description="Python Serial Port Extension",
+ version="2.2",
+ author="Chris Liechti",
+ author_email="cliechti@gmx.net",
+ url="http://pyserial.sourceforge.net/",
+ packages=['serial'],
+ license="Python",
+ long_description="Python Serial Port Extension for Win32, Linux, BSD, Jython",
+ classifiers = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: End Users/Desktop',
+ 'License :: OSI Approved :: Python Software Foundation License',
+ 'Natural Language :: English',
+ 'Operating System :: POSIX',
+ 'Operating System :: Microsoft :: Windows',
+ 'Programming Language :: Python',
+ 'Topic :: Communications',
+ 'Topic :: Software Development :: Libraries',
+ 'Topic :: Terminals :: Serial',
+ ],
+)
diff --git a/cesar/maximus/python/lib/proto/uspp/AUTHORS b/cesar/maximus/python/lib/proto/uspp/AUTHORS
new file mode 100644
index 0000000000..f21051cb3a
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/AUTHORS
@@ -0,0 +1,4 @@
+Isaac Barona Martínez <ibarona@tid.es> Madrid (SPAIN)
+Damien Géranton <dgeranton@voila.fr>
+Douglas Jones <dfj23@drexel.edu>
+J.Grauheding <juergen.grauheding@a-city.de>
diff --git a/cesar/maximus/python/lib/proto/uspp/Copyright b/cesar/maximus/python/lib/proto/uspp/Copyright
new file mode 100644
index 0000000000..a9ed744a19
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/Copyright
@@ -0,0 +1,21 @@
+USPP Library (Universal Serial Port Python Library)
+
+Copyright (C) 2006 Isaac Barona Martínez <ibarona@tid.es>
+
+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; either
+version 2.1 of the License, or (at your option) any later version.
+
+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.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+The complete text of the GNU Lesser General Public License can be found in
+the file 'lesser.txt'.
diff --git a/cesar/maximus/python/lib/proto/uspp/Readme b/cesar/maximus/python/lib/proto/uspp/Readme
new file mode 100644
index 0000000000..623cc2b9b6
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/Readme
@@ -0,0 +1,190 @@
+ USPP Library
+
+ Universal Serial Port Python Library
+
+ Copyright 2006 Isaac Barona <ibarona@gmail.com>
+
+
+Contents
+--------
+ 1. Introduction
+ 2. Motivation
+ 3. Where can I find it
+ 4. Features
+ 5. Pre-requisites
+ 6. Usage and documentation
+ 7. Where does it work
+ 8. Known problems
+ 9. To-do list
+10. Porting to other platforms
+11. Licence
+12. Author
+13. Version
+
+
+1. Introduction
+---------------
+
+USPP Library is a multi-platform Python module to access serial ports. At the
+moment, it only works in Windows, Linux and MacOS but as it is written entirely
+in Python (doesn't wrap any C/C++ library) I hope you can extend it to support
+any other platforms.
+
+
+2. Motivation
+-------------
+
+I like very much to make electronic widgets with microcontrollers, specially
+those that can be connected to the computer to send and receive data.
+Some months ago, I discovered Python and inmediatelly liked it a lot.
+I started playing with it and saw that I could use it to make prototypes of
+comunication protocols between computer and microcontrollers really
+fast and easily than using C. At the same time, I was interested in
+working over different platforms.
+I started looking for Python modules to access serial port and I found
+the following projects:
+
+ * win32comport_demo from the win32 extension module
+ * win32comm module of wheineman@uconect.net
+ * Sio Module of Roger Rurnham (rburnham@cri-inc.com)
+ * pyxal (Python X10 Abstraction Layer) of Les Smithson
+ (lsmithson@open-networks.co.uk)
+
+but they were not multi-platform, were just a wrap of propietary libraries or
+were just simple examples of serial port access.
+For these reasons and also for learning more Python, I decided to start
+this project. Of course, I have used all this projects as reference to
+my module and so, I want to thanks the authors for their excellent work and
+for allowing us to study the code.
+I hope you enjoy using the uspp module as much as I am enjoying doing it.
+
+
+3. Where can I find it
+----------------------
+
+You may find it at:
+ * http://ibarona.googlepages.com/uspp
+ * http://www.telefonica.net/web/babur
+
+as a tar.gz package or as a winzip file.
+
+
+4. Features
+-----------
+
+This module has the following features:
+
+ - hight level access to serial port under several platforms.
+ - autodetects the platform in which it is working and exports
+ the correct classes for that platform.
+ - object oriented approach.
+ - file object semantic operations over the ports.
+ - allows using the serial port with different speeds and
+ characteristics.
+ - RS-232 and RS-485 modes (now only RS-232). In RS-485 mode
+ the communication is half-duplex and uses the RTS line
+ to control the direction of the transference.
+ - blocking, non-blocking or configurable timeout reads.
+
+
+5. Prerequisites
+----------------
+
+You need the following to use the library:
+
+ - Python 2.1 or better
+ - In windows you need the win32 extension modules
+
+
+6. Usage and documentation
+--------------------------
+
+You only have to import in your program the uspp module and automatically
+it loads the correct classes for the platform in which you are running
+the program.
+
+First of all you have to create a SerialPort object with the settings you
+want. If a SerialPortException is not generated then you just can
+use the read and write methods of the object to read and write to
+the serial port.
+
+Example:
+
+>>> from uspp import *
+>>> tty=SerialPort("COM2", 1000, 9600)
+>>> # Opens COM2 at 9600 bps and with a read timeout of 1 second.
+>>> tty.write("a") # Writes a character to the COM2 port
+>>> # Now suppose we receive the string "abc"
+>>> tty.inWaiting()
+3
+>>> tty.read()
+'a'
+>>> tty.inWaiting()
+2
+>>> tty.read(2)
+'bc'
+
+
+Documentation of the different classes and methods can be found on
+uspp module docstring.
+
+
+7. Where does it work
+---------------------
+
+The library has been tested in Windows 95, Windows XP and Windows 2000
+machines with Python 2.1+ and in a Linux (2.0.34 kernel) machine with
+Python 2.1+.
+
+
+8. Known problems
+-----------------
+
+
+
+
+9. To-do list
+-------------
+
+This is the to-do list:
+
+ - implement RS-485 mode.
+ - port the library to other platforms so that it can be really
+ multi-platform.
+
+
+10. Porting to other platforms
+-----------------------------
+
+If you want to port the library to other platforms you only have to follow
+these steps:
+
+* Create a new python file called SerialPort_XXXX.py in which you
+implement the same public classes and methods found in the SerialPort_win
+and SerialPort_linux modules.
+* Append the new platform to the uspp.py file.
+
+
+11. Licence
+----------
+
+This code is released under the "LGPL" that can be found in
+http://www.gnu.org/copyleft/lesser.html or in the lesser.txt file that
+is with the library.
+If you use this software, I'd like to know about it.
+
+
+12. Author
+---------
+
+This library has been created by Isaac Barona Martinez <ibarona@gmail.com>.
+
+
+13. Version
+----------
+
+0.1 - 09/01/2001 (September 2001)
+0.2 - 05/13/2003
+1.0 - 02/24/2006
+
+
diff --git a/cesar/maximus/python/lib/proto/uspp/Readme_es b/cesar/maximus/python/lib/proto/uspp/Readme_es
new file mode 100644
index 0000000000..08e1a9a7aa
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/Readme_es
@@ -0,0 +1,199 @@
+ USPP Library
+
+ Universal Serial Port Python Library
+ (Librería en Python para el acceso universal al puerto serie)
+
+ Copyright 2006 Isaac Barona <ibarona@gmail.com>
+
+
+Contenidos
+----------
+ 1. Introducción
+ 2. Motivación
+ 3. Dónde encontrar la librería
+ 4. Características
+ 5. Pre-requisitos
+ 6. Utilización y documentación
+ 7. Dónde funciona
+ 8. Problemas pendientes
+ 9. Tareas pendientes
+10. Portado a otras plataformas
+11. Licencia
+12. Autor
+13. Versión
+
+
+1. Introducción
+---------------
+
+La librería USPP es un módulo desarrollado en Python para el acceso
+multiplataforma al puerto serie. En el momento, sólo funciona en Linux
+Windows y MacOS, pero como está escrita completamente en Python
+(no es únicamente un recubrimiento en Python de una librería desarrollada
+en C/C++) espero que pueda ser ampliada para que soporte otras plataformas.
+
+
+2. Motivación
+-------------
+
+A mí me gusta mucho hacer pequeños cacharros electrónicos con
+microcontroladores, especialmente aquellos que pueden ser conectados a
+un ordenador para enviar y recibir datos.
+Hace un par de meses descubrí Python y realmente me encantó.
+Empezé a jugar con él y ví que podía utilizarlo para hacer prototipos
+de protocolos de comunicación entre el ordenador y los microcontroladores
+de manera mucho más fácil y rápida que utilizando C (que era el lenguaje
+que solía utilizar). Al mismo tiempo, estaba interesado en poder utilizar
+los desarrollos bajo diferentes arquitecturas.
+Empezé a buscar en la red módulos de Python que accedieran al puerto serie
+y encontré los siguientes:
+
+ * win32comport_demo que viene junto a la extensión win32.
+ * Módulo win32comm de wheineman@uconect.net.
+ * Sio Module de Roger Rurnham (rburnham@cri-inc.com)
+ * pyxal (Python X10 Abstraction Layer) de Les Smithson
+ (lsmithson@open-networks.co.uk)
+
+pero no eran multiplataforma, eran únicamente un recubrimiento de una librería
+propietaria o eran simples ejemplos de acceso al puerto serie bajo una
+determinada plataforma.
+Por estas razones, y también por supuesto, por aprender más Python, decidí
+empezar este proyecto. Por supuesto, he utilizado los módulos indicados
+anteriormente como referencia para realizar mi librería y por tanto, me
+creo en la obligación de felicitar a sus autores por su excelente trabajo y
+por haberlo compartido con los demás.
+
+Espero que disfrutes utilizándo el módulo uspp tanto como yo lo
+he hecho haciéndolo.
+
+
+3. Dónde encontrar la librería
+------------------------------
+
+Puedes encontrarla en:
+ * http://ibarona.googlepages.com/uspp
+ * http://www.telefonica.net/web/babur
+
+como un fichero tar.gz o como un fichero .zip.
+
+
+4. Características
+------------------
+
+Este módulo tiene las siguientes características destacadas:
+
+ - acceso de alto nivel al puerto serie bajo diversas plataformas.
+ - autodetecta la plataforma en la que se está ejecutando y
+ carga las clases adecuadas para esa plataforma.
+ - Orientado a objetos.
+ - Las operaciones sobre el puerto serie tienen la misma semántica
+ que las operaciones sobre objetos de tipo fichero.
+ - permite utilizar el puerto serie con diferentes velocidades y
+ características.
+ - permite la utilización del puerto bajo dos modos de funcionamiento:
+ RS-232 y RS-485 (de momento, sólo RS-232). En modo 485 la
+ comunicación es half-duplex y se utiliza la línea RTS para controlar
+ la dirección de la transferencia.
+ - lecturas en modo bloqueante, no bloqueante o con timeout.
+
+
+5. Pre-requisitos
+----------------
+
+Se necesita los siguiente para utilizar la librería:
+
+ - Python 2.1 o superior
+ - En windows los módulos win32
+
+
+6. Utilización y documentación
+------------------------------
+
+Únicamente tienes que importar en tu programa el módulo uspp y automáticamente
+él se encarga de cargar las clases adecuadas para la plataforma en la que
+se está ejecutando el programa.
+
+Lo primero de todo, tendrás que crear un objeto de tipo SerialPort con las
+características que desees. Si no se genera ninguna excepción del tipo
+SerialPortException, puedes utilizar los métodos de lectura y escritura
+del objeto para leer y escribir en el puerto serie.
+
+Ejemplo:
+
+>>> from uspp import *
+>>> tty=SerialPort("COM2", 1000, 9600)
+>>> # Abre el puerto serie COM2 a 9600 bps y con un timeout de 1 segundo.
+>>> tty.write("a") # Envía el carácter 'a' al puerto serie.
+>>> # Ahora suponemos que recibimos el string 'abc'
+>>> tty.inWaiting()
+3
+>>> tty.read()
+'a'
+>>> tty.inWaiting()
+2
+>>> tty.read(2)
+'bc'
+
+
+La documentación de las diferentes clases y métodos que componen el módulo
+puede encontrarse en el string de documentación del módulo uspp.
+
+
+7. Dónde funciona
+-----------------
+
+La librería ha sido probada en una máquina con Windows 95, Windows XP y
+Windows 2000 con Python 2.1+ y en un Linux (con el kernel 2.0.34) con Python
+2.1+.
+
+
+8. Problemas pendientes
+-----------------------
+
+
+
+
+9. Tareas pendientes
+--------------------
+
+Esta es la lista de tareas pendientes:
+
+ - implementar el modo RS-485.
+ - portar la librería a otras plataformas de forma que sea
+ realmente multiplataforma.
+
+
+10. Portado a otras plataformas
+-------------------------------
+
+Si quieres portar la librería a otras plataformas sólo tienes que seguir
+los siguientes pasos:
+
+* Crear un nuevo fichero en python llamado SerialPort_XXX.py en el que
+implementes las mismas clases y métodos públicos que aparecen en los
+módulos SerialPort_win y SerialPort_linux.
+* Añadir la nueva plataforma en el fichero uspp.py.
+
+
+11. Licencia
+------------
+
+Este código se libera bajo la licencia "LGPL" que puedes encontrar en
+http://www.gnu.org/copyleft/lesser.html o en el fichero lesser.txt que
+acompaña a la librería.
+Si utilizas este software estaría muy agradecido de saberlo.
+
+
+12. Autor
+---------
+
+Esta librería ha sido creada por Isaac Barona Martínez <ibarona@gmail.com>.
+
+
+13. Versión
+----------
+
+0.1 - 01/09/2001
+0.2 - 13/05/2003
+1.0 - 24/02/2006
+
diff --git a/cesar/maximus/python/lib/proto/uspp/SerialPort_darwin.py b/cesar/maximus/python/lib/proto/uspp/SerialPort_darwin.py
new file mode 100644
index 0000000000..ff478b511f
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/SerialPort_darwin.py
@@ -0,0 +1,326 @@
+##########################################################################
+# USPP Library (Universal Serial Port Python Library)
+#
+# Copyright (C) 2006 Isaac Barona <ibarona@gmail.com>
+#
+# 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; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##########################################################################
+
+#-------------------------------------------------------------------------
+# Project: USPP Library (Universal Serial Port Python Library)
+# Name: SerialPort_darwin.py
+# Purpose: Handle low level access to serial port in MacOS.
+#
+# Author: Isaac Barona Martinez <ibarona@gmail.com>
+# Copyright: (c) 2001 by Isaac Barona Martínez
+# Licence: LGPL
+#
+# Created: 26 June 2001
+# History: 06.02.2003 Modified and extended by J.Grauheding
+# <juergen.grauheding@a-city.de>
+# adapt it for Python 2.2 on Mac OS X
+# Douglas Jones (dfj23@drexel.edu)
+# - readline method.
+#
+#-------------------------------------------------------------------------
+
+"""
+SerialPort_darwin.py - Handle low level access to serial port in Mac OS X.
+
+See also uspp module docstring.
+
+
+"""
+
+import os
+import tty
+import termios
+import array
+import fcntl
+import exceptions
+import string
+
+class SerialPortException(exceptions.Exception):
+ """Exception raise in the SerialPort methods"""
+ def __init__(self, args=None):
+ self.args=args
+
+
+class SerialPort:
+ """Encapsulate methods for accesing to a serial port."""
+
+ BaudRatesDic={
+ 50: termios.B50,
+ 75: termios.B75,
+ 110: termios.B110,
+ 134: termios.B134,
+ 150: termios.B150,
+ 200: termios.B200,
+ 300: termios.B300,
+ 600: termios.B600,
+ 1200: termios.B1200,
+ 1800: termios.B1800,
+ 2400: termios.B2400,
+ 4800: termios.B4800,
+ 9600: termios.B9600,
+ 19200: termios.B19200,
+ 38400: termios.B38400,
+ 57600: termios.B57600,
+ 115200: termios.B115200,
+ 230400: termios.B230400
+ }
+ buf = array.array('h', '\000'*4)
+
+ def __init__(self, dev, timeout=None, speed=None, mode='232', params=None):
+ """Open the serial port named by the string 'dev'
+
+ 'dev' can be any of the following strings: '/dev/ttyS0', '/dev/ttyS1',
+ ..., '/dev/ttySX' or '/dev/cua0', '/dev/cua1', ..., '/dev/cuaX'.
+
+ 'timeout' specifies the inter-byte timeout or first byte timeout
+ (in miliseconds) for all subsequent reads on SerialPort.
+ If we specify None time-outs are not used for reading operations
+ (blocking reading).
+ If 'timeout' is 0 then reading operations are non-blocking. It
+ specifies that the reading operation is to return inmediately
+ with the bytes that have already been received, even if
+ no bytes have been received.
+
+ 'speed' is an integer that specifies the input and output baud rate to
+ use. Possible values are: 110, 300, 600, 1200, 2400, 4800, 9600,
+ 19200, 38400, 57600 and 115200.
+ If None a default speed of 9600 bps is selected.
+
+ 'mode' specifies if we are using RS-232 or RS-485. The RS-485 mode
+ is half duplex and use the RTS signal to indicate the
+ direction of the communication (transmit or recive).
+ Default to RS232 mode (at moment, only the RS-232 mode is
+ implemented).
+
+ 'params' is a list that specifies properties of the serial
+ communication.
+ If params=None it uses default values for the number of bits
+ per byte (8), the parity (NOPARITY) and the number of stop bits (1)
+ else params is the termios package mode array to use for
+ initialization.
+
+ """
+ self.__devName, self.__timeout, self.__speed=dev, timeout, speed
+ self.__mode=mode
+ self.__params=params
+ try:
+ self.__handle=os.open(dev, os.O_RDWR)
+ except:
+ raise SerialPortException('Unable to open port')
+
+ self.__configure()
+
+ def __del__(self):
+ """Close the serial port and restore its initial configuration
+
+ To close the serial port we have to do explicity: del s
+ (where s is an instance of SerialPort)
+ """
+
+ termios.tcsetattr(self.__handle, termios.TCSANOW, self.__oldmode)
+
+ try:
+ os.close(self.__handle)
+ except IOError:
+ raise SerialPortException('Unable to close port')
+
+
+ def __configure(self):
+ """Configure the serial port.
+
+ Private method called in the class constructor that configure the
+ serial port with the characteristics given in the constructor.
+ """
+ if not self.__speed:
+ self.__speed=9600
+
+ # Save the initial port configuration
+ self.__oldmode=termios.tcgetattr(self.__handle)
+ if not self.__params:
+ # self.__params is a list of attributes of the file descriptor
+ # self.__handle as follows:
+ # [c_iflag, c_oflag, c_cflag, c_lflag, c_ispeed, c_ospeed, cc]
+ # where cc is a list of the tty special characters.
+ self.__params=[]
+ # c_iflag
+ self.__params.append(termios.IGNPAR)
+ # c_oflag
+ self.__params.append(0)
+ # c_cflag
+ self.__params.append(termios.CS8|termios.CLOCAL|termios.CREAD)
+ # c_lflag
+ self.__params.append(0)
+ # c_ispeed
+ self.__params.append(SerialPort.BaudRatesDic[self.__speed])
+ # c_ospeed
+ self.__params.append(SerialPort.BaudRatesDic[self.__speed])
+ # XXX FIX: Theorically, it should be better to put:
+ # cc=[0]*termios.NCCS
+ # but it doesn't work because NCCS is 19 and self.__oldmode[6]
+ # is 32 ¿¿¿¿¿¿¿¿¿¿¿ Any help ??????????????
+ cc=[0]*len(self.__oldmode[6])
+ if self.__timeout==None:
+ # A reading is only complete when VMIN characters have
+ # been received (blocking reading)
+ cc[termios.VMIN]=1
+ cc[termios.VTIME]=0
+ elif self.__timeout==0:
+ # Non-blocking reading. The reading operation returns
+ # inmeditately, returning the characters waiting to
+ # be read.
+ cc[termios.VMIN]=0
+ cc[termios.VTIME]=0
+ else:
+ # Time-out reading. For a reading to be correct
+ # a character must be recieved in VTIME*100 seconds.
+ cc[termios.VMIN]=0
+ cc[termios.VTIME]=self.__timeout/100
+ self.__params.append(cc) # c_cc
+
+ termios.tcsetattr(self.__handle, termios.TCSANOW, self.__params)
+
+
+ def fileno(self):
+ """Return the file descriptor for opened device.
+
+ This information can be used for example with the
+ select funcion.
+ """
+ return self.__handle
+
+
+ def setraw(self):
+ tty.setraw(self.__handle)
+
+ def setcbreak(self):
+ tty.setcbreak(self.__handle)
+
+ def __read1(self):
+ """Read 1 byte from the serial port.
+
+ Generate an exception if no byte is read and self.timeout!=0
+ because a timeout has expired.
+ """
+ byte = os.read(self.__handle, 1)
+ if len(byte)==0 and self.__timeout!=0: # Time-out
+ raise SerialPortException('Timeout')
+ else:
+ return byte
+
+
+ def read(self, num=1):
+ """Read num bytes from the serial port.
+
+ Uses the private method __read1 to read num bytes. If an exception
+ is generated in any of the calls to __read1 the exception is reraised.
+ """
+ s=''
+ for i in range(num):
+ s=s+SerialPort.__read1(self)
+
+ return s
+
+
+ def readline(self):
+ """Read a line from the serial port. Returns input once a '\n'
+ character is found.
+ Douglas Jones (dfj23@drexel.edu) 09/09/2005.
+ """
+
+ s = ''
+ while not '\n' in s:
+ s = s+SerialPort.__read1(self)
+
+ return s
+
+
+ def write(self, s):
+ """Write the string s to the serial port"""
+
+ os.write(self.__handle, s)
+
+ def inWaiting(self):
+ """Returns the number of bytes waiting to be read
+ mod. by J.Grauheding
+ """
+ rbuf=fcntl.ioctl(self.__handle, termios.TIOCINQ, self.buf)
+ return rbuf
+
+ def outWaiting(self):
+ """Returns the number of bytes waiting to be write
+ mod. by J.Grauheding
+ """
+ rbuf=fcntl.ioctl(self.__handle, termios.TIOCOUTQ, self.buf)
+ return rbuf
+
+
+ def flush(self):
+ """Discards all bytes from the output or input buffer"""
+ termios.tcflush(self.__handle, termios.TCIOFLUSH)
+
+ def rts_on(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMGET, SerialPort.buf)
+ SerialPort.buf[1] = ord(rbuf[3]) | termios.TIOCM_RTS
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMSET, SerialPort.buf)
+ return rbuf
+
+ def rts_off(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMGET, self.buf)
+ self.buf[1]=ord(rbuf[3]) & ~termios.TIOCM_RTS
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMSET, self.buf)
+ return rbuf
+
+ def dtr_on(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMGET, SerialPort.buf)
+ SerialPort.buf[1] = ord(rbuf[3]) | termios.TIOCM_DTR
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMSET, SerialPort.buf)
+ return rbuf
+
+ def dtr_off(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMGET, self.buf)
+ self.buf[1]=ord(rbuf[3]) & ~termios.TIOCM_DTR
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMSET, self.buf)
+ return rbuf
+
+ def cts(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMGET, self.buf)
+ return ord(rbuf[3]) & termios.TIOCM_CTS
+
+ def cd(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMGET, self.buf)
+ return ord(rbuf[3]) & termios.TIOCM_CAR
+
+ def dsr(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMGET, self.buf)
+ return ord(rbuf[2]) & (termios.TIOCM_DSR>>8)
+
+ def ri(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, termios.TIOCMGET, self.buf)
+ return ord(rbuf[3]) & termios.TIOCM_RNG
+
+
diff --git a/cesar/maximus/python/lib/proto/uspp/SerialPort_linux.py b/cesar/maximus/python/lib/proto/uspp/SerialPort_linux.py
new file mode 100644
index 0000000000..de8d69714e
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/SerialPort_linux.py
@@ -0,0 +1,329 @@
+# -*- coding: iso-8859-1 -*-
+
+##########################################################################
+# USPP Library (Universal Serial Port Python Library)
+#
+# Copyright (C) 2006 Isaac Barona <ibarona@gmail.com>
+#
+# 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; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##########################################################################
+
+#------------------------------------------------------------------------
+# Project: USPP Library (Universal Serial Port Python Library)
+# Name: SerialPort_linux.py
+# Purpose: Handle low level access to serial port in linux.
+#
+# Author: Isaac Barona Martinez <ibarona@gmail.com>
+# Copyright: (c) 2006 by Isaac Barona Martínez
+# Licence: LGPL
+#
+# Created: 26 June 2001
+# History:
+# 20 January 2002 : Damien Geranton <dgeranton@voila.fr>
+# - NCCS worry fixed. We must not use TERMIOS
+# - inWaiting call fixed.
+# 09 Sept 2005: Douglas Jones <dfj23@drexel.edu>
+# - readline method.
+#
+#-------------------------------------------------------------------------
+
+"""
+SerialPort_linux.py - Handle low level access to serial port in linux.
+
+See also uspp module docstring.
+
+
+"""
+
+import os
+from termios import *
+import fcntl
+import exceptions
+import struct
+import array
+
+
+class SerialPortException(exceptions.Exception):
+ """Exception raise in the SerialPort methods"""
+ def __init__(self, args=None):
+ self.args=args
+
+
+class SerialPort:
+ """Encapsulate methods for accesing to a serial port."""
+
+ BaudRatesDic={
+ 110: B110,
+ 300: B300,
+ 600: B600,
+ 1200: B1200,
+ 2400: B2400,
+ 4800: B4800,
+ 9600: B9600,
+ 19200: B19200,
+ 38400: B38400,
+ 57600: B57600,
+ 115200: B115200
+ }
+ buf = array.array('h', '\000'*4)
+
+ def __init__(self, dev, timeout=None, speed=None, mode='232', params=None):
+ """Open the serial port named by the string 'dev'
+
+ 'dev' can be any of the following strings: '/dev/ttyS0', '/dev/ttyS1',
+ ..., '/dev/ttySX' or '/dev/cua0', '/dev/cua1', ..., '/dev/cuaX'.
+
+ 'timeout' specifies the inter-byte timeout or first byte timeout
+ (in miliseconds) for all subsequent reads on SerialPort.
+ If we specify None time-outs are not used for reading operations
+ (blocking reading).
+ If 'timeout' is 0 then reading operations are non-blocking. It
+ specifies that the reading operation is to return inmediately
+ with the bytes that have already been received, even if
+ no bytes have been received.
+
+ 'speed' is an integer that specifies the input and output baud rate to
+ use. Possible values are: 110, 300, 600, 1200, 2400, 4800, 9600,
+ 19200, 38400, 57600 and 115200.
+ If None a default speed of 9600 bps is selected.
+
+ 'mode' specifies if we are using RS-232 or RS-485. The RS-485 mode
+ is half duplex and use the RTS signal to indicate the
+ direction of the communication (transmit or recive).
+ Default to RS232 mode (at moment, only the RS-232 mode is
+ implemented).
+
+ 'params' is a list that specifies properties of the serial
+ communication.
+ If params=None it uses default values for the number of bits
+ per byte (8), the parity (NOPARITY) and the number of stop bits (1)
+ else params is the termios package mode array to use for
+ initialization.
+
+ """
+ self.__devName, self.__timeout, self.__speed=dev, timeout, speed
+ self.__mode=mode
+ self.__params=params
+ try:
+ self.__handle=os.open(dev, os.O_RDWR)
+ except:
+ raise SerialPortException('Unable to open port')
+
+ self.__configure()
+
+ def __del__(self):
+ """Close the serial port and restore its initial configuration
+
+ To close the serial port we have to do explicity: del s
+ (where s is an instance of SerialPort)
+ """
+
+ tcsetattr(self.__handle, TCSANOW, self.__oldmode)
+
+ try:
+ os.close(self.__handle)
+ except IOError:
+ raise SerialPortException('Unable to close port')
+
+
+ def __configure(self):
+ """Configure the serial port.
+
+ Private method called in the class constructor that configure the
+ serial port with the characteristics given in the constructor.
+ """
+ if not self.__speed:
+ self.__speed=9600
+
+ # Save the initial port configuration
+ self.__oldmode=tcgetattr(self.__handle)
+ if not self.__params:
+ # self.__params is a list of attributes of the file descriptor
+ # self.__handle as follows:
+ # [c_iflag, c_oflag, c_cflag, c_lflag, c_ispeed, c_ospeed, cc]
+ # where cc is a list of the tty special characters.
+ self.__params=[]
+ # c_iflag
+ self.__params.append(IGNPAR)
+ # c_oflag
+ self.__params.append(0)
+ # c_cflag
+ self.__params.append(CS8|CLOCAL|CREAD)
+ # c_lflag
+ self.__params.append(0)
+ # c_ispeed
+ self.__params.append(SerialPort.BaudRatesDic[self.__speed])
+ # c_ospeed
+ self.__params.append(SerialPort.BaudRatesDic[self.__speed])
+ cc=[0]*NCCS
+ if self.__timeout==None:
+ # A reading is only complete when VMIN characters have
+ # been received (blocking reading)
+ cc[VMIN]=1
+ cc[VTIME]=0
+ elif self.__timeout==0:
+ # Non-blocking reading. The reading operation returns
+ # inmeditately, returning the characters waiting to
+ # be read.
+ cc[VMIN]=0
+ cc[VTIME]=0
+ else:
+ # Time-out reading. For a reading to be correct
+ # a character must be recieved in VTIME*100 seconds.
+ cc[VMIN]=0
+ cc[VTIME]=self.__timeout/100
+ self.__params.append(cc) # c_cc
+
+ tcsetattr(self.__handle, TCSANOW, self.__params)
+
+
+ def fileno(self):
+ """Return the file descriptor for opened device.
+
+ This information can be used for example with the
+ select funcion.
+ """
+ return self.__handle
+
+
+ def __read1(self):
+ """Read 1 byte from the serial port.
+
+ Generate an exception if no byte is read and self.timeout!=0
+ because a timeout has expired.
+ """
+ byte = os.read(self.__handle, 1)
+ if len(byte)==0 and self.__timeout!=0: # Time-out
+ raise SerialPortException('Timeout')
+ else:
+ return byte
+
+
+ def read(self, num=1):
+ """Read num bytes from the serial port.
+
+ Uses the private method __read1 to read num bytes. If an exception
+ is generated in any of the calls to __read1 the exception is reraised.
+ """
+ s=''
+ for i in range(num):
+ s=s+SerialPort.__read1(self)
+
+ return s
+
+
+ def readline(self):
+ """Read a line from the serial port. Returns input once a '\n'
+ character is found.
+ Douglas Jones (dfj23@drexel.edu) 09/09/2005.
+ """
+
+ s = ''
+ while not '\n' in s:
+ s = s+SerialPort.__read1(self)
+
+ return s
+
+
+ def write(self, s):
+ """Write the string s to the serial port"""
+
+ os.write(self.__handle, s)
+
+
+ def inWaiting(self):
+ """Returns the number of bytes waiting to be read"""
+ data = struct.pack("L", 0)
+ data=fcntl.ioctl(self.__handle, TIOCINQ, data)
+ return struct.unpack("L", data)[0]
+
+ def outWaiting(self):
+ """Returns the number of bytes waiting to be write
+ mod. by J.Grauheding
+ result needs some finetunning
+ """
+ rbuf=fcntl.ioctl(self.__handle, TIOCOUTQ, self.buf)
+ return rbuf
+
+ def getlsr(self):
+ """Returns the status of the UART LSR Register
+ J.Grauheding
+ """
+ rbuf=fcntl.ioctl(self.__handle, TIOCSERGETLSR, self.buf)
+ return ord(rbuf[0])
+
+ def get_temt(self):
+ """Returns the Tranmitterbuffer Empty Bit of LSR Register
+ J.Grauheding
+ test result against TIOCSER_TEMT
+ """
+ rbuf=fcntl.ioctl(self.__handle, TIOCSERGETLSR, self.buf)
+ return ord(rbuf[0]) & TIOSER_TEMT
+
+
+ def flush(self):
+ """Discards all bytes from the output or input buffer"""
+ tcflush(self.__handle, TCIOFLUSH)
+
+ def rts_on(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, TIOCMGET, SerialPort.buf)
+ SerialPort.buf[1] = ord(rbuf[3]) | TIOCM_RTS
+ rbuf = fcntl.ioctl(self.__handle, TIOCMSET, SerialPort.buf)
+ return rbuf
+
+ def rts_off(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)
+ self.buf[1]=ord(rbuf[3]) & ~TIOCM_RTS
+ rbuf = fcntl.ioctl(self.__handle, TIOCMSET, self.buf)
+ return rbuf
+
+ def dtr_on(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, TIOCMGET, SerialPort.buf)
+ SerialPort.buf[1] = ord(rbuf[3]) | TIOCM_DTR
+ rbuf = fcntl.ioctl(self.__handle, TIOCMSET, SerialPort.buf)
+ return rbuf
+
+ def dtr_off(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)
+ self.buf[1]=ord(rbuf[3]) & ~TIOCM_DTR
+ rbuf = fcntl.ioctl(self.__handle, TIOCMSET, self.buf)
+ return rbuf
+
+ def cts(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)
+ return ord(rbuf[3]) & TIOCM_CTS
+
+ def cd(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)
+ return ord(rbuf[3]) & TIOCM_CAR
+
+ def dsr(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)
+ return ord(rbuf[2]) & (TIOCM_DSR>>8)
+
+ def ri(self):
+ """ J.Grauheding """
+ rbuf = fcntl.ioctl(self.__handle, TIOCMGET, self.buf)
+ return ord(rbuf[3]) & TIOCM_RNG
+
+
+
diff --git a/cesar/maximus/python/lib/proto/uspp/SerialPort_win.py b/cesar/maximus/python/lib/proto/uspp/SerialPort_win.py
new file mode 100644
index 0000000000..80410b9f40
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/SerialPort_win.py
@@ -0,0 +1,239 @@
+# -*- coding: iso-8859-1 -*-
+
+##########################################################################
+# USPP Library (Universal Serial Port Python Library)
+#
+# Copyright (C) 2006 Isaac Barona <ibarona@gmail.com>
+#
+# 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; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##########################################################################
+
+#-------------------------------------------------------------------------
+# Project: USPP Library (Universal Serial Port Python Library)
+# Name: SerialPort_win.py
+# Purpose: Handle low level access to serial port in windows.
+#
+# Author: Isaac Barona Martinez <ibarona@gmail.com>
+# Copyright: (c) 2001 by Isaac Barona Martínez
+# Licence: LGPL
+#
+# Created: 26 June 2001
+# History:
+# 20 January 2002 : Damien Géranton <dgeranton@voila.fr>
+# Bug fix for Win2000, the file must not be open with
+# FILE_FLAG_OVERLAPPED
+#
+#-------------------------------------------------------------------------
+
+"""
+SerialPort_win.py - Handle low level access to serial port in windows.
+
+See also uspp module docstring.
+
+"""
+
+
+from win32file import *
+from win32event import *
+import win32con
+import exceptions
+
+class SerialPortException(exceptions.Exception):
+ """Exception raise in the SerialPort methods"""
+ def __init__(self, args=None):
+ self.args=args
+
+
+class SerialPort:
+ """Encapsulate methods for accesing to a serial port."""
+
+ BaudRatesDic={110: CBR_110,
+ 300: CBR_300,
+ 600: CBR_600,
+ 1200: CBR_1200,
+ 2400: CBR_2400,
+ 4800: CBR_4800,
+ 9600: CBR_9600,
+ 19200: CBR_19200,
+ 38400: CBR_38400,
+ 57600: CBR_57600,
+ 115200: CBR_115200,
+ }
+
+ def __init__(self, dev, timeout=None, speed=None, mode='232', params=None):
+ """Open the serial port named by the string 'dev'
+
+ 'dev' can be any of the following strings: 'COM1', 'COM2', ... 'COMX'
+
+ 'timeout' specifies the inter-byte timeout or first byte timeout
+ (in miliseconds) for all subsequent reads on SerialPort.
+ If we specify None time-outs are not used for reading operations
+ (blocking reading).
+ If 'timeout' is 0 then reading operations are non-blocking. It
+ specifies that the reading operation is to return inmediately
+ with the bytes that have already been received, even if
+ no bytes have been received.
+
+ 'speed' is an integer that specifies the input and output baud rate to
+ use. Possible values are: 110, 300, 600, 1200, 2400, 4800, 9600,
+ 19200, 38400, 57600 and 115200.
+ If None a default speed of 9600 bps is selected.
+
+ 'mode' specifies if we are using RS-232 or RS-485. The RS-485 mode
+ is half duplex and use the RTS signal to indicate the
+ direction of the communication (transmit or recive).
+ Default to RS232 mode (at moment, only the RS-232 mode is
+ implemented).
+
+ 'params' is a list that specifies properties of the serial
+ communication.
+ If params=None it uses default values for the number of bits
+ per byte (8), the parity (NOPARITY) and the number of stop bits (1)
+ else params must be a list with three items setting up the
+ these values in this order.
+
+ """
+ self.__devName, self.__timeout, self.__speed=dev, timeout, speed
+ self.__mode=mode
+ self.__params=params
+ try:
+ self.__handle=CreateFile (dev,
+ win32con.GENERIC_READ|win32con.GENERIC_WRITE,
+ 0, # exclusive access
+ None, # no security
+ win32con.OPEN_EXISTING,
+ win32con.FILE_ATTRIBUTE_NORMAL,
+ None)
+ except:
+ raise SerialPortException('Unable to open port')
+
+ self.__configure()
+
+ def __del__(self):
+ """Close the serial port
+
+ To close the serial port we have to do explicity: del s
+ (where s is an instance of SerialPort)
+ """
+ try:
+ CloseHandle(self.__handle)
+ except IOError:
+ raise SerialPortException('Unable to close port')
+
+
+ def __configure(self):
+ """Configure the serial port.
+
+ Private method called in the class constructor that configure the
+ serial port with the characteristics given in the constructor.
+ """
+ if not self.__speed:
+ self.__speed=9600
+ # Tell the port we want a notification on each char
+ SetCommMask(self.__handle, EV_RXCHAR)
+ # Setup a 4k buffer
+ SetupComm(self.__handle, 4096, 4096)
+ # Remove anything that was there
+ PurgeComm(self.__handle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|
+ PURGE_RXCLEAR)
+
+ # Setup the timeouts parameters for the port
+ # timeouts is a tuple with the following items:
+ # [0] int : ReadIntervalTimeout
+ # [1] int : ReadTotalTimeoutMultiplier
+ # [2] int : ReadTotalTimeoutConstant
+ # [3] int : WriteTotalTimeoutMultiplier
+ # [4] int : WriteTotalTimeoutConstant
+
+ if self.__timeout==None:
+ timeouts= 0, 0, 0, 0, 0
+ elif self.__timeout==0:
+ timeouts = win32con.MAXDWORD, 0, 0, 0, 1000
+ else:
+ timeouts= self.__timeout, 0, self.__timeout, 0 , 1000
+ SetCommTimeouts(self.__handle, timeouts)
+
+ # Setup the connection info
+ dcb=GetCommState(self.__handle)
+ dcb.BaudRate=SerialPort.BaudRatesDic[self.__speed]
+ if not self.__params:
+ dcb.ByteSize=8
+ dcb.Parity=NOPARITY
+ dcb.StopBits=ONESTOPBIT
+ else:
+ dcb.ByteSize, dcb.Parity, dcb.StopBits=self.__params
+ SetCommState(self.__handle, dcb)
+
+
+ def fileno(self):
+ """Return the file descriptor for opened device.
+
+ This information can be used for example with the
+ select function.
+ """
+ return self.__handle
+
+
+ def read(self, num=1):
+ """Read num bytes from the serial port.
+
+ If self.__timeout!=0 and != None and the number of read bytes is less
+ than num an exception is generated because a timeout has expired.
+ If self.__timeout==0 read is non-blocking and inmediately returns
+ up to num bytes that have previously been received.
+ """
+
+ (hr, buff) = ReadFile(self.__handle, num)
+ if len(buff)<>num and self.__timeout!=0: # Time-out
+ raise SerialPortException('Timeout')
+ else:
+ return buff
+
+
+ def readline(self):
+ """Read a line from the serial port. Returns input once a '\n'
+ character is found.
+
+ """
+
+ s = ''
+ while not '\n' in s:
+ s = s+SerialPort.read1(self,1)
+
+ return s
+
+
+ def write(self, s):
+ """Write the string s to the serial port"""
+ overlapped=OVERLAPPED()
+ overlapped.hEvent=CreateEvent(None, 0,0, None)
+ WriteFile(self.__handle, s, overlapped)
+ # Wait for the write to complete
+ WaitForSingleObject(overlapped.hEvent, INFINITE)
+
+ def inWaiting(self):
+ """Returns the number of bytes waiting to be read"""
+ flags, comstat = ClearCommError(self.__handle)
+ return comstat.cbInQue
+
+ def flush(self):
+ """Discards all bytes from the output or input buffer"""
+ PurgeComm(self.__handle, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|
+ PURGE_RXCLEAR)
+
+
+
+
+
diff --git a/cesar/maximus/python/lib/proto/uspp/lesser.txt b/cesar/maximus/python/lib/proto/uspp/lesser.txt
new file mode 100644
index 0000000000..54905a6050
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/lesser.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ 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.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/cesar/maximus/python/lib/proto/uspp/uspp.htm b/cesar/maximus/python/lib/proto/uspp/uspp.htm
new file mode 100644
index 0000000000..d3bffac7c7
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/uspp.htm
@@ -0,0 +1,635 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>ibarona - USPP(Universal Serial Port Python Library)</title>
+
+
+
+
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <style type="text/css">
+ #g_title p, #g_footer p, #g_description p {
+ margin: 0;
+ }
+ /*
+
+ -- -- -- -- -- -- --
+ Browser Fixes
+ -- -- -- -- -- -- --
+
+ This file uses CSS filtering methods to fix various
+ layout bugs.
+
+ Each of the following three imported files is a
+ separate, browser-specific CSS file that keeps all
+ hacks out of the main style sheet.
+
+ Over time, as supporting these browsers no longer
+ remains a priority, cleaning up the hacks is as
+ easy as deleting the @import statement below, or
+ simply no longer linking this file from the HTML.
+
+ */
+
+ /*
+ fix ie6 "peekaboo bug" using the "holly hack".
+ Note, this style only gets applied to ie6
+ */
+ * html .wrapper {
+ height: 0.1%;
+ }
+
+ /*
+ * IE5 mac - overrides the IE/Win hack
+ */
+
+ /*\*//*/
+
+ * html #threecolumn div {
+ height: auto;
+ }
+
+ /**/
+
+
+ /*
+ * IE5/Win-specific CSS -ensures #container wraps all content on window resize
+ */
+
+ @media tty {
+ i{content:"\";/*" "*/}} * html #container { height: 1%; } /*";}
+ }/* */
+ /* Styling for editable elements. Eventually, this will be part of the style. */
+ .editable {
+ border: 1px dashed blue;
+ }
+
+ #footer {
+ clear: both;
+ }
+
+ /* Extra divs hidden by default. The custom CSS can override this though */
+ #extraDiv1, #extraDiv2, #extraDiv3, #extraDiv4, #extraDiv5, #extraDiv6 {
+ display: none;
+ }
+
+ /*
+ -- -- -- -- -- -- --
+ 1 Column Layout
+ -- -- -- -- -- -- --
+ */
+
+ /* Center #container, constrain to 718px width
+ ----------------------------------------------- */
+ body {
+ text-align: center;
+ }
+ #container {
+ width: 718px;
+ text-align: left;
+ margin: 0 auto;
+ }
+
+ #main-content {
+ overflow: hidden;
+ }
+
+ /** BEGIN CUSTOM SKIN **/
+ /*
+
+ -- -- -- -- -- -- --
+ Base CSS
+ -- -- -- -- -- -- --
+
+ This file simply removes default styling on most HTML elements in
+ order to reduce the need to later override them.
+
+ */
+
+ h1,h2,h3,h4,h5,h6,pre,code,p {font-size: 1em;}
+ dl,li,dt,dd,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,fieldset,input {margin: 0; padding: 0;}
+ a img,:link img,:visited img {border: none;}
+ address {font-style: normal;}/*
+
+ -- -- -- -- -- -- --
+ Type Scheme: Deco
+ -- -- -- -- -- -- --
+
+ */
+
+ body {
+ font: 76% Verdana, sans-serif;
+ }
+
+ h1, h2, h3, h4, h5, h6, p.description {
+ font-family: "Trebuchet MS", Trebuchet, sans-serif;
+ }
+ h1 {
+ font-size: 3em;
+ font-weight: bold;
+ letter-spacing: 2px;
+ }
+ h2 {
+ font-size: 2em;
+ font-weight: normal;
+ }
+ h3 {
+ font-size: 1.5em;
+ }
+ h4 {
+ font-size: 1.2em;
+ letter-spacing: 0.2em;
+ }
+ h5 {
+ font-size: 1.2em;
+ }
+ h6 {
+ font-size: 1em;
+ font-weight: bold;
+ }
+
+ p, td {
+ line-height: 1.8em;
+ }
+ code, kbd {
+ font-size: 1.25em;
+ }/*
+
+ -- -- -- -- -- -- --
+ STYLE: Micro
+ -- -- -- -- -- -- --
+
+ */
+
+
+
+
+ /* ie6win */
+
+ /* IE/Win fixes for various layouts
+ ----------------------------------------------- */
+ * html #onecolumn #header {
+ margin-right: -3px;
+ }
+ * html #onecolumn #header,
+ * html #twocolumn-left #header, * html #twocolumn-right #header,
+ * html #twocolumn-liquid-left #header, * html #twocolumn-liquid-right #header {
+ padding-bottom: 1px;
+ }
+ * html #twocolumn-left #main-content, * html #twocolumn-right #main-content {
+ width: 459px;
+ }
+ * html #threecolumn #main-content {
+ width: 409px;
+ }
+
+ /* ie5mac */
+
+ /*\*//*/
+ /* Undoing IE/Win fixes
+ ----------------------------------------------- */
+ * html #onecolumn #header {
+ margin-right: 0;
+ }
+ * html #twocolumn-left #header, * html #twocolumn-right #header,
+ * html #twocolumn-liquid-left #header, * html #twocolumn-liquid-right #header {
+ padding-bottom: 0;
+ }
+ * html #twocolumn-left #main-content, * html #twocolumn-right #main-content {
+ width: 479px;
+ }
+ * html #threecolumn #main-content {
+ width: 429px;
+ }
+ /**/
+
+ @media tty {
+ i{content:"\";/*" "*/}} td { font-size: 0.8em; } /*";}
+ }/* */
+
+
+
+ /* Basic HTML style
+ ----------------------------------------------- */
+ body {
+ font: 76% "Lucida Grande", "Lucida Sans Unicode", Arial, sans-serif;
+ color: #000;
+ background: #fff;
+ margin: 0;
+ padding: 0;
+ }
+ blockquote {
+ margin: 1em 2em;
+ font-style: italic;
+ }
+ caption {
+ font-weight: bold;
+ color: #444;
+ background: #ccc;
+ border-bottom: 0;
+ padding: 0.3em 1em;
+ }
+ dd {
+ margin: 1em 2em;
+ }
+ dl {
+ margin: 2em 0;
+ }
+ dt {
+ font-weight: bold;
+ }
+ hr {
+ margin: 2em 0;
+ color: #C7C7C7;
+ background: #C7C7C7;
+ border-color: #C7C7C7;
+ border-style: none;
+ height: 1px;
+ }
+ li {
+ margin: 1em 0;
+ }
+ table {
+ border: solid 1px #ccc;
+ }
+ td {
+ vertical-align: top;
+ padding: 0.5em;
+ }
+ th {
+ text-align: left;
+ color: #fff;
+ background: #777;
+ padding: 0.5em;
+ }
+ ol, ul {
+ margin: 2em 0;
+ padding-left: 1em;
+ }
+
+
+
+ /* Nested HTML elements, and basic classes
+ ----------------------------------------------- */
+ ol li {
+ list-style-type: decimal;
+ margin-left: 2em;
+ }
+ ul li {
+ margin-left: 2em;
+ list-style-type: square;
+ }
+ td p {
+ margin-top: 0;
+ }
+
+
+
+ /* Set the stage with main layout tweaks
+ ----------------------------------------------- */
+ #container {
+ border: solid 7px #999;
+ border-left: 0;
+ border-right: 0;
+ padding-top: 1px;
+ }
+ #header {
+ color: #04172D;
+ border-top: solid 3px #777;
+ padding: 0;
+ margin: 0 0 1.5em 0;
+ }
+ #main-content .wrapper {
+ margin: 0;
+ }
+ .description {
+ font: normal 1em "Lucida Grande", "Lucida Sans Unicode", Arial, sans-serif;
+ color: #444;
+ background: #C7C7C7;
+ padding: 3px 25px 2.2em 25px;
+ margin: 0;
+ line-height: 1;
+ }
+ #footer {
+ clear: both;
+ color: #999;
+ padding: 0 1em 1em 1em;
+ border-bottom: solid 3px #777;
+ margin-bottom: 1px;
+ }
+
+
+ /* Content area offset
+ ----------------------------------------------- */
+ #main-content .wrapper {
+ padding: 0 25px;
+ }
+
+ #main-content td p {
+ margin: 0 0 1em 0;
+ }
+
+
+
+ /* Custom font definitions
+ ----------------------------------------------- */
+ p {
+ margin: 1em 0;
+ line-height: 1.5;
+ }
+ h1,h2,h3,h4,h5,h6 {
+ font-family: "Trebuchet MS", arial, sans-serif;
+ }
+ h1 {
+ color: #B2B2B2;
+ font-size: 2.4em;
+ letter-spacing: 0.2em;
+ font-weight: normal;
+ padding: 1em 25px 0 25px;
+ }
+ h2 {
+ margin: 0 0 0.5em 0;
+ color: #777;
+ font-size: 1.4em;
+ font-weight: normal;
+ border-bottom: double 3px #C7C7C7;
+ padding: 0 0 0.4em 0;
+ }
+ h3 {
+ font-size: 1.2em;
+ background: #eee;
+ border: dotted 1px #C7C7C7;
+ padding: 0.2em;
+ }
+ h4 {
+ font-size: 1.2em;
+ padding: 0 0 0.2em 0;
+ margin: 0.6em 0 0 0.4em;
+ color: #777;
+ }
+ h5 {
+ border-bottom: dotted 1px #C7C7C7;
+ }
+ h6 {
+ color: #777;
+ border-left: solid 1.2em #777;
+ padding-left: 0.6em;
+ }
+
+ a:link {
+ color: #9db2df;
+ }
+ a:hover {
+ text-decoration: none;
+ border-bottom: 1px dotted #bb242d;
+ background-color: #e0e0e0;
+ }
+
+
+ /* Sidebar
+ ----------------------------------------------- */
+ #sidebar h3, #sidebar-alternate h3 {
+ margin: 0;
+ color: #777;
+ background: none;
+ font-size: 1.4em;
+ font-weight: normal;
+ border: none;
+ padding: 0;
+ }
+
+ #sidebar blockquote, #sidebar blockquote p,
+ #sidebar-alternate blockquote, #sidebar-alternate blockquote p {
+ margin-left: 0;
+ margin-right: 0;
+ }
+ #sidebar blockquote {
+ margin: 1em 0;
+ padding: 0;
+ }
+ #adsense {
+ text-align: center;
+ }
+
+
+
+ .editable {
+ border: dashed 1px #c33;
+ }
+
+
+
+
+ /* Tweaks for Two-column Right layout
+ ----------------------------------------------- */
+ #twocolumn-right #sidebar .wrapper {
+ margin: 0 10px;
+ }
+
+
+
+ /* Tweaks for Two-column Left layout
+ ----------------------------------------------- */
+ #twocolumn-left #sidebar .wrapper {
+ margin: 0 10px;
+ }
+
+
+ /* Tweaks for Three-column layout
+ ----------------------------------------------- */
+ #threecolumn #sidebar .wrapper {
+ margin: 0 10px;
+ }
+ #threecolumn #sidebar-alternate .wrapper {
+ margin: 0 10px;
+ }
+ /*
+
+ -- -- -- -- -- -- --
+ COLOR SCHEME: Blueprint
+ -- -- -- -- -- -- --
+
+ */
+
+
+ /* Basic HTML style
+ ----------------------------------------------- */
+ a:link {
+ color: #445AA9;
+ }
+ a:visited {
+ color: #283D88;
+ }
+ body {
+ color: #283769;
+ background: #ECEEF6;
+ }
+ caption {
+ color: inherit;
+ background: #ECEEF6;
+ }
+ hr {
+ color: #C7C7C7;
+ background: #C7C7C7;
+ border-color: #C7C7C7;
+ }
+ table {
+ background: #fff;
+ border-color: #B3BCDC;
+ }
+ th {
+ color: #fff;
+ background: #445AA9;
+ }
+
+
+
+ /* Set the stage with main layout tweaks
+ ----------------------------------------------- */
+ #container {
+ background-color: #F6F7FB;
+ border-color: #6678B8;
+ }
+ #header {
+ color: #445AA9;
+ border-top-color: #6678B8;
+ }
+ .description {
+ color: #445AA9;
+ background: #C9D0E6;
+ }
+ #footer {
+ color: #5064AE;
+ border-bottom-color: #6678B8;
+ }
+
+
+
+ /* Custom font definitions
+ ----------------------------------------------- */
+ h1 {
+ color: #445AA9;
+ }
+ h2 {
+ color: #5064AE;
+ border-bottom-color: #B3BCDC;
+ }
+ h3 {
+ background: #ECEEF6;
+ border-color: #C9D0E6;
+ }
+ h4 {
+ border-bottom-color: #B3BCDC;
+ color: #1A4292;
+ }
+ h5 {
+ border-bottom-color: #C7C7C7;
+ }
+ h6 {
+ color: #5064AE;
+ border-left-color: #B3BCDC;
+ }
+
+
+
+
+
+ /* Sidebar
+ ----------------------------------------------- */
+ #sidebar h3, #sidebar-alternate h3 {
+ color: #5064AE;
+ background: none;
+ }
+ /** END CUSTOM SKIN **/
+ </style><!-- Hack to avoid flash of unstyled content in IE -->
+
+
+ <script> </script></head><body id="onecolumn">
+ <div id="container">
+ <div class="wrapper">
+ <div id="header">
+ <div class="wrapper">
+ <h1 id="page-title"><div id="g_title">USPP(Universal Serial Port Python Library)<br></div></h1>
+ <div style="clear: both;"></div>
+ <p class="description"></p><div id="g_description"><p>Isaac Barona (ibarona@gmail.com)&nbsp;</p></div>
+ <div style="clear: both;"></div>
+ </div>
+ </div>
+
+ <div id="main-content">
+ <div class="wrapper">
+ <div class="content-item"><div id="g_body"><h2>Introduction</h2><p><i>USPP Library </i>is a multi-platform Python module to access serial ports.
+At the moment, it only works in Windows, Linux and MacOS but as it is written entirely in Python (doesn't wrap any C/C++
+library) I hope you can extend it to support any other platforms.&nbsp;</p><h2>Motivation</h2><p>
+I like very much to make electronic widgets with microcontrollers, specially
+those that can be connected to the computer to send and receive data.
+</p><p>Some months ago, I discovered Python and inmediatelly liked it a lot.
+I started playing with it and saw that I could use it to make prototypes of
+comunication protocols between computer and microcontrollers really
+fast and easily than using C. At the same time, I was interested in
+working over different platforms.
+</p><p>I started looking for Python modules to access serial port and I found
+the following projects:
+</p><ul><li><i>win32comport_demo</i> from the win32 extension module</li><li><i>win32comm</i> module of wheineman@uconect.net</li><li><i>Sio Module </i>of Roger Rurnham (rburnham@cri-inc.com)</li><li><i>pyxal (Python X10 Abstraction Layer) </i>of Les Smithson (lsmithson@open-networks.co.uk)</li></ul><p>but they were not multi-platform, were just a wrap of propietary libraries or
+were just simple examples of serial port access.
+</p><p>For these reasons and also for learning more Python, I decided to start
+this project. Of course, I have used all this projects as reference to
+my module and so, I want to thanks the authors for their excellent work and
+for allowing us to study the code.
+I hope you enjoy using the uspp module as much as I am enjoying doing it.</p><h2>Features</h2><p>
+This module has the following features:
+</p><ul><li>hight level access to serial port under several platforms.</li><li>autodetects the platform in which it is working and exports the correct
+classes for that platform.</li><li>object oriented approach.</li><li>file object semantic operations over the ports.</li><li>allows using the serial port with different speeds and
+characteristics.</li><li>RS-232 and RS-485 modes (now only RS-232). In RS-485 mode the communication
+is half-duplex and uses the RTS line to control the direction of the
+transference.</li><li>blocking, non-blocking or configurable timeout reads.</li></ul><h2>&nbsp;Prerequisites</h2><p>You need the following to use the library:
+</p><ul><li>Python 2.1 or better</li><li>In windows you need the win32 extension modules. You can get it from <a href="http://sourceforge.net/projects/pywin32/">here</a>.<br></li></ul><h2>Usage and documentation</h2><p>You only have to import in your program the <i>uspp</i> module and automatically
+it loads the correct classes for the platform in which you are running
+the program.
+
+</p><p>First of all you have to create a <i>SerialPort</i> object with the settings you
+want. If a <i>SerialPortException</i> is not generated then you just can
+use the read and write methods of the object to read and write to
+the serial port.
+
+</p><p>Example:
+
+</p><pre><tt><br>&gt;&gt;&gt; from uspp import *<br>&gt;&gt;&gt; tty=SerialPort("COM2", 1000, 9600) <br>&gt;&gt;&gt; # Opens COM2 at 9600 bps and with a read timeout of 1 second.<br>&gt;&gt;&gt; tty.write("a") # Writes a character to the COM2 port<br>&gt;&gt;&gt; # Now suppose we receive the string "abc"<br>&gt;&gt;&gt; tty.inWaiting()<br>3<br>&gt;&gt;&gt; tty.read()<br>'a'<br>&gt;&gt;&gt; tty.inWaiting()<br>2<br>&gt;&gt;&gt; tty.read(2)<br>'bc'<br></tt></pre>
+
+<p>Documentation of the different classes and methods can be found on
+uspp module docstring.</p><h2>Where does it works?&nbsp;</h2><p>&nbsp;
+The library has been tested in&nbsp; Windows 95, Windows XP and Windows 2000&nbsp; machines with Python 2.0+
+and in a Linux (2.0.34 and 2.4.20 kernels) machine with Python 2.1+.</p><h2>Porting to other frameworks</h2><p>
+If you want to port the library to other platforms you only have to follow
+these steps:
+</p><ul><li>Create a new python file called <i>SerialPort_XXXX.py </i>in which you
+implement the same public classes and methods found in the
+<i>SerialPort_win</i>
+and <i>SerialPort_linux</i> modules.</li><li>Append the new platform to the <i>uspp.py</i> file.</li></ul><h2>License&nbsp;</h2><p>&nbsp;
+This code is released under the "GPL" that can be found in
+<a href="http://www.gnu.org/copyleft/gpl.html%20">http://www.gnu.org/copyleft/gpl.html </a>or in the GPL.txt file that
+is with the library.
+</p><p>If you use this software, I'd like to know about it.</p><h2>&nbsp;Author</h2><p>
+This library has been created by Isaac Barona Martínez
+<a href="mailto:ibarona%20at%20gmail.com">(ibarona at gmail.com)</a>&nbsp;</p><h2>Versions <br></h2><h3>Version 1.0 - 02/24/2006 (February 2006) &nbsp;&nbsp;&nbsp;</h3><p>Lot
+to time after 0.1 version I have enouth time to publish the final
+version of the library. This version correct some bugs of 0.1 version,
+works in MacOS and have been extended.</p><p>The library contains more functions in Linux and MacOS platforms than in Windows platform.&nbsp;</p><p>I have to thanks a lot of people his contribution to the library, especially:</p><ul><li>Damien Geranton &lt;dgeranton at voila.fr&gt;&nbsp;</li><li>Douglas Jones &lt;dfj23 at drexel.edu&gt;</li><li>&nbsp;J.Grauheding &lt;juergen.grauheding at a-city.de&gt; </li></ul><p>&nbsp;Files:</p><ul><ul><li>Zip file: uspp-0_1.zip</li><li>tar.gz file: uspp-0_1.tar.gz</li></ul></ul><h4>&nbsp;</h4><h3>Version 0.1 - 09/01/2001 (September 2001)</h3><p></p></div></div>
+ <div style="clear: both;"></div>
+ </div>
+ </div>
+
+ <div id="footer"><div class="wrapper">
+ <hr>
+ <p></p><div id="g_footer">&nbsp;</div>
+ <div style="clear: both;"></div>
+ </div></div>
+
+ </div>
+ </div>
+
+
+<div id="extraDiv1"><span></span></div><div id="extraDiv2"><span></span></div>
+<div id="extraDiv3"><span></span></div><div id="extraDiv4"><span></span></div>
+<div id="extraDiv5"><span></span></div><div id="extraDiv6"><span></span></div>
+
+</body></html> \ No newline at end of file
diff --git a/cesar/maximus/python/lib/proto/uspp/uspp.py b/cesar/maximus/python/lib/proto/uspp/uspp.py
new file mode 100644
index 0000000000..1255613d62
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/uspp.py
@@ -0,0 +1,193 @@
+#! /usr/bin/env python
+
+# -*- coding: iso-8859-1 -*-
+
+##########################################################################
+# USPP Library (Universal Serial Port Python Library)
+#
+# Copyright (C) 2006 Isaac Barona <ibarona@gmail.com>
+#
+# 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; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# 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.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##########################################################################
+
+#-------------------------------------------------------------------------
+# Project: USPP Library (Universal Serial Port Python Library)
+# Name: uspp.py
+# Purpose: Main module. Imports the correct module for the platform
+# in which it is running.
+#
+# Author: Isaac Barona Martinez <ibarona@gmail.com>
+# Copyright: (c) 2006 by Isaac Barona Martinez
+# Licence: LGPL
+#
+# Created: 26 June 2001
+# History:
+# 05/08/2001: Release version 0.1.
+# 24/02/2006: Final version 1.0.
+#
+#-------------------------------------------------------------------------
+
+
+"""
+USPP - Universal Serial Port Python Library
+
+This module exports a SerialPort class to access serial ports in
+different platforms (currently W9X and Linux) with the same code.
+
+When the library user import the uspp module, it automatically
+loads the correct class implementation for the platform in which
+is running.
+
+The public classes, exceptions and methods are the following:
+
+SerialPortException
+===================
+Exception raised in the SerialPort methods.
+
+
+SerialPort
+==========
+Class that encapsulate methods to access serial ports. It has the
+following public methods:
+
+* __init__(self, dev, timeout=None, speed=None, mode='232', params=None)
+
+ Create an object to access serial port 'dev'
+
+ Arguments:
+
+ dev: String that indicate the name of the port. Possible values are:
+ In Linux: '/dev/ttyS0', '/dev/ttyS1', ..., '/dev/ttySX' or
+ '/dev/cua0', '/dev/cua1', ..., '/dev/cuaX'
+ In W9X: 'COM1', 'COM2', ..., 'COMX'
+
+ timeout: specifies in milliseconds the inter-byte timeout. Possible
+ values are:
+ * None: For blocking readings. Time-outs are not used for reading
+ operations.
+ * 0: For non-blocking readings. The reading operation is to return
+ inmediately with the characters that have already been received,
+ even if no characters have been received.
+ * >0: For time-out readings. A character must be read in less than
+ this value.
+
+ speed: integer that specifies the input and output baud rate to
+ use. Possible values are: 110, 300, 600, 1200, 2400, 4800, 9600,
+ 19200, 38400, 57600 and 115200.
+ If None a default speed of 9600 bps is selected.
+
+ mode: string that specifies RS-232 or RS-485 mode. The RS-485 mode
+ is half duplex and use the RTS signal to indicate the
+ direction of the communication (transmit or recive).
+ Posible values are: '232' or '485'. Default to RS232 mode (the
+ only implemented just now).
+
+ params: list that specifies properties of the serial communication.
+ If params=None it uses default values for the number of bits
+ per byte (8), the parity (NOPARITY) and the number of stop bits (1)
+ else:
+ * In W9X: params must be a list with three items setting up the
+ these values in this order.
+ * In Linux: params must is the termios package mode array to use
+ for initialization.
+
+
+
+* __del__(self):
+
+ Destroy the SerialPort object and close the serial port. It is a good
+ idea that when you finish working with the serial port you explicity
+ do: del tty (where tty is a SerialPort object).
+
+* fileno(self):
+
+ Returns the file descriptor of the serial port. This information is
+ sometimes necessary for example if you want to use the select function.
+
+* read(self, num=1):
+
+ Read num bytes from the serial port. Depending the timeout value used in
+ the inicialitation this operation can be:
+
+ - Blocking (if timeout=None): The operation blocks until num bytes
+ arrive the serial port.
+ - Non-blocking (if timeout=0): The operation returns inmediatelly
+ with as many as num bytes that were waiting in the serial port to be read.
+ - Time-out (if timeout>0): A byte must arrive in less milliseconds than
+ the specified. If the number of read bytes is less than num a
+ SerialPortException is raised because a time-out has happened.
+
+* write(self, s):
+
+ Write the string s to the serial port.
+
+* inWaiting(self):
+
+ Returns the number of bytes waiting to be read.
+
+
+* flush(self):
+
+ Discards all characters from the output or input buffer.
+
+
+
+NOTE ON CHARACTERS AND BYTES
+============================
+
+The write and read methods of the SerialPort class expect data
+in string buffers. Do not think this library only works for
+ASCII communications. To interpret string elements as bytes (integer number)
+you only have to use the built-in ord() function. To convert a byte
+into a string element, use chr().
+
+Example: Suppose you want to transmit the following three bytes:
+0x02, 0x10, 0x30. You only have to do:
+
+packet = ''
+packet = packet + chr(0x02) + chr(0x10) + chr(0x30)
+tty.write(packet)
+
+So, you can see the bytes you send or receive as integers or as characters
+depending the situation.
+
+
+
+"""
+
+
+
+__author__="Isaac Barona Martinez <ibarona@tid.es>"
+
+__copyright__="""
+Copyright (C) 2001 Isaac Barona Martinez <ibarona@tid.es>
+
+This library 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; version 2 dated
+June, 1991.
+"""
+
+__version__="0.1"
+
+
+import sys
+
+if sys.platform=='win32':
+ from SerialPort_win import *
+elif sys.platform=='linux2':
+ from SerialPort_linux import *
+else:
+ sys.exit('Sorry, no implemented for this platform yet')
diff --git a/cesar/maximus/python/lib/proto/uspp/uspp_es.htm b/cesar/maximus/python/lib/proto/uspp/uspp_es.htm
new file mode 100644
index 0000000000..337ee34dc5
--- /dev/null
+++ b/cesar/maximus/python/lib/proto/uspp/uspp_es.htm
@@ -0,0 +1,629 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>ibarona - USPP(Universal Serial Port Python Library)</title>
+
+
+
+
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <style type="text/css">
+ #g_title p, #g_footer p, #g_description p {
+ margin: 0;
+ }
+ /*
+
+ -- -- -- -- -- -- --
+ Browser Fixes
+ -- -- -- -- -- -- --
+
+ This file uses CSS filtering methods to fix various
+ layout bugs.
+
+ Each of the following three imported files is a
+ separate, browser-specific CSS file that keeps all
+ hacks out of the main style sheet.
+
+ Over time, as supporting these browsers no longer
+ remains a priority, cleaning up the hacks is as
+ easy as deleting the @import statement below, or
+ simply no longer linking this file from the HTML.
+
+ */
+
+ /*
+ fix ie6 "peekaboo bug" using the "holly hack".
+ Note, this style only gets applied to ie6
+ */
+ * html .wrapper {
+ height: 0.1%;
+ }
+
+ /*
+ * IE5 mac - overrides the IE/Win hack
+ */
+
+ /*\*//*/
+
+ * html #threecolumn div {
+ height: auto;
+ }
+
+ /**/
+
+
+ /*
+ * IE5/Win-specific CSS -ensures #container wraps all content on window resize
+ */
+
+ @media tty {
+ i{content:"\";/*" "*/}} * html #container { height: 1%; } /*";}
+ }/* */
+ /* Styling for editable elements. Eventually, this will be part of the style. */
+ .editable {
+ border: 1px dashed blue;
+ }
+
+ #footer {
+ clear: both;
+ }
+
+ /* Extra divs hidden by default. The custom CSS can override this though */
+ #extraDiv1, #extraDiv2, #extraDiv3, #extraDiv4, #extraDiv5, #extraDiv6 {
+ display: none;
+ }
+
+ /*
+ -- -- -- -- -- -- --
+ 1 Column Layout
+ -- -- -- -- -- -- --
+ */
+
+ /* Center #container, constrain to 718px width
+ ----------------------------------------------- */
+ body {
+ text-align: center;
+ }
+ #container {
+ width: 718px;
+ text-align: left;
+ margin: 0 auto;
+ }
+
+ #main-content {
+ overflow: hidden;
+ }
+
+ /** BEGIN CUSTOM SKIN **/
+ /*
+
+ -- -- -- -- -- -- --
+ Base CSS
+ -- -- -- -- -- -- --
+
+ This file simply removes default styling on most HTML elements in
+ order to reduce the need to later override them.
+
+ */
+
+ h1,h2,h3,h4,h5,h6,pre,code,p {font-size: 1em;}
+ dl,li,dt,dd,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,fieldset,input {margin: 0; padding: 0;}
+ a img,:link img,:visited img {border: none;}
+ address {font-style: normal;}/*
+
+ -- -- -- -- -- -- --
+ Type Scheme: Deco
+ -- -- -- -- -- -- --
+
+ */
+
+ body {
+ font: 76% Verdana, sans-serif;
+ }
+
+ h1, h2, h3, h4, h5, h6, p.description {
+ font-family: "Trebuchet MS", Trebuchet, sans-serif;
+ }
+ h1 {
+ font-size: 3em;
+ font-weight: bold;
+ letter-spacing: 2px;
+ }
+ h2 {
+ font-size: 2em;
+ font-weight: normal;
+ }
+ h3 {
+ font-size: 1.5em;
+ }
+ h4 {
+ font-size: 1.2em;
+ letter-spacing: 0.2em;
+ }
+ h5 {
+ font-size: 1.2em;
+ }
+ h6 {
+ font-size: 1em;
+ font-weight: bold;
+ }
+
+ p, td {
+ line-height: 1.8em;
+ }
+ code, kbd {
+ font-size: 1.25em;
+ }/*
+
+ -- -- -- -- -- -- --
+ STYLE: Micro
+ -- -- -- -- -- -- --
+
+ */
+
+
+
+
+ /* ie6win */
+
+ /* IE/Win fixes for various layouts
+ ----------------------------------------------- */
+ * html #onecolumn #header {
+ margin-right: -3px;
+ }
+ * html #onecolumn #header,
+ * html #twocolumn-left #header, * html #twocolumn-right #header,
+ * html #twocolumn-liquid-left #header, * html #twocolumn-liquid-right #header {
+ padding-bottom: 1px;
+ }
+ * html #twocolumn-left #main-content, * html #twocolumn-right #main-content {
+ width: 459px;
+ }
+ * html #threecolumn #main-content {
+ width: 409px;
+ }
+
+ /* ie5mac */
+
+ /*\*//*/
+ /* Undoing IE/Win fixes
+ ----------------------------------------------- */
+ * html #onecolumn #header {
+ margin-right: 0;
+ }
+ * html #twocolumn-left #header, * html #twocolumn-right #header,
+ * html #twocolumn-liquid-left #header, * html #twocolumn-liquid-right #header {
+ padding-bottom: 0;
+ }
+ * html #twocolumn-left #main-content, * html #twocolumn-right #main-content {
+ width: 479px;
+ }
+ * html #threecolumn #main-content {
+ width: 429px;
+ }
+ /**/
+
+ @media tty {
+ i{content:"\";/*" "*/}} td { font-size: 0.8em; } /*";}
+ }/* */
+
+
+
+ /* Basic HTML style
+ ----------------------------------------------- */
+ body {
+ font: 76% "Lucida Grande", "Lucida Sans Unicode", Arial, sans-serif;
+ color: #000;
+ background: #fff;
+ margin: 0;
+ padding: 0;
+ }
+ blockquote {
+ margin: 1em 2em;
+ font-style: italic;
+ }
+ caption {
+ font-weight: bold;
+ color: #444;
+ background: #ccc;
+ border-bottom: 0;
+ padding: 0.3em 1em;
+ }
+ dd {
+ margin: 1em 2em;
+ }
+ dl {
+ margin: 2em 0;
+ }
+ dt {
+ font-weight: bold;
+ }
+ hr {
+ margin: 2em 0;
+ color: #C7C7C7;
+ background: #C7C7C7;
+ border-color: #C7C7C7;
+ border-style: none;
+ height: 1px;
+ }
+ li {
+ margin: 1em 0;
+ }
+ table {
+ border: solid 1px #ccc;
+ }
+ td {
+ vertical-align: top;
+ padding: 0.5em;
+ }
+ th {
+ text-align: left;
+ color: #fff;
+ background: #777;
+ padding: 0.5em;
+ }
+ ol, ul {
+ margin: 2em 0;
+ padding-left: 1em;
+ }
+
+
+
+ /* Nested HTML elements, and basic classes
+ ----------------------------------------------- */
+ ol li {
+ list-style-type: decimal;
+ margin-left: 2em;
+ }
+ ul li {
+ margin-left: 2em;
+ list-style-type: square;
+ }
+ td p {
+ margin-top: 0;
+ }
+
+
+
+ /* Set the stage with main layout tweaks
+ ----------------------------------------------- */
+ #container {
+ border: solid 7px #999;
+ border-left: 0;
+ border-right: 0;
+ padding-top: 1px;
+ }
+ #header {
+ color: #04172D;
+ border-top: solid 3px #777;
+ padding: 0;
+ margin: 0 0 1.5em 0;
+ }
+ #main-content .wrapper {
+ margin: 0;
+ }
+ .description {
+ font: normal 1em "Lucida Grande", "Lucida Sans Unicode", Arial, sans-serif;
+ color: #444;
+ background: #C7C7C7;
+ padding: 3px 25px 2.2em 25px;
+ margin: 0;
+ line-height: 1;
+ }
+ #footer {
+ clear: both;
+ color: #999;
+ padding: 0 1em 1em 1em;
+ border-bottom: solid 3px #777;
+ margin-bottom: 1px;
+ }
+
+
+ /* Content area offset
+ ----------------------------------------------- */
+ #main-content .wrapper {
+ padding: 0 25px;
+ }
+
+ #main-content td p {
+ margin: 0 0 1em 0;
+ }
+
+
+
+ /* Custom font definitions
+ ----------------------------------------------- */
+ p {
+ margin: 1em 0;
+ line-height: 1.5;
+ }
+ h1,h2,h3,h4,h5,h6 {
+ font-family: "Trebuchet MS", arial, sans-serif;
+ }
+ h1 {
+ color: #B2B2B2;
+ font-size: 2.4em;
+ letter-spacing: 0.2em;
+ font-weight: normal;
+ padding: 1em 25px 0 25px;
+ }
+ h2 {
+ margin: 0 0 0.5em 0;
+ color: #777;
+ font-size: 1.4em;
+ font-weight: normal;
+ border-bottom: double 3px #C7C7C7;
+ padding: 0 0 0.4em 0;
+ }
+ h3 {
+ font-size: 1.2em;
+ background: #eee;
+ border: dotted 1px #C7C7C7;
+ padding: 0.2em;
+ }
+ h4 {
+ font-size: 1.2em;
+ padding: 0 0 0.2em 0;
+ margin: 0.6em 0 0 0.4em;
+ color: #777;
+ }
+ h5 {
+ border-bottom: dotted 1px #C7C7C7;
+ }
+ h6 {
+ color: #777;
+ border-left: solid 1.2em #777;
+ padding-left: 0.6em;
+ }
+
+ a:link {
+ color: #9db2df;
+ }
+ a:hover {
+ text-decoration: none;
+ border-bottom: 1px dotted #bb242d;
+ background-color: #e0e0e0;
+ }
+
+
+ /* Sidebar
+ ----------------------------------------------- */
+ #sidebar h3, #sidebar-alternate h3 {
+ margin: 0;
+ color: #777;
+ background: none;
+ font-size: 1.4em;
+ font-weight: normal;
+ border: none;
+ padding: 0;
+ }
+
+ #sidebar blockquote, #sidebar blockquote p,
+ #sidebar-alternate blockquote, #sidebar-alternate blockquote p {
+ margin-left: 0;
+ margin-right: 0;
+ }
+ #sidebar blockquote {
+ margin: 1em 0;
+ padding: 0;
+ }
+ #adsense {
+ text-align: center;
+ }
+
+
+
+ .editable {
+ border: dashed 1px #c33;
+ }
+
+
+
+
+ /* Tweaks for Two-column Right layout
+ ----------------------------------------------- */
+ #twocolumn-right #sidebar .wrapper {
+ margin: 0 10px;
+ }
+
+
+
+ /* Tweaks for Two-column Left layout
+ ----------------------------------------------- */
+ #twocolumn-left #sidebar .wrapper {
+ margin: 0 10px;
+ }
+
+
+ /* Tweaks for Three-column layout
+ ----------------------------------------------- */
+ #threecolumn #sidebar .wrapper {
+ margin: 0 10px;
+ }
+ #threecolumn #sidebar-alternate .wrapper {
+ margin: 0 10px;
+ }
+ /*
+
+ -- -- -- -- -- -- --
+ COLOR SCHEME: Blueprint
+ -- -- -- -- -- -- --
+
+ */
+
+
+ /* Basic HTML style
+ ----------------------------------------------- */
+ a:link {
+ color: #445AA9;
+ }
+ a:visited {
+ color: #283D88;
+ }
+ body {
+ color: #283769;
+ background: #ECEEF6;
+ }
+ caption {
+ color: inherit;
+ background: #ECEEF6;
+ }
+ hr {
+ color: #C7C7C7;
+ background: #C7C7C7;
+ border-color: #C7C7C7;
+ }
+ table {
+ background: #fff;
+ border-color: #B3BCDC;
+ }
+ th {
+ color: #fff;
+ background: #445AA9;
+ }
+
+
+
+ /* Set the stage with main layout tweaks
+ ----------------------------------------------- */
+ #container {
+ background-color: #F6F7FB;
+ border-color: #6678B8;
+ }
+ #header {
+ color: #445AA9;
+ border-top-color: #6678B8;
+ }
+ .description {
+ color: #445AA9;
+ background: #C9D0E6;
+ }
+ #footer {
+ color: #5064AE;
+ border-bottom-color: #6678B8;
+ }
+
+
+
+ /* Custom font definitions
+ ----------------------------------------------- */
+ h1 {
+ color: #445AA9;
+ }
+ h2 {
+ color: #5064AE;
+ border-bottom-color: #B3BCDC;
+ }
+ h3 {
+ background: #ECEEF6;
+ border-color: #C9D0E6;
+ }
+ h4 {
+ border-bottom-color: #B3BCDC;
+ color: #1A4292;
+ }
+ h5 {
+ border-bottom-color: #C7C7C7;
+ }
+ h6 {
+ color: #5064AE;
+ border-left-color: #B3BCDC;
+ }
+
+
+
+
+
+ /* Sidebar
+ ----------------------------------------------- */
+ #sidebar h3, #sidebar-alternate h3 {
+ color: #5064AE;
+ background: none;
+ }
+ /** END CUSTOM SKIN **/
+ </style><!-- Hack to avoid flash of unstyled content in IE -->
+
+
+ <script> </script></head><body id="onecolumn">
+ <div id="container">
+ <div class="wrapper">
+ <div id="header">
+ <div class="wrapper">
+ <h1 id="page-title"><div id="g_title">USPP(Universal Serial Port Python Library)</div></h1>
+ <div style="clear: both;"></div>
+ <p class="description"></p><div id="g_description"><p>Isaac Barona (ibarona@gmail.com) <br></p></div>
+ <div style="clear: both;"></div>
+ </div>
+ </div>
+
+ <div id="main-content">
+ <div class="wrapper">
+ <div class="content-item"><div id="g_body"><h2>Introduccion</h2><p>La
+librería USPP es un módulo desarrollado en Python para el acceso
+multiplataforma al puerto serie. En el momento, sólo funciona en Linux,
+Windows y MacOS, pero como está escrita completamente en Python&nbsp;
+(no es únicamente un recubrimiento en Python de una librería
+desarrollada&nbsp; en C/C++) espero que pueda ser ampliada para que
+soporte otras plataformas.<i><br><br></i></p><h2>Motivacion</h2><p>&nbsp;A
+mí me gusta mucho hacer pequeños cacharros electrónicos con
+microcontroladores, especialmente aquellos que pueden ser conectados a
+un ordenador para enviar y recibir datos. Hace un par de meses descubrí
+Python y realmente me encantó. Empezé a jugar con él y ví que podía
+utilizarlo para hacer prototipos de protocolos de comunicación entre el
+ordenador y los microcontroladores&nbsp; de manera mucho más fácil y
+rápida que utilizando C (que era el lenguaje que solía utilizar). Al
+mismo tiempo, estaba interesado en poder utilizar los desarrollos bajo
+diferentes arquitecturas. Empezé a buscar en la red módulos de Python
+que accedieran al puerto serie<br>y encontré los siguientes:<br><br>&nbsp;&nbsp; &nbsp;* win32comport_demo que viene junto a la extensión win32.<br>&nbsp;&nbsp; &nbsp;* Módulo win32comm de wheineman@uconect.net.<br>&nbsp;&nbsp; &nbsp;* Sio Module de Roger Rurnham (rburnham@cri-inc.com)<br>&nbsp;&nbsp; &nbsp;* pyxal (Python X10 Abstraction Layer) de Les Smithson <br>&nbsp;&nbsp; &nbsp;&nbsp; (lsmithson@open-networks.co.uk)<br><br>pero
+no eran multiplataforma, eran únicamente un recubrimiento de una
+librería propietaria o eran simples ejemplos de acceso al puerto serie
+bajo una&nbsp; determinada plataforma.<br>Por estas razones, y también
+por supuesto, por aprender más Python, decidí empezar este proyecto.
+Por supuesto, he utilizado los módulos indicados anteriormente como
+referencia para realizar mi librería y por tanto, me creo en la
+obligación de felicitar a sus autores por su excelente trabajo y por
+haberlo compartido con los demás.<br><br>Espero que disfrutes utilizándo el módulo uspp tanto como yo lo&nbsp; he hecho haciéndolo.</p><h2>Características&nbsp;</h2><p>Este módulo tiene las siguientes características destacadas:<br>&nbsp;</p><ul><li>&nbsp;acceso de alto nivel al puerto serie bajo diversas plataformas.</li><li>autodetecta la plataforma en la que se está ejecutando y carga las clases adecuadas para esa plataforma.</li><li>Orientado a objetos.</li><li>Las operaciones sobre el puerto serie tienen la misma semántica que las operaciones sobre objetos de tipo fichero.</li><li>&nbsp;permite utilizar el puerto serie con diferentes velocidades y características.</li><li>permite
+la utilización del puerto bajo dos modos de funcionamiento: RS-232 y
+RS-485 (de momento, sólo RS-232). En modo 485 la comunicación es
+half-duplex y se utiliza la línea RTS para controlar la dirección de la
+transferencia.</li><li>lecturas en modo bloqueante, no bloqueante o con timeout.</li></ul><h2>Prerequisitos</h2><p>Se necesita los siguiente para utilizar la librería:</p><ul><li>Python 2.1 o superior</li><li>En windows los módulos win32</li></ul><h2>Utilización y documentación<br></h2><p>Únicamente
+tienes que importar en tu programa el módulo uspp y automáticamente él
+se encarga de cargar las clases adecuadas para la plataforma en la que
+se está ejecutando el programa.<br><br>Lo primero de todo, tendrás que
+crear un objeto de tipo SerialPort con las características que desees.
+Si no se genera ninguna excepción del tipo SerialPortException, puedes
+utilizar los métodos de lectura y escritura<br>del objeto para leer y escribir en el puerto serie.<br><br>Ejemplo:</p><pre><tt><tt>&gt;&gt;&gt; from uspp import *<br>&gt;&gt;&gt; tty=SerialPort("COM2", 1000, 9600) <br>&gt;&gt;&gt; # Opens COM2 at 9600 bps and with a read timeout of 1 second.<br>&gt;&gt;&gt; tty.write("a") # Writes a character to the COM2 port<br>&gt;&gt;&gt; # Now suppose we receive the string "abc"<br>&gt;&gt;&gt; tty.inWaiting()<br>3<br>&gt;&gt;&gt; tty.read()<br>'a'<br>&gt;&gt;&gt; tty.inWaiting()<br>2<br>&gt;&gt;&gt; tty.read(2)<br>'bc'</tt></tt></pre><pre><tt><tt>&nbsp;</tt></tt></pre><pre><br></pre><p><font face="arial,sans-serif" size="2">La
+documentación de las diferentes clases y métodos que componen el módulo
+puede encontrarse en el string de documentación del módulo uspp.</font></p><h2>Donde funciona<br></h2><p>La
+librería ha sido probada en una máquina con Windows 95, Windows XP y
+Windows 2000 con Python 2.1+ y en un Linux (con el kernel 2.0.34) con
+Python 2.1+.</p><h2>Portado a otras plataformas<br></h2><p></p><p>&nbsp;Si quieres portar la librería a otras plataformas sólo tienes que seguir los siguientes pasos:</p><ul><li>Crear
+un nuevo fichero en python llamado SerialPort_XXX.py en el que
+implementes las mismas clases y métodos públicos que aparecen en los
+módulos SerialPort_win y SerialPort_linux.</li><li>Añadir la nueva plataforma en el fichero uspp.py.<br></li></ul><h2>&nbsp;Licencia&nbsp;</h2><p>Este
+código se libera bajo la licencia "LGPL" que puedes encontrar en&nbsp;
+http://www.gnu.org/copyleft/lesser.html o en el fichero lesser.txt que
+acompaña a la librería. Si utilizas este software estaría muy
+agradecido de saberlo.&nbsp;</p><h2>Autor</h2><p>Esta librería ha sido creada por Isaac Barona Martínez &lt;ibarona@gmail.com&gt;.</p><h2>Versiones</h2><h3>Versión 1.0 - 24/02/2006&nbsp;</h3><p>Mucho
+tiempo después de la versión 0.1 he tenido el tiempo suficiente de
+liberar la versión definitiva de la librería. Esta versión corrige los
+errores encontrados en la versión anterior, funciona en MacOS y ha sido
+ampliada.</p><p>La libería contiene más funciones en las versiones para Linux y MacOS que para Windows.&nbsp;</p><p>Tengo que agradecer a muchas personas su contribución a esta librería, especialmente a:</p><ul><li>Damien Geranton &lt;dgeranton at voila.fr&gt;&nbsp;</li><li>Douglas Jones &lt;dfj23 at drexel.edu&gt;</li><li>J.Grauheding &lt;juergen.grauheding at a-city.de&gt;</li></ul><p>Puedes descargar los ficheros desde aqui:</p><ul><li>Zip file: uspp-0_1.zip</li><li>tar.gz file: uspp-0_1.tar.gz</li></ul><h3>&nbsp;Version 0.1 - 01/09/2001 (Septiembre 2001)</h3><p>&nbsp;</p><p>&nbsp;</p></div></div>
+ <div style="clear: both;"></div>
+ </div>
+ </div>
+
+ <div id="footer"><div class="wrapper">
+ <hr>
+ <p></p><div id="g_footer">&nbsp;</div>
+ <div style="clear: both;"></div>
+ </div></div>
+
+ </div>
+ </div>
+
+
+<div id="extraDiv1"><span></span></div><div id="extraDiv2"><span></span></div>
+<div id="extraDiv3"><span></span></div><div id="extraDiv4"><span></span></div>
+<div id="extraDiv5"><span></span></div><div id="extraDiv6"><span></span></div>
+
+</body></html> \ No newline at end of file
diff --git a/cesar/maximus/python/lib/script.py b/cesar/maximus/python/lib/script.py
new file mode 100644
index 0000000000..b7bb708405
--- /dev/null
+++ b/cesar/maximus/python/lib/script.py
@@ -0,0 +1,173 @@
+# -*- coding:Utf-8 -*-
+
+#import sys
+#sys.path.append('./test')
+#sys.path.append('../test')
+#import startup
+
+
+# MME SCRIPT EXAMPLE
+
+#from mmentryMethod import *
+from framing import *
+#from binascii import * #binascii library is used : crc32(),
+
+#from fcVfFields import *
+#myFcVfFields = FcVfFields()
+
+#myFcVfFields.createFc_AV(myDt_AV=1)
+
+#print "Create mac frame"
+#myMacFrame = MACFrame()
+
+
+mmentryMethod.createCC_CCO_APPOINT_REQ_MMENTRY(myReqType=0x0, myMacAddress=0x414243444546)
+#mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0, myOda=staAAddress, myOsa=maxAddress)
+rsp1 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCC_ASSOC_REQ_MMENTRY(myReqType=0x0, myNid=0x01020304050607, myCcoCapability=0x02, myProxyNetworkingCapability=0x00)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0, myOda=staAAddress, myOsa=maxAddress)
+rsp2 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCC_ASSOC_CNF_MMENTRY(myResult=0, myNid=0x00010203040506, mySnidAccess=0x09, myStaTei=0x81, myLeaseTime=0x000A)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0, myOda=staAAddress, myOsa=maxAddress)
+rsp3 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_UNASSOCIATED_STA_IND_MMENTRY(myNid=0x070809101112, myCcoCapability=0x01)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0, myOda=staAAddress, myOsa=maxAddress)
+rsp4 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_RSP_MMENTRY(myResult=1, myPid=2, myPrn=0x1234)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0, myOda=staAAddress, myOsa=maxAddress)
+rsp5 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_SET_KEY_REQ_MMENTRY(myKeyType=1, myMyNonce=2, myYourNonce=3, myPid=2, myPrn=5, myPmn=6, myCcoCapability=1, myNid=7, myNewEks=8, myNewKey=9)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0, myOda=staAAddress, myOsa=maxAddress)
+rsp6 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_SET_KEY_CNF_MMENTRY(myResult=9, myMyNonce=8, myYourNonce=7, myPid=6, myPrn=5, myPmn=4, myCcoCapability=9)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0, myOda=staAAddress, myOsa=maxAddress)
+rsp7 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_GET_KEY_REQ_MMENTRY(myRequestType=1, myRequestedKeyType=2, myNid=0x1, myMyNonce=4, myPid=5, myPrn=6, myPmn=7, myHashKey=None)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0, myOda=staAAddress, myOsa=maxAddress)
+rsp8 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_GET_KEY_REQ_MMENTRY(myRequestType=1, myRequestedKeyType=4, myNid=3, myMyNonce=4, myPid=5, myPrn=6, myPmn=7, myHashKey=None)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0, myOda=staAAddress, myOsa=maxAddress)
+rsp9 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_GET_KEY_CNF_MMENTRY(myResult=1, myRequestedKeyType=5, myMyNonce=2, myYourNonce=3, myNid=0x11121314151617, myEks=0x04, myPid=0, myPrn=0, myPmn=0, myKey=0x4142434445464748494A4B4C4D4E4F50)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0x0, myOda=staAAddress, myOsa=maxAddress)
+rsp0 = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_GET_KEY_CNF_MMENTRY(myResult=0, myRequestedKeyType=4, myMyNonce=1, myYourNonce=3, myNid=4, myEks=0x0f, myPid=5, myPrn=7, myPmn=6, myKey=0x31323334353637384847464544434241, myHashKey=None)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0x0f, myOda=staAAddress, myOsa=maxAddress)
+rspa = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_MME_ERROR_IND_MMENTRY(myReasonCode=1, myRx_MMV=2, myRx_MMTYPE=4, myInvalidByteOffset=5)
+#mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0x0f, myOda=staAAddress, myOsa=maxAddress)
+rspb = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCC_SET_TEI_MAP_IND_MMENTRY(myMode=1, myNum=0xff, myTei=0x10, myAddr=0x123400, myStatus=2)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0x0f, myOda=staAAddress, myOsa=maxAddress)
+rspc = myMacFields.createMacFrame()
+
+
+mmentryMethod.createCM_SC_JOIN_REQ_MMENTRY(myCcoCapability=0x00)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myPeks=0x0f, myOda=staAAddress, myOsa=maxAddress)
+rspd = myMacFields.createMacFrame()
+
+
+
+
+
+#INTERPRETATION
+
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp1[6:])
+#mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+#mmentryMethod.createCC_CCO_APPOINT_REQ_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+mmentryMethod.createCC_CCO_APPOINT_REQ_MMENTRY(myMmentry=mmEntryData)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp2[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+mmentryMethod.createCC_ASSOC_REQ_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp3[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+mmentryMethod.createCC_ASSOC_CNF_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp4[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+mmentryMethod.createCM_UNASSOCIATED_STA_IND_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp5[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_RSP_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp6[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+mmentryMethod.createCM_SET_KEY_REQ_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp7[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+mmentryMethod.createCM_SET_KEY_CNF_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp8[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+mmentryMethod.createCM_GET_KEY_REQ_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp9[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+mmentryMethod.createCM_GET_KEY_REQ_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rsp0[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x4142434445464748494A4B4C4D4E4F50, myEncryptedFields=mmEntryData)
+mmentryMethod.createCM_GET_KEY_CNF_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rspa[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x31323334353637384847464544434241, myEncryptedFields=mmEntryData)
+mmentryMethod.createCM_GET_KEY_CNF_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rspb[6:])
+#mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x31323334353637384847464544434241, myEncryptedFields=mmEntryData)
+#mmentryMethod.createCM_MME_ERROR_IND_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+mmentryMethod.createCM_MME_ERROR_IND_MMENTRY(myMmentry=mmEntryData)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rspc[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x31323334353637384847464544434241, myEncryptedFields=mmEntryData)
+mmentryMethod.createCC_SET_TEI_MAP_IND_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+mmEntryData = myEncapsulatedMme.createEncapsulatedMmEntry(myEncapsulatedMmEntry=rspd[6:])
+mmentryMethod.createCM_ENCRYPTED_PAYLOAD_IND_MMENTRY(myKey=0x31323334353637384847464544434241, myEncryptedFields=mmEntryData)
+mmentryMethod.createCM_SC_JOIN_REQ_MMENTRY(myMmentry=mmentryMethod.mmentryFields.mmOrHlePayloadEncryptedField)
+
+
+print "----- My Ended Coucou -----"
+
+myStaA.remove()
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cesar/maximus/python/lib/station/test_tx_rx.elf b/cesar/maximus/python/lib/station/test_tx_rx.elf
new file mode 100755
index 0000000000..11b8cdc58f
--- /dev/null
+++ b/cesar/maximus/python/lib/station/test_tx_rx.elf
Binary files differ
diff --git a/cesar/maximus/python/maximus/__init__.py b/cesar/maximus/python/maximus/__init__.py
new file mode 100644
index 0000000000..fffd7b6d7a
--- /dev/null
+++ b/cesar/maximus/python/maximus/__init__.py
@@ -0,0 +1,16 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = ["channel", "cli", "ethernet", "fsm", "macframe", "mme", "result", "simu", "station", "utils"]
+
+from channel import *
+from cli import *
+from ethernet import *
+from fsm import *
+from macframe import *
+from mme import *
+from result import *
+from simu import *
+from station import *
+from utils import *
diff --git a/cesar/maximus/python/maximus/channel/__init__.py b/cesar/maximus/python/maximus/channel/__init__.py
new file mode 100644
index 0000000000..c7fbe1e2ad
--- /dev/null
+++ b/cesar/maximus/python/maximus/channel/__init__.py
@@ -0,0 +1,7 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = ["snr"]
+
+from snr import set_snr
diff --git a/cesar/maximus/python/maximus/channel/snr.py b/cesar/maximus/python/maximus/channel/snr.py
new file mode 100644
index 0000000000..4df7672c65
--- /dev/null
+++ b/cesar/maximus/python/maximus/channel/snr.py
@@ -0,0 +1,52 @@
+#! usr/bin/env python
+
+#print __name__
+
+def set_snr(maximus, value=16, file=None, src=None, dst=None, both_directions=False):
+ """Set the SNR.
+ If calling this function without arguments,
+ by default the SNR is set to 16 dB for all transmissions.
+ Non-optional argument:
+ maximus - the Maximus object, already initialized
+ Optional arguments:
+ value - the SNR value in dB
+ file - the SNR description file complete path and name
+ src - the transmitting station
+ dst - the destination station
+ both_directions - a boolean specifying if the SNR is the same in both directions (from src to dst and from dst to src)
+ """
+
+ # Source and destination stations can be Python STA objects or C++ Sta objects.
+ # In case of Python STA objects,
+ # the C++ Sta object has to be extracted using the get() method of the STA class.
+ try:
+ src = src.get()
+ except:
+ pass
+ try:
+ dst = dst.get()
+ except:
+ pass
+
+ # SNR can be set via a value in dB or via a description file.
+ if file is None:
+ snr = value
+ else:
+ snr = file
+
+ # Depending on function arguments, call the appropriate Maximus interface function:
+ # set_snr()
+ # set_snr_from_src()
+ # set_snr_to_dst()
+ # set_snr_from_src_to_dst()
+
+ if src is None:
+ if dst is None:
+ maximus.set_snr(snr)
+ else:
+ maximus.set_snr_to_dst(snr, dst, both_directions)
+ else:
+ if dst is None:
+ maximus.set_snr_from_src(snr, src, both_directions)
+ else:
+ maximus.set_snr_from_src_to_dst(snr, src, dst, both_directions)
diff --git a/cesar/maximus/python/maximus/cli/__init__.py b/cesar/maximus/python/maximus/cli/__init__.py
new file mode 100644
index 0000000000..730e8c685d
--- /dev/null
+++ b/cesar/maximus/python/maximus/cli/__init__.py
@@ -0,0 +1,5 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = []
diff --git a/cesar/maximus/python/maximus/ethernet/__init__.py b/cesar/maximus/python/maximus/ethernet/__init__.py
new file mode 100644
index 0000000000..fa21730e37
--- /dev/null
+++ b/cesar/maximus/python/maximus/ethernet/__init__.py
@@ -0,0 +1,10 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = ["buffer", "create", "eth", "scapy"]
+
+from buffer import alloc_data_buffer, alloc_mme_buffer, alloc_interface_buffer, realloc_buffer, get_buffer_dict
+from eth import Eth
+from scapy import *
+from maximus.macframe.msdu import MSDU_TYPES
diff --git a/cesar/maximus/python/maximus/ethernet/buffer.py b/cesar/maximus/python/maximus/ethernet/buffer.py
new file mode 100644
index 0000000000..a00b4c39e9
--- /dev/null
+++ b/cesar/maximus/python/maximus/ethernet/buffer.py
@@ -0,0 +1,189 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.macframe.msdu import MSDU_TYPES, MSDU
+from maximus.utils.exception import Error, OutOfRangeError
+from maximus.utils.format import *
+
+# Constants to check arguments validity
+MAX_VALUE_OF_BUFFER_NB = MAX_VALUE_OF_U32
+SIZE_OF_BUFFER_ID = SIZE_OF_U32
+
+class Buffer(MSDU):
+ """The Buffer object is composed of the 6 following fields:
+ buffer_id - the current buffer ID
+ buffer_dict - the list of current allocated buffers (ID and type)
+ buffer_realloc - indicates if buffer reallocation is automatic
+ maximus - the Maximus object
+ type - type of buffer
+ buffer_nb - number of buffers to allocate
+ """
+ # Static attributes of the class
+ buffer_id = 0
+ buffer_dict = {}
+ buffer_realloc = True
+ __maximus = None
+
+ def __init__(self, type, buffer_nb=1, maximus=None):
+ """Initialize the Buffer with following attributes:
+ type - a Python string
+ buffer_nb - a Python integer
+ maximus - the Maximus object
+ """
+ self.set_type(type)
+ self.set_buffer_nb(buffer_nb)
+ self.__set_maximus(maximus)
+
+ def set_type(self, type):
+ """This function sets the Buffer object type.
+ The Buffer type can be a Python integer (u8)
+ or a Python string equals to 'ETHERNET_TYPE_DATA_BUFFER_ADD',
+ 'ETHERNET_TYPE_MME_BUFFER_ADD',
+ 'ETHERNET_TYPE_INTERFACE_BUFFER_ADD',
+ or 'ETHERNET_TYPE_BUFFER_RELEASED'.
+ """
+ self.__type = 0
+ for i, j in enumerate(MSDU_TYPES):
+ if type == i or type == j:
+ self.__type = i
+ if self.__type is None:
+ raise OutOfRangeError("Buffer type")
+
+ def set_buffer_nb(self, buffer_nb):
+ """This function sets the number of buffers to allocate.
+ The number of buffers must be a Python integer (u32).
+ """
+ self.__buffer_nb = 0
+ if type(buffer_nb) is not int or buffer_nb <= 0 or buffer_nb > MAX_VALUE_OF_BUFFER_NB:
+ raise OutOfRangeError("Number of buffers")
+ else:
+ self.__buffer_nb = buffer_nb
+
+ def set_buffer_realloc(self, auto):
+ """This function enables or disables the automatic buffer allocation.
+ Auto must be a Python boolean.
+ """
+ if type(auto) is not bool:
+ raise TypeError("Auto")
+ else:
+ self.__class__.buffer_realloc = auto
+
+ def __set_maximus(self, maximus):
+ """This function sets the Maximus object.
+ """
+ if maximus is not None and self.__class__.__maximus is None:
+ self.__class__.__maximus = maximus
+
+ def __inc_buffer_id(self):
+ """This function increments the buffer ID (static attribute of the class).
+ """
+ self.__class__.buffer_id += 1
+
+ def __add_buffer(self, id, type):
+ """This function adds a buffer into the buffer dictionary (static attribute of the class).
+ """
+ self.__class__.buffer_dict[id] = type
+
+ def __remove_buffer(self, id):
+ """This function removes a buffer from the buffer dictionary (static attribute of the class).
+ """
+ del self.__class__.buffer_dict[id]
+
+ def realloc(self, station_id, payload):
+ """If requested by user, this function allocates a new buffer to replace released buffer.
+ """
+ from maximus.simu.rx import recv
+ if self.get_buffer_realloc():
+ if len(payload) != SIZE_OF_BUFFER_ID:
+ raise Error('Buffer ID length')
+ else:
+ buffer = Buffer(type=self.__class__.buffer_dict[hptoh32(payload)], maximus=self.__get_maximus())
+ # Request to Maximus to send the MSDU asynchronously
+ while not self.__get_maximus().is_station_idle(station_id):
+ self.__get_maximus().process()
+ self.__get_maximus().send_msdu(buffer, station_id)
+
+ def set_msdu_attr(self, payload):
+ """This function sets the MSDU attributes from the received Ethernet Frame.
+ """
+ if len(payload) != SIZE_OF_BUFFER_ID:
+ raise Error('Buffer ID length')
+ else:
+ self.__remove_buffer(hptoh32(payload))
+
+ def get(self):
+ """This function returns the Buffer object into a string composed of the 2 following fields:
+ number of buffers to allocate (u32)
+ ID of each buffer to allocate (u32)
+ """
+ buffer = htohp32(self.get_buffer_nb())
+ for n in range(0, self.get_buffer_nb()):
+ self.__inc_buffer_id()
+ buffer += htohp32(self.get_buffer_id())
+ for i, j in enumerate(MSDU_TYPES):
+ if self.get_ether_type() == i:
+ self.__add_buffer(self.get_buffer_id(), j)
+ return buffer
+
+ def get_ether_type(self):
+ """This function returns the Buffer object type into a Python integer (u8).
+ """
+ return self.__type # 3, 4, 5 or 6
+
+ def get_type(self):
+ """This function returns the Buffer object type into a Python string.
+ """
+ return MSDU_TYPES[self.get_ether_type()] # 'ETHERNET_TYPE_DATA_BUFFER_ADD',
+ # 'ETHERNET_TYPE_MME_BUFFER_ADD',
+ # 'ETHERNET_TYPE_INTERFACE_BUFFER_ADD',
+ # or 'ETHERNET_TYPE_BUFFER_RELEASED'
+
+ def get_buffer_nb(self):
+ """This function gets the number of buffers to allocate.
+ The number of buffers is a Python integer (u32).
+ """
+ return self.__buffer_nb
+
+ def get_buffer_id(self):
+ """This function returns the current buffer ID.
+ """
+ return self.__class__.buffer_id
+
+ def get_buffer_dict(self):
+ """This function returns the current buffer dictionary.
+ """
+ return self.__class__.buffer_dict
+
+ def get_buffer_realloc(self):
+ """This function gets if the current buffer reallocation is enabled or disabled.
+ """
+ return self.__class__.buffer_realloc
+
+ def __get_maximus(self):
+ """This function gets the Maximus object.
+ """
+ if self.__class__.__maximus is None:
+ raise Error("Maximus object not set")
+ return self.__class__.__maximus
+
+
+def alloc_data_buffer(maximus, station, buffer_nb=1):
+ buffer = Buffer(type='ETHERNET_TYPE_DATA_BUFFER_ADD', buffer_nb=buffer_nb, maximus=maximus)
+ buffer.sendnrecv(maximus, station, count=0) # recv(maximus, count=0) to set creation functions
+
+def alloc_mme_buffer(maximus, station, buffer_nb=1):
+ buffer = Buffer(type='ETHERNET_TYPE_MME_BUFFER_ADD', buffer_nb=buffer_nb, maximus=maximus)
+ buffer.sendnrecv(maximus, station, count=0) # recv(maximus, count=0) to set creation functions
+
+def alloc_interface_buffer(maximus, station, buffer_nb=1):
+ buffer = Buffer(type='ETHERNET_TYPE_INTERFACE_BUFFER_ADD', buffer_nb=buffer_nb, maximus=maximus)
+ buffer.sendnrecv(maximus, station, count=0) # recv(maximus, count=0) to set creation functions
+
+def realloc_buffer(auto):
+ buffer = Buffer('ETHERNET_TYPE_NONE')
+ buffer.set_buffer_realloc(auto)
+
+def get_buffer_dict():
+ buffer = Buffer('ETHERNET_TYPE_NONE')
+ return buffer.get_buffer_dict()
diff --git a/cesar/maximus/python/maximus/ethernet/create.py b/cesar/maximus/python/maximus/ethernet/create.py
new file mode 100644
index 0000000000..09c16d9152
--- /dev/null
+++ b/cesar/maximus/python/maximus/ethernet/create.py
@@ -0,0 +1,22 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.ethernet.buffer import Buffer
+from maximus.ethernet.eth import Eth
+from maximus.ethernet.sniffer import Sniffer
+
+def create_eth():
+ """This function creates and returns a new Eth object.
+ """
+ return Eth()
+
+def create_buffer():
+ """This function creates and returns a new Buffer object.
+ """
+ return Buffer('ETHERNET_TYPE_BUFFER_RELEASED')
+
+def create_sniffer(way, encryption, sniffer_type):
+ """This function creates and returns a new Sniffer object.
+ """
+ return Sniffer(way, encryption, sniffer_type)
diff --git a/cesar/maximus/python/maximus/ethernet/eth.py b/cesar/maximus/python/maximus/ethernet/eth.py
new file mode 100644
index 0000000000..5b06f64f26
--- /dev/null
+++ b/cesar/maximus/python/maximus/ethernet/eth.py
@@ -0,0 +1,109 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.ethernet.scapy import *
+from maximus.macframe.msdu import MIN_SIZE_OF_MSDU, MSDU_TYPES, MSDU
+from maximus.utils.exception import Error, OutOfRangeError
+from maximus.utils.format import *
+from struct import pack, unpack
+
+# Constants to check arguments validity
+SIZE_OF_DST = SIZE_OF_U48 # in octets
+SIZE_OF_SRC = SIZE_OF_DST # in octets
+SIZE_OF_VLANTAG = SIZE_OF_U32 # in octets
+MIN_VALUE_OF_VLANTAG = 0x81000000
+MAX_VALUE_OF_VLANTAG = 0x8100FFFF
+SIZE_OF_TYPE = SIZE_OF_U16 # in octets
+MIN_SIZE_OF_HEADER = SIZE_OF_DST + SIZE_OF_SRC + SIZE_OF_TYPE # in octets
+MAX_SIZE_OF_HEADER = MIN_SIZE_OF_HEADER + SIZE_OF_VLANTAG # in octets
+
+#class VLANTag(Field):
+# def __init__(self, name):
+# Field.__init__(self, name, 0x00000000, 'I')
+
+class Eth(MSDU, Packet):
+ name = "Eth"
+ aliastypes = [ Ether ]
+ #fields_desc = [DestMACField("dst"), SourceMACField("src"), VLANTag("vlantag"), XShortEnumField("type", 0x0000, ETHER_TYPES)]
+ fields_desc = [DestMACField("dst"), SourceMACField("src"), XShortEnumField("type", 0x0000, ETHER_TYPES)]
+
+ def set_msdu_attr(self, payload):
+ """Set the Eth attributes from the received Ethernet Frame.
+ """
+ if len(payload) < MIN_SIZE_OF_HEADER:
+ raise Error('Ethernet Frame length')
+
+ # Set Eth Header: dst, src, vlantag (optional), type
+ #
+
+ # Set dst
+ begin = 0
+ end = SIZE_OF_DST
+ address = hex(ntoh48(payload[begin:end])).strip('0x').strip('L')
+ dst = ''
+ for i in range (0, len(address), 2):
+ dst += address[i:i+2]
+ if i < len(address)-2:
+ dst += ':'
+ self.dst = dst.lower()
+
+ # Set src
+ begin = end
+ end += SIZE_OF_SRC
+ address = hex(ntoh48(payload[begin:end])).strip('0x').strip('L')
+ src = ''
+ for i in range (0, len(address), 2):
+ src += address[i:i+2]
+ if i < len(address)-2:
+ src += ':'
+ self.src = src.lower()
+
+ # Check vlantag
+ begin = end
+ if ntoh32(payload[begin:end + SIZE_OF_VLANTAG]) <= MAX_VALUE_OF_VLANTAG\
+ and ntoh32(payload[begin:end + SIZE_OF_VLANTAG]) >= MIN_VALUE_OF_VLANTAG:
+ # Set vlantag
+ end += SIZE_OF_VLANTAG
+ self.vlantag = ntoh32(payload[begin:end])
+
+ # Set type
+ begin = end
+ end += SIZE_OF_TYPE
+ self.type = ntoh16(payload[begin:end])
+
+ # Set Eth Payload
+ self.payload = payload[end:]
+
+ def get(self):
+ """This function returns the Ethernet frame into a string.
+ """
+ eth = str(self)
+
+ # Check vlantag
+ try:
+ if type(self.vlantag) is int or type(self.vlantag) is long:
+ if self.vlantag <= MAX_VALUE_OF_VLANTAG and self.vlantag >= MIN_VALUE_OF_VLANTAG:
+ eth = eth[:SIZE_OF_DST + SIZE_OF_SRC] + hton32(self.vlantag) + eth[SIZE_OF_DST + SIZE_OF_SRC:]
+ else:
+ raise OutOfRangeError("vlantag")
+ else:
+ raise TypeError("vlantag")
+ except AttributeError:
+ pass
+
+ return eth + self.pad(MIN_SIZE_OF_MSDU - len(eth))
+
+ def get_ether_type(self):
+ """This function returns the Ethernet Frame object type into a Python integer (uint8_t).
+ """
+ type = 0
+ for i, j in enumerate(MSDU_TYPES):
+ if j == self.get_type():
+ type = i
+ return type # 1
+
+ def get_type(self):
+ """This function returns the Ethernet Frame object type into a Python string.
+ """
+ return MSDU_TYPES[1] # 'ETHERNET_TYPE_DATA'
diff --git a/cesar/maximus/python/maximus/ethernet/scapy.py b/cesar/maximus/python/maximus/ethernet/scapy.py
new file mode 100644
index 0000000000..5c1641fde7
--- /dev/null
+++ b/cesar/maximus/python/maximus/ethernet/scapy.py
@@ -0,0 +1,13244 @@
+#! /usr/bin/env python
+
+#############################################################################
+## ##
+## scapy.py --- Interactive packet manipulation tool ##
+## see http://www.secdev.org/projects/scapy/ ##
+## for more informations ##
+## ##
+## Copyright (C) 2003 Philippe Biondi <phil@secdev.org> ##
+## ##
+## 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; version 2. ##
+## ##
+## 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. ##
+## ##
+#############################################################################
+
+
+from __future__ import generators
+import os
+
+BASE_VERSION = "1.1.1"
+
+HG_NODE = "$Node$"
+REVISION = "$Revision$"
+
+VERSION = "v%s / %s" % (BASE_VERSION, (REVISION+"--")[11:23])
+
+DEFAULT_CONFIG_FILE = os.path.join(os.environ["HOME"], ".scapy_startup.py")
+
+try:
+ os.stat(DEFAULT_CONFIG_FILE)
+except OSError:
+ DEFAULT_CONFIG_FILE = None
+
+def usage():
+ print """Usage: scapy.py [-s sessionfile] [-c new_startup_file] [-C]
+ -C: do not read startup file"""
+ sys.exit(0)
+
+
+#############################
+##### Logging subsystem #####
+#############################
+
+class Scapy_Exception(Exception):
+ pass
+
+import logging,traceback,time
+
+class ScapyFreqFilter(logging.Filter):
+ def __init__(self):
+ logging.Filter.__init__(self)
+ self.warning_table = {}
+ def filter(self, record):
+ wt = conf.warning_threshold
+ if wt > 0:
+ stk = traceback.extract_stack()
+ caller=None
+ for f,l,n,c in stk:
+ if n == 'warning':
+ break
+ caller = l
+ tm,nb = self.warning_table.get(caller, (0,0))
+ ltm = time.time()
+ if ltm-tm > wt:
+ tm = ltm
+ nb = 0
+ else:
+ if nb < 2:
+ nb += 1
+ if nb == 2:
+ record.msg = "more "+record.msg
+ else:
+ return 0
+ self.warning_table[caller] = (tm,nb)
+ return 1
+
+log_scapy = logging.getLogger("scapy")
+console_handler = logging.StreamHandler()
+console_handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
+log_scapy.addHandler(console_handler)
+log_runtime = logging.getLogger("scapy.runtime") # logs at runtime
+log_runtime.addFilter(ScapyFreqFilter())
+log_interactive = logging.getLogger("scapy.interactive") # logs in interactive functions
+log_loading = logging.getLogger("scapy.loading") # logs when loading scapy
+
+if __name__ == "__main__":
+ log_scapy.setLevel(1)
+
+
+##################
+##### Module #####
+##################
+
+import socket, sys, getopt, string, struct, random, code
+import cPickle, copy, types, gzip, base64, re, zlib, array
+from sets import Set
+from select import select
+from glob import glob
+from fcntl import ioctl
+import itertools
+import fcntl
+import warnings
+warnings.filterwarnings("ignore","tempnam",RuntimeWarning, __name__)
+
+
+try:
+ import Gnuplot
+ GNUPLOT=1
+except ImportError:
+ log_loading.info("did not find python gnuplot wrapper . Won't be able to plot")
+ GNUPLOT=0
+
+try:
+ import pyx
+ PYX=1
+except ImportError:
+ log_loading.info("Can't import PyX. Won't be able to use psdump() or pdfdump()")
+ PYX=0
+
+
+LINUX=sys.platform.startswith("linux")
+OPENBSD=sys.platform.startswith("openbsd")
+FREEBSD=sys.platform.startswith("freebsd")
+DARWIN=sys.platform.startswith("darwin")
+BIG_ENDIAN= struct.pack("H",1) == "\x00\x01"
+X86_64 = (os.uname()[4] == 'x86_64')
+SOLARIS=sys.platform.startswith("sunos")
+
+
+if LINUX:
+ DNET=PCAP=0
+else:
+ DNET=PCAP=1
+
+
+if PCAP:
+ try:
+ import pcap
+ PCAP = 1
+ except ImportError:
+ if LINUX:
+ log_loading.warning("did not find pcap module. Fallback to linux primitives")
+ PCAP = 0
+ else:
+ if __name__ == "__main__":
+ log_loading.error("did not find pcap module")
+ raise SystemExit
+ else:
+ raise
+
+if DNET:
+ try:
+ import dnet
+ DNET = 1
+ except ImportError:
+ if LINUX:
+ log_loading.warning("did not find dnet module. Fallback to linux primitives")
+ DNET = 0
+ else:
+ if __name__ == "__main__":
+ log_loading.error("did not find dnet module")
+ raise SystemExit
+ else:
+ raise
+
+if not PCAP:
+ f = os.popen("tcpdump -V 2> /dev/null")
+ if f.close() >> 8 == 0x7f:
+ log_loading.warning("Failed to execute tcpdump. Check it is installed and in the PATH")
+ TCPDUMP=0
+ else:
+ TCPDUMP=1
+ del(f)
+
+
+
+try:
+ from Crypto.Cipher import ARC4
+except ImportError:
+ log_loading.info("Can't find Crypto python lib. Won't be able to decrypt WEP")
+
+
+# Workarround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470
+try:
+ socket.inet_aton("255.255.255.255")
+except socket.error:
+ def inet_aton(x):
+ if x == "255.255.255.255":
+ return "\xff"*4
+ else:
+ return socket.inet_aton(x)
+else:
+ inet_aton = socket.inet_aton
+
+inet_ntoa = socket.inet_ntoa
+try:
+ inet_ntop = socket.inet_ntop
+ inet_pton = socket.inet_pton
+except AttributeError:
+ log_loading.info("inet_ntop/pton functions not found. Python IPv6 support not present")
+
+
+if SOLARIS:
+ # GRE is missing on Solaris
+ socket.IPPROTO_GRE = 47
+
+###############################
+## Direct Access dictionnary ##
+###############################
+
+def fixname(x):
+ if x and x[0] in "0123456789":
+ x = "n_"+x
+ return x.translate("________________________________________________0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______abcdefghijklmnopqrstuvwxyz_____________________________________________________________________________________________________________________________________")
+
+
+class DADict_Exception(Scapy_Exception):
+ pass
+
+class DADict:
+ def __init__(self, _name="DADict", **kargs):
+ self._name=_name
+ self.__dict__.update(kargs)
+ def fixname(self,val):
+ return fixname(val)
+ def __contains__(self, val):
+ return val in self.__dict__
+ def __getitem__(self, attr):
+ return getattr(self, attr)
+ def __setitem__(self, attr, val):
+ return setattr(self, self.fixname(attr), val)
+ def __iter__(self):
+ return iter(map(lambda (x,y):y,filter(lambda (x,y):x and x[0]!="_", self.__dict__.items())))
+ def _show(self):
+ for k in self.__dict__.keys():
+ if k and k[0] != "_":
+ print "%10s = %r" % (k,getattr(self,k))
+ def __repr__(self):
+ return "<%s/ %s>" % (self._name," ".join(filter(lambda x:x and x[0]!="_",self.__dict__.keys())))
+
+ def _branch(self, br, uniq=0):
+ if uniq and br._name in self:
+ raise DADict_Exception("DADict: [%s] already branched in [%s]" % (br._name, self._name))
+ self[br._name] = br
+
+ def _my_find(self, *args, **kargs):
+ if args and self._name not in args:
+ return False
+ for k in kargs:
+ if k not in self or self[k] != kargs[k]:
+ return False
+ return True
+
+ def _find(self, *args, **kargs):
+ return self._recurs_find((), *args, **kargs)
+ def _recurs_find(self, path, *args, **kargs):
+ if self in path:
+ return None
+ if self._my_find(*args, **kargs):
+ return self
+ for o in self:
+ if isinstance(o, DADict):
+ p = o._recurs_find(path+(self,), *args, **kargs)
+ if p is not None:
+ return p
+ return None
+ def _find_all(self, *args, **kargs):
+ return self._recurs_find_all((), *args, **kargs)
+ def _recurs_find_all(self, path, *args, **kargs):
+ r = []
+ if self in path:
+ return r
+ if self._my_find(*args, **kargs):
+ r.append(self)
+ for o in self:
+ if isinstance(o, DADict):
+ p = o._recurs_find_all(path+(self,), *args, **kargs)
+ r += p
+ return r
+ def keys(self):
+ return filter(lambda x:x and x[0]!="_", self.__dict__.keys())
+
+
+
+############
+## Consts ##
+############
+
+ETHER_ANY = "\x00"*6
+ETHER_BROADCAST = "\xff"*6
+
+ETH_P_ALL = 3
+ETH_P_IP = 0x800
+ETH_P_ARP = 0x806
+
+# From net/if_arp.h
+ARPHDR_ETHER = 1
+ARPHDR_METRICOM = 23
+ARPHDR_PPP = 512
+ARPHDR_LOOPBACK = 772
+ARPHDR_TUN = 65534
+
+# From bits/ioctls.h
+SIOCGIFHWADDR = 0x8927 # Get hardware address
+SIOCGIFADDR = 0x8915 # get PA address
+SIOCGIFNETMASK = 0x891b # get network PA mask
+SIOCGIFNAME = 0x8910 # get iface name
+SIOCSIFLINK = 0x8911 # set iface channel
+SIOCGIFCONF = 0x8912 # get iface list
+SIOCGIFFLAGS = 0x8913 # get flags
+SIOCSIFFLAGS = 0x8914 # set flags
+SIOCGIFINDEX = 0x8933 # name -> if_index mapping
+SIOCGIFCOUNT = 0x8938 # get number of devices
+
+
+# From if.h
+IFF_UP = 0x1 # Interface is up.
+IFF_BROADCAST = 0x2 # Broadcast address valid.
+IFF_DEBUG = 0x4 # Turn on debugging.
+IFF_LOOPBACK = 0x8 # Is a loopback net.
+IFF_POINTOPOINT = 0x10 # Interface is point-to-point link.
+IFF_NOTRAILERS = 0x20 # Avoid use of trailers.
+IFF_RUNNING = 0x40 # Resources allocated.
+IFF_NOARP = 0x80 # No address resolution protocol.
+IFF_PROMISC = 0x100 # Receive all packets.
+
+
+
+# From netpacket/packet.h
+PACKET_ADD_MEMBERSHIP = 1
+PACKET_DROP_MEMBERSHIP = 2
+PACKET_RECV_OUTPUT = 3
+PACKET_RX_RING = 5
+PACKET_STATISTICS = 6
+PACKET_MR_MULTICAST = 0
+PACKET_MR_PROMISC = 1
+PACKET_MR_ALLMULTI = 2
+
+
+# From bits/socket.h
+SOL_PACKET = 263
+# From asm/socket.h
+SO_ATTACH_FILTER = 26
+SOL_SOCKET = 1
+
+# From net/route.h
+RTF_UP = 0x0001 # Route usable
+RTF_REJECT = 0x0200
+
+# From BSD net/bpf.h
+#BIOCIMMEDIATE=0x80044270
+BIOCIMMEDIATE=-2147204496
+
+MTU = 1600
+
+
+# file parsing to get some values :
+
+def load_protocols(filename):
+ spaces = re.compile("[ \t]+|\n")
+ dct = DADict(_name=filename)
+ try:
+ for l in open(filename):
+ try:
+ shrp = l.find("#")
+ if shrp >= 0:
+ l = l[:shrp]
+ l = l.strip()
+ if not l:
+ continue
+ lt = tuple(re.split(spaces, l))
+ if len(lt) < 2 or not lt[0]:
+ continue
+ dct[lt[0]] = int(lt[1])
+ except Exception,e:
+ log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e))
+ except IOError:
+ log_loading.info("Can't open /etc/protocols file")
+ return dct
+
+IP_PROTOS=load_protocols("/etc/protocols")
+
+def load_ethertypes(filename):
+ spaces = re.compile("[ \t]+|\n")
+ dct = DADict(_name=filename)
+ try:
+ f=open(filename)
+ for l in f:
+ try:
+ shrp = l.find("#")
+ if shrp >= 0:
+ l = l[:shrp]
+ l = l.strip()
+ if not l:
+ continue
+ lt = tuple(re.split(spaces, l))
+ if len(lt) < 2 or not lt[0]:
+ continue
+ dct[lt[0]] = int(lt[1], 16)
+ except Exception,e:
+ log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e))
+ f.close()
+ except IOError,msg:
+ pass
+ return dct
+
+ETHER_TYPES=load_ethertypes("/etc/ethertypes")
+
+def load_services(filename):
+ spaces = re.compile("[ \t]+|\n")
+ tdct=DADict(_name="%s-tcp"%filename)
+ udct=DADict(_name="%s-udp"%filename)
+ try:
+ f=open(filename)
+ for l in f:
+ try:
+ shrp = l.find("#")
+ if shrp >= 0:
+ l = l[:shrp]
+ l = l.strip()
+ if not l:
+ continue
+ lt = tuple(re.split(spaces, l))
+ if len(lt) < 2 or not lt[0]:
+ continue
+ if lt[1].endswith("/tcp"):
+ tdct[lt[0]] = int(lt[1].split('/')[0])
+ elif lt[1].endswith("/udp"):
+ udct[lt[0]] = int(lt[1].split('/')[0])
+ except Exception,e:
+ log_loading.warning("Couldn't file [%s]: line [%r] (%s)" % (filename,l,e))
+ f.close()
+ except IOError:
+ log_loading.info("Can't open /etc/services file")
+ return tdct,udct
+
+TCP_SERVICES,UDP_SERVICES=load_services("/etc/services")
+
+class ManufDA(DADict):
+ def fixname(self, val):
+ return val
+ def _get_manuf_couple(self, mac):
+ oui = ":".join(mac.split(":")[:3]).upper()
+ return self.__dict__.get(oui,(mac,mac))
+ def _get_manuf(self, mac):
+ return self._get_manuf_couple(mac)[1]
+ def _get_short_manuf(self, mac):
+ return self._get_manuf_couple(mac)[0]
+ def _resolve_MAC(self, mac):
+ oui = ":".join(mac.split(":")[:3]).upper()
+ if oui in self:
+ return ":".join([self[oui][0]]+ mac.split(":")[3:])
+ return mac
+
+
+
+
+def load_manuf(filename):
+ try:
+ manufdb=ManufDA(_name=filename)
+ for l in open(filename):
+ try:
+ l = l.strip()
+ if not l or l.startswith("#"):
+ continue
+ oui,shrt=l.split()[:2]
+ i = l.find("#")
+ if i < 0:
+ lng=shrt
+ else:
+ lng = l[i+2:]
+ manufdb[oui] = shrt,lng
+ except Exception,e:
+ log_loading.warning("Couldn't parse one line from [%s] [%r] (%s)" % (filename, l, e))
+ except IOError:
+ #log_loading.warning("Couldn't open [%s] file" % filename)
+ pass
+ return manufdb
+
+MANUFDB = load_manuf("/usr/share/wireshark/wireshark/manuf")
+
+
+
+
+###########
+## Tools ##
+###########
+
+def sane_color(x):
+ r=""
+ for i in x:
+ j = ord(i)
+ if (j < 32) or (j >= 127):
+ r=r+conf.color_theme.not_printable(".")
+ else:
+ r=r+i
+ return r
+
+def sane(x):
+ r=""
+ for i in x:
+ j = ord(i)
+ if (j < 32) or (j >= 127):
+ r=r+"."
+ else:
+ r=r+i
+ return r
+
+def lhex(x):
+ if type(x) in (int,long):
+ return hex(x)
+ elif type(x) is tuple:
+ return "(%s)" % ", ".join(map(lhex, x))
+ elif type(x) is list:
+ return "[%s]" % ", ".join(map(lhex, x))
+ else:
+ return x
+
+def hexdump(x):
+ x=str(x)
+ l = len(x)
+ i = 0
+ while i < l:
+ print "%04x " % i,
+ for j in range(16):
+ if i+j < l:
+ print "%02X" % ord(x[i+j]),
+ else:
+ print " ",
+ if j%16 == 7:
+ print "",
+ print " ",
+ print sane_color(x[i:i+16])
+ i += 16
+
+def linehexdump(x, onlyasc=0, onlyhex=0):
+ x = str(x)
+ l = len(x)
+ if not onlyasc:
+ for i in range(l):
+ print "%02X" % ord(x[i]),
+ print "",
+ if not onlyhex:
+ print sane_color(x)
+
+def chexdump(x):
+ x=str(x)
+ print ", ".join(map(lambda x: "%#04x"%ord(x), x))
+
+def hexstr(x, onlyasc=0, onlyhex=0):
+ s = []
+ if not onlyasc:
+ s.append(" ".join(map(lambda x:"%02x"%ord(x), x)))
+ if not onlyhex:
+ s.append(sane(x))
+ return " ".join(s)
+
+
+def hexdiff(x,y):
+ x=str(x)[::-1]
+ y=str(y)[::-1]
+ SUBST=1
+ INSERT=1
+ d={}
+ d[-1,-1] = 0,(-1,-1)
+ for j in range(len(y)):
+ d[-1,j] = d[-1,j-1][0]+INSERT, (-1,j-1)
+ for i in range(len(x)):
+ d[i,-1] = d[i-1,-1][0]+INSERT, (i-1,-1)
+
+ for j in range(len(y)):
+ for i in range(len(x)):
+ d[i,j] = min( ( d[i-1,j-1][0]+SUBST*(x[i] != y[j]), (i-1,j-1) ),
+ ( d[i-1,j][0]+INSERT, (i-1,j) ),
+ ( d[i,j-1][0]+INSERT, (i,j-1) ) )
+
+
+ backtrackx = []
+ backtracky = []
+ i=len(x)-1
+ j=len(y)-1
+ while not (i == j == -1):
+ i2,j2 = d[i,j][1]
+ backtrackx.append(x[i2+1:i+1])
+ backtracky.append(y[j2+1:j+1])
+ i,j = i2,j2
+
+
+
+ x = y = i = 0
+ colorize = { 0: lambda x:x,
+ -1: conf.color_theme.left,
+ 1: conf.color_theme.right }
+
+ dox=1
+ doy=0
+ l = len(backtrackx)
+ while i < l:
+ separate=0
+ linex = backtrackx[i:i+16]
+ liney = backtracky[i:i+16]
+ xx = sum(len(k) for k in linex)
+ yy = sum(len(k) for k in liney)
+ if dox and not xx:
+ dox = 0
+ doy = 1
+ if dox and linex == liney:
+ doy=1
+
+ if dox:
+ xd = y
+ j = 0
+ while not linex[j]:
+ j += 1
+ xd -= 1
+ print colorize[doy-dox]("%04x" % xd),
+ x += xx
+ line=linex
+ else:
+ print " ",
+ if doy:
+ yd = y
+ j = 0
+ while not liney[j]:
+ j += 1
+ yd -= 1
+ print colorize[doy-dox]("%04x" % yd),
+ y += yy
+ line=liney
+ else:
+ print " ",
+
+ print " ",
+
+ cl = ""
+ for j in range(16):
+ if i+j < l:
+ if line[j]:
+ col = colorize[(linex[j]!=liney[j])*(doy-dox)]
+ print col("%02X" % ord(line[j])),
+ if linex[j]==liney[j]:
+ cl += sane_color(line[j])
+ else:
+ cl += col(sane(line[j]))
+ else:
+ print " ",
+ cl += " "
+ else:
+ print " ",
+ if j == 7:
+ print "",
+
+
+ print " ",cl
+
+ if doy or not yy:
+ doy=0
+ dox=1
+ i += 16
+ else:
+ if yy:
+ dox=0
+ doy=1
+ else:
+ i += 16
+
+
+crc32 = zlib.crc32
+
+if BIG_ENDIAN:
+ def checksum(pkt):
+ if len(pkt) % 2 == 1:
+ pkt += "\0"
+ s = sum(array.array("H", pkt))
+ s = (s >> 16) + (s & 0xffff)
+ s += s >> 16
+ s = ~s
+ return s & 0xffff
+else:
+ def checksum(pkt):
+ if len(pkt) % 2 == 1:
+ pkt += "\0"
+ s = sum(array.array("H", pkt))
+ s = (s >> 16) + (s & 0xffff)
+ s += s >> 16
+ s = ~s
+ return (((s>>8)&0xff)|s<<8) & 0xffff
+
+def warning(x):
+ log_runtime.warning(x)
+
+def mac2str(mac):
+ return "".join(map(lambda x: chr(int(x,16)), mac.split(":")))
+
+def str2mac(s):
+ return ("%02x:"*6)[:-1] % tuple(map(ord, s))
+
+def strxor(x,y):
+ return "".join(map(lambda x,y:chr(ord(x)^ord(y)),x,y))
+
+def atol(x):
+ try:
+ ip = inet_aton(x)
+ except socket.error:
+ ip = inet_aton(socket.gethostbyname(x))
+ return struct.unpack("!I", ip)[0]
+def ltoa(x):
+ return inet_ntoa(struct.pack("!I", x))
+
+def itom(x):
+ return (0xffffffff00000000L>>x)&0xffffffffL
+
+def do_graph(graph,prog=None,format="svg",target=None, type=None,string=None,options=None):
+ """do_graph(graph, prog=conf.prog.dot, format="svg",
+ target="| conf.prog.display", options=None, [string=1]):
+ string: if not None, simply return the graph string
+ graph: GraphViz graph description
+ format: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
+ target: filename or redirect. Defaults pipe to Imagemagick's display program
+ prog: which graphviz program to use
+ options: options to be passed to prog"""
+
+
+ if string:
+ return graph
+ if type is not None:
+ format=type
+ if prog is None:
+ prog = conf.prog.dot
+ if target is None:
+ target = "| %s" % conf.prog.display
+ if format is not None:
+ format = "-T %s" % format
+ w,r = os.popen2("%s %s %s %s" % (prog,options or "", format or "", target))
+ w.write(graph)
+ w.close()
+
+_TEX_TR = {
+ "{":"{\\tt\\char123}",
+ "}":"{\\tt\\char125}",
+ "\\":"{\\tt\\char92}",
+ "^":"\\^{}",
+ "$":"\\$",
+ "#":"\\#",
+ "~":"\\~",
+ "_":"\\_",
+ "&":"\\&",
+ "%":"\\%",
+ "|":"{\\tt\\char124}",
+ "~":"{\\tt\\char126}",
+ "<":"{\\tt\\char60}",
+ ">":"{\\tt\\char62}",
+ }
+
+def tex_escape(x):
+ s = ""
+ for c in x:
+ s += _TEX_TR.get(c,c)
+ return s
+
+def colgen(*lstcol,**kargs):
+ """Returns a generator that mixes provided quantities forever
+ trans: a function to convert the three arguments into a color. lambda x,y,z:(x,y,z) by default"""
+ if len(lstcol) < 2:
+ lstcol *= 2
+ trans = kargs.get("trans", lambda x,y,z: (x,y,z))
+ while 1:
+ for i in range(len(lstcol)):
+ for j in range(len(lstcol)):
+ for k in range(len(lstcol)):
+ if i != j or j != k or k != i:
+ yield trans(lstcol[(i+j)%len(lstcol)],lstcol[(j+k)%len(lstcol)],lstcol[(k+i)%len(lstcol)])
+
+def incremental_label(label="tag%05i", start=0):
+ while True:
+ yield label % start
+ start += 1
+
+#########################
+#### Enum management ####
+#########################
+
+class EnumElement:
+ _value=None
+ def __init__(self, key, value):
+ self._key = key
+ self._value = value
+ def __repr__(self):
+ return "<%s %s[%r]>" % (self.__dict__.get("_name", self.__class__.__name__), self._key, self._value)
+ def __getattr__(self, attr):
+ return getattr(self._value, attr)
+ def __str__(self):
+ return self._key
+ def __eq__(self, other):
+ return self._value == int(other)
+
+
+class Enum_metaclass(type):
+ element_class = EnumElement
+ def __new__(cls, name, bases, dct):
+ rdict={}
+ for k,v in dct.iteritems():
+ if type(v) is int:
+ v = cls.element_class(k,v)
+ dct[k] = v
+ rdict[v] = k
+ dct["__rdict__"] = rdict
+ return super(Enum_metaclass, cls).__new__(cls, name, bases, dct)
+ def __getitem__(self, attr):
+ return self.__rdict__[attr]
+ def __contains__(self, val):
+ return val in self.__rdict__
+ def get(self, attr, val=None):
+ return self._rdict__.get(attr, val)
+ def __repr__(self):
+ return "<%s>" % self.__dict__.get("name", self.__name__)
+
+
+
+
+##############################
+## Session saving/restoring ##
+##############################
+
+
+def save_session(fname, session=None, pickleProto=-1):
+ if session is None:
+ session = scapy_session
+
+ to_be_saved = session.copy()
+
+ if to_be_saved.has_key("__builtins__"):
+ del(to_be_saved["__builtins__"])
+
+ for k in to_be_saved.keys():
+ if type(to_be_saved[k]) in [types.TypeType, types.ClassType, types.ModuleType]:
+ log_interactive.error("[%s] (%s) can't be saved." % (k, type(to_be_saved[k])))
+ del(to_be_saved[k])
+
+ try:
+ os.rename(fname, fname+".bak")
+ except OSError:
+ pass
+ f=gzip.open(fname,"wb")
+ cPickle.dump(to_be_saved, f, pickleProto)
+ f.close()
+
+def load_session(fname):
+ try:
+ s = cPickle.load(gzip.open(fname,"rb"))
+ except IOError:
+ s = cPickle.load(open(fname,"rb"))
+ scapy_session.clear()
+ scapy_session.update(s)
+
+def update_session(fname):
+ try:
+ s = cPickle.load(gzip.open(fname,"rb"))
+ except IOError:
+ s = cPickle.load(open(fname,"rb"))
+ scapy_session.update(s)
+
+
+def export_object(obj):
+ print base64.encodestring(gzip.zlib.compress(cPickle.dumps(obj,2),9))
+
+def import_object(obj=None):
+ if obj is None:
+ obj = sys.stdin.read()
+ return cPickle.loads(gzip.zlib.decompress(base64.decodestring(obj.strip())))
+
+
+def save_object(fname, obj):
+ cPickle.dump(obj,gzip.open(fname,"wb"))
+
+def load_object(fname):
+ return cPickle.load(gzip.open(fname,"rb"))
+
+
+#################
+## Debug class ##
+#################
+
+class debug:
+ recv=[]
+ sent=[]
+ match=[]
+
+
+####################
+## IP Tools class ##
+####################
+
+class IPTools:
+ """Add more powers to a class that have a "src" attribute."""
+ def whois(self):
+ os.system("whois %s" % self.src)
+ def ottl(self):
+ t = [32,64,128,255]+[self.ttl]
+ t.sort()
+ return t[t.index(self.ttl)+1]
+ def hops(self):
+ return self.ottl()-self.ttl-1
+
+
+##############################
+## Routing/Interfaces stuff ##
+##############################
+
+class Route:
+ def __init__(self):
+ self.resync()
+ self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ self.cache = {}
+
+ def invalidate_cache(self):
+ self.cache = {}
+
+ def resync(self):
+ self.invalidate_cache()
+ self.routes = read_routes()
+
+ def __repr__(self):
+ rt = "Network Netmask Gateway Iface Output IP\n"
+ for net,msk,gw,iface,addr in self.routes:
+ rt += "%-15s %-15s %-15s %-15s %-15s\n" % (ltoa(net),
+ ltoa(msk),
+ gw,
+ iface,
+ addr)
+ return rt
+
+ def make_route(self, host=None, net=None, gw=None, dev=None):
+ if host is not None:
+ thenet,msk = host,32
+ elif net is not None:
+ thenet,msk = net.split("/")
+ msk = int(msk)
+ else:
+ raise Scapy_Exception("make_route: Incorrect parameters. You should specify a host or a net")
+ if gw is None:
+ gw="0.0.0.0"
+ if dev is None:
+ if gw:
+ nhop = gw
+ else:
+ nhop = thenet
+ dev,ifaddr,x = self.route(nhop)
+ else:
+ ifaddr = get_if_addr(dev)
+ return (atol(thenet), itom(msk), gw, dev, ifaddr)
+
+ def add(self, *args, **kargs):
+ """Ex:
+ add(net="192.168.1.0/24",gw="1.2.3.4")
+ """
+ self.invalidate_cache()
+ self.routes.append(self.make_route(*args,**kargs))
+
+
+ def delt(self, *args, **kargs):
+ """delt(host|net, gw|dev)"""
+ self.invalidate_cache()
+ route = self.make_route(*args,**kargs)
+ try:
+ i=self.routes.index(route)
+ del(self.routes[i])
+ except ValueError:
+ warning("no matching route found")
+
+ def ifchange(self, iff, addr):
+ self.invalidate_cache()
+ the_addr,the_msk = (addr.split("/")+["32"])[:2]
+ the_msk = itom(int(the_msk))
+ the_rawaddr = atol(the_addr)
+ the_net = the_rawaddr & the_msk
+
+
+ for i in range(len(self.routes)):
+ net,msk,gw,iface,addr = self.routes[i]
+ if iface != iff:
+ continue
+ if gw == '0.0.0.0':
+ self.routes[i] = (the_net,the_msk,gw,iface,the_addr)
+ else:
+ self.routes[i] = (net,msk,gw,iface,the_addr)
+ for i in arp_cache.keys():
+ del(arp_cache[i])
+
+
+
+ def ifdel(self, iff):
+ self.invalidate_cache()
+ new_routes=[]
+ for rt in self.routes:
+ if rt[3] != iff:
+ new_routes.append(rt)
+ self.routes=new_routes
+
+ def ifadd(self, iff, addr):
+ self.invalidate_cache()
+ the_addr,the_msk = (addr.split("/")+["32"])[:2]
+ the_msk = itom(int(the_msk))
+ the_rawaddr = atol(the_addr)
+ the_net = the_rawaddr & the_msk
+ self.routes.append((the_net,the_msk,'0.0.0.0',iff,the_addr))
+
+
+ def route(self,dest,verbose=None):
+ if dest in self.cache:
+ return self.cache[dest]
+ if verbose is None:
+ verbose=conf.verb
+ # Transform "192.168.*.1-5" to one IP of the set
+ dst = dest.split("/")[0]
+ dst = dst.replace("*","0")
+ while 1:
+ l = dst.find("-")
+ if l < 0:
+ break
+ m = (dst[l:]+".").find(".")
+ dst = dst[:l]+dst[l+m:]
+
+
+ dst = atol(dst)
+ pathes=[]
+ for d,m,gw,i,a in self.routes:
+ aa = atol(a)
+ if aa == dst:
+ pathes.append((0xffffffffL,("lo",a,"0.0.0.0")))
+ if (dst & m) == (d & m):
+ pathes.append((m,(i,a,gw)))
+ if not pathes:
+ if verbose:
+ warning("No route found (no default route?)")
+ return "lo","0.0.0.0","0.0.0.0" #XXX linux specific!
+ # Choose the more specific route (greatest netmask).
+ # XXX: we don't care about metrics
+ pathes.sort()
+ ret = pathes[-1][1]
+ self.cache[dest] = ret
+ return ret
+
+ def get_if_bcast(self, iff):
+ for net, msk, gw, iface, addr in self.routes:
+ if (iff == iface and net != 0L):
+ bcast = atol(addr)|(~msk&0xffffffffL); # FIXME: check error in atol()
+ return ltoa(bcast);
+ warning("No broadcast address found for iface %s\n" % iff);
+
+if DNET:
+ def get_if_raw_hwaddr(iff):
+ if iff[:2] == "lo":
+ return (772, '\x00'*6)
+ try:
+ l = dnet.intf().get(iff)
+ l = l["link_addr"]
+ except:
+ raise Scapy_Exception("Error in attempting to get hw address for interface [%s]" % iff)
+ return l.type,l.data
+ def get_if_raw_addr(ifname):
+ i = dnet.intf()
+ return i.get(ifname)["addr"].data
+else:
+ def get_if_raw_hwaddr(iff):
+ return struct.unpack("16xh6s8x",get_if(iff,SIOCGIFHWADDR))
+
+ def get_if_raw_addr(iff):
+ try:
+ return get_if(iff, SIOCGIFADDR)[20:24]
+ except IOError:
+ return "\0\0\0\0"
+
+
+if PCAP:
+ def get_if_list():
+ # remove 'any' interface
+ return map(lambda x:x[0],filter(lambda x:x[1] is None,pcap.findalldevs()))
+ def get_working_if():
+ try:
+ return pcap.lookupdev()
+ except pcap.pcapc.EXCEPTION:
+ return 'lo'
+
+ def attach_filter(s, filter):
+ warning("attach_filter() should not be called in PCAP mode")
+ def set_promisc(s,iff,val=1):
+ warning("set_promisc() should not be called in DNET/PCAP mode")
+
+else:
+ def get_if_list():
+ f=open("/proc/net/dev","r")
+ lst = []
+ f.readline()
+ f.readline()
+ for l in f:
+ lst.append(l.split(":")[0].strip())
+ return lst
+ def get_working_if():
+ for i in get_if_list():
+ if i == 'lo':
+ continue
+ ifflags = struct.unpack("16xH14x",get_if(i,SIOCGIFFLAGS))[0]
+ if ifflags & IFF_UP:
+ return i
+ return "lo"
+ def attach_filter(s, filter):
+ # XXX We generate the filter on the interface conf.iface
+ # because tcpdump open the "any" interface and ppp interfaces
+ # in cooked mode. As we use them in raw mode, the filter will not
+ # work... one solution could be to use "any" interface and translate
+ # the filter from cooked mode to raw mode
+ # mode
+ if not TCPDUMP:
+ return
+ try:
+ f = os.popen("%s -i %s -ddd -s 1600 '%s'" % (conf.prog.tcpdump,conf.iface,filter))
+ except OSError,msg:
+ log_interactive.warning("Failed to execute tcpdump: (%s)")
+ return
+ lines = f.readlines()
+ if f.close():
+ raise Scapy_Exception("Filter parse error")
+ nb = int(lines[0])
+ bpf = ""
+ for l in lines[1:]:
+ bpf += struct.pack("HBBI",*map(long,l.split()))
+
+ # XXX. Argl! We need to give the kernel a pointer on the BPF,
+ # python object header seems to be 20 bytes. 36 bytes for x86 64bits arch.
+ if X86_64:
+ bpfh = struct.pack("HL", nb, id(bpf)+36)
+ else:
+ bpfh = struct.pack("HI", nb, id(bpf)+20)
+ s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, bpfh)
+
+ def set_promisc(s,iff,val=1):
+ mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "")
+ if val:
+ cmd = PACKET_ADD_MEMBERSHIP
+ else:
+ cmd = PACKET_DROP_MEMBERSHIP
+ s.setsockopt(SOL_PACKET, cmd, mreq)
+
+
+if not LINUX:
+
+ def new_read_routes():
+
+ rtlst = []
+ def addrt(rt,lst):
+ dst,gw = rt
+ lst.append(rt)
+
+ r = dnet.route()
+ print r.loop(addrt, rtlst)
+ return rtlst
+
+ def read_routes():
+ if SOLARIS:
+ f=os.popen("netstat -rvn") # -f inet
+ elif FREEBSD:
+ f=os.popen("netstat -rnW") # -W to handle long interface names
+ else:
+ f=os.popen("netstat -rn") # -f inet
+ ok = 0
+ mtu_present = False
+ routes = []
+ for l in f.readlines():
+ if not l:
+ break
+ l = l.strip()
+ if l.find("----") >= 0: # a separation line
+ continue
+ if l.find("Destination") >= 0:
+ ok = 1
+ if l.find("Mtu") >= 0:
+ mtu_present = True
+ continue
+ if ok == 0:
+ continue
+ if not l:
+ break
+ if SOLARIS:
+ dest,mask,gw,netif,mxfrg,rtt,ref,flg = l.split()[:8]
+ else:
+ if mtu_present:
+ dest,gw,flg,ref,use,mtu,netif = l.split()[:7]
+ else:
+ dest,gw,flg,ref,use,netif = l.split()[:6]
+ if flg.find("Lc") >= 0:
+ continue
+ if dest == "default":
+ dest = 0L
+ netmask = 0L
+ else:
+ if SOLARIS:
+ netmask = atol(mask)
+ elif "/" in dest:
+ dest,netmask = dest.split("/")
+ netmask = itom(int(netmask))
+ else:
+ netmask = itom((dest.count(".") + 1) * 8)
+ dest += ".0"*(3-dest.count("."))
+ dest = atol(dest)
+ if not "G" in flg:
+ gw = '0.0.0.0'
+ ifaddr = get_if_addr(netif)
+ routes.append((dest,netmask,gw,netif,ifaddr))
+ f.close()
+ return routes
+
+ def read_interfaces():
+ i = dnet.intf()
+ ifflist = {}
+ def addif(iff,lst):
+ if not iff.has_key("addr"):
+ return
+ if not iff.has_key("link_addr"):
+ return
+ rawip = iff["addr"].data
+ ip = inet_ntoa(rawip)
+ rawll = iff["link_addr"].data
+ ll = str2mac(rawll)
+ lst[iff["name"]] = (rawll,ll,rawip,ip)
+ i.loop(addif, ifflist)
+ return ifflist
+
+
+else:
+
+ def read_routes():
+ f=open("/proc/net/route","r")
+ routes = []
+ s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x","lo"))
+ addrfamily = struct.unpack("h",ifreq[16:18])[0]
+ if addrfamily == socket.AF_INET:
+ ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x","lo"))
+ msk = socket.ntohl(struct.unpack("I",ifreq2[20:24])[0])
+ dst = socket.ntohl(struct.unpack("I",ifreq[20:24])[0]) & msk
+ ifaddr = inet_ntoa(ifreq[20:24])
+ routes.append((dst, msk, "0.0.0.0", "lo", ifaddr))
+ else:
+ warning("Interface lo: unkown address family (%i)"% addrfamily)
+
+ for l in f.readlines()[1:]:
+ iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split()
+ flags = int(flags,16)
+ if flags & RTF_UP == 0:
+ continue
+ if flags & RTF_REJECT:
+ continue
+ try:
+ ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff))
+ except IOError: # interface is present in routing tables but does not have any assigned IP
+ ifaddr="0.0.0.0"
+ else:
+ addrfamily = struct.unpack("h",ifreq[16:18])[0]
+ if addrfamily == socket.AF_INET:
+ ifaddr = inet_ntoa(ifreq[20:24])
+ else:
+ warning("Interface %s: unkown address family (%i)"%(iff, addrfamily))
+ continue
+ routes.append((socket.htonl(long(dst,16))&0xffffffffL,
+ socket.htonl(long(msk,16))&0xffffffffL,
+ inet_ntoa(struct.pack("I",long(gw,16))),
+ iff, ifaddr))
+
+ f.close()
+ return routes
+
+ def get_if(iff,cmd):
+ s=socket.socket()
+ ifreq = ioctl(s, cmd, struct.pack("16s16x",iff))
+ s.close()
+ return ifreq
+
+
+ def get_if_index(iff):
+ return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0])
+
+
+
+def get_if_addr(iff):
+ return inet_ntoa(get_if_raw_addr(iff))
+
+def get_if_hwaddr(iff):
+ addrfamily, mac = get_if_raw_hwaddr(iff)
+ if addrfamily in [ARPHDR_ETHER,ARPHDR_LOOPBACK]:
+ return str2mac(mac)
+ else:
+ raise Scapy_Exception("Unsupported address family (%i) for interface [%s]" % (addrfamily,iff))
+
+
+
+#####################
+## ARP cache stuff ##
+#####################
+
+ARPTIMEOUT=120
+
+# XXX Fill arp_cache with /etc/ether and arp cache
+arp_cache={}
+
+if 0 and DNET: ## XXX Can't use this because it does not resolve IPs not in cache
+ dnet_arp_object = dnet.arp()
+ def getmacbyip(ip):
+ tmp = map(ord, inet_aton(ip))
+ if (tmp[0] & 0xf0) == 0xe0: # mcast @
+ return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
+ iff,a,gw = conf.route.route(ip)
+ if iff == "lo":
+ return "ff:ff:ff:ff:ff:ff"
+ if gw != "0.0.0.0":
+ ip = gw
+ res = dnet_arp_object.get(dnet.addr(ip))
+ if res is None:
+ return None
+ else:
+ return res.ntoa()
+else:
+ def getmacbyip(ip):
+ tmp = map(ord, inet_aton(ip))
+ if (tmp[0] & 0xf0) == 0xe0: # mcast @
+ return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
+ iff,a,gw = conf.route.route(ip)
+ if ( (iff == "lo") or (ip == conf.route.get_if_bcast(iff)) ):
+ return "ff:ff:ff:ff:ff:ff"
+ if gw != "0.0.0.0":
+ ip = gw
+
+ if arp_cache.has_key(ip):
+ mac, timeout = arp_cache[ip]
+ if not timeout or (time.time()-timeout < ARPTIMEOUT):
+ return mac
+
+ res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
+ type=ETH_P_ARP,
+ iface = iff,
+ timeout=2,
+ verbose=0,
+ nofilter=1)
+ if res is not None:
+ mac = res.payload.hwsrc
+ arp_cache[ip] = (mac,time.time())
+ return mac
+ return None
+
+
+####################
+## Random numbers ##
+####################
+
+class VolatileValue:
+ def __repr__(self):
+ return "<%s>" % self.__class__.__name__
+ def __getattr__(self, attr):
+ if attr == "__setstate__":
+ raise AttributeError(attr)
+ return getattr(self._fix(),attr)
+ def _fix(self):
+ return None
+
+
+class RandField(VolatileValue):
+ pass
+
+
+class RandNum(RandField):
+ min = 0
+ max = 0
+ def __init__(self, min, max):
+ self.min = min
+ self.max = max
+ def _fix(self):
+ # XXX: replace with sth that guarantee unicity
+ return random.randrange(self.min, self.max)
+
+class RandNumGamma(RandField):
+ def __init__(self, alpha, beta):
+ self.alpha = alpha
+ self.beta = beta
+ def _fix(self):
+ return int(round(random.gammavariate(self.alpha, self.beta)))
+
+class RandNumGauss(RandField):
+ def __init__(self, mu, sigma):
+ self.mu = mu
+ self.sigma = sigma
+ def _fix(self):
+ return int(round(random.gauss(self.mu, self.sigma)))
+
+class RandNumExpo(RandField):
+ def __init__(self, lambd):
+ self.lambd = lambd
+ def _fix(self):
+ return int(round(random.expovariate(self.lambd)))
+
+class RandByte(RandNum):
+ def __init__(self):
+ RandNum.__init__(self, 0, 2L**8)
+
+class RandShort(RandNum):
+ def __init__(self):
+ RandNum.__init__(self, 0, 2L**16)
+
+class RandInt(RandNum):
+ def __init__(self):
+ RandNum.__init__(self, 0, 2L**32)
+
+class RandSInt(RandNum):
+ def __init__(self):
+ RandNum.__init__(self, -2L**31, 2L**31)
+
+class RandLong(RandNum):
+ def __init__(self):
+ RandNum.__init__(self, 0, 2L**64)
+
+class RandSLong(RandNum):
+ def __init__(self):
+ RandNum.__init__(self, -2L**63, 2L**63)
+
+class RandChoice(RandField):
+ def __init__(self, *args):
+ self._choice = args
+ def _fix(self):
+ return random.choice(self._choice)
+
+class RandString(RandField):
+ def __init__(self, size, chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"):
+ self.chars = chars
+ self.size = size
+ def _fix(self):
+ s = ""
+ for i in range(self.size):
+ s += random.choice(self.chars)
+ return s
+
+class RandBin(RandString):
+ def __init__(self, size):
+ RandString.__init__(self, size, "".join(map(chr,range(256))))
+
+
+class RandTermString(RandString):
+ def __init__(self, size, term):
+ RandString.__init__(self, size, "".join(map(chr,range(1,256))))
+ self.term = term
+ def _fix(self):
+ return RandString._fix(self)+self.term
+
+
+
+class RandIP(RandString):
+ def __init__(self, iptemplate="0.0.0.0/0"):
+ self.ip = Net(iptemplate)
+ def _fix(self):
+ return self.ip.choice()
+
+class RandMAC(RandString):
+ def __init__(self, template="*"):
+ template += ":*:*:*:*:*"
+ template = template.split(":")
+ self.mac = ()
+ for i in range(6):
+ if template[i] == "*":
+ v = RandByte()
+ elif "-" in template[i]:
+ x,y = template[i].split("-")
+ v = RandNum(int(x,16), int(y,16))
+ else:
+ v = int(template[i],16)
+ self.mac += (v,)
+ def _fix(self):
+ return "%02x:%02x:%02x:%02x:%02x:%02x" % self.mac
+
+
+class RandOID(RandString):
+ def __init__(self, fmt=None, depth=RandNumExpo(0.1), idnum=RandNumExpo(0.01)):
+ self.ori_fmt = fmt
+ if fmt is not None:
+ fmt = fmt.split(".")
+ for i in range(len(fmt)):
+ if "-" in fmt[i]:
+ fmt[i] = tuple(map(int, fmt[i].split("-")))
+ self.fmt = fmt
+ self.depth = depth
+ self.idnum = idnum
+ def __repr__(self):
+ if self.ori_fmt is None:
+ return "<%s>" % self.__class__.__name__
+ else:
+ return "<%s [%s]>" % (self.__class__.__name__, self.ori_fmt)
+ def _fix(self):
+ if self.fmt is None:
+ return ".".join(map(str, [self.idnum for i in xrange(1+self.depth)]))
+ else:
+ oid = []
+ for i in self.fmt:
+ if i == "*":
+ oid.append(str(self.idnum))
+ elif i == "**":
+ oid += map(str, [self.idnum for i in xrange(1+self.depth)])
+ elif type(i) is tuple:
+ oid.append(str(random.randrange(*i)))
+ else:
+ oid.append(i)
+ return ".".join(oid)
+
+
+
+class RandASN1Object(RandField):
+ def __init__(self, objlist=None):
+ if objlist is None:
+ objlist = map(lambda x:x._asn1_obj,
+ filter(lambda x:hasattr(x,"_asn1_obj"), ASN1_Class_UNIVERSAL.__rdict__.values()))
+ self.objlist = objlist
+ self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ def _fix(self, n=0):
+ o = random.choice(self.objlist)
+ if issubclass(o, ASN1_INTEGER):
+ return o(int(random.gauss(0,1000)))
+ elif issubclass(o, ASN1_STRING):
+ z = int(random.expovariate(0.05)+1)
+ return o("".join([random.choice(self.chars) for i in range(z)]))
+ elif issubclass(o, ASN1_SEQUENCE) and (n < 10):
+ z = int(random.expovariate(0.08)+1)
+ return o(map(lambda x:x._fix(n+1), [self.__class__(objlist=self.objlist)]*z))
+ return ASN1_INTEGER(int(random.gauss(0,1000)))
+
+
+# Automatic timestamp
+
+class AutoTime(VolatileValue):
+ def __init__(self, base=None):
+ if base == None:
+ self.diff = 0
+ else:
+ self.diff = time.time()-base
+ def _fix(self):
+ return time.time()-self.diff
+
+class IntAutoTime(AutoTime):
+ def _fix(self):
+ return int(time.time()-self.diff)
+
+
+
+class DelayedEval(VolatileValue):
+ """ Exemple of usage: DelayedEval("time.time()") """
+ def __init__(self, expr):
+ self.expr = expr
+ def _fix(self):
+ return eval(self.expr)
+
+
+class IncrementalValue(VolatileValue):
+ def __init__(self, start=0, step=1, restart=-1):
+ self.start = self.val = start
+ self.step = step
+ self.restart = restart
+ def _fix(self):
+ v = self.val
+ if self.val == self.restart :
+ self.val = self.start
+ else:
+ self.val += self.step
+ return v
+
+def corrupt_bytes(s, p=0.01, n=None):
+ s = array.array("B",str(s))
+ l = len(s)
+ if n is None:
+ n = max(1,int(l*p))
+ for i in random.sample(xrange(l), n):
+ s[i] = random.randint(0,255)
+ return s.tostring()
+
+def corrupt_bits(s, p=0.01, n=None):
+ s = array.array("B",str(s))
+ l = len(s)*8
+ if n is None:
+ n = max(1,int(l*p))
+ for i in random.sample(xrange(l), n):
+ s[i/8] ^= 1 << (i%8)
+ return s.tostring()
+
+
+class CorruptedBytes(VolatileValue):
+ def __init__(self, s, p=0.01, n=None):
+ self.s = s
+ self.p = p
+ self.n = n
+ def _fix(self):
+ return corrupt_bytes(self.s, self.p, self.n)
+
+class CorruptedBits(CorruptedBytes):
+ def _fix(self):
+ return corrupt_bits(self.s, self.p, self.n)
+
+##############
+#### ASN1 ####
+##############
+
+class ASN1_Error(Exception):
+ pass
+
+class ASN1_Encoding_Error(ASN1_Error):
+ pass
+
+class ASN1_Decoding_Error(ASN1_Error):
+ pass
+
+class ASN1_BadTag_Decoding_Error(ASN1_Decoding_Error):
+ pass
+
+
+
+class ASN1Codec(EnumElement):
+ def register_stem(cls, stem):
+ cls._stem = stem
+ def dec(cls, s, context=None):
+ return cls._stem.dec(s, context=context)
+ def safedec(cls, s, context=None):
+ return cls._stem.safedec(s, context=context)
+ def get_stem(cls):
+ return cls.stem
+
+
+class ASN1_Codecs_metaclass(Enum_metaclass):
+ element_class = ASN1Codec
+
+class ASN1_Codecs:
+ __metaclass__ = ASN1_Codecs_metaclass
+ BER = 1
+ DER = 2
+ PER = 3
+ CER = 4
+ LWER = 5
+ BACnet = 6
+ OER = 7
+ SER = 8
+ XER = 9
+
+class ASN1Tag(EnumElement):
+ def __init__(self, key, value, context=None, codec=None):
+ EnumElement.__init__(self, key, value)
+ self._context = context
+ if codec == None:
+ codec = {}
+ self._codec = codec
+ def clone(self): # /!\ not a real deep copy. self.codec is shared
+ return self.__class__(self._key, self._value, self._context, self._codec)
+ def register_asn1_object(self, asn1obj):
+ self._asn1_obj = asn1obj
+ def asn1_object(self, val):
+ if hasattr(self,"_asn1_obj"):
+ return self._asn1_obj(val)
+ raise ASN1_Error("%r does not have any assigned ASN1 object" % self)
+ def register(self, codecnum, codec):
+ self._codec[codecnum] = codec
+ def get_codec(self, codec):
+ try:
+ c = self._codec[codec]
+ except KeyError,msg:
+ raise ASN1_Error("Codec %r not found for tag %r" % (codec, self))
+ return c
+
+class ASN1_Class_metaclass(Enum_metaclass):
+ element_class = ASN1Tag
+ def __new__(cls, name, bases, dct): # XXX factorise a bit with Enum_metaclass.__new__()
+ for b in bases:
+ for k,v in b.__dict__.iteritems():
+ if k not in dct and isinstance(v,ASN1Tag):
+ dct[k] = v.clone()
+
+ rdict = {}
+ for k,v in dct.iteritems():
+ if type(v) is int:
+ v = ASN1Tag(k,v)
+ dct[k] = v
+ rdict[v] = v
+ elif isinstance(v, ASN1Tag):
+ rdict[v] = v
+ dct["__rdict__"] = rdict
+
+ cls = type.__new__(cls, name, bases, dct)
+ for v in cls.__dict__.values():
+ if isinstance(v, ASN1Tag):
+ v.context = cls # overwrite ASN1Tag contexts, even cloned ones
+ return cls
+
+
+class ASN1_Class:
+ __metaclass__ = ASN1_Class_metaclass
+
+class ASN1_Class_UNIVERSAL(ASN1_Class):
+ name = "UNIVERSAL"
+ ERROR = -3
+ RAW = -2
+ NONE = -1
+ ANY = 0
+ BOOLEAN = 1
+ INTEGER = 2
+ BIT_STRING = 3
+ STRING = 4
+ NULL = 5
+ OID = 6
+ OBJECT_DESCRIPTOR = 7
+ EXTERNAL = 8
+ REAL = 9
+ ENUMERATED = 10
+ EMBEDDED_PDF = 11
+ UTF8_STRING = 12
+ RELATIVE_OID = 13
+ SEQUENCE = 0x30#XXX 16 ??
+ SET = 0x31 #XXX 17 ??
+ NUMERIC_STRING = 18
+ PRINTABLE_STRING = 19
+ T61_STRING = 20
+ VIDEOTEX_STRING = 21
+ IA5_STRING = 22
+ UTC_TIME = 23
+ GENERALIZED_TIME = 24
+ GRAPHIC_STRING = 25
+ ISO646_STRING = 26
+ GENERAL_STRING = 27
+ UNIVERSAL_STRING = 28
+ CHAR_STRING = 29
+ BMP_STRING = 30
+ COUNTER32 = 0x41
+ TIME_TICKS = 0x43
+
+class ASN1_Object_metaclass(type):
+ def __new__(cls, name, bases, dct):
+ c = super(ASN1_Object_metaclass, cls).__new__(cls, name, bases, dct)
+ try:
+ c.tag.register_asn1_object(c)
+ except:
+ warning("Error registering %r for %r" % (c.tag, c.codec))
+ return c
+
+
+class ASN1_Object:
+ __metaclass__ = ASN1_Object_metaclass
+ tag = ASN1_Class_UNIVERSAL.ANY
+ def __init__(self, val):
+ self.val = val
+ def enc(self, codec):
+ return self.tag.get_codec(codec).enc(self.val)
+ def __repr__(self):
+ return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), self.val)
+ def __str__(self):
+ return self.enc(conf.ASN1_default_codec)
+ def strshow(self, lvl=0):
+ return (" "*lvl)+repr(self)+"\n"
+ def show(self, lvl=0):
+ print self.strshow(lvl)
+ def __eq__(self, other):
+ return self.val == other
+ def __cmp__(self, other):
+ return cmp(self.val, other)
+
+class ASN1_DECODING_ERROR(ASN1_Object):
+ tag = ASN1_Class_UNIVERSAL.ERROR
+ def __init__(self, val, exc=None):
+ ASN1_Object.__init__(self, val)
+ self.exc = exc
+ def __repr__(self):
+ return "<%s[%r]{{%s}}>" % (self.__dict__.get("name", self.__class__.__name__),
+ self.val, self.exc.args[0])
+ def enc(self, codec):
+ if isinstance(self.val, ASN1_Object):
+ return self.val.enc(codec)
+ return self.val
+
+class ASN1_force(ASN1_Object):
+ tag = ASN1_Class_UNIVERSAL.RAW
+ def enc(self, codec):
+ if isinstance(self.val, ASN1_Object):
+ return self.val.enc(codec)
+ return self.val
+
+class ASN1_BADTAG(ASN1_force):
+ pass
+
+class ASN1_INTEGER(ASN1_Object):
+ tag = ASN1_Class_UNIVERSAL.INTEGER
+
+class ASN1_STRING(ASN1_Object):
+ tag = ASN1_Class_UNIVERSAL.STRING
+
+class ASN1_BIT_STRING(ASN1_STRING):
+ tag = ASN1_Class_UNIVERSAL.BIT_STRING
+
+class ASN1_PRINTABLE_STRING(ASN1_STRING):
+ tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
+
+class ASN1_T61_STRING(ASN1_STRING):
+ tag = ASN1_Class_UNIVERSAL.T61_STRING
+
+class ASN1_IA5_STRING(ASN1_STRING):
+ tag = ASN1_Class_UNIVERSAL.IA5_STRING
+
+class ASN1_NUMERIC_STRING(ASN1_STRING):
+ tag = ASN1_Class_UNIVERSAL.NUMERIC_STRING
+
+class ASN1_VIDEOTEX_STRING(ASN1_STRING):
+ tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING
+
+class ASN1_UTC_TIME(ASN1_STRING):
+ tag = ASN1_Class_UNIVERSAL.UTC_TIME
+
+class ASN1_TIME_TICKS(ASN1_INTEGER):
+ tag = ASN1_Class_UNIVERSAL.TIME_TICKS
+
+class ASN1_BOOLEAN(ASN1_INTEGER):
+ tag = ASN1_Class_UNIVERSAL.BOOLEAN
+
+class ASN1_NULL(ASN1_INTEGER):
+ tag = ASN1_Class_UNIVERSAL.NULL
+
+class ASN1_COUNTER32(ASN1_INTEGER):
+ tag = ASN1_Class_UNIVERSAL.COUNTER32
+
+class ASN1_SEQUENCE(ASN1_Object):
+ tag = ASN1_Class_UNIVERSAL.SEQUENCE
+ def strshow(self, lvl=0):
+ s = (" "*lvl)+("# %s:" % self.__class__.__name__)+"\n"
+ for o in self.val:
+ s += o.strshow(lvl=lvl+1)
+ return s
+
+class ASN1_SET(ASN1_SEQUENCE):
+ tag = ASN1_Class_UNIVERSAL.SET
+
+class ASN1_OID(ASN1_Object):
+ tag = ASN1_Class_UNIVERSAL.OID
+ def __init__(self, val):
+ val = conf.mib._oid(val)
+ ASN1_Object.__init__(self, val)
+ def __repr__(self):
+ return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), conf.mib._oidname(self.val))
+
+
+
+##################
+## BER encoding ##
+##################
+
+
+
+#####[ BER tools ]#####
+
+
+class BER_Exception(Exception):
+ pass
+
+class BER_Decoding_Error(ASN1_Decoding_Error):
+ def __init__(self, msg, decoded=None, remaining=None):
+ Exception.__init__(self, msg)
+ self.remaining = remaining
+ self.decoded = decoded
+ def __str__(self):
+ s = Exception.__str__(self)
+ if isinstance(self.decoded, BERcodec_Object):
+ s+="\n### Already decoded ###\n%s" % self.decoded.strshow()
+ else:
+ s+="\n### Already decoded ###\n%r" % self.decoded
+ s+="\n### Remaining ###\n%r" % self.remaining
+ return s
+
+class BER_BadTag_Decoding_Error(BER_Decoding_Error, ASN1_BadTag_Decoding_Error):
+ pass
+
+def BER_len_enc(l, size=0):
+ if l <= 127 and size==0:
+ return chr(l)
+ s = ""
+ while l or size>0:
+ s = chr(l&0xff)+s
+ l >>= 8L
+ size -= 1
+ if len(s) > 127:
+ raise BER_Exception("BER_len_enc: Length too long (%i) to be encoded [%r]" % (len(s),s))
+ return chr(len(s)|0x80)+s
+def BER_len_dec(s):
+ l = ord(s[0])
+ if not l & 0x80:
+ return l,s[1:]
+ l &= 0x7f
+ if len(s) <= l:
+ raise BER_Decoding_Error("BER_len_dec: Got %i bytes while expecting %i" % (len(s)-1, l),remaining=s)
+ ll = 0L
+ for c in s[1:l+1]:
+ ll <<= 8L
+ ll |= ord(c)
+ return ll,s[l+1:]
+
+def BER_num_enc(l, size=1):
+ x=[]
+ while l or size>0:
+ x.insert(0, l & 0x7f)
+ if len(x) > 1:
+ x[0] |= 0x80
+ l >>= 7
+ size -= 1
+ return "".join([chr(k) for k in x])
+def BER_num_dec(s):
+ x = 0
+ for i in range(len(s)):
+ c = ord(s[i])
+ x <<= 7
+ x |= c&0x7f
+ if not c&0x80:
+ break
+ if c&0x80:
+ raise BER_Decoding_Error("BER_num_dec: unfinished number description", remaining=s)
+ return x, s[i+1:]
+
+#####[ BER classes ]#####
+
+class BERcodec_metaclass(type):
+ def __new__(cls, name, bases, dct):
+ c = super(BERcodec_metaclass, cls).__new__(cls, name, bases, dct)
+ try:
+ c.tag.register(c.codec, c)
+ except:
+ warning("Error registering %r for %r" % (c.tag, c.codec))
+ return c
+
+
+class BERcodec_Object:
+ __metaclass__ = BERcodec_metaclass
+ codec = ASN1_Codecs.BER
+ tag = ASN1_Class_UNIVERSAL.ANY
+
+ @classmethod
+ def asn1_object(cls, val):
+ return cls.tag.asn1_object(val)
+
+ @classmethod
+ def check_string(cls, s):
+ if not s:
+ raise BER_Decoding_Error("%s: Got empty object while expecting tag %r" %
+ (cls.__name__,cls.tag), remaining=s)
+ @classmethod
+ def check_type(cls, s):
+ cls.check_string(s)
+ if cls.tag != ord(s[0]):
+ raise BER_BadTag_Decoding_Error("%s: Got tag [%i/%#x] while expecting %r" %
+ (cls.__name__, ord(s[0]), ord(s[0]),cls.tag), remaining=s)
+ return s[1:]
+ @classmethod
+ def check_type_get_len(cls, s):
+ s2 = cls.check_type(s)
+ if not s2:
+ raise BER_Decoding_Error("%s: No bytes while expecting a length" %
+ cls.__name__, remaining=s)
+ return BER_len_dec(s2)
+ @classmethod
+ def check_type_check_len(cls, s):
+ l,s3 = cls.check_type_get_len(s)
+ if len(s3) < l:
+ raise BER_Decoding_Error("%s: Got %i bytes while expecting %i" %
+ (cls.__name__, len(s3), l), remaining=s)
+ return l,s3[:l],s3[l:]
+
+ @classmethod
+ def do_dec(cls, s, context=None, safe=False):
+ if context is None:
+ context = cls.tag.context
+ cls.check_string(s)
+ p = ord(s[0])
+ if p not in context:
+ t = s
+ if len(t) > 18:
+ t = t[:15]+"..."
+ raise BER_Decoding_Error("Unknown prefix [%02x] for [%r]" % (p,t), remaining=s)
+ codec = context[p].get_codec(ASN1_Codecs.BER)
+ return codec.dec(s,context,safe)
+
+ @classmethod
+ def dec(cls, s, context=None, safe=False):
+ if not safe:
+ return cls.do_dec(s, context, safe)
+ try:
+ return cls.do_dec(s, context, safe)
+ except BER_BadTag_Decoding_Error,e:
+ o,remain = BERcodec_Object.dec(e.remaining, context, safe)
+ return ASN1_BADTAG(o),remain
+ except BER_Decoding_Error, e:
+ return ASN1_DECODING_ERROR(s, exc=e),""
+ except ASN1_Error, e:
+ return ASN1_DECODING_ERROR(s, exc=e),""
+
+ @classmethod
+ def safedec(cls, s, context=None):
+ return cls.dec(s, context, safe=True)
+
+
+ @classmethod
+ def enc(cls, s):
+ if type(s) is str:
+ return BERcodec_STRING.enc(s)
+ else:
+ return BERcodec_INTEGER.enc(int(s))
+
+
+
+ASN1_Codecs.BER.register_stem(BERcodec_Object)
+
+
+class BERcodec_INTEGER(BERcodec_Object):
+ tag = ASN1_Class_UNIVERSAL.INTEGER
+ @classmethod
+ def enc(cls, i):
+ s = []
+ while 1:
+ s.append(i&0xff)
+ if -127 <= i < 0:
+ break
+ if 128 <= i <= 255:
+ s.append(0)
+ i >>= 8
+ if not i:
+ break
+ s = map(chr, s)
+ s.append(BER_len_enc(len(s)))
+ s.append(chr(cls.tag))
+ s.reverse()
+ return "".join(s)
+ @classmethod
+ def do_dec(cls, s, context=None, safe=False):
+ l,s,t = cls.check_type_check_len(s)
+ x = 0L
+ if s:
+ if ord(s[0])&0x80: # negative int
+ x = -1L
+ for c in s:
+ x <<= 8
+ x |= ord(c)
+ return cls.asn1_object(x),t
+
+
+class BERcodec_BOOLEAN(BERcodec_INTEGER):
+ tag = ASN1_Class_UNIVERSAL.BOOLEAN
+
+class BERcodec_NULL(BERcodec_INTEGER):
+ tag = ASN1_Class_UNIVERSAL.NULL
+ @classmethod
+ def enc(cls, i):
+ if i == 0:
+ return chr(cls.tag)+"\0"
+ else:
+ return super(cls,cls).enc(i)
+
+class BERcodec_STRING(BERcodec_Object):
+ tag = ASN1_Class_UNIVERSAL.STRING
+ @classmethod
+ def enc(cls,s):
+ return chr(cls.tag)+BER_len_enc(len(s))+s
+ @classmethod
+ def do_dec(cls, s, context=None, safe=False):
+ l,s,t = cls.check_type_check_len(s)
+ return cls.tag.asn1_object(s),t
+
+class BERcodec_BIT_STRING(BERcodec_STRING):
+ tag = ASN1_Class_UNIVERSAL.BIT_STRING
+
+class BERcodec_PRINTABLE_STRING(BERcodec_STRING):
+ tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING
+
+class BERcodec_T61_STRING (BERcodec_STRING):
+ tag = ASN1_Class_UNIVERSAL.T61_STRING
+
+class BERcodec_IA5_STRING(BERcodec_STRING):
+ tag = ASN1_Class_UNIVERSAL.IA5_STRING
+
+class BERcodec_UTC_TIME(BERcodec_STRING):
+ tag = ASN1_Class_UNIVERSAL.UTC_TIME
+
+class BERcodec_TIME_TICKS(BERcodec_INTEGER):
+ tag = ASN1_Class_UNIVERSAL.TIME_TICKS
+
+class BERcodec_COUNTER32(BERcodec_INTEGER):
+ tag = ASN1_Class_UNIVERSAL.COUNTER32
+
+class BERcodec_SEQUENCE(BERcodec_Object):
+ tag = ASN1_Class_UNIVERSAL.SEQUENCE
+ @classmethod
+ def enc(cls, l):
+ if type(l) is not str:
+ l = "".join(map(lambda x: x.enc(cls.codec), l))
+ return chr(cls.tag)+BER_len_enc(len(l))+l
+ @classmethod
+ def do_dec(cls, s, context=None, safe=False):
+ if context is None:
+ context = cls.tag.context
+ l,st = cls.check_type_get_len(s) # we may have len(s) < l
+ s,t = st[:l],st[l:]
+ obj = []
+ while s:
+ try:
+ o,s = BERcodec_Object.dec(s, context, safe)
+ except BER_Decoding_Error, err:
+ print "enrichi %r <- %r %r" % (err.remaining,t,s), obj
+ err.remaining += t
+ if err.decoded is not None:
+ obj.append(err.decoded)
+ err.decoded = obj
+ raise
+ obj.append(o)
+ if len(st) < l:
+ raise BER_Decoding_Error("Not enough bytes to decode sequence", decoded=obj)
+ return cls.asn1_object(obj),t
+
+class BERcodec_SET(BERcodec_SEQUENCE):
+ tag = ASN1_Class_UNIVERSAL.SET
+
+
+class BERcodec_OID(BERcodec_Object):
+ tag = ASN1_Class_UNIVERSAL.OID
+
+ @classmethod
+ def enc(cls, oid):
+ lst = [int(x) for x in oid.strip(".").split(".")]
+ if len(lst) >= 2:
+ lst[1] += 40*lst[0]
+ del(lst[0])
+ s = "".join([BER_num_enc(k) for k in lst])
+ return chr(cls.tag)+BER_len_enc(len(s))+s
+ @classmethod
+ def do_dec(cls, s, context=None, safe=False):
+ l,s,t = cls.check_type_check_len(s)
+ lst = []
+ while s:
+ l,s = BER_num_dec(s)
+ lst.append(l)
+ if (len(lst) > 0):
+ lst.insert(0,lst[0]/40)
+ lst[1] %= 40
+ return cls.asn1_object(".".join([str(k) for k in lst])), t
+
+
+#################
+## MIB parsing ##
+#################
+
+_mib_re_integer = re.compile("^[0-9]+$")
+_mib_re_both = re.compile("^([a-zA-Z_][a-zA-Z0-9_-]*)\(([0-9]+)\)$")
+_mib_re_oiddecl = re.compile("$\s*([a-zA-Z0-9_-]+)\s+OBJECT[^:]+::=\s*\{([^\}]+)\}",re.M)
+_mib_re_strings = re.compile('"[^"]*"')
+_mib_re_comments = re.compile('--.*(\r|\n)')
+
+class MIBDict(DADict):
+ def _findroot(self, x):
+ if x.startswith("."):
+ x = x[1:]
+ if not x.endswith("."):
+ x += "."
+ max=0
+ root="."
+ for k in self.keys():
+ if x.startswith(self[k]+"."):
+ if max < len(self[k]):
+ max = len(self[k])
+ root = k
+ return root, x[max:-1]
+ def _oidname(self, x):
+ root,remainder = self._findroot(x)
+ return root+remainder
+ def _oid(self, x):
+ xl = x.strip(".").split(".")
+ p = len(xl)-1
+ while p >= 0 and _mib_re_integer.match(xl[p]):
+ p -= 1
+ if p != 0 or xl[p] not in self:
+ return x
+ xl[p] = self[xl[p]]
+ return ".".join(xl[p:])
+ def _make_graph(self, other_keys=[], **kargs):
+ nodes = [(k,self[k]) for k in self.keys()]
+ oids = [self[k] for k in self.keys()]
+ for k in other_keys:
+ if k not in oids:
+ nodes.append(self.oidname(k),k)
+ s = 'digraph "mib" {\n\trankdir=LR;\n\n'
+ for k,o in nodes:
+ s += '\t"%s" [ label="%s" ];\n' % (o,k)
+ s += "\n"
+ for k,o in nodes:
+ parent,remainder = self._findroot(o[:-1])
+ remainder = remainder[1:]+o[-1]
+ if parent != ".":
+ parent = self[parent]
+ s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o,remainder)
+ s += "}\n"
+ do_graph(s, **kargs)
+
+
+def mib_register(ident, value, the_mib, unresolved):
+ if ident in the_mib or ident in unresolved:
+ return ident in the_mib
+ resval = []
+ not_resolved = 0
+ for v in value:
+ if _mib_re_integer.match(v):
+ resval.append(v)
+ else:
+ v = fixname(v)
+ if v not in the_mib:
+ not_resolved = 1
+ if v in the_mib:
+ v = the_mib[v]
+ elif v in unresolved:
+ v = unresolved[v]
+ if type(v) is list:
+ resval += v
+ else:
+ resval.append(v)
+ if not_resolved:
+ unresolved[ident] = resval
+ return False
+ else:
+ the_mib[ident] = resval
+ keys = unresolved.keys()
+ i = 0
+ while i < len(keys):
+ k = keys[i]
+ if mib_register(k,unresolved[k], the_mib, {}):
+ del(unresolved[k])
+ del(keys[i])
+ i = 0
+ else:
+ i += 1
+
+ return True
+
+
+def load_mib(filenames):
+ the_mib = {'iso': ['1']}
+ unresolved = {}
+ for k in conf.mib.keys():
+ mib_register(k, conf.mib[k].split("."), the_mib, unresolved)
+
+ if type(filenames) is str:
+ filenames = [filenames]
+ for fnames in filenames:
+ for fname in glob(fnames):
+ f = open(fname)
+ text = f.read()
+ cleantext = " ".join(_mib_re_strings.split(" ".join(_mib_re_comments.split(text))))
+ for m in _mib_re_oiddecl.finditer(cleantext):
+ ident,oid = m.groups()
+ ident=fixname(ident)
+ oid = oid.split()
+ for i in range(len(oid)):
+ m = _mib_re_both.match(oid[i])
+ if m:
+ oid[i] = m.groups()[1]
+ mib_register(ident, oid, the_mib, unresolved)
+
+ newmib = MIBDict(_name="MIB")
+ for k,o in the_mib.iteritems():
+ newmib[k]=".".join(o)
+ for k,o in unresolved.iteritems():
+ newmib[k]=".".join(o)
+
+ conf.mib=newmib
+
+
+
+################
+## Generators ##
+################
+
+class Gen(object):
+ def __iter__(self):
+ return iter([])
+
+class SetGen(Gen):
+ def __init__(self, set, _iterpacket=1):
+ self._iterpacket=_iterpacket
+ if type(set) is list:
+ self.set = set
+ elif isinstance(set, PacketList):
+ self.set = list(set)
+ else:
+ self.set = [set]
+ def transf(self, element):
+ return element
+ def __iter__(self):
+ for i in self.set:
+ if (type(i) is tuple) and (len(i) == 2) and type(i[0]) is int and type(i[1]) is int:
+ if (i[0] <= i[1]):
+ j=i[0]
+ while j <= i[1]:
+ yield j
+ j += 1
+ elif isinstance(i, Gen) and (self._iterpacket or not isinstance(i,Packet)):
+ for j in i:
+ yield j
+ else:
+ yield i
+ def __repr__(self):
+ return "<SetGen %s>" % self.set.__repr__()
+
+class Net(Gen):
+ """Generate a list of IPs from a network address or a name"""
+ name = "ip"
+ ipaddress = re.compile(r"^(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)(/[0-3]?[0-9])?$")
+ def __init__(self, net):
+ self.repr=net
+
+ tmp=net.split('/')+["32"]
+ if not self.ipaddress.match(net):
+ tmp[0]=socket.gethostbyname(tmp[0])
+ netmask = int(tmp[1])
+
+ def parse_digit(a,netmask):
+ netmask = min(8,max(netmask,0))
+ if a == "*":
+ a = (0,256)
+ elif a.find("-") >= 0:
+ x,y = map(int,a.split("-"))
+ if x > y:
+ y = x
+ a = (x & (0xffL<<netmask) , max(y, (x | (0xffL>>(8-netmask))))+1)
+ else:
+ a = (int(a) & (0xffL<<netmask),(int(a) | (0xffL>>(8-netmask)))+1)
+ return a
+
+ self.parsed = map(lambda x,y: parse_digit(x,y), tmp[0].split("."), map(lambda x,nm=netmask: x-nm, (8,16,24,32)))
+
+ def __iter__(self):
+ for d in xrange(*self.parsed[3]):
+ for c in xrange(*self.parsed[2]):
+ for b in xrange(*self.parsed[1]):
+ for a in xrange(*self.parsed[0]):
+ yield "%i.%i.%i.%i" % (a,b,c,d)
+ def choice(self):
+ ip = []
+ for v in self.parsed:
+ ip.append(str(random.randint(v[0],v[1]-1)))
+ return ".".join(ip)
+
+ def __repr__(self):
+ return "Net(%r)" % self.repr
+
+class OID(Gen):
+ name = "OID"
+ def __init__(self, oid):
+ self.oid = oid
+ self.cmpt = []
+ fmt = []
+ for i in oid.split("."):
+ if "-" in i:
+ fmt.append("%i")
+ self.cmpt.append(tuple(map(int, i.split("-"))))
+ else:
+ fmt.append(i)
+ self.fmt = ".".join(fmt)
+ def __repr__(self):
+ return "OID(%r)" % self.oid
+ def __iter__(self):
+ ii = [k[0] for k in self.cmpt]
+ while 1:
+ yield self.fmt % tuple(ii)
+ i = 0
+ while 1:
+ if i >= len(ii):
+ raise StopIteration
+ if ii[i] < self.cmpt[i][1]:
+ ii[i]+=1
+ break
+ else:
+ ii[i] = self.cmpt[i][0]
+ i += 1
+
+
+#############
+## Results ##
+#############
+
+class PacketList:
+ res = []
+ def __init__(self, res=None, name="PacketList", stats=None):
+ """create a packet list from a list of packets
+ res: the list of packets
+ stats: a list of classes that will appear in the stats (defaults to [TCP,UDP,ICMP])"""
+ if stats is None:
+ stats = [ TCP,UDP,ICMP ]
+ self.stats = stats
+ if res is None:
+ res = []
+ if isinstance(res, PacketList):
+ res = res.res
+ self.res = res
+ self.listname = name
+ def _elt2pkt(self, elt):
+ return elt
+ def _elt2sum(self, elt):
+ return elt.summary()
+ def _elt2show(self, elt):
+ return self._elt2sum(elt)
+ def __repr__(self):
+# stats=dict.fromkeys(self.stats,0) ## needs python >= 2.3 :(
+ stats = dict(map(lambda x: (x,0), self.stats))
+ other = 0
+ for r in self.res:
+ f = 0
+ for p in stats:
+ if self._elt2pkt(r).haslayer(p):
+ stats[p] += 1
+ f = 1
+ break
+ if not f:
+ other += 1
+ s = ""
+ ct = conf.color_theme
+ for p in stats:
+ s += " %s%s%s" % (ct.packetlist_proto(p.name),
+ ct.punct(":"),
+ ct.packetlist_value(stats[p]))
+ s += " %s%s%s" % (ct.packetlist_proto("Other"),
+ ct.punct(":"),
+ ct.packetlist_value(other))
+ return "%s%s%s%s%s" % (ct.punct("<"),
+ ct.packetlist_name(self.listname),
+ ct.punct(":"),
+ s,
+ ct.punct(">"))
+ def __getattr__(self, attr):
+ return getattr(self.res, attr)
+ def __getitem__(self, item):
+ if isinstance(item,type) and issubclass(item,Packet):
+ return self.__class__(filter(lambda x: item in self._elt2pkt(x),self.res),
+ name="%s from %s"%(item.__name__,self.listname))
+ if type(item) is slice:
+ return self.__class__(self.res.__getitem__(item),
+ name = "mod %s" % self.listname)
+ return self.res.__getitem__(item)
+ def __getslice__(self, *args, **kargs):
+ return self.__class__(self.res.__getslice__(*args, **kargs),
+ name="mod %s"%self.listname)
+ def __add__(self, other):
+ return self.__class__(self.res+other.res,
+ name="%s+%s"%(self.listname,other.listname))
+ def summary(self, prn=None, lfilter=None):
+ """prints a summary of each packet
+prn: function to apply to each packet instead of lambda x:x.summary()
+lfilter: truth function to apply to each packet to decide whether it will be displayed"""
+ for r in self.res:
+ if lfilter is not None:
+ if not lfilter(r):
+ continue
+ if prn is None:
+ print self._elt2sum(r)
+ else:
+ print prn(r)
+ def nsummary(self,prn=None, lfilter=None):
+ """prints a summary of each packet with the packet's number
+prn: function to apply to each packet instead of lambda x:x.summary()
+lfilter: truth function to apply to each packet to decide whether it will be displayed"""
+ for i in range(len(self.res)):
+ if lfilter is not None:
+ if not lfilter(self.res[i]):
+ continue
+ print conf.color_theme.id(i,"%04i"),
+ if prn is None:
+ print self._elt2sum(self.res[i])
+ else:
+ print prn(self.res[i])
+ def display(self): # Deprecated. Use show()
+ """deprecated. is show()"""
+ self.show()
+ def show(self, *args, **kargs):
+ """Best way to display the packet list. Defaults to nsummary() method"""
+ return self.nsummary(*args, **kargs)
+
+ def filter(self, func):
+ """Returns a packet list filtered by a truth function"""
+ return self.__class__(filter(func,self.res),
+ name="filtered %s"%self.listname)
+ def make_table(self, *args, **kargs):
+ """Prints a table using a function that returs for each packet its head column value, head row value and displayed value
+ ex: p.make_table(lambda x:(x[IP].dst, x[TCP].dport, x[TCP].sprintf("%flags%")) """
+ return make_table(self.res, *args, **kargs)
+ def make_lined_table(self, *args, **kargs):
+ """Same as make_table, but print a table with lines"""
+ return make_lined_table(self.res, *args, **kargs)
+ def make_tex_table(self, *args, **kargs):
+ """Same as make_table, but print a table with LaTeX syntax"""
+ return make_tex_table(self.res, *args, **kargs)
+
+ def plot(self, f, lfilter=None,**kargs):
+ """Applies a function to each packet to get a value that will be plotted with GnuPlot. A gnuplot object is returned
+ lfilter: a truth function that decides whether a packet must be ploted"""
+ g=Gnuplot.Gnuplot()
+ l = self.res
+ if lfilter is not None:
+ l = filter(lfilter, l)
+ l = map(f,l)
+ g.plot(Gnuplot.Data(l, **kargs))
+ return g
+
+ def diffplot(self, f, delay=1, lfilter=None, **kargs):
+ """diffplot(f, delay=1, lfilter=None)
+ Applies a function to couples (l[i],l[i+delay])"""
+ g = Gnuplot.Gnuplot()
+ l = self.res
+ if lfilter is not None:
+ l = filter(lfilter, l)
+ l = map(f,l[:-delay],l[delay:])
+ g.plot(Gnuplot.Data(l, **kargs))
+ return g
+
+ def multiplot(self, f, lfilter=None, **kargs):
+ """Uses a function that returns a label and a value for this label, then plots all the values label by label"""
+ g=Gnuplot.Gnuplot()
+ l = self.res
+ if lfilter is not None:
+ l = filter(lfilter, l)
+
+ d={}
+ for e in l:
+ k,v = f(e)
+ if k in d:
+ d[k].append(v)
+ else:
+ d[k] = [v]
+ data=[]
+ for k in d:
+ data.append(Gnuplot.Data(d[k], title=k, **kargs))
+
+ g.plot(*data)
+ return g
+
+
+ def rawhexdump(self):
+ """Prints an hexadecimal dump of each packet in the list"""
+ for p in self:
+ hexdump(self._elt2pkt(p))
+
+ def hexraw(self, lfilter=None):
+ """Same as nsummary(), except that if a packet has a Raw layer, it will be hexdumped
+ lfilter: a truth function that decides whether a packet must be displayed"""
+ for i in range(len(self.res)):
+ p = self._elt2pkt(self.res[i])
+ if lfilter is not None and not lfilter(p):
+ continue
+ print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
+ p.sprintf("%.time%"),
+ self._elt2sum(self.res[i]))
+ if p.haslayer(Raw):
+ hexdump(p.getlayer(Raw).load)
+
+ def hexdump(self, lfilter=None):
+ """Same as nsummary(), except that packets are also hexdumped
+ lfilter: a truth function that decides whether a packet must be displayed"""
+ for i in range(len(self.res)):
+ p = self._elt2pkt(self.res[i])
+ if lfilter is not None and not lfilter(p):
+ continue
+ print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
+ p.sprintf("%.time%"),
+ self._elt2sum(self.res[i]))
+ hexdump(p)
+
+ def padding(self, lfilter=None):
+ """Same as hexraw(), for Padding layer"""
+ for i in range(len(self.res)):
+ p = self._elt2pkt(self.res[i])
+ if p.haslayer(Padding):
+ if lfilter is None or lfilter(p):
+ print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
+ p.sprintf("%.time%"),
+ self._elt2sum(self.res[i]))
+ hexdump(p.getlayer(Padding).load)
+
+ def nzpadding(self, lfilter=None):
+ """Same as padding() but only non null padding"""
+ for i in range(len(self.res)):
+ p = self._elt2pkt(self.res[i])
+ if p.haslayer(Padding):
+ pad = p.getlayer(Padding).load
+ if pad == pad[0]*len(pad):
+ continue
+ if lfilter is None or lfilter(p):
+ print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
+ p.sprintf("%.time%"),
+ self._elt2sum(self.res[i]))
+ hexdump(p.getlayer(Padding).load)
+
+
+ def conversations(self, getsrcdst=None,**kargs):
+ """Graphes a conversations between sources and destinations and display it
+ (using graphviz and imagemagick)
+ getsrcdst: a function that takes an element of the list and return the source and dest
+ by defaults, return source and destination IP
+ type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
+ target: filename or redirect. Defaults pipe to Imagemagick's display program
+ prog: which graphviz program to use"""
+ if getsrcdst is None:
+ getsrcdst = lambda x:(x[IP].src, x[IP].dst)
+ conv = {}
+ for p in self.res:
+ p = self._elt2pkt(p)
+ try:
+ c = getsrcdst(p)
+ except:
+ #XXX warning()
+ continue
+ conv[c] = conv.get(c,0)+1
+ gr = 'digraph "conv" {\n'
+ for s,d in conv:
+ gr += '\t "%s" -> "%s"\n' % (s,d)
+ gr += "}\n"
+ return do_graph(gr, **kargs)
+
+ def afterglow(self, src=None, event=None, dst=None, **kargs):
+ """Experimental clone attempt of http://sourceforge.net/projects/afterglow
+ each datum is reduced as src -> event -> dst and the data are graphed.
+ by default we have IP.src -> IP.dport -> IP.dst"""
+ if src is None:
+ src = lambda x: x[IP].src
+ if event is None:
+ event = lambda x: x[IP].dport
+ if dst is None:
+ dst = lambda x: x[IP].dst
+ sl = {}
+ el = {}
+ dl = {}
+ for i in self.res:
+ try:
+ s,e,d = src(i),event(i),dst(i)
+ if s in sl:
+ n,l = sl[s]
+ n += 1
+ if e not in l:
+ l.append(e)
+ sl[s] = (n,l)
+ else:
+ sl[s] = (1,[e])
+ if e in el:
+ n,l = el[e]
+ n+=1
+ if d not in l:
+ l.append(d)
+ el[e] = (n,l)
+ else:
+ el[e] = (1,[d])
+ dl[d] = dl.get(d,0)+1
+ except:
+ continue
+
+ import math
+ def normalize(n):
+ return 2+math.log(n)/4.0
+
+ def minmax(x):
+ m,M = min(x),max(x)
+ if m == M:
+ m = 0
+ if M == 0:
+ M = 1
+ return m,M
+
+ mins,maxs = minmax(map(lambda (x,y): x, sl.values()))
+ mine,maxe = minmax(map(lambda (x,y): x, el.values()))
+ mind,maxd = minmax(dl.values())
+
+ gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n'
+
+ gr += "# src nodes\n"
+ for s in sl:
+ n,l = sl[s]; n = 1+float(n-mins)/(maxs-mins)
+ gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (`s`,`s`,n,n)
+ gr += "# event nodes\n"
+ for e in el:
+ n,l = el[e]; n = n = 1+float(n-mine)/(maxe-mine)
+ gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`e`,`e`,n,n)
+ for d in dl:
+ n = dl[d]; n = n = 1+float(n-mind)/(maxd-mind)
+ gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`d`,`d`,n,n)
+
+ gr += "###\n"
+ for s in sl:
+ n,l = sl[s]
+ for e in l:
+ gr += ' "src.%s" -> "evt.%s";\n' % (`s`,`e`)
+ for e in el:
+ n,l = el[e]
+ for d in l:
+ gr += ' "evt.%s" -> "dst.%s";\n' % (`e`,`d`)
+
+ gr += "}"
+ open("/tmp/aze","w").write(gr)
+ return do_graph(gr, **kargs)
+
+
+
+ def timeskew_graph(self, ip, **kargs):
+ """Tries to graph the timeskew between the timestamps and real time for a given ip"""
+ res = map(lambda x: self._elt2pkt(x), self.res)
+ b = filter(lambda x:x.haslayer(IP) and x.getlayer(IP).src == ip and x.haslayer(TCP), res)
+ c = []
+ for p in b:
+ opts = p.getlayer(TCP).options
+ for o in opts:
+ if o[0] == "Timestamp":
+ c.append((p.time,o[1][0]))
+ if not c:
+ warning("No timestamps found in packet list")
+ return
+ d = map(lambda (x,y): (x%2000,((x-c[0][0])-((y-c[0][1])/1000.0))),c)
+ g = Gnuplot.Gnuplot()
+ g.plot(Gnuplot.Data(d,**kargs))
+ return g
+
+ def _dump_document(self, **kargs):
+ d = pyx.document.document()
+ l = len(self.res)
+ for i in range(len(self.res)):
+ elt = self.res[i]
+ c = self._elt2pkt(elt).canvas_dump(**kargs)
+ cbb = c.bbox()
+ c.text(cbb.left(),cbb.top()+1,r"\font\cmssfont=cmss12\cmssfont{Frame %i/%i}" % (i,l),[pyx.text.size.LARGE])
+ if conf.verb >= 2:
+ os.write(1,".")
+ d.append(pyx.document.page(c, paperformat=pyx.document.paperformat.A4,
+ margin=1*pyx.unit.t_cm,
+ fittosize=1))
+ return d
+
+
+
+ def psdump(self, filename = None, **kargs):
+ """Creates a multipage poscript file with a psdump of every packet
+ filename: name of the file to write to. If empty, a temporary file is used and
+ conf.prog.psreader is called"""
+ d = self._dump_document(**kargs)
+ if filename is None:
+ filename = "/tmp/scapy.psd.%i" % os.getpid()
+ d.writePSfile(filename)
+ os.system("%s %s.ps &" % (conf.prog.psreader,filename))
+ else:
+ d.writePSfile(filename)
+ print
+
+ def pdfdump(self, filename = None, **kargs):
+ """Creates a PDF file with a psdump of every packet
+ filename: name of the file to write to. If empty, a temporary file is used and
+ conf.prog.pdfreader is called"""
+ d = self._dump_document(**kargs)
+ if filename is None:
+ filename = "/tmp/scapy.psd.%i" % os.getpid()
+ d.writePDFfile(filename)
+ os.system("%s %s.pdf &" % (conf.prog.pdfreader,filename))
+ else:
+ d.writePDFfile(filename)
+ print
+
+ def sr(self,multi=0):
+ """sr([multi=1]) -> (SndRcvList, PacketList)
+ Matches packets in the list and return ( (matched couples), (unmatched packets) )"""
+ remain = self.res[:]
+ sr = []
+ i = 0
+ while i < len(remain):
+ s = remain[i]
+ j = i
+ while j < len(remain)-1:
+ j += 1
+ r = remain[j]
+ if r.answers(s):
+ sr.append((s,r))
+ if multi:
+ remain[i]._answered=1
+ remain[j]._answered=2
+ continue
+ del(remain[j])
+ del(remain[i])
+ i -= 1
+ break
+ i += 1
+ if multi:
+ remain = filter(lambda x:not hasattr(x,"_answered"), remain)
+ return SndRcvList(sr),PacketList(remain)
+
+
+
+
+
+
+class Dot11PacketList(PacketList):
+ def __init__(self, res=None, name="Dot11List", stats=None):
+ if stats is None:
+ stats = [Dot11WEP, Dot11Beacon, UDP, ICMP, TCP]
+
+ PacketList.__init__(self, res, name, stats)
+ def toEthernet(self):
+ data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res))
+ r2 = []
+ for p in data:
+ q = p.copy()
+ q.unwep()
+ r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP
+ return PacketList(r2,name="Ether from %s"%self.listname)
+
+
+
+class SndRcvList(PacketList):
+ def __init__(self, res=None, name="Results", stats=None):
+ PacketList.__init__(self, res, name, stats)
+ def _elt2pkt(self, elt):
+ return elt[1]
+ def _elt2sum(self, elt):
+ return "%s ==> %s" % (elt[0].summary(),elt[1].summary())
+
+
+class ARPingResult(SndRcvList):
+ def __init__(self, res=None, name="ARPing", stats=None):
+ PacketList.__init__(self, res, name, stats)
+
+ def show(self):
+ for s,r in self.res:
+ print r.sprintf("%Ether.src% %ARP.psrc%")
+
+
+class AS_resolver:
+ server = None
+ options = "-k"
+ def __init__(self, server=None, port=43, options=None):
+ if server is not None:
+ self.server = server
+ self.port = port
+ if options is not None:
+ self.options = options
+
+ def _start(self):
+ self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.s.connect((self.server,self.port))
+ if self.options:
+ self.s.send(self.options+"\n")
+ self.s.recv(8192)
+ def _stop(self):
+ self.s.close()
+
+ def _parse_whois(self, txt):
+ asn,desc = None,""
+ for l in txt.splitlines():
+ if not asn and l.startswith("origin:"):
+ asn = l[7:].strip()
+ if l.startswith("descr:"):
+ if desc:
+ desc += r"\n"
+ desc += l[6:].strip()
+ if asn is not None and desc:
+ break
+ return asn,desc.strip()
+
+ def _resolve_one(self, ip):
+ self.s.send("%s\n" % ip)
+ x = ""
+ while not ("%" in x or "source" in x):
+ x += self.s.recv(8192)
+ asn, desc = self._parse_whois(x)
+ return ip,asn,desc
+ def resolve(self, *ips):
+ self._start()
+ ret = []
+ for ip in ips:
+ ip,asn,desc = self._resolve_one(ip)
+ if asn is not None:
+ ret.append((ip,asn,desc))
+ self._stop()
+ return ret
+
+class AS_resolver_riswhois(AS_resolver):
+ server = "riswhois.ripe.net"
+ options = "-k -M -1"
+
+
+class AS_resolver_radb(AS_resolver):
+ server = "whois.ra.net"
+ options = "-k -M"
+
+
+class AS_resolver_cymru(AS_resolver):
+ server = "whois.cymru.com"
+ options = None
+ def resolve(self, *ips):
+ ASNlist = []
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.connect((self.server,self.port))
+ s.send("begin\r\n"+"\r\n".join(ips)+"\r\nend\r\n")
+ r = ""
+ while 1:
+ l = s.recv(8192)
+ if l == "":
+ break
+ r += l
+ s.close()
+ for l in r.splitlines()[1:]:
+ if "|" not in l:
+ continue
+ asn,ip,desc = map(str.strip, l.split("|"))
+ if asn == "NA":
+ continue
+ asn = int(asn)
+ ASNlist.append((ip,asn,desc))
+ return ASNlist
+
+class AS_resolver_multi(AS_resolver):
+ resolvers_list = ( AS_resolver_cymru(),AS_resolver_riswhois(),AS_resolver_radb() )
+ def __init__(self, *reslist):
+ if reslist:
+ self.resolvers_list = reslist
+ def resolve(self, *ips):
+ todo = ips
+ ret = []
+ for ASres in self.resolvers_list:
+ res = ASres.resolve(*todo)
+ resolved = [ ip for ip,asn,desc in res ]
+ todo = [ ip for ip in todo if ip not in resolved ]
+ ret += res
+ return ret
+
+
+
+class TracerouteResult(SndRcvList):
+ def __init__(self, res=None, name="Traceroute", stats=None):
+ PacketList.__init__(self, res, name, stats)
+ self.graphdef = None
+ self.graphASres = 0
+ self.padding = 0
+ self.hloc = None
+ self.nloc = None
+
+ def show(self):
+ return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"),
+ s.ttl,
+ r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}")))
+
+
+ def get_trace(self):
+ trace = {}
+ for s,r in self.res:
+ if IP not in s:
+ continue
+ d = s[IP].dst
+ if d not in trace:
+ trace[d] = {}
+ trace[d][s[IP].ttl] = r[IP].src, ICMP not in r
+ for k in trace.values():
+ m = filter(lambda x:k[x][1], k.keys())
+ if not m:
+ continue
+ m = min(m)
+ for l in k.keys():
+ if l > m:
+ del(k[l])
+ return trace
+
+ def trace3D(self):
+ """Give a 3D representation of the traceroute.
+ right button: rotate the scene
+ middle button: zoom
+ left button: move the scene
+ left button on a ball: toggle IP displaying
+ ctrl-left button on a ball: scan ports 21,22,23,25,80 and 443 and display the result"""
+ trace = self.get_trace()
+ import visual
+
+ class IPsphere(visual.sphere):
+ def __init__(self, ip, **kargs):
+ visual.sphere.__init__(self, **kargs)
+ self.ip=ip
+ self.label=None
+ self.setlabel(self.ip)
+ def setlabel(self, txt,visible=None):
+ if self.label is not None:
+ if visible is None:
+ visible = self.label.visible
+ self.label.visible = 0
+ elif visible is None:
+ visible=0
+ self.label=visual.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible)
+ def action(self):
+ self.label.visible ^= 1
+
+ visual.scene = visual.display()
+ visual.scene.exit_on_close(0)
+ start = visual.box()
+ rings={}
+ tr3d = {}
+ for i in trace:
+ tr = trace[i]
+ tr3d[i] = []
+ ttl = tr.keys()
+ for t in range(1,max(ttl)+1):
+ if t not in rings:
+ rings[t] = []
+ if t in tr:
+ if tr[t] not in rings[t]:
+ rings[t].append(tr[t])
+ tr3d[i].append(rings[t].index(tr[t]))
+ else:
+ rings[t].append(("unk",-1))
+ tr3d[i].append(len(rings[t])-1)
+ for t in rings:
+ r = rings[t]
+ l = len(r)
+ for i in range(l):
+ if r[i][1] == -1:
+ col = (0.75,0.75,0.75)
+ elif r[i][1]:
+ col = visual.color.green
+ else:
+ col = visual.color.blue
+
+ s = IPsphere(pos=((l-1)*visual.cos(2*i*visual.pi/l),(l-1)*visual.sin(2*i*visual.pi/l),2*t),
+ ip = r[i][0],
+ color = col)
+ for trlst in tr3d.values():
+ if t <= len(trlst):
+ if trlst[t-1] == i:
+ trlst[t-1] = s
+ forecol = colgen(0.625, 0.4375, 0.25, 0.125)
+ for trlst in tr3d.values():
+ col = forecol.next()
+ start = (0,0,0)
+ for ip in trlst:
+ visual.cylinder(pos=start,axis=ip.pos-start,color=col,radius=0.2)
+ start = ip.pos
+
+ movcenter=None
+ while 1:
+ if visual.scene.kb.keys:
+ k = visual.scene.kb.getkey()
+ if k == "esc":
+ break
+ if visual.scene.mouse.events:
+ ev = visual.scene.mouse.getevent()
+ if ev.press == "left":
+ o = ev.pick
+ if o:
+ if ev.ctrl:
+ if o.ip == "unk":
+ continue
+ savcolor = o.color
+ o.color = (1,0,0)
+ a,b=sr(IP(dst=o.ip)/TCP(dport=[21,22,23,25,80,443]),timeout=2)
+ o.color = savcolor
+ if len(a) == 0:
+ txt = "%s:\nno results" % o.ip
+ else:
+ txt = "%s:\n" % o.ip
+ for s,r in a:
+ txt += r.sprintf("{TCP:%IP.src%:%TCP.sport% %TCP.flags%}{TCPerror:%IPerror.dst%:%TCPerror.dport% %IP.src% %ir,ICMP.type%}\n")
+ o.setlabel(txt, visible=1)
+ else:
+ if hasattr(o, "action"):
+ o.action()
+ elif ev.drag == "left":
+ movcenter = ev.pos
+ elif ev.drop == "left":
+ movcenter = None
+ if movcenter:
+ visual.scene.center -= visual.scene.mouse.pos-movcenter
+ movcenter = visual.scene.mouse.pos
+
+
+ def world_trace(self):
+ ips = {}
+ rt = {}
+ ports_done = {}
+ for s,r in self.res:
+ ips[r.src] = None
+ if s.haslayer(TCP) or s.haslayer(UDP):
+ trace_id = (s.src,s.dst,s.proto,s.dport)
+ elif s.haslayer(ICMP):
+ trace_id = (s.src,s.dst,s.proto,s.type)
+ else:
+ trace_id = (s.src,s.dst,s.proto,0)
+ trace = rt.get(trace_id,{})
+ if not r.haslayer(ICMP) or r.type != 11:
+ if ports_done.has_key(trace_id):
+ continue
+ ports_done[trace_id] = None
+ trace[s.ttl] = r.src
+ rt[trace_id] = trace
+
+ trt = {}
+ for trace_id in rt:
+ trace = rt[trace_id]
+ loctrace = []
+ for i in range(max(trace.keys())):
+ ip = trace.get(i,None)
+ if ip is None:
+ continue
+ loc = locate_ip(ip)
+ if loc is None:
+ continue
+# loctrace.append((ip,loc)) # no labels yet
+ loctrace.append(loc)
+ if loctrace:
+ trt[trace_id] = loctrace
+
+ tr = map(lambda x: Gnuplot.Data(x,with="lines"), trt.values())
+ g = Gnuplot.Gnuplot()
+ world = Gnuplot.File(conf.gnuplot_world,with="lines")
+ g.plot(world,*tr)
+ return g
+
+ def make_graph(self,ASres=None,padding=0):
+ if ASres is None:
+ ASres = conf.AS_resolver
+ self.graphASres = ASres
+ self.graphpadding = padding
+ ips = {}
+ rt = {}
+ ports = {}
+ ports_done = {}
+ for s,r in self.res:
+ r = r[IP] or r[IPv6] or r
+ s = s[IP] or s[IPv6] or s
+ ips[r.src] = None
+ if TCP in s:
+ trace_id = (s.src,s.dst,6,s.dport)
+ elif UDP in s:
+ trace_id = (s.src,s.dst,17,s.dport)
+ elif ICMP in s:
+ trace_id = (s.src,s.dst,1,s.type)
+ else:
+ trace_id = (s.src,s.dst,s.proto,0)
+ trace = rt.get(trace_id,{})
+ ttl = IPv6 in s and s.hlim or s.ttl
+ if not (ICMP in r and r[ICMP].type == 11) and not (IPv6 in r and ICMPv6TimeExceeded in r):
+ if trace_id in ports_done:
+ continue
+ ports_done[trace_id] = None
+ p = ports.get(r.src,[])
+ if TCP in r:
+ p.append(r.sprintf("<T%ir,TCP.sport%> %TCP.sport% %TCP.flags%"))
+ trace[ttl] = r.sprintf('"%r,src%":T%ir,TCP.sport%')
+ elif UDP in r:
+ p.append(r.sprintf("<U%ir,UDP.sport%> %UDP.sport%"))
+ trace[ttl] = r.sprintf('"%r,src%":U%ir,UDP.sport%')
+ elif ICMP in r:
+ p.append(r.sprintf("<I%ir,ICMP.type%> ICMP %ICMP.type%"))
+ trace[ttl] = r.sprintf('"%r,src%":I%ir,ICMP.type%')
+ else:
+ p.append(r.sprintf("{IP:<P%ir,proto%> IP %proto%}{IPv6:<P%ir,nh%> IPv6 %nh%}"))
+ trace[ttl] = r.sprintf('"%r,src%":{IP:P%ir,proto%}{IPv6:P%ir,nh%}')
+ ports[r.src] = p
+ else:
+ trace[ttl] = r.sprintf('"%r,src%"')
+ rt[trace_id] = trace
+
+ # Fill holes with unk%i nodes
+ unknown_label = incremental_label("unk%i")
+ blackholes = []
+ bhip = {}
+ for rtk in rt:
+ trace = rt[rtk]
+ k = trace.keys()
+ for n in range(min(k), max(k)):
+ if not trace.has_key(n):
+ trace[n] = unknown_label.next()
+ if not ports_done.has_key(rtk):
+ if rtk[2] == 1: #ICMP
+ bh = "%s %i/icmp" % (rtk[1],rtk[3])
+ elif rtk[2] == 6: #TCP
+ bh = "%s %i/tcp" % (rtk[1],rtk[3])
+ elif rtk[2] == 17: #UDP
+ bh = '%s %i/udp' % (rtk[1],rtk[3])
+ else:
+ bh = '%s %i/proto' % (rtk[1],rtk[2])
+ ips[bh] = None
+ bhip[rtk[1]] = bh
+ bh = '"%s"' % bh
+ trace[max(k)+1] = bh
+ blackholes.append(bh)
+
+ # Find AS numbers
+ ASN_query_list = dict.fromkeys(map(lambda x:x.rsplit(" ",1)[0],ips)).keys()
+ if ASres is None:
+ ASNlist = []
+ else:
+ ASNlist = ASres.resolve(*ASN_query_list)
+
+ ASNs = {}
+ ASDs = {}
+ for ip,asn,desc, in ASNlist:
+ if asn is None:
+ continue
+ iplist = ASNs.get(asn,[])
+ if ip in bhip:
+ if ip in ports:
+ iplist.append(ip)
+ iplist.append(bhip[ip])
+ else:
+ iplist.append(ip)
+ ASNs[asn] = iplist
+ ASDs[asn] = desc
+
+
+ backcolorlist=colgen("60","86","ba","ff")
+ forecolorlist=colgen("a0","70","40","20")
+
+ s = "digraph trace {\n"
+
+ s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
+
+ s += "\n#ASN clustering\n"
+ for asn in ASNs:
+ s += '\tsubgraph cluster_%s {\n' % asn
+ col = backcolorlist.next()
+ s += '\t\tcolor="#%s%s%s";' % col
+ s += '\t\tnode [fillcolor="#%s%s%s",style=filled];' % col
+ s += '\t\tfontsize = 10;'
+ s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn])
+ for ip in ASNs[asn]:
+
+ s += '\t\t"%s";\n'%ip
+ s += "\t}\n"
+
+
+
+
+ s += "#endpoints\n"
+ for p in ports:
+ s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p]))
+
+ s += "\n#Blackholes\n"
+ for bh in blackholes:
+ s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh
+
+ if padding:
+ s += "\n#Padding\n"
+ pad={}
+ for snd,rcv in self.res:
+ if rcv.src not in ports and rcv.haslayer(Padding):
+ p = rcv.getlayer(Padding).load
+ if p != "\x00"*len(p):
+ pad[rcv.src]=None
+ for rcv in pad:
+ s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv
+
+
+
+ s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
+
+
+ for rtk in rt:
+ s += "#---[%s\n" % `rtk`
+ s += '\t\tedge [color="#%s%s%s"];\n' % forecolorlist.next()
+ trace = rt[rtk]
+ k = trace.keys()
+ for n in range(min(k), max(k)):
+ s += '\t%s ->\n' % trace[n]
+ s += '\t%s;\n' % trace[max(k)]
+
+ s += "}\n";
+ self.graphdef = s
+
+ def graph(self, ASres=None, padding=0, **kargs):
+ """x.graph(ASres=conf.AS_resolver, other args):
+ ASres=None : no AS resolver => no clustering
+ ASres=AS_resolver() : default whois AS resolver (riswhois.ripe.net)
+ ASres=AS_resolver_cymru(): use whois.cymru.com whois database
+ ASres=AS_resolver(server="whois.ra.net")
+ type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
+ target: filename or redirect. Defaults pipe to Imagemagick's display program
+ prog: which graphviz program to use"""
+ if ASres is None:
+ ASres = conf.AS_resolver
+ if (self.graphdef is None or
+ self.graphASres != ASres or
+ self.graphpadding != padding):
+ self.make_graph(ASres,padding)
+
+ return do_graph(self.graphdef, **kargs)
+
+
+
+
+############
+## Fields ##
+############
+
+class Field:
+ """For more informations on how this work, please refer to
+ http://www.secdev.org/projects/scapy/files/scapydoc.pdf
+ chapter ``Adding a New Field''"""
+ islist=0
+ holds_packets=0
+ def __init__(self, name, default, fmt="H"):
+ self.name = name
+ if fmt[0] in "@=<>!":
+ self.fmt = fmt
+ else:
+ self.fmt = "!"+fmt
+ self.default = self.any2i(None,default)
+ self.sz = struct.calcsize(self.fmt)
+ self.owners = []
+
+ def register_owner(self, cls):
+ self.owners.append(cls)
+
+ def i2len(self, pkt, x):
+ """Convert internal value to a length usable by a FieldLenField"""
+ return self.sz
+ def i2count(self, pkt, x):
+ """Convert internal value to a number of elements usable by a FieldLenField.
+ Always 1 except for list fields"""
+ return 1
+ def h2i(self, pkt, x):
+ """Convert human value to internal value"""
+ return x
+ def i2h(self, pkt, x):
+ """Convert internal value to human value"""
+ return x
+ def m2i(self, pkt, x):
+ """Convert machine value to internal value"""
+ return x
+ def i2m(self, pkt, x):
+ """Convert internal value to machine value"""
+ if x is None:
+ x = 0
+ return x
+ def any2i(self, pkt, x):
+ """Try to understand the most input values possible and make an internal value from them"""
+ return self.h2i(pkt, x)
+ def i2repr(self, pkt, x):
+ """Convert internal value to a nice representation"""
+ if x is None:
+ x = 0
+ return repr(self.i2h(pkt,x))
+ def addfield(self, pkt, s, val):
+ """Add an internal value to a string"""
+ return s+struct.pack(self.fmt, self.i2m(pkt,val))
+ def getfield(self, pkt, s):
+ """Extract an internal value from a string"""
+ return s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
+ def do_copy(self, x):
+ if hasattr(x, "copy"):
+ return x.copy()
+ if type(x) is list:
+ x = x[:]
+ for i in xrange(len(x)):
+ if isinstance(x[i], Packet):
+ x[i] = x[i].copy()
+ return x
+ def __repr__(self):
+ return "<Field (%s).%s>" % (",".join(x.__name__ for x in self.owners),self.name)
+ def copy(self):
+ return copy.deepcopy(self)
+ def randval(self):
+ """Return a volatile object whose value is both random and suitable for this field"""
+ fmtt = self.fmt[-1]
+ if fmtt in "BHIQ":
+ return {"B":RandByte,"H":RandShort,"I":RandInt, "Q":RandLong}[fmtt]()
+ elif fmtt == "s":
+ if self.fmt[0] in "0123456789":
+ l = int(self.fmt[:-1])
+ else:
+ l = int(self.fmt[1:-1])
+ return RandBin(l)
+ else:
+ warning("no random class for [%s] (fmt=%s)." % (self.name, self.fmt))
+
+
+
+
+class Emph:
+ fld = ""
+ def __init__(self, fld):
+ self.fld = fld
+ def __getattr__(self, attr):
+ return getattr(self.fld,attr)
+ def __hash__(self):
+ return hash(self.fld)
+ def __eq__(self, other):
+ return self.fld == other
+
+
+class ActionField:
+ _fld = None
+ def __init__(self, fld, action_method, **kargs):
+ self._fld = fld
+ self._action_method = action_method
+ self._privdata = kargs
+ def any2i(self, pkt, val):
+ getattr(pkt, self._action_method)(val, self._fld, **self._privdata)
+ return getattr(self._fld, "any2i")(pkt, val)
+ def __getattr__(self, attr):
+ return getattr(self._fld,attr)
+
+
+class ConditionalField:
+ fld = None
+ def __init__(self, fld, cond):
+ self.fld = fld
+ self.cond = cond
+ def _evalcond(self,pkt):
+ return self.cond(pkt)
+
+ def getfield(self, pkt, s):
+ if self._evalcond(pkt):
+ return self.fld.getfield(pkt,s)
+ else:
+ return s,None
+
+ def addfield(self, pkt, s, val):
+ if self._evalcond(pkt):
+ return self.fld.addfield(pkt,s,val)
+ else:
+ return s
+ def __getattr__(self, attr):
+ return getattr(self.fld,attr)
+
+
+class PadField:
+ """Add bytes after the proxified field so that it ends at the specified
+ alignment from its begining"""
+ _fld = None
+ def __init__(self, fld, align, padwith=None):
+ self._fld = fld
+ self._align = align
+ self._padwith = padwith or ""
+
+ def addfield(self, pkt, s, val):
+ sval = self._fld.addfield(pkt, "", val)
+ return s+sval+struct.pack("%is" % (-len(sval)%self._align), self._padwith)
+
+ def __getattr__(self, attr):
+ return getattr(self._fld,attr)
+
+
+class MACField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "6s")
+ def i2m(self, pkt, x):
+ if x is None:
+ return "\0\0\0\0\0\0"
+ return mac2str(x)
+ def m2i(self, pkt, x):
+ return str2mac(x)
+ def any2i(self, pkt, x):
+ if type(x) is str and len(x) is 6:
+ x = self.m2i(pkt, x)
+ return x
+ def i2repr(self, pkt, x):
+ x = self.i2h(pkt, x)
+ if self in conf.resolve:
+ x = conf.manufdb._resolve_MAC(x)
+ return x
+ def randval(self):
+ return RandMAC()
+
+class DestMACField(MACField):
+ def __init__(self, name):
+ MACField.__init__(self, name, None)
+ def i2h(self, pkt, x):
+ if x is None:
+ dstip = None
+ if isinstance(pkt.payload, IPv6):
+ dstip = pkt.payload.dst
+ elif isinstance(pkt.payload, IP):
+ dstip = pkt.payload.dst
+ elif isinstance(pkt.payload, ARP):
+ dstip = pkt.payload.pdst
+ if isinstance(dstip, Gen):
+ dstip = dstip.__iter__().next()
+ if dstip is not None:
+ if isinstance(pkt.payload, IPv6):
+ x = getmacbyip6(dstip)
+ else:
+ x = getmacbyip(dstip)
+ if x is None:
+ x = "ff:ff:ff:ff:ff:ff"
+ warning("Mac address to reach %s not found\n"%dstip)
+ return MACField.i2h(self, pkt, x)
+ def i2m(self, pkt, x):
+ return MACField.i2m(self, pkt, self.i2h(pkt, x))
+
+class SourceMACField(MACField):
+ def __init__(self, name):
+ MACField.__init__(self, name, None)
+ def i2h(self, pkt, x):
+ if x is None:
+ dstip = None
+ if isinstance(pkt.payload, IPv6):
+ dstip = pkt.payload.dst
+ elif isinstance(pkt.payload, IP):
+ dstip = pkt.payload.dst
+ elif isinstance(pkt.payload, ARP):
+ dstip = pkt.payload.pdst
+ if isinstance(dstip, Gen):
+ dstip = dstip.__iter__().next()
+ if dstip is not None:
+ if isinstance(pkt.payload, IPv6):
+ iff,a,nh = conf.route6.route(dstip)
+ else:
+ iff,a,gw = conf.route.route(dstip)
+ try:
+ x = get_if_hwaddr(iff)
+ except:
+ pass
+ if x is None:
+ x = "00:00:00:00:00:00"
+ return MACField.i2h(self, pkt, x)
+ def i2m(self, pkt, x):
+ return MACField.i2m(self, pkt, self.i2h(pkt, x))
+
+class ARPSourceMACField(MACField):
+ def __init__(self, name):
+ MACField.__init__(self, name, None)
+ def i2h(self, pkt, x):
+ if x is None:
+ dstip = pkt.pdst
+ if isinstance(dstip, Gen):
+ dstip = dstip.__iter__().next()
+ if dstip is not None:
+ iff,a,gw = conf.route.route(dstip)
+ try:
+ x = get_if_hwaddr(iff)
+ except:
+ pass
+ if x is None:
+ x = "00:00:00:00:00:00"
+ return MACField.i2h(self, pkt, x)
+ def i2m(self, pkt, x):
+ return MACField.i2m(self, pkt, self.i2h(pkt, x))
+
+class Dot11AddrMACField(MACField):
+ def is_applicable(self, pkt):
+ return 1
+ def addfield(self, pkt, s, val):
+ if self.is_applicable(pkt):
+ return MACField.addfield(self, pkt, s, val)
+ else:
+ return s
+ def getfield(self, pkt, s):
+ if self.is_applicable(pkt):
+ return MACField.getfield(self, pkt, s)
+ else:
+ return s,None
+
+class Dot11Addr2MACField(Dot11AddrMACField):
+ def is_applicable(self, pkt):
+ if pkt.type == 1:
+ return pkt.subtype in [ 0xb, 0xa, 0xe, 0xf] # RTS, PS-Poll, CF-End, CF-End+CF-Ack
+ return 1
+
+class Dot11Addr3MACField(Dot11AddrMACField):
+ def is_applicable(self, pkt):
+ if pkt.type in [0,2]:
+ return 1
+ return 0
+
+class Dot11Addr4MACField(Dot11AddrMACField):
+ def is_applicable(self, pkt):
+ if pkt.type == 2:
+ if pkt.FCfield & 0x3 == 0x3: # To-DS and From-DS are set
+ return 1
+ return 0
+
+class IPField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "4s")
+ def h2i(self, pkt, x):
+ if type(x) is str:
+ try:
+ inet_aton(x)
+ except socket.error:
+ x = Net(x)
+ elif type(x) is list:
+ x = [self.h2i(pkt, n) for n in x]
+ return x
+ def resolve(self, x):
+ if self in conf.resolve:
+ try:
+ ret = socket.gethostbyaddr(x)[0]
+ except:
+ pass
+ else:
+ if ret:
+ return ret
+ return x
+ def i2m(self, pkt, x):
+ return inet_aton(x)
+ def m2i(self, pkt, x):
+ return inet_ntoa(x)
+ def any2i(self, pkt, x):
+ return self.h2i(pkt,x)
+ def i2repr(self, pkt, x):
+ return self.resolve(self.i2h(pkt, x))
+ def randval(self):
+ return RandIP()
+
+class SourceIPField(IPField):
+ def __init__(self, name, dstname):
+ IPField.__init__(self, name, None)
+ self.dstname = dstname
+ def i2m(self, pkt, x):
+ if x is None:
+ iff,x,gw = conf.route.route(getattr(pkt,self.dstname))
+ return IPField.i2m(self, pkt, x)
+ def i2h(self, pkt, x):
+ if x is None:
+ dst=getattr(pkt,self.dstname)
+ if isinstance(dst,Gen):
+ r = map(conf.route.route, dst)
+ r.sort()
+ if r[0] == r[-1]:
+ x=r[0][1]
+ else:
+ warning("More than one possible route for %s"%repr(dst))
+ return None
+ else:
+ iff,x,gw = conf.route.route(dst)
+ return IPField.i2h(self, pkt, x)
+
+
+
+
+class ByteField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "B")
+
+class XByteField(ByteField):
+ def i2repr(self, pkt, x):
+ if x is None:
+ x = 0
+ return lhex(self.i2h(pkt, x))
+
+class X3BytesField(XByteField):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "!I")
+ def addfield(self, pkt, s, val):
+ return s+struct.pack(self.fmt, self.i2m(pkt,val))[1:4]
+ def getfield(self, pkt, s):
+ return s[3:], self.m2i(pkt, struct.unpack(self.fmt, "\x00"+s[:3])[0])
+
+
+class ShortField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "H")
+
+class LEShortField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "<H")
+
+class XShortField(ShortField):
+ def i2repr(self, pkt, x):
+ if x is None:
+ x = 0
+ return lhex(self.i2h(pkt, x))
+
+
+class IntField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "I")
+
+class SignedIntField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "i")
+ def randval(self):
+ return RandSInt()
+
+class LEIntField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "<I")
+
+class LESignedIntField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "<i")
+ def randval(self):
+ return RandSInt()
+
+class XIntField(IntField):
+ def i2repr(self, pkt, x):
+ if x is None:
+ x = 0
+ return lhex(self.i2h(pkt, x))
+
+
+class LongField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "Q")
+
+class XLongField(LongField):
+ def i2repr(self, pkt, x):
+ if x is None:
+ x = 0
+ return lhex(self.i2h(pkt, x))
+
+def FIELD_LENGTH_MANAGEMENT_DEPRECATION(x):
+ try:
+ for tb in traceback.extract_stack()+[("??",-1,None,"")]:
+ f,l,_,line = tb
+ if line.startswith("fields_desc"):
+ break
+ except:
+ f,l="??",-1
+ log_loading.warning("Deprecated use of %s (%s l. %i). See http://trac.secdev.org/scapy/wiki/LengthFields" % (x,f,l))
+
+class StrField(Field):
+ def __init__(self, name, default, fmt="H", remain=0, shift=0):
+ Field.__init__(self,name,default,fmt)
+ self.remain = remain
+ self.shift = shift
+ if shift != 0:
+ FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+ def i2len(self, pkt, i):
+ return len(i)+self.shift
+ def i2m(self, pkt, x):
+ if x is None:
+ x = ""
+ return x
+ def addfield(self, pkt, s, val):
+ return s+self.i2m(pkt, val)
+ def getfield(self, pkt, s):
+ if self.remain == 0:
+ return "",self.m2i(pkt, s)
+ else:
+ return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
+ def randval(self):
+ return RandBin(RandNum(0,1200))
+
+class PacketField(StrField):
+ holds_packets=1
+ def __init__(self, name, default, cls, remain=0, shift=0):
+ StrField.__init__(self, name, default, remain=remain, shift=shift)
+ self.cls = cls
+ def i2m(self, pkt, i):
+ return str(i)
+ def m2i(self, pkt, m):
+ return self.cls(m)
+ def getfield(self, pkt, s):
+ i = self.m2i(pkt, s)
+ remain = ""
+ if i.haslayer(Padding):
+ r = i.getlayer(Padding)
+ del(r.underlayer.payload)
+ remain = r.load
+ return remain,i
+
+class PacketLenField(PacketField):
+ holds_packets=1
+ def __init__(self, name, default, cls, fld=None, length_from=None, shift=0):
+ PacketField.__init__(self, name, default, cls, shift=shift)
+ self.length_from = length_from
+ if fld is not None or shift != 0:
+ FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+ self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
+ def getfield(self, pkt, s):
+ l = self.length_from(pkt)
+ i = self.m2i(pkt, s[:l])
+ return s[l:],i
+
+
+class PacketListField(PacketField):
+ islist = 1
+ holds_packets=1
+ def __init__(self, name, default, cls, fld=None, count_from=None, length_from=None, shift=0):
+ if default is None:
+ default = [] # Create a new list for each instance
+ PacketField.__init__(self, name, default, cls, shift=shift)
+ self.count_from = count_from
+ self.length_from = length_from
+
+ if fld is not None or shift != 0:
+ FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+ if fld is not None:
+ self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
+
+ def any2i(self, pkt, x):
+ if type(x) is not list:
+ return [x]
+ else:
+ return x
+ def i2count(self, pkt, val):
+ if type(val) is list:
+ return len(val)
+ return 1
+ def i2len(self, pkt, val):
+ return sum( len(p) for p in val )
+ def do_copy(self, x):
+ return map(lambda p:p.copy(), x)
+ def getfield(self, pkt, s):
+ c = l = None
+ if self.length_from is not None:
+ l = self.length_from(pkt)
+ elif self.count_from is not None:
+ c = self.count_from(pkt)
+
+ lst = []
+ ret = ""
+ remain = s
+ if l is not None:
+ remain,ret = s[:l],s[l:]
+ while remain:
+ if c is not None:
+ if c <= 0:
+ break
+ c -= 1
+ p = self.m2i(pkt,remain)
+ if Padding in p:
+ pad = p[Padding]
+ remain = pad.load
+ del(pad.underlayer.payload)
+ else:
+ remain = ""
+ lst.append(p)
+ return remain+ret,lst
+ def addfield(self, pkt, s, val):
+ return s+"".join(map(str, val))
+
+
+class StrFixedLenField(StrField):
+ def __init__(self, name, default, length=None, length_from=None, shift=0):
+ StrField.__init__(self, name, default, shift=shift)
+ self.length_from = length_from
+ if length is not None:
+ self.length_from = lambda pkt,length=length: length
+ def getfield(self, pkt, s):
+ l = self.length_from(pkt)
+ return s[l:], self.m2i(pkt,s[:l])
+ def addfield(self, pkt, s, val):
+ l = self.length_from(pkt)
+ return s+struct.pack("%is"%l,self.i2m(pkt, val))
+ def randval(self):
+ try:
+ l = self.length_from(None)
+ except:
+ l = RandNum(0,200)
+ return RandBin(l)
+
+class NetBIOSNameField(StrFixedLenField):
+ def __init__(self, name, default, length=31, shift=0):
+ StrFixedLenField.__init__(self, name, default, length, shift=shift)
+ def i2m(self, pkt, x):
+ if x is None:
+ x = ""
+ x += " "*(self.length/2)
+ x = x[:(self.length/2)]
+ x = "".join(map(lambda x: chr(0x41+(ord(x)>>4))+chr(0x41+(ord(x)&0xf)), x))
+ x = " "+x
+ return x
+ def m2i(self, pkt, x):
+ x = x.strip("\x00").strip(" ")
+ return "".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
+
+class StrLenField(StrField):
+ def __init__(self, name, default, fld=None, length_from=None, shift=0):
+ StrField.__init__(self, name, default, shift=shift)
+ self.length_from = length_from
+ if fld is not None or shift != 0:
+ FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+ self.length_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
+ def getfield(self, pkt, s):
+ l = self.length_from(pkt)
+ return s[l:], self.m2i(pkt,s[:l])
+
+class FieldListField(Field):
+ islist=1
+ def __init__(self, name, default, field, fld=None, shift=0, length_from=None, count_from=None):
+ if default is None:
+ default = [] # Create a new list for each instance
+ Field.__init__(self, name, default)
+ self.count_from = count_from
+ self.length_from = length_from
+ self.field = field
+ if fld is not None or shift != 0:
+ FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+ self.count_from = lambda pkt,fld=fld,shift=shift: getattr(pkt,fld)-shift
+
+
+ def i2count(self, pkt, val):
+ if type(val) is list:
+ return len(val)
+ return 1
+ def i2len(self, pkt, val):
+ return sum( self.field.i2len(pkt,v) for v in val )
+
+ def i2m(self, pkt, val):
+ if val is None:
+ val = []
+ return val
+ def any2i(self, pkt, x):
+ if type(x) is not list:
+ return [x]
+ else:
+ return x
+ def addfield(self, pkt, s, val):
+ val = self.i2m(pkt, val)
+ for v in val:
+ s = self.field.addfield(pkt, s, v)
+ return s
+ def getfield(self, pkt, s):
+ c = l = None
+ if self.length_from is not None:
+ l = self.length_from(pkt)
+ elif self.count_from is not None:
+ c = self.count_from(pkt)
+
+ val = []
+ ret=""
+ if l is not None:
+ s,ret = s[:l],s[l:]
+
+ while s:
+ if c is not None:
+ if c <= 0:
+ break
+ c -= 1
+ s,v = self.field.getfield(pkt, s)
+ val.append(v)
+ return s+ret, val
+
+class FieldLenField(Field):
+ def __init__(self, name, default, length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):
+ Field.__init__(self, name, default, fmt)
+ self.length_of=length_of
+ self.count_of=count_of
+ self.adjust=adjust
+ if fld is not None:
+ FIELD_LENGTH_MANAGEMENT_DEPRECATION(self.__class__.__name__)
+ self.length_of = fld
+ def i2m(self, pkt, x):
+ if x is None:
+ if self.length_of is not None:
+ fld,fval = pkt.getfield_and_val(self.length_of)
+ f = fld.i2len(pkt, fval)
+ else:
+ fld,fval = pkt.getfield_and_val(self.count_of)
+ f = fld.i2count(pkt, fval)
+ x = self.adjust(pkt,f)
+ return x
+
+# see http://www.iana.org/assignments/ipsec-registry for details
+ISAKMPAttributeTypes= { "Encryption": (1, { "DES-CBC" : 1,
+ "IDEA-CBC" : 2,
+ "Blowfish-CBC" : 3,
+ "RC5-R16-B64-CBC" : 4,
+ "3DES-CBC" : 5,
+ "CAST-CBC" : 6,
+ "AES-CBC" : 7,
+ "CAMELLIA-CBC" : 8, }, 0),
+ "Hash": (2, { "MD5": 1,
+ "SHA": 2,
+ "Tiger": 3,
+ "SHA2-256": 4,
+ "SHA2-384": 5,
+ "SHA2-512": 6,}, 0),
+ "Authentication":(3, { "PSK": 1,
+ "DSS": 2,
+ "RSA Sig": 3,
+ "RSA Encryption": 4,
+ "RSA Encryption Revised": 5,
+ "ElGamal Encryption": 6,
+ "ElGamal Encryption Revised": 7,
+ "ECDSA Sig": 8,
+ "HybridInitRSA": 64221,
+ "HybridRespRSA": 64222,
+ "HybridInitDSS": 64223,
+ "HybridRespDSS": 64224,
+ "XAUTHInitPreShared": 65001,
+ "XAUTHRespPreShared": 65002,
+ "XAUTHInitDSS": 65003,
+ "XAUTHRespDSS": 65004,
+ "XAUTHInitRSA": 65005,
+ "XAUTHRespRSA": 65006,
+ "XAUTHInitRSAEncryption": 65007,
+ "XAUTHRespRSAEncryption": 65008,
+ "XAUTHInitRSARevisedEncryption": 65009,
+ "XAUTHRespRSARevisedEncryptio": 65010, }, 0),
+ "GroupDesc": (4, { "768MODPgr" : 1,
+ "1024MODPgr" : 2,
+ "EC2Ngr155" : 3,
+ "EC2Ngr185" : 4,
+ "1536MODPgr" : 5,
+ "2048MODPgr" : 14,
+ "3072MODPgr" : 15,
+ "4096MODPgr" : 16,
+ "6144MODPgr" : 17,
+ "8192MODPgr" : 18, }, 0),
+ "GroupType": (5, {"MODP": 1,
+ "ECP": 2,
+ "EC2N": 3}, 0),
+ "GroupPrime": (6, {}, 1),
+ "GroupGenerator1":(7, {}, 1),
+ "GroupGenerator2":(8, {}, 1),
+ "GroupCurveA": (9, {}, 1),
+ "GroupCurveB": (10, {}, 1),
+ "LifeType": (11, {"Seconds": 1,
+ "Kilobytes": 2, }, 0),
+ "LifeDuration": (12, {}, 1),
+ "PRF": (13, {}, 0),
+ "KeyLength": (14, {}, 0),
+ "FieldSize": (15, {}, 0),
+ "GroupOrder": (16, {}, 1),
+ }
+
+# the name 'ISAKMPTransformTypes' is actually a misnomer (since the table
+# holds info for all ISAKMP Attribute types, not just transforms, but we'll
+# keep it for backwards compatibility... for now at least
+ISAKMPTransformTypes = ISAKMPAttributeTypes
+
+ISAKMPTransformNum = {}
+for n in ISAKMPTransformTypes:
+ val = ISAKMPTransformTypes[n]
+ tmp = {}
+ for e in val[1]:
+ tmp[val[1][e]] = e
+ ISAKMPTransformNum[val[0]] = (n,tmp, val[2])
+del(n)
+del(e)
+del(tmp)
+del(val)
+
+
+class ISAKMPTransformSetField(StrLenField):
+ islist=1
+ def type2num(self, (typ,val)):
+ type_val,enc_dict,tlv = ISAKMPTransformTypes.get(typ, (typ,{},0))
+ val = enc_dict.get(val, val)
+ s = ""
+ if (val & ~0xffff):
+ if not tlv:
+ warning("%r should not be TLV but is too big => using TLV encoding" % typ)
+ n = 0
+ while val:
+ s = chr(val&0xff)+s
+ val >>= 8
+ n += 1
+ val = n
+ else:
+ type_val |= 0x8000
+ return struct.pack("!HH",type_val, val)+s
+ def num2type(self, typ, enc):
+ val = ISAKMPTransformNum.get(typ,(typ,{}))
+ enc = val[1].get(enc,enc)
+ return (val[0],enc)
+ def i2m(self, pkt, i):
+ if i is None:
+ return ""
+ i = map(self.type2num, i)
+ return "".join(i)
+ def m2i(self, pkt, m):
+ # I try to ensure that we don't read off the end of our packet based
+ # on bad length fields we're provided in the packet. There are still
+ # conditions where struct.unpack() may not get enough packet data, but
+ # worst case that should result in broken attributes (which would
+ # be expected). (wam)
+ lst = []
+ while len(m) >= 4:
+ trans_type, = struct.unpack("!H", m[:2])
+ is_tlv = not (trans_type & 0x8000)
+ if is_tlv:
+ # We should probably check to make sure the attribute type we
+ # are looking at is allowed to have a TLV format and issue a
+ # warning if we're given an TLV on a basic attribute.
+ value_len, = struct.unpack("!H", m[2:4])
+ if value_len+4 > len(m):
+ warning("Bad length for ISAKMP tranform type=%#6x" % trans_type)
+ value = m[4:4+value_len]
+ value = reduce(lambda x,y: (x<<8L)|y, struct.unpack("!%s" % ("B"*len(value),), value),0)
+ else:
+ trans_type &= 0x7fff
+ value_len=0
+ value, = struct.unpack("!H", m[2:4])
+ m=m[4+value_len:]
+ lst.append(self.num2type(trans_type, value))
+ if len(m) > 0:
+ warning("Extra bytes after ISAKMP transform dissection [%r]" % m)
+ return lst
+
+class StrNullField(StrField):
+ def addfield(self, pkt, s, val):
+ return s+self.i2m(pkt, val)+"\x00"
+ def getfield(self, pkt, s):
+ l = s.find("\x00")
+ if l < 0:
+ #XXX \x00 not found
+ return "",s
+ return s[l+1:],self.m2i(pkt, s[:l])
+ def randval(self):
+ return RandTermString(RandNum(0,1200),"\x00")
+
+class StrStopField(StrField):
+ def __init__(self, name, default, stop, additionnal=0):
+ Field.__init__(self, name, default)
+ self.stop=stop
+ self.additionnal=additionnal
+ def getfield(self, pkt, s):
+ l = s.find(self.stop)
+ if l < 0:
+ return "",s
+# raise Scapy_Exception,"StrStopField: stop value [%s] not found" %stop
+ l += len(self.stop)+self.additionnal
+ return s[l:],s[:l]
+ def randval(self):
+ return RandTermString(RandNum(0,1200),self.stop)
+
+class LenField(Field):
+ def i2m(self, pkt, x):
+ if x is None:
+ x = len(pkt.payload)
+ return x
+
+class BCDFloatField(Field):
+ def i2m(self, pkt, x):
+ return int(256*x)
+ def m2i(self, pkt, x):
+ return x/256.0
+
+class BitField(Field):
+ def __init__(self, name, default, size):
+ Field.__init__(self, name, default)
+ self.rev = size < 0
+ self.size = abs(size)
+ def reverse(self, val):
+ if self.size == 16:
+ val = socket.ntohs(val)
+ elif self.size == 32:
+ val = socket.ntohl(val)
+ return val
+
+ def addfield(self, pkt, s, val):
+ val = self.i2m(pkt, val)
+ if type(s) is tuple:
+ s,bitsdone,v = s
+ else:
+ bitsdone = 0
+ v = 0
+ if self.rev:
+ val = self.reverse(val)
+ v <<= self.size
+ v |= val & ((1L<<self.size) - 1)
+ bitsdone += self.size
+ while bitsdone >= 8:
+ bitsdone -= 8
+ s = s+struct.pack("!B", v >> bitsdone)
+ v &= (1L<<bitsdone)-1
+ if bitsdone:
+ return s,bitsdone,v
+ else:
+ return s
+ def getfield(self, pkt, s):
+ if type(s) is tuple:
+ s,bn = s
+ else:
+ bn = 0
+ # we don't want to process all the string
+ nb_bytes = (self.size+bn-1)/8 + 1
+ w = s[:nb_bytes]
+
+ # split the substring byte by byte
+ bytes = struct.unpack('!%dB' % nb_bytes , w)
+
+ b = 0L
+ for c in range(nb_bytes):
+ b |= long(bytes[c]) << (nb_bytes-c-1)*8
+
+ # get rid of high order bits
+ b &= (1L << (nb_bytes*8-bn)) - 1
+
+ # remove low order bits
+ b = b >> (nb_bytes*8 - self.size - bn)
+
+ if self.rev:
+ b = self.reverse(b)
+
+ bn += self.size
+ s = s[bn/8:]
+ bn = bn%8
+ b = self.m2i(pkt, b)
+ if bn:
+ return (s,bn),b
+ else:
+ return s,b
+ def randval(self):
+ return RandNum(0,2**self.size-1)
+
+
+class BitFieldLenField(BitField):
+ def __init__(self, name, default, size, length_of=None, count_of=None, adjust=lambda pkt,x:x):
+ BitField.__init__(self, name, default, size)
+ self.length_of=length_of
+ self.count_of=count_of
+ self.adjust=adjust
+ def i2m(self, pkt, x):
+ return FieldLenField.i2m.im_func(self, pkt, x)
+
+
+class XBitField(BitField):
+ def i2repr(self, pkt, x):
+ return lhex(self.i2h(pkt,x))
+
+
+class EnumField(Field):
+ def __init__(self, name, default, enum, fmt = "H"):
+ i2s = self.i2s = {}
+ s2i = self.s2i = {}
+ if type(enum) is list:
+ keys = xrange(len(enum))
+ else:
+ keys = enum.keys()
+ if filter(lambda x: type(x) is str, keys):
+ i2s,s2i = s2i,i2s
+ for k in keys:
+ i2s[k] = enum[k]
+ s2i[enum[k]] = k
+ Field.__init__(self, name, default, fmt)
+ def any2i_one(self, pkt, x):
+ if type(x) is str:
+ x = self.s2i[x]
+ return x
+ def i2repr_one(self, pkt, x):
+ if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
+ return self.i2s[x]
+ return repr(x)
+
+ def any2i(self, pkt, x):
+ if type(x) is list:
+ return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
+ else:
+ return self.any2i_one(pkt,x)
+ def i2repr(self, pkt, x):
+ if type(x) is list:
+ return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
+ else:
+ return self.i2repr_one(pkt,x)
+
+class CharEnumField(EnumField):
+ def __init__(self, name, default, enum, fmt = "1s"):
+ EnumField.__init__(self, name, default, enum, fmt)
+ k = self.i2s.keys()
+ if k and len(k[0]) != 1:
+ self.i2s,self.s2i = self.s2i,self.i2s
+ def any2i_one(self, pkt, x):
+ if len(x) != 1:
+ x = self.s2i[x]
+ return x
+
+class BitEnumField(BitField,EnumField):
+ def __init__(self, name, default, size, enum):
+ EnumField.__init__(self, name, default, enum)
+ self.rev = size < 0
+ self.size = abs(size)
+ def any2i(self, pkt, x):
+ return EnumField.any2i(self, pkt, x)
+ def i2repr(self, pkt, x):
+ return EnumField.i2repr(self, pkt, x)
+
+class ShortEnumField(EnumField):
+ def __init__(self, name, default, enum):
+ EnumField.__init__(self, name, default, enum, "H")
+
+class LEShortEnumField(EnumField):
+ def __init__(self, name, default, enum):
+ EnumField.__init__(self, name, default, enum, "<H")
+
+class ByteEnumField(EnumField):
+ def __init__(self, name, default, enum):
+ EnumField.__init__(self, name, default, enum, "B")
+
+class IntEnumField(EnumField):
+ def __init__(self, name, default, enum):
+ EnumField.__init__(self, name, default, enum, "I")
+
+class SignedIntEnumField(EnumField):
+ def __init__(self, name, default, enum):
+ EnumField.__init__(self, name, default, enum, "i")
+ def randval(self):
+ return RandSInt()
+
+class LEIntEnumField(EnumField):
+ def __init__(self, name, default, enum):
+ EnumField.__init__(self, name, default, enum, "<I")
+
+class XShortEnumField(ShortEnumField):
+ def i2repr_one(self, pkt, x):
+ if self not in conf.noenum and not isinstance(x,VolatileValue) and x in self.i2s:
+ return self.i2s[x]
+ return lhex(x)
+
+# Little endian long field
+class LELongField(Field):
+ def __init__(self, name, default):
+ Field.__init__(self, name, default, "<Q")
+
+# Little endian fixed length field
+class LEFieldLenField(FieldLenField):
+ def __init__(self, name, default, length_of=None, fmt = "<H", count_of=None, adjust=lambda pkt,x:x, fld=None):
+ FieldLenField.__init__(self, name, default, length_of=length_of, fmt=fmt, fld=fld, adjust=adjust)
+
+
+class FlagsField(BitField):
+ def __init__(self, name, default, size, names):
+ BitField.__init__(self, name, default, size)
+ self.multi = type(names) is list
+ if self.multi:
+ self.names = map(lambda x:[x], names)
+ else:
+ self.names = names
+ def any2i(self, pkt, x):
+ if type(x) is str:
+ if self.multi:
+ x = map(lambda y:[y], x.split("+"))
+ y = 0
+ for i in x:
+ y |= 1 << self.names.index(i)
+ x = y
+ return x
+ def i2repr(self, pkt, x):
+ if self.multi:
+ r = []
+ else:
+ r = ""
+ i=0
+ while x:
+ if x & 1:
+ r += self.names[i]
+ i += 1
+ x >>= 1
+ if self.multi:
+ r = "+".join(r)
+ return r
+
+
+
+
+
+class IPoptionsField(StrField):
+ def i2m(self, pkt, x):
+ return x+"\x00"*(3-((len(x)+3)%4))
+ def getfield(self, pkt, s):
+ opsz = (pkt.ihl-5)*4
+ if opsz < 0:
+ warning("bad ihl (%i). Assuming ihl=5"%pkt.ihl)
+ opsz = 0
+ return s[opsz:],s[:opsz]
+ def randval(self):
+ return RandBin(RandNum(0,39))
+
+
+TCPOptions = (
+ { 0 : ("EOL",None),
+ 1 : ("NOP",None),
+ 2 : ("MSS","!H"),
+ 3 : ("WScale","!B"),
+ 4 : ("SAckOK",None),
+ 5 : ("SAck","!"),
+ 8 : ("Timestamp","!II"),
+ 14 : ("AltChkSum","!BH"),
+ 15 : ("AltChkSumOpt",None)
+ },
+ { "EOL":0,
+ "NOP":1,
+ "MSS":2,
+ "WScale":3,
+ "SAckOK":4,
+ "SAck":5,
+ "Timestamp":8,
+ "AltChkSum":14,
+ "AltChkSumOpt":15,
+ } )
+
+class TCPOptionsField(StrField):
+ islist=1
+ def getfield(self, pkt, s):
+ opsz = (pkt.dataofs-5)*4
+ if opsz < 0:
+ warning("bad dataofs (%i). Assuming dataofs=5"%pkt.dataofs)
+ opsz = 0
+ return s[opsz:],self.m2i(pkt,s[:opsz])
+ def m2i(self, pkt, x):
+ opt = []
+ while x:
+ onum = ord(x[0])
+ if onum == 0:
+ opt.append(("EOL",None))
+ x=x[1:]
+ break
+ if onum == 1:
+ opt.append(("NOP",None))
+ x=x[1:]
+ continue
+ olen = ord(x[1])
+ if olen < 2:
+ warning("Malformed TCP option (announced length is %i)" % olen)
+ olen = 2
+ oval = x[2:olen]
+ if TCPOptions[0].has_key(onum):
+ oname, ofmt = TCPOptions[0][onum]
+ if onum == 5: #SAck
+ ofmt += "%iI" % (len(oval)/4)
+ if ofmt and struct.calcsize(ofmt) == len(oval):
+ oval = struct.unpack(ofmt, oval)
+ if len(oval) == 1:
+ oval = oval[0]
+ opt.append((oname, oval))
+ else:
+ opt.append((onum, oval))
+ x = x[olen:]
+ return opt
+
+ def i2m(self, pkt, x):
+ opt = ""
+ for oname,oval in x:
+ if type(oname) is str:
+ if oname == "NOP":
+ opt += "\x01"
+ continue
+ elif oname == "EOL":
+ opt += "\x00"
+ continue
+ elif TCPOptions[1].has_key(oname):
+ onum = TCPOptions[1][oname]
+ ofmt = TCPOptions[0][onum][1]
+ if onum == 5: #SAck
+ ofmt += "%iI" % len(oval)
+ if ofmt is not None and (type(oval) is not str or "s" in ofmt):
+ if type(oval) is not tuple:
+ oval = (oval,)
+ oval = struct.pack(ofmt, *oval)
+ else:
+ warning("option [%s] unknown. Skipped."%oname)
+ continue
+ else:
+ onum = oname
+ if type(oval) is not str:
+ warning("option [%i] is not string."%onum)
+ continue
+ opt += chr(onum)+chr(2+len(oval))+oval
+ return opt+"\x00"*(3-((len(opt)+3)%4))
+ def randval(self):
+ return [] # XXX
+
+
+class DNSStrField(StrField):
+ def i2m(self, pkt, x):
+ x = [k[:63] for k in x.split(".")] # Truncate chunks that cannont be encoded (more than 63 bytes..)
+ x = map(lambda y: chr(len(y))+y, x)
+ x = "".join(x)
+ if x[-1] != "\x00":
+ x += "\x00"
+ return x
+ def getfield(self, pkt, s):
+ n = ""
+ while 1:
+ l = ord(s[0])
+ s = s[1:]
+ if not l:
+ break
+ if l & 0xc0:
+ raise Scapy_Exception("DNS message can't be compressed at this point!")
+ else:
+ n += s[:l]+"."
+ s = s[l:]
+ return s, n
+
+
+class DNSRRCountField(ShortField):
+ holds_packets=1
+ def __init__(self, name, default, rr):
+ ShortField.__init__(self, name, default)
+ self.rr = rr
+ def _countRR(self, pkt):
+ x = getattr(pkt,self.rr)
+ i = 0
+ while isinstance(x, DNSRR) or isinstance(x, DNSQR):
+ x = x.payload
+ i += 1
+ return i
+
+ def i2m(self, pkt, x):
+ if x is None:
+ x = self._countRR(pkt)
+ return x
+ def i2h(self, pkt, x):
+ if x is None:
+ x = self._countRR(pkt)
+ return x
+
+
+def DNSgetstr(s,p):
+ name = ""
+ q = 0
+ jpath = [p]
+ while 1:
+ if p >= len(s):
+ warning("DNS RR prematured end (ofs=%i, len=%i)"%(p,len(s)))
+ break
+ l = ord(s[p])
+ p += 1
+ if l & 0xc0:
+ if not q:
+ q = p+1
+ if p >= len(s):
+ warning("DNS incomplete jump token at (ofs=%i)" % p)
+ break
+ p = ((l & 0x3f) << 8) + ord(s[p]) - 12
+ if p in jpath:
+ warning("DNS decompression loop detected")
+ break
+ jpath.append(p)
+ continue
+ elif l > 0:
+ name += s[p:p+l]+"."
+ p += l
+ continue
+ break
+ if q:
+ p = q
+ return name,p
+
+
+class DNSRRField(StrField):
+ holds_packets=1
+ def __init__(self, name, countfld, passon=1):
+ StrField.__init__(self, name, None)
+ self.countfld = countfld
+ self.passon = passon
+ def i2m(self, pkt, x):
+ if x is None:
+ return ""
+ return str(x)
+ def decodeRR(self, name, s, p):
+ ret = s[p:p+10]
+ type,cls,ttl,rdlen = struct.unpack("!HHIH", ret)
+ p += 10
+ rr = DNSRR("\x00"+ret+s[p:p+rdlen])
+ if rr.type in [2, 3, 4, 5]:
+ rr.rdata = DNSgetstr(s,p)[0]
+ del(rr.rdlen)
+
+ p += rdlen
+
+ rr.rrname = name
+ return rr,p
+ def getfield(self, pkt, s):
+ if type(s) is tuple :
+ s,p = s
+ else:
+ p = 0
+ ret = None
+ c = getattr(pkt, self.countfld)
+ if c > len(s):
+ warning("wrong value: DNS.%s=%i" % (self.countfld,c))
+ return s,""
+ while c:
+ c -= 1
+ name,p = DNSgetstr(s,p)
+ rr,p = self.decodeRR(name, s, p)
+ if ret is None:
+ ret = rr
+ else:
+ ret.add_payload(rr)
+ if self.passon:
+ return (s,p),ret
+ else:
+ return s[p:],ret
+
+
+class DNSQRField(DNSRRField):
+ holds_packets=1
+ def decodeRR(self, name, s, p):
+ ret = s[p:p+4]
+ p += 4
+ rr = DNSQR("\x00"+ret)
+ rr.qname = name
+ return rr,p
+
+
+
+class RDataField(StrLenField):
+ def m2i(self, pkt, s):
+ family = None
+ if pkt.type == 1:
+ family = socket.AF_INET
+ elif pkt.type == 28:
+ family = socket.AF_INET6
+ elif pkt.type == 12:
+ s = DNSgetstr(s, 0)[0]
+ if family is not None:
+ s = inet_ntop(family, s)
+ return s
+ def i2m(self, pkt, s):
+ if pkt.type == 1:
+ if s:
+ s = inet_aton(s)
+ elif pkt.type == 28:
+ if s:
+ s = inet_pton(socket.AF_INET6, s)
+ elif pkt.type in [2,3,4,5]:
+ s = "".join(map(lambda x: chr(len(x))+x, s.split(".")))
+ if ord(s[-1]):
+ s += "\x00"
+ return s
+
+class RDLenField(Field):
+ def __init__(self, name):
+ Field.__init__(self, name, None, "H")
+ def i2m(self, pkt, x):
+ if x is None:
+ rdataf = pkt.get_field("rdata")
+ x = len(rdataf.i2m(pkt, pkt.rdata))
+ return x
+ def i2h(self, pkt, x):
+ if x is None:
+ rdataf = pkt.get_field("rdata")
+ x = len(rdataf.i2m(pkt, pkt.rdata))
+ return x
+
+# seconds between 01-01-1900 and 01-01-1970
+ntp_basetime = 2208988800
+
+class TimeStampField(BitField):
+ def __init__(self, name, default, size):
+ BitField.__init__(self, name, default, size)
+ self.size = size
+ def getfield(self, pkt, s):
+ s,timestamp = BitField.getfield(self, pkt, s)
+
+ if timestamp:
+ # timestamp is a 64 bits field :
+ # + first 32 bits : number of seconds since 1900
+ # + last 32 bits : fraction part
+ timestamp >>= 32
+ timestamp -= ntp_basetime
+
+ from time import gmtime, strftime
+ b = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime(timestamp))
+ else:
+ b = 'None'
+
+ return s, b
+ def addfield(self, pkt, s, val):
+ t = -1
+ if type(val) is str:
+ from time import strptime, mktime
+ t = int(mktime(strptime(val))) + ntp_basetime + 3600
+ else:
+ if val == -1:
+ from time import time
+ t = int(time()) + ntp_basetime
+ else:
+ t = val
+ t <<= 32
+ return BitField.addfield(self,pkt,s, t)
+
+class FloatField(BitField):
+ def getfield(self, pkt, s):
+ s,b = BitField.getfield(self, pkt, s)
+
+ # fraction point between bits 15 and 16.
+ sec = b >> 16
+ frac = b & (1L << (32+1)) - 1
+ frac /= 65536.0
+ b = sec+frac
+ return s,b
+
+class Dot11SCField(LEShortField):
+ def is_applicable(self, pkt):
+ return pkt.type != 1 # control frame
+ def addfield(self, pkt, s, val):
+ if self.is_applicable(pkt):
+ return LEShortField.addfield(self, pkt, s, val)
+ else:
+ return s
+ def getfield(self, pkt, s):
+ if self.is_applicable(pkt):
+ return LEShortField.getfield(self, pkt, s)
+ else:
+ return s,None
+
+#####################
+#### ASN1 Fields ####
+#####################
+
+class ASN1F_badsequence(Exception):
+ pass
+
+class ASN1F_element:
+ pass
+
+class ASN1F_field(ASN1F_element):
+ holds_packets=0
+ islist=0
+
+ ASN1_tag = ASN1_Class_UNIVERSAL.ANY
+
+ def __init__(self, name, default):
+ self.name = name
+ self.default = default
+
+ def i2repr(self, pkt, x):
+ if x is None:
+ x = 0
+ return repr(x)
+ def i2h(self, pkt, x):
+ if x is None:
+ x = 0
+ return x
+ def any2i(self, pkt, x):
+ return x
+ def m2i(self, pkt, x):
+ return self.ASN1_tag.get_codec(pkt.ASN1_codec).safedec(x)
+ def i2m(self, pkt, x):
+ if x is None:
+ x = 0
+ if isinstance(x, ASN1_Object):
+ if ( self.ASN1_tag == ASN1_Class_UNIVERSAL.ANY
+ or x.tag == ASN1_Class_UNIVERSAL.RAW
+ or x.tag == ASN1_Class_UNIVERSAL.ERROR
+ or self.ASN1_tag == x.tag ):
+ return x.enc(pkt.ASN1_codec)
+ else:
+ raise ASN1_Error("Encoding Error: got %r instead of an %r for field [%s]" % (x, self.ASN1_tag, self.name))
+ return self.ASN1_tag.get_codec(pkt.ASN1_codec).enc(x)
+
+ def do_copy(self, x):
+ if hasattr(x, "copy"):
+ return x.copy()
+ if type(x) is list:
+ x = x[:]
+ for i in xrange(len(x)):
+ if isinstance(x[i], Packet):
+ x[i] = x[i].copy()
+ return x
+
+ def build(self, pkt):
+ return self.i2m(pkt, getattr(pkt, self.name))
+
+ def set_val(self, pkt, val):
+ setattr(pkt, self.name, val)
+
+ def dissect(self, pkt, s):
+ v,s = self.m2i(pkt, s)
+ self.set_val(pkt, v)
+ return s
+
+ def get_fields_list(self):
+ return [self]
+
+ def __hash__(self):
+ return hash(self.name)
+ def __str__(self):
+ return self.name
+ def __eq__(self, other):
+ return self.name == other
+ def __repr__(self):
+ return self.name
+ def randval(self):
+ return RandInt()
+
+
+class ASN1F_INTEGER(ASN1F_field):
+ ASN1_tag= ASN1_Class_UNIVERSAL.INTEGER
+ def randval(self):
+ return RandNum(-2**64, 2**64)
+
+class ASN1F_enum_INTEGER(ASN1F_INTEGER):
+ def __init__(self, name, default, enum):
+ ASN1F_INTEGER.__init__(self, name, default)
+ i2s = self.i2s = {}
+ s2i = self.s2i = {}
+ if type(enum) is list:
+ keys = xrange(len(enum))
+ else:
+ keys = enum.keys()
+ if filter(lambda x: type(x) is str, keys):
+ i2s,s2i = s2i,i2s
+ for k in keys:
+ i2s[k] = enum[k]
+ s2i[enum[k]] = k
+ def any2i_one(self, pkt, x):
+ if type(x) is str:
+ x = self.s2i[x]
+ return x
+ def i2repr_one(self, pkt, x):
+ return self.i2s.get(x, repr(x))
+
+ def any2i(self, pkt, x):
+ if type(x) is list:
+ return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
+ else:
+ return self.any2i_one(pkt,x)
+ def i2repr(self, pkt, x):
+ if type(x) is list:
+ return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
+ else:
+ return self.i2repr_one(pkt,x)
+
+class ASN1F_STRING(ASN1F_field):
+ ASN1_tag = ASN1_Class_UNIVERSAL.STRING
+ def randval(self):
+ return RandString(RandNum(0, 1000))
+
+class ASN1F_OID(ASN1F_field):
+ ASN1_tag = ASN1_Class_UNIVERSAL.OID
+ def randval(self):
+ return RandOID()
+
+class ASN1F_SEQUENCE(ASN1F_field):
+ ASN1_tag = ASN1_Class_UNIVERSAL.SEQUENCE
+ def __init__(self, *seq, **kargs):
+ if "ASN1_tag" in kargs:
+ self.ASN1_tag = kargs["ASN1_tag"]
+ self.seq = seq
+ def __repr__(self):
+ return "<%s%r>" % (self.__class__.__name__,self.seq,)
+ def get_fields_list(self):
+ return reduce(lambda x,y: x+y.get_fields_list(), self.seq, [])
+ def build(self, pkt):
+ s = reduce(lambda x,y: x+y.build(pkt), self.seq, "")
+ return self.i2m(pkt, s)
+ def dissect(self, pkt, s):
+ codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
+ try:
+ i,s,remain = codec.check_type_check_len(s)
+ for obj in self.seq:
+ s = obj.dissect(pkt,s)
+ if s:
+ warning("Too many bytes to decode sequence: [%r]" % s) # XXX not reversible!
+ return remain
+ except ASN1_Error,e:
+ raise ASN1F_badsequence(e)
+
+class ASN1F_SEQUENCE_OF(ASN1F_SEQUENCE):
+ holds_packets = 1
+ islist = 1
+ def __init__(self, name, default, asn1pkt, ASN1_tag=0x30):
+ self.asn1pkt = asn1pkt
+ self.tag = chr(ASN1_tag)
+ self.name = name
+ self.default = default
+ def get_fields_list(self):
+ return [self]
+ def build(self, pkt):
+ val = getattr(pkt, self.name)
+ if isinstance(val, ASN1_Object) and val.tag == ASN1_Class_UNIVERSAL.RAW:
+ s = val
+ else:
+ s = "".join(map(str, val ))
+ return self.i2m(pkt, s)
+ def dissect(self, pkt, s):
+ codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
+ i,s1,remain = codec.check_type_check_len(s)
+ lst = []
+ while s1:
+ try:
+ p = self.asn1pkt(s1)
+ except ASN1F_badsequence:
+ lst.append(Raw(s1))
+ break
+ lst.append(p)
+ if Raw in p:
+ s1 = p[Raw].load
+ del(p[Raw].underlayer.payload)
+ else:
+ break
+ self.set_val(pkt, lst)
+ return remain
+ def randval(self):
+ return fuzz(self.asn1pkt())
+
+class ASN1F_PACKET(ASN1F_field):
+ holds_packets = 1
+ def __init__(self, name, default, cls):
+ ASN1_field.__init__(self, name, default)
+ self.cls = cls
+ def i2m(self, pkt, x):
+ if x is None:
+ x = ""
+ return str(x)
+ def extract_packet(self, cls, x):
+ try:
+ c = cls(x)
+ except ASN1F_badsequence:
+ c = Raw(x)
+ cpad = c[Padding]
+ x = ""
+ if cpad is not None:
+ x = cpad.load
+ del(cpad.underlayer.payload)
+ return c,x
+ def m2i(self, pkt, x):
+ return self.extract_packet(self.cls, x)
+
+
+class ASN1F_CHOICE(ASN1F_PACKET):
+ ASN1_tag = ASN1_Class_UNIVERSAL.NONE
+ def __init__(self, name, default, *args):
+ self.name=name
+ self.choice = {}
+ for p in args:
+ self.choice[p.ASN1_root.ASN1_tag] = p
+# self.context=context
+ self.default=default
+ def m2i(self, pkt, x):
+ if len(x) == 0:
+ return Raw(),""
+ raise ASN1_Error("ASN1F_CHOICE: got empty string")
+ if ord(x[0]) not in self.choice:
+ return Raw(x),"" # XXX return RawASN1 packet ? Raise error
+ raise ASN1_Error("Decoding Error: choice [%i] not found in %r" % (ord(x[0]), self.choice.keys()))
+
+ z = ASN1F_PACKET.extract_packet(self, self.choice[ord(x[0])], x)
+ return z
+ def randval(self):
+ return RandChoice(*map(lambda x:fuzz(x()), self.choice.values()))
+
+
+
+###########################
+## Packet abstract class ##
+###########################
+
+class Packet_metaclass(type):
+ def __new__(cls, name, bases, dct):
+ newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct)
+ for f in newcls.fields_desc:
+ f.register_owner(newcls)
+ return newcls
+ def __getattr__(self, attr):
+ for k in self.fields_desc:
+ if k.name == attr:
+ return k
+ raise AttributeError(attr)
+
+class NewDefaultValues(Packet_metaclass):
+ """NewDefaultValues metaclass. Example usage:
+ class MyPacket(Packet):
+ fields_desc = [ StrField("my_field", "my default value"), ]
+
+ class MyPacket_variant(MyPacket):
+ __metaclass__ = NewDefaultValues
+ my_field = "my new default value"
+ """
+ def __new__(cls, name, bases, dct):
+ fields = None
+ for b in bases:
+ if hasattr(b,"fields_desc"):
+ fields = b.fields_desc
+ break
+ if fields is None:
+ raise Scapy_Exception("No fields_desc in superclasses")
+
+ new_fields = []
+ for f in fields:
+ if f.name in dct:
+ f = f.copy()
+ f.default = dct[f.name]
+ del(dct[f.name])
+ new_fields.append(f)
+ dct["fields_desc"] = new_fields
+ return super(NewDefaultValues, cls).__new__(cls, name, bases, dct)
+
+class Packet(Gen):
+ __metaclass__ = Packet_metaclass
+ name=None
+
+ fields_desc = []
+
+ aliastypes = []
+ overload_fields = {}
+
+ underlayer = None
+
+ payload_guess = []
+ initialized = 0
+ show_indent=1
+ explicit = 0
+
+ @classmethod
+ def from_hexcap(cls):
+ return cls(import_hexcap())
+
+ @classmethod
+ def upper_bonds(self):
+ for fval,upper in self.payload_guess:
+ print "%-20s %s" % (upper.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
+
+ @classmethod
+ def lower_bonds(self):
+ for lower,fval in self.overload_fields.iteritems():
+ print "%-20s %s" % (lower.__name__, ", ".join("%-12s" % ("%s=%r"%i) for i in fval.iteritems()))
+
+ def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, **fields):
+ self.time = time.time()
+ if self.name is None:
+ self.name = self.__class__.__name__
+ self.aliastypes = [ self.__class__ ] + self.aliastypes
+ self.default_fields = {}
+ self.overloaded_fields = {}
+ self.fields={}
+ self.fieldtype={}
+ self.packetfields=[]
+ self.__dict__["payload"] = NoPayload()
+ self.init_fields()
+ self.underlayer = _underlayer
+ self.initialized = 1
+ if _pkt:
+ self.dissect(_pkt)
+ if not _internal:
+ self.dissection_done(self)
+ for f in fields.keys():
+ self.fields[f] = self.get_field(f).any2i(self,fields[f])
+ if type(post_transform) is list:
+ self.post_transforms = post_transform
+ elif post_transform is None:
+ self.post_transforms = []
+ else:
+ self.post_transforms = [post_transform]
+
+ def init_fields(self):
+ self.do_init_fields(self.fields_desc)
+
+ def do_init_fields(self, flist):
+ for f in flist:
+ self.default_fields[f.name] = f.default
+ self.fieldtype[f.name] = f
+ if f.holds_packets:
+ self.packetfields.append(f)
+
+ def dissection_done(self,pkt):
+ """DEV: will be called after a dissection is completed"""
+ self.post_dissection(pkt)
+ self.payload.dissection_done(pkt)
+
+ def post_dissection(self, pkt):
+ """DEV: is called after the dissection of the whole packet"""
+ pass
+
+ def get_field(self, fld):
+ """DEV: returns the field instance from the name of the field"""
+ return self.fieldtype[fld]
+
+ def add_payload(self, payload):
+ if payload is None:
+ return
+ elif not isinstance(self.payload, NoPayload):
+ self.payload.add_payload(payload)
+ else:
+ if isinstance(payload, Packet):
+ self.__dict__["payload"] = payload
+ payload.add_underlayer(self)
+ for t in self.aliastypes:
+ if payload.overload_fields.has_key(t):
+ self.overloaded_fields = payload.overload_fields[t]
+ break
+ elif type(payload) is str:
+ self.__dict__["payload"] = Raw(load=payload)
+ else:
+ raise TypeError("payload must be either 'Packet' or 'str', not [%s]" % repr(payload))
+ def remove_payload(self):
+ self.payload.remove_underlayer(self)
+ self.__dict__["payload"] = NoPayload()
+ self.overloaded_fields = {}
+ def add_underlayer(self, underlayer):
+ self.underlayer = underlayer
+ def remove_underlayer(self,other):
+ self.underlayer = None
+ def copy(self):
+ """Returns a deep copy of the instance."""
+ clone = self.__class__()
+ clone.fields = self.fields.copy()
+ for k in clone.fields:
+ clone.fields[k]=self.get_field(k).do_copy(clone.fields[k])
+ clone.default_fields = self.default_fields.copy()
+ clone.overloaded_fields = self.overloaded_fields.copy()
+ clone.overload_fields = self.overload_fields.copy()
+ clone.underlayer=self.underlayer
+ clone.explicit=self.explicit
+ clone.post_transforms=self.post_transforms[:]
+ clone.__dict__["payload"] = self.payload.copy()
+ clone.payload.add_underlayer(clone)
+ return clone
+
+ def getfieldval(self, attr):
+ if attr in self.fields:
+ return self.fields[attr]
+ if attr in self.overloaded_fields:
+ return self.overloaded_fields[attr]
+ if attr in self.default_fields:
+ return self.default_fields[attr]
+ return self.payload.getfieldval(attr)
+
+ def getfield_and_val(self, attr):
+ if attr in self.fields:
+ return self.get_field(attr),self.fields[attr]
+ if attr in self.overloaded_fields:
+ return self.get_field(attr),self.overloaded_fields[attr]
+ if attr in self.default_fields:
+ return self.get_field(attr),self.default_fields[attr]
+ return self.payload.getfield_and_val(attr)
+
+ def __getattr__(self, attr):
+ if self.initialized:
+ fld,v = self.getfield_and_val(attr)
+ if fld is not None:
+ return fld.i2h(self, v)
+ return v
+ raise AttributeError(attr)
+
+ def __setattr__(self, attr, val):
+ if self.initialized:
+ if self.default_fields.has_key(attr):
+ fld = self.get_field(attr)
+ if fld is None:
+ any2i = lambda x,y: y
+ else:
+ any2i = fld.any2i
+ self.fields[attr] = any2i(self, val)
+ self.explicit=0
+ elif attr == "payload":
+ self.remove_payload()
+ self.add_payload(val)
+ else:
+ self.__dict__[attr] = val
+ else:
+ self.__dict__[attr] = val
+ def __delattr__(self, attr):
+ if self.initialized:
+ if self.fields.has_key(attr):
+ del(self.fields[attr])
+ self.explicit=0 # in case a default value must be explicited
+ return
+ elif self.default_fields.has_key(attr):
+ return
+ elif attr == "payload":
+ self.remove_payload()
+ return
+ if self.__dict__.has_key(attr):
+ del(self.__dict__[attr])
+ else:
+ raise AttributeError(attr)
+
+ def __repr__(self):
+ s = ""
+ ct = conf.color_theme
+ for f in self.fields_desc:
+ if f.name in self.fields:
+ val = f.i2repr(self, self.fields[f.name])
+ elif f.name in self.overloaded_fields:
+ val = f.i2repr(self, self.overloaded_fields[f.name])
+ else:
+ continue
+ if isinstance(f, Emph):
+ ncol = ct.emph_field_name
+ vcol = ct.emph_field_value
+ else:
+ ncol = ct.field_name
+ vcol = ct.field_value
+
+
+ s += " %s%s%s" % (ncol(f.name),
+ ct.punct("="),
+ vcol(val))
+ return "%s%s %s %s%s%s"% (ct.punct("<"),
+ ct.layer_name(self.__class__.__name__),
+ s,
+ ct.punct("|"),
+ repr(self.payload),
+ ct.punct(">"))
+ def __str__(self):
+ return self.build()
+ def __div__(self, other):
+ if isinstance(other, Packet):
+ cloneA = self.copy()
+ cloneB = other.copy()
+ cloneA.add_payload(cloneB)
+ return cloneA
+ elif type(other) is str:
+ return self/Raw(load=other)
+ else:
+ return other.__rdiv__(self)
+ def __rdiv__(self, other):
+ if type(other) is str:
+ return Raw(load=other)/self
+ else:
+ raise TypeError
+ def __mul__(self, other):
+ if type(other) is int:
+ return [self]*other
+ else:
+ raise TypeError
+ def __rmul__(self,other):
+ return self.__mul__(other)
+
+ def __nonzero__(self):
+ return True
+ def __len__(self):
+ return len(self.__str__())
+ def do_build(self):
+ p=""
+ for f in self.fields_desc:
+ p = f.addfield(self, p, self.getfieldval(f.name))
+ return p
+
+ def post_build(self, pkt, pay):
+ """DEV: called right after the current layer is build."""
+ return pkt+pay
+
+ def build_payload(self):
+ return self.payload.build(internal=1)
+
+ def build(self,internal=0):
+ if not self.explicit:
+ self = self.__iter__().next()
+ pkt = self.do_build()
+ for t in self.post_transforms:
+ pkt = t(pkt)
+ pay = self.build_payload()
+ try:
+ p = self.post_build(pkt,pay)
+ except TypeError:
+ log_runtime.error("API changed! post_build() now takes 2 arguments. Compatibility is only assured for a short transition time")
+ p = self.post_build(pkt+pay)
+ if not internal:
+ pad = self.payload.getlayer(Padding)
+ if pad:
+ p += pad.build()
+ p = self.build_done(p)
+ return p
+
+ def build_done(self, p):
+ return self.payload.build_done(p)
+
+ def do_build_ps(self):
+ p=""
+ pl = []
+ q=""
+ for f in self.fields_desc:
+ p = f.addfield(self, p, self.getfieldval(f.name) )
+ if type(p) is str:
+ r = p[len(q):]
+ q = p
+ else:
+ r = ""
+ pl.append( (f, f.i2repr(self,self.getfieldval(f.name)), r) )
+
+ pkt,lst = self.payload.build_ps(internal=1)
+ p += pkt
+ lst.append( (self, pl) )
+
+ return p,lst
+
+ def build_ps(self,internal=0):
+ p,lst = self.do_build_ps()
+# if not internal:
+# pkt = self
+# while pkt.haslayer(Padding):
+# pkt = pkt.getlayer(Padding)
+# lst.append( (pkt, [ ("loakjkjd", pkt.load, pkt.load) ] ) )
+# p += pkt.load
+# pkt = pkt.payload
+ return p,lst
+
+
+ def psdump(self, filename=None, **kargs):
+ """psdump(filename=None, layer_shift=0, rebuild=1)
+Creates an EPS file describing a packet. If filename is not provided a temporary file is created and gs is called."""
+ canvas = self.canvas_dump(**kargs)
+ if filename is None:
+ fname = "/tmp/scapy.%i"%os.getpid()
+ canvas.writeEPSfile(fname)
+ os.system("%s '%s.eps' &" % (conf.prog.psreader,fname))
+ else:
+ canvas.writeEPSfile(filename)
+
+ def pdfdump(self, filename=None, **kargs):
+ """pdfdump(filename=None, layer_shift=0, rebuild=1)
+ Creates a PDF file describing a packet. If filename is not provided a temporary file is created and xpdf is called."""
+ canvas = self.canvas_dump(**kargs)
+ if filename is None:
+ fname = "/tmp/scapy.%i"%os.getpid()
+ canvas.writePDFfile(fname)
+ os.system("%s '%s.pdf' &" % (conf.prog.pdfreader,fname))
+ else:
+ canvas.writePDFfile(filename)
+
+
+ def canvas_dump(self, layer_shift=0, rebuild=1):
+ canvas = pyx.canvas.canvas()
+ if rebuild:
+ p,t = self.__class__(str(self)).build_ps()
+ else:
+ p,t = self.build_ps()
+ YTXT=len(t)
+ for n,l in t:
+ YTXT += len(l)
+ YTXT = float(YTXT)
+ YDUMP=YTXT
+
+ XSTART = 1
+ XDSTART = 10
+ y = 0.0
+ yd = 0.0
+ xd = 0
+ XMUL= 0.55
+ YMUL = 0.4
+
+ backcolor=colgen(0.6, 0.8, 1.0, trans=pyx.color.rgb)
+ forecolor=colgen(0.2, 0.5, 0.8, trans=pyx.color.rgb)
+# backcolor=makecol(0.376, 0.729, 0.525, 1.0)
+
+
+ def hexstr(x):
+ s = []
+ for c in x:
+ s.append("%02x" % ord(c))
+ return " ".join(s)
+
+
+ def make_dump_txt(x,y,txt):
+ return pyx.text.text(XDSTART+x*XMUL, (YDUMP-y)*YMUL, r"\tt{%s}"%hexstr(txt), [pyx.text.size.Large])
+
+ def make_box(o):
+ return pyx.box.rect(o.left(), o.bottom(), o.width(), o.height(), relcenter=(0.5,0.5))
+
+ def make_frame(lst):
+ if len(lst) == 1:
+ b = lst[0].bbox()
+ b.enlarge(pyx.unit.u_pt)
+ return b.path()
+ else:
+ fb = lst[0].bbox()
+ fb.enlarge(pyx.unit.u_pt)
+ lb = lst[-1].bbox()
+ lb.enlarge(pyx.unit.u_pt)
+ if len(lst) == 2 and fb.left() > lb.right():
+ return pyx.path.path(pyx.path.moveto(fb.right(), fb.top()),
+ pyx.path.lineto(fb.left(), fb.top()),
+ pyx.path.lineto(fb.left(), fb.bottom()),
+ pyx.path.lineto(fb.right(), fb.bottom()),
+ pyx.path.moveto(lb.left(), lb.top()),
+ pyx.path.lineto(lb.right(), lb.top()),
+ pyx.path.lineto(lb.right(), lb.bottom()),
+ pyx.path.lineto(lb.left(), lb.bottom()))
+ else:
+ # XXX
+ gb = lst[1].bbox()
+ if gb != lb:
+ gb.enlarge(pyx.unit.u_pt)
+ kb = lst[-2].bbox()
+ if kb != gb and kb != lb:
+ kb.enlarge(pyx.unit.u_pt)
+ return pyx.path.path(pyx.path.moveto(fb.left(), fb.top()),
+ pyx.path.lineto(fb.right(), fb.top()),
+ pyx.path.lineto(fb.right(), kb.bottom()),
+ pyx.path.lineto(lb.right(), kb.bottom()),
+ pyx.path.lineto(lb.right(), lb.bottom()),
+ pyx.path.lineto(lb.left(), lb.bottom()),
+ pyx.path.lineto(lb.left(), gb.top()),
+ pyx.path.lineto(fb.left(), gb.top()),
+ pyx.path.closepath(),)
+
+
+ def make_dump(s, shift=0, y=0, col=None, bkcol=None, larg=16):
+ c = pyx.canvas.canvas()
+ tlist = []
+ while s:
+ dmp,s = s[:larg-shift],s[larg-shift:]
+ txt = make_dump_txt(shift, y, dmp)
+ tlist.append(txt)
+ shift += len(dmp)
+ if shift >= 16:
+ shift = 0
+ y += 1
+ if col is None:
+ col = pyx.color.rgb.red
+ if bkcol is None:
+ col = pyx.color.rgb.white
+ c.stroke(make_frame(tlist),[col,pyx.deco.filled([bkcol]),pyx.style.linewidth.Thick])
+ for txt in tlist:
+ c.insert(txt)
+ return c, tlist[-1].bbox(), shift, y
+
+
+ last_shift,last_y=0,0.0
+ while t:
+ bkcol = backcolor.next()
+ proto,fields = t.pop()
+ y += 0.5
+ pt = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % proto.name, [ pyx.text.size.Large])
+ y += 1
+ ptbb=pt.bbox()
+ ptbb.enlarge(pyx.unit.u_pt*2)
+ canvas.stroke(ptbb.path(),[pyx.color.rgb.black, pyx.deco.filled([bkcol])])
+ canvas.insert(pt)
+ for fname, fval, fdump in fields:
+ col = forecolor.next()
+ ft = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fname.name))
+ if fval is not None:
+ if len(fval) > 18:
+ fval = fval[:18]+"[...]"
+ else:
+ fval=""
+ vt = pyx.text.text(XSTART+3, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fval))
+ y += 1.0
+ if fdump:
+ dt,target,last_shift,last_y = make_dump(fdump, last_shift, last_y, col, bkcol)
+
+ dtb = dt.bbox()
+ dtb=target
+ vtb = vt.bbox()
+ bxvt = make_box(vtb)
+ bxdt = make_box(dtb)
+ dtb.enlarge(pyx.unit.u_pt)
+ try:
+ if yd < 0:
+ cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=-90)
+ else:
+ cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=90)
+ except:
+ pass
+ else:
+ canvas.stroke(cnx,[pyx.style.linewidth.thin,pyx.deco.earrow.small,col])
+
+ canvas.insert(dt)
+
+ canvas.insert(ft)
+ canvas.insert(vt)
+ last_y += layer_shift
+
+ return canvas
+
+
+
+ def extract_padding(self, s):
+ """DEV: to be overloaded to extract current layer's padding. Return a couple of strings (actual layer, padding)"""
+ return s,None
+
+ def post_dissect(self, s):
+ """DEV: is called right after the current layer has been dissected"""
+ return s
+
+ def pre_dissect(self, s):
+ """DEV: is called right before the current layer is dissected"""
+ return s
+
+ def do_dissect(self, s):
+ flist = self.fields_desc[:]
+ flist.reverse()
+ while s and flist:
+ f = flist.pop()
+ s,fval = f.getfield(self, s)
+ self.fields[f.name] = fval
+
+ return s
+
+ def do_dissect_payload(self, s):
+ if s:
+ cls = self.guess_payload_class(s)
+ try:
+ p = cls(s, _internal=1, _underlayer=self)
+ except KeyboardInterrupt:
+ raise
+ except:
+ if conf.debug_dissector:
+ if isinstance(cls,type) and issubclass(cls,Packet):
+ log_runtime.error("%s dissector failed" % cls.name)
+ else:
+ log_runtime.error("%s.guess_payload_class() returned [%s]" % (self.__class__.__name__,repr(cls)))
+ if cls is not None:
+ raise
+ p = Raw(s, _internal=1, _underlayer=self)
+ self.add_payload(p)
+
+ def dissect(self, s):
+ s = self.pre_dissect(s)
+
+ s = self.do_dissect(s)
+
+ s = self.post_dissect(s)
+
+ payl,pad = self.extract_padding(s)
+ self.do_dissect_payload(payl)
+ if pad and conf.padding:
+ self.add_payload(Padding(pad))
+
+
+ def guess_payload_class(self, payload):
+ """DEV: Guesses the next payload class from layer bonds. Can be overloaded to use a different mechanism."""
+ for t in self.aliastypes:
+ for fval, cls in t.payload_guess:
+ ok = 1
+ for k in fval.keys():
+ if not hasattr(self, k) or fval[k] != self.getfieldval(k):
+ ok = 0
+ break
+ if ok:
+ return cls
+ return self.default_payload_class(payload)
+
+ def default_payload_class(self, payload):
+ """DEV: Returns the default payload class if nothing has been found by the guess_payload_class() method."""
+ return Raw
+
+ def hide_defaults(self):
+ """Removes fields' values that are the same as default values."""
+ for k in self.fields.keys():
+ if self.default_fields.has_key(k):
+ if self.default_fields[k] == self.fields[k]:
+ del(self.fields[k])
+ self.payload.hide_defaults()
+
+
+ def __iter__(self):
+ def loop(todo, done, self=self):
+ if todo:
+ eltname = todo.pop()
+ elt = self.getfieldval(eltname)
+ if not isinstance(elt, Gen):
+ if self.get_field(eltname).islist:
+ elt = SetGen([elt])
+ else:
+ elt = SetGen(elt)
+ for e in elt:
+ done[eltname]=e
+ for x in loop(todo[:], done):
+ yield x
+ else:
+ if isinstance(self.payload,NoPayload):
+ payloads = [None]
+ else:
+ payloads = self.payload
+ for payl in payloads:
+ done2=done.copy()
+ for k in done2:
+ if isinstance(done2[k], VolatileValue):
+ done2[k] = done2[k]._fix()
+ pkt = self.__class__()
+ pkt.explicit = 1
+ pkt.fields = done2
+ pkt.time = self.time
+ pkt.underlayer = self.underlayer
+ pkt.overload_fields = self.overload_fields.copy()
+ pkt.post_transforms = self.post_transforms
+ if payl is not None:
+ pkt.add_payload(payl)
+ yield pkt
+
+ if self.explicit:
+ todo = []
+ done = self.fields
+ else:
+ todo = [ k for (k,v) in itertools.chain(self.default_fields.iteritems(),
+ self.overloaded_fields.iteritems())
+ if isinstance(v, VolatileValue) ] + self.fields.keys()
+ done = {}
+ return loop(todo, done)
+
+ def __gt__(self, other):
+ """True if other is an answer from self (self ==> other)."""
+ if isinstance(other, Packet):
+ return other < self
+ elif type(other) is str:
+ return 1
+ else:
+ raise TypeError((self, other))
+ def __lt__(self, other):
+ """True if self is an answer from other (other ==> self)."""
+ if isinstance(other, Packet):
+ return self.answers(other)
+ elif type(other) is str:
+ return 1
+ else:
+ raise TypeError((self, other))
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return False
+ for f in self.fields_desc:
+ if f not in other.fields_desc:
+ return False
+ if self.getfieldval(f.name) != other.getfieldval(f.name):
+ return False
+ return self.payload == other.payload
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def hashret(self):
+ """DEV: returns a string that has the same value for a request and its answer."""
+ return self.payload.hashret()
+ def answers(self, other):
+ """DEV: true if self is an answer from other"""
+ if other.__class__ == self.__class__:
+ return self.payload.answers(other.payload)
+ return 0
+
+ def haslayer(self, cls):
+ """true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax."""
+ if self.__class__ == cls or self.__class__.__name__ == cls:
+ return 1
+ for f in self.packetfields:
+ fvalue_gen = self.getfieldval(f.name)
+ if fvalue_gen is None:
+ continue
+ if not f.islist:
+ fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
+ for fvalue in fvalue_gen:
+ if isinstance(fvalue, Packet):
+ ret = fvalue.haslayer(cls)
+ if ret:
+ return ret
+ return self.payload.haslayer(cls)
+ def getlayer(self, cls, nb=1, _track=None):
+ """Return the nb^th layer that is an instance of cls."""
+ if type(cls) is str and "." in cls:
+ ccls,fld = cls.split(".",1)
+ else:
+ ccls,fld = cls,None
+ if self.__class__ == cls or self.__class__.name == ccls:
+ if nb == 1:
+ if fld is None:
+ return self
+ else:
+ return self.getfieldval(fld)
+ else:
+ nb -=1
+ for f in self.packetfields:
+ fvalue_gen = self.getfieldval(f.name)
+ if fvalue_gen is None:
+ continue
+ if not f.islist:
+ fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
+ for fvalue in fvalue_gen:
+ if isinstance(fvalue, Packet):
+ track=[]
+ ret = fvalue.getlayer(cls, nb, _track=track)
+ if ret is not None:
+ return ret
+ nb = track[0]
+ return self.payload.getlayer(cls,nb,_track=_track)
+
+ def __getitem__(self, cls):
+ if type(cls) is slice:
+ if cls.stop:
+ ret = self.getlayer(cls.start, cls.stop)
+ else:
+ ret = self.getlayer(cls.start)
+ if ret is None and cls.step is not None:
+ ret = cls.step
+ return ret
+ else:
+ return self.getlayer(cls)
+
+ def __contains__(self, cls):
+ """"cls in self" returns true if self has a layer which is an instance of cls."""
+ return self.haslayer(cls)
+
+
+
+ def display(self,*args,**kargs): # Deprecated. Use show()
+ """Deprecated. Use show() method."""
+ self.show(*args,**kargs)
+ def show(self, indent=3, lvl="", label_lvl=""):
+ """Prints a hierarchical view of the packet. "indent" gives the size of indentation for each layer."""
+ ct = conf.color_theme
+ print "%s%s %s %s" % (label_lvl,
+ ct.punct("###["),
+ ct.layer_name(self.name),
+ ct.punct("]###"))
+ for f in self.fields_desc:
+ if isinstance(f, Emph):
+ ncol = ct.emph_field_name
+ vcol = ct.emph_field_value
+ else:
+ ncol = ct.field_name
+ vcol = ct.field_value
+ fvalue = self.getfieldval(f.name)
+ if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list):
+ print "%s \\%-10s\\" % (label_lvl+lvl, ncol(f.name))
+ fvalue_gen = SetGen(fvalue,_iterpacket=0)
+ for fvalue in fvalue_gen:
+ fvalue.show(indent=indent, label_lvl=label_lvl+lvl+" |")
+ else:
+ print "%s %-10s%s %s" % (label_lvl+lvl,
+ ncol(f.name),
+ ct.punct("="),
+ vcol(f.i2repr(self,fvalue)))
+ self.payload.show(indent=indent, lvl=lvl+(" "*indent*self.show_indent), label_lvl=label_lvl)
+ def show2(self):
+ """Prints a hierarchical view of an assembled version of the packet, so that automatic fields are calculated (checksums, etc.)"""
+ self.__class__(str(self)).show()
+
+ def sprintf(self, fmt, relax=1):
+ """sprintf(format, [relax=1]) -> str
+where format is a string that can include directives. A directive begins and
+ends by % and has the following format %[fmt[r],][cls[:nb].]field%.
+
+fmt is a classic printf directive, "r" can be appended for raw substitution
+(ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
+(ex: for IP/IP packets, IP:2.src is the src of the upper IP layer).
+Special case : "%.time%" is the creation time.
+Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% "
+ "%03xr,IP.proto% %r,TCP.flags%")
+
+Moreover, the format string can include conditionnal statements. A conditionnal
+statement looks like : {layer:string} where layer is a layer name, and string
+is the string to insert in place of the condition if it is true, i.e. if layer
+is present. If layer is preceded by a "!", the result si inverted. Conditions
+can be imbricated. A valid statement can be :
+ p.sprintf("This is a{TCP: TCP}{UDP: UDP}{ICMP:n ICMP} packet")
+ p.sprintf("{IP:%IP.dst% {ICMP:%ICMP.type%}{TCP:%TCP.dport%}}")
+
+A side effect is that, to obtain "{" and "}" characters, you must use
+"%(" and "%)".
+"""
+
+ escape = { "%": "%",
+ "(": "{",
+ ")": "}" }
+
+
+ # Evaluate conditions
+ while "{" in fmt:
+ i = fmt.rindex("{")
+ j = fmt[i+1:].index("}")
+ cond = fmt[i+1:i+j+1]
+ k = cond.find(":")
+ if k < 0:
+ raise Scapy_Exception("Bad condition in format string: [%s] (read sprintf doc!)"%cond)
+ cond,format = cond[:k],cond[k+1:]
+ res = False
+ if cond[0] == "!":
+ res = True
+ cond = cond[1:]
+ if self.haslayer(cond):
+ res = not res
+ if not res:
+ format = ""
+ fmt = fmt[:i]+format+fmt[i+j+2:]
+
+ # Evaluate directives
+ s = ""
+ while "%" in fmt:
+ i = fmt.index("%")
+ s += fmt[:i]
+ fmt = fmt[i+1:]
+ if fmt and fmt[0] in escape:
+ s += escape[fmt[0]]
+ fmt = fmt[1:]
+ continue
+ try:
+ i = fmt.index("%")
+ sfclsfld = fmt[:i]
+ fclsfld = sfclsfld.split(",")
+ if len(fclsfld) == 1:
+ f = "s"
+ clsfld = fclsfld[0]
+ elif len(fclsfld) == 2:
+ f,clsfld = fclsfld
+ else:
+ raise Scapy_Exception
+ if "." in clsfld:
+ cls,fld = clsfld.split(".")
+ else:
+ cls = self.__class__.__name__
+ fld = clsfld
+ num = 1
+ if ":" in cls:
+ cls,num = cls.split(":")
+ num = int(num)
+ fmt = fmt[i+1:]
+ except:
+ raise Scapy_Exception("Bad format string [%%%s%s]" % (fmt[:25], fmt[25:] and "..."))
+ else:
+ if fld == "time":
+ val = time.strftime("%H:%M:%S.%%06i", time.localtime(self.time)) % int((self.time-int(self.time))*1000000)
+ elif cls == self.__class__.__name__ and hasattr(self, fld):
+ if num > 1:
+ val = self.payload.sprintf("%%%s,%s:%s.%s%%" % (f,cls,num-1,fld), relax)
+ f = "s"
+ elif f[-1] == "r": # Raw field value
+ val = getattr(self,fld)
+ f = f[:-1]
+ if not f:
+ f = "s"
+ else:
+ val = getattr(self,fld)
+ if fld in self.fieldtype:
+ val = self.fieldtype[fld].i2repr(self,val)
+ else:
+ val = self.payload.sprintf("%%%s%%" % sfclsfld, relax)
+ f = "s"
+ s += ("%"+f) % val
+
+ s += fmt
+ return s
+
+ def mysummary(self):
+ """DEV: can be overloaded to return a string that summarizes the layer.
+ Only one mysummary() is used in a whole packet summary: the one of the upper layer,
+ except if a mysummary() also returns (as a couple) a list of layers whose
+ mysummary() must be called if they are present."""
+ return ""
+
+ def summary(self, intern=0):
+ """Prints a one line summary of a packet."""
+ found,s,needed = self.payload.summary(intern=1)
+ if s:
+ s = " / "+s
+ ret = ""
+ if not found or self.__class__ in needed:
+ ret = self.mysummary()
+ if type(ret) is tuple:
+ ret,n = ret
+ needed += n
+ if ret or needed:
+ found = 1
+ if not ret:
+ ret = self.__class__.__name__
+ ret = "%s%s" % (ret,s)
+ if intern:
+ return found,ret,needed
+ else:
+ return ret
+
+ def lastlayer(self,layer=None):
+ """Returns the uppest layer of the packet"""
+ return self.payload.lastlayer(self)
+
+ def decode_payload_as(self,cls):
+ """Reassembles the payload and decode it using another packet class"""
+ s = str(self.payload)
+ self.payload = cls(s)
+
+ def libnet(self):
+ """Not ready yet. Should give the necessary C code that interfaces with libnet to recreate the packet"""
+ print "libnet_build_%s(" % self.__class__.name.lower()
+ det = self.__class__(str(self))
+ for f in self.fields_desc:
+ val = det.getfieldval(f.name)
+ if val is None:
+ val = 0
+ elif type(val) is int:
+ val = str(val)
+ else:
+ val = '"%s"' % str(val)
+ print "\t%s, \t\t/* %s */" % (val,f.name)
+ print ");"
+ def command(self):
+ """Returns a string representing the command you have to type to obtain the same packet"""
+ f = []
+ for fn,fv in self.fields.items():
+ fld = self.get_field(fn)
+ if isinstance(fv, Packet):
+ fv = fv.command()
+ elif fld.islist and fld.holds_packets and type(fv) is list:
+ fv = "[%s]" % ",".join( map(Packet.command, fv))
+ else:
+ fv = repr(fv)
+ f.append("%s=%s" % (fn, fv))
+ c = "%s(%s)" % (self.__class__.__name__, ", ".join(f))
+ pc = self.payload.command()
+ if pc:
+ c += "/"+pc
+ return c
+
+
+class ASN1_Packet(Packet):
+ ASN1_root = None
+ ASN1_codec = None
+ def init_fields(self):
+ flist = self.ASN1_root.get_fields_list()
+ self.do_init_fields(flist)
+ self.fields_desc = flist
+ def do_build(self):
+ return self.ASN1_root.build(self)
+ def do_dissect(self, x):
+ return self.ASN1_root.dissect(self, x)
+
+
+class NoPayload(Packet,object):
+ def __new__(cls, *args, **kargs):
+ singl = cls.__dict__.get("__singl__")
+ if singl is None:
+ cls.__singl__ = singl = object.__new__(cls)
+ Packet.__init__(singl, *args, **kargs)
+ return singl
+ def __init__(self, *args, **kargs):
+ pass
+ def dissection_done(self,pkt):
+ return
+ def add_payload(self, payload):
+ raise Scapy_Exception("Can't add payload to NoPayload instance")
+ def remove_payload(self):
+ pass
+ def add_underlayer(self,underlayer):
+ pass
+ def remove_underlayer(self,other):
+ pass
+ def copy(self):
+ return self
+ def __repr__(self):
+ return ""
+ def __str__(self):
+ return ""
+ def __nonzero__(self):
+ return False
+ def build(self, internal=0):
+ return ""
+ def build_done(self, p):
+ return p
+ def build_ps(self, internal=0):
+ return "",[]
+ def getfieldval(self, attr):
+ raise AttributeError(attr)
+ def getfield_and_val(self, attr):
+ raise AttributeError(attr)
+ def __getattr__(self, attr):
+ if attr in self.__dict__:
+ return self.__dict__[attr]
+ elif attr in self.__class__.__dict__:
+ return self.__class__.__dict__[attr]
+ else:
+ raise AttributeError, attr
+ def hide_defaults(self):
+ pass
+ def __iter__(self):
+ return iter([])
+ def __eq__(self, other):
+ if isinstance(other, NoPayload):
+ return True
+ return False
+ def hashret(self):
+ return ""
+ def answers(self, other):
+ return isinstance(other, NoPayload) or isinstance(other, Padding)
+ def haslayer(self, cls):
+ return 0
+ def getlayer(self, cls, nb=1, _track=None):
+ if _track is not None:
+ _track.append(nb)
+ return None
+ def show(self, indent=3, lvl="", label_lvl=""):
+ pass
+ def sprintf(self, fmt, relax):
+ if relax:
+ return "??"
+ else:
+ raise Scapy_Exception("Format not found [%s]"%fmt)
+ def summary(self, intern=0):
+ return 0,"",[]
+ def lastlayer(self,layer):
+ return layer
+ def command(self):
+ return ""
+
+
+####################
+## packet classes ##
+####################
+
+
+class Raw(Packet):
+ name = "Raw"
+ fields_desc = [ StrField("load", "") ]
+ def answers(self, other):
+ return 1
+# s = str(other)
+# t = self.load
+# l = min(len(s), len(t))
+# return s[:l] == t[:l]
+
+class Padding(Raw):
+ name = "Padding"
+ def build(self, internal=0):
+ if internal:
+ return ""
+ else:
+ return Raw.build(self)
+
+class Ether(Packet):
+ name = "Ethernet"
+ fields_desc = [ DestMACField("dst"),
+ SourceMACField("src"),
+ XShortEnumField("type", 0x0000, ETHER_TYPES) ]
+ def hashret(self):
+ return struct.pack("H",self.type)+self.payload.hashret()
+ def answers(self, other):
+ if isinstance(other,Ether):
+ if self.type == other.type:
+ return self.payload.answers(other.payload)
+ return 0
+ def mysummary(self):
+ return self.sprintf("%src% > %dst% (%type%)")
+
+class PPPoE(Packet):
+ name = "PPP over Ethernet"
+ fields_desc = [ BitField("version", 1, 4),
+ BitField("type", 1, 4),
+ ByteEnumField("code", 0, {0:"Session"}),
+ XShortField("sessionid", 0x0),
+ ShortField("len", None) ]
+
+ def post_build(self, p, pay):
+ p += pay
+ if self.len is None:
+ l = len(p)-6
+ p = p[:4]+struct.pack("!H", l)+p[6:]
+ return p
+
+class PPPoED(PPPoE):
+ name = "PPP over Ethernet Discovery"
+ fields_desc = [ BitField("version", 1, 4),
+ BitField("type", 1, 4),
+ ByteEnumField("code", 0x09, {0x09:"PADI",0x07:"PADO",0x19:"PADR",0x65:"PADS",0xa7:"PADT"}),
+ XShortField("sessionid", 0x0),
+ ShortField("len", None) ]
+
+class Dot3(Packet):
+ name = "802.3"
+ fields_desc = [ MACField("dst", ETHER_BROADCAST),
+ MACField("src", ETHER_ANY),
+ LenField("len", None, "H") ]
+ def extract_padding(self,s):
+ l = self.len
+ return s[:l],s[l:]
+ def answers(self, other):
+ if isinstance(other,Dot3):
+ return self.payload.answers(other.payload)
+ return 0
+ def mysummary(self):
+ return "802.3 %s > %s" % (self.src, self.dst)
+
+
+class LLC(Packet):
+ name = "LLC"
+ fields_desc = [ XByteField("dsap", 0x00),
+ XByteField("ssap", 0x00),
+ ByteField("ctrl", 0) ]
+
+
+class CookedLinux(Packet):
+ name = "cooked linux"
+ fields_desc = [ ShortEnumField("pkttype",0, {0: "unicast",
+ 4:"sent-by-us"}), #XXX incomplete
+ XShortField("lladdrtype",512),
+ ShortField("lladdrlen",0),
+ StrFixedLenField("src","",8),
+ XShortEnumField("proto",0x800,ETHER_TYPES) ]
+
+
+
+class SNAP(Packet):
+ name = "SNAP"
+ fields_desc = [ X3BytesField("OUI",0x000000),
+ XShortEnumField("code", 0x000, ETHER_TYPES) ]
+
+
+class Dot1Q(Packet):
+ name = "802.1Q"
+ aliastypes = [ Ether ]
+ fields_desc = [ BitField("prio", 0, 3),
+ BitField("id", 0, 1),
+ BitField("vlan", 1, 12),
+ XShortEnumField("type", 0x0000, ETHER_TYPES) ]
+ def answers(self, other):
+ if isinstance(other,Dot1Q):
+ if ( (self.type == other.type) and
+ (self.vlan == other.vlan) ):
+ return self.payload.answers(other.payload)
+ else:
+ return self.payload.answers(other)
+ return 0
+ def default_payload_class(self, pay):
+ if self.type <= 1500:
+ return LLC
+ return Raw
+ def extract_padding(self,s):
+ if self.type <= 1500:
+ return s[:self.type],s[self.type:]
+ return s,None
+ def mysummary(self):
+ if isinstance(self.underlayer, Ether):
+ return self.underlayer.sprintf("802.1q %Ether.src% > %Ether.dst% (%Dot1Q.type%) vlan %Dot1Q.vlan%")
+ else:
+ return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%")
+
+
+
+
+class RadioTap(Packet):
+ name = "RadioTap dummy"
+ fields_desc = [ ByteField('version', 0),
+ ByteField('pad', 0),
+ FieldLenField('len', None, 'notdecoded', '@H', adjust=lambda pkt,x:x+8),
+ FlagsField('present', None, -32, ['TSFT','Flags','Rate','Channel','FHSS','dBm_AntSignal',
+ 'dBm_AntNoise','Lock_Quality','TX_Attenuation','dB_TX_Attenuation',
+ 'dBm_TX_Power', 'Antenna', 'dB_AntSignal', 'dB_AntNoise',
+ 'b14', 'b15','b16','b17','b18','b19','b20','b21','b22','b23',
+ 'b24','b25','b26','b27','b28','b29','b30','Ext']),
+ StrLenField('notdecoded', "", length_from= lambda pkt:pkt.len-8) ]
+
+class STP(Packet):
+ name = "Spanning Tree Protocol"
+ fields_desc = [ ShortField("proto", 0),
+ ByteField("version", 0),
+ ByteField("bpdutype", 0),
+ ByteField("bpduflags", 0),
+ ShortField("rootid", 0),
+ MACField("rootmac", ETHER_ANY),
+ IntField("pathcost", 0),
+ ShortField("bridgeid", 0),
+ MACField("bridgemac", ETHER_ANY),
+ ShortField("portid", 0),
+ BCDFloatField("age", 1),
+ BCDFloatField("maxage", 20),
+ BCDFloatField("hellotime", 2),
+ BCDFloatField("fwddelay", 15) ]
+
+
+class EAPOL(Packet):
+ name = "EAPOL"
+ fields_desc = [ ByteField("version", 1),
+ ByteEnumField("type", 0, ["EAP_PACKET", "START", "LOGOFF", "KEY", "ASF"]),
+ LenField("len", None, "H") ]
+
+ EAP_PACKET= 0
+ START = 1
+ LOGOFF = 2
+ KEY = 3
+ ASF = 4
+ def extract_padding(self, s):
+ l = self.len
+ return s[:l],s[l:]
+ def hashret(self):
+ return chr(self.type)+self.payload.hashret()
+ def answers(self, other):
+ if isinstance(other,EAPOL):
+ if ( (self.type == self.EAP_PACKET) and
+ (other.type == self.EAP_PACKET) ):
+ return self.payload.answers(other.payload)
+ return 0
+ def mysummary(self):
+ return self.sprintf("EAPOL %EAPOL.type%")
+
+
+class EAP(Packet):
+ name = "EAP"
+ fields_desc = [ ByteEnumField("code", 4, {1:"REQUEST",2:"RESPONSE",3:"SUCCESS",4:"FAILURE"}),
+ ByteField("id", 0),
+ ShortField("len",None),
+ ConditionalField(ByteEnumField("type",0, {1:"ID",4:"MD5"}), lambda pkt:pkt.code not in [EAP.SUCCESS, EAP.FAILURE])
+
+ ]
+
+ REQUEST = 1
+ RESPONSE = 2
+ SUCCESS = 3
+ FAILURE = 4
+ TYPE_ID = 1
+ TYPE_MD5 = 4
+ def answers(self, other):
+ if isinstance(other,EAP):
+ if self.code == self.REQUEST:
+ return 0
+ elif self.code == self.RESPONSE:
+ if ( (other.code == self.REQUEST) and
+ (other.type == self.type) ):
+ return 1
+ elif other.code == self.RESPONSE:
+ return 1
+ return 0
+
+ def post_build(self, p, pay):
+ if self.len is None:
+ l = len(p)+len(pay)
+ p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
+ return p+pay
+
+
+class ARP(Packet):
+ name = "ARP"
+ fields_desc = [ XShortField("hwtype", 0x0001),
+ XShortEnumField("ptype", 0x0800, ETHER_TYPES),
+ ByteField("hwlen", 6),
+ ByteField("plen", 4),
+ ShortEnumField("op", 1, {"who-has":1, "is-at":2, "RARP-req":3, "RARP-rep":4, "Dyn-RARP-req":5, "Dyn-RAR-rep":6, "Dyn-RARP-err":7, "InARP-req":8, "InARP-rep":9}),
+ ARPSourceMACField("hwsrc"),
+ SourceIPField("psrc","pdst"),
+ MACField("hwdst", ETHER_ANY),
+ IPField("pdst", "0.0.0.0") ]
+ who_has = 1
+ is_at = 2
+ def answers(self, other):
+ if isinstance(other,ARP):
+ if ( (self.op == self.is_at) and
+ (other.op == self.who_has) and
+ (self.psrc == other.pdst) ):
+ return 1
+ return 0
+ def extract_padding(self, s):
+ return "",s
+ def mysummary(self):
+ if self.op == self.is_at:
+ return "ARP is at %s says %s" % (self.hwsrc, self.psrc)
+ elif self.op == self.who_has:
+ return "ARP who has %s says %s" % (self.pdst, self.psrc)
+ else:
+ return "ARP %ARP.op% %ARP.psrc% > %ARP.pdst%"
+
+
+class IP(Packet, IPTools):
+ name = "IP"
+ fields_desc = [ BitField("version" , 4 , 4),
+ BitField("ihl", None, 4),
+ XByteField("tos", 0),
+ ShortField("len", None),
+ ShortField("id", 1),
+ FlagsField("flags", 0, 3, ["MF","DF","evil"]),
+ BitField("frag", 0, 13),
+ ByteField("ttl", 64),
+ ByteEnumField("proto", 0, IP_PROTOS),
+ XShortField("chksum", None),
+ #IPField("src", "127.0.0.1"),
+ Emph(SourceIPField("src","dst")),
+ Emph(IPField("dst", "127.0.0.1")),
+ IPoptionsField("options", "") ]
+ def post_build(self, p, pay):
+ ihl = self.ihl
+ if ihl is None:
+ ihl = len(p)/4
+ p = chr(((self.version&0xf)<<4) | ihl&0x0f)+p[1:]
+ if self.len is None:
+ l = len(p)+len(pay)
+ p = p[:2]+struct.pack("!H", l)+p[4:]
+ if self.chksum is None:
+ ck = checksum(p)
+ p = p[:10]+chr(ck>>8)+chr(ck&0xff)+p[12:]
+ return p+pay
+
+ def extract_padding(self, s):
+ l = self.len - (self.ihl << 2)
+ return s[:l],s[l:]
+
+ def send(self, s, slp=0):
+ for p in self:
+ try:
+ s.sendto(str(p), (p.dst,0))
+ except socket.error, msg:
+ log_runtime.error(msg)
+ if slp:
+ time.sleep(slp)
+ def hashret(self):
+ if ( (self.proto == socket.IPPROTO_ICMP)
+ and (isinstance(self.payload, ICMP))
+ and (self.payload.type in [3,4,5,11,12]) ):
+ return self.payload.payload.hashret()
+ else:
+ if conf.checkIPsrc and conf.checkIPaddr:
+ return strxor(inet_aton(self.src),inet_aton(self.dst))+struct.pack("B",self.proto)+self.payload.hashret()
+ else:
+ return struct.pack("B", self.proto)+self.payload.hashret()
+ def answers(self, other):
+ if not isinstance(other,IP):
+ return 0
+ if conf.checkIPaddr and (self.dst != other.src):
+ return 0
+ if ( (self.proto == socket.IPPROTO_ICMP) and
+ (isinstance(self.payload, ICMP)) and
+ (self.payload.type in [3,4,5,11,12]) ):
+ # ICMP error message
+ return self.payload.payload.answers(other)
+
+ else:
+ if ( (conf.checkIPaddr and (self.src != other.dst)) or
+ (self.proto != other.proto) ):
+ return 0
+ return self.payload.answers(other.payload)
+ def mysummary(self):
+ s = self.sprintf("%IP.src% > %IP.dst% %IP.proto%")
+ if self.frag:
+ s += " frag:%i" % self.frag
+ return s
+
+
+
+class TCP(Packet):
+ name = "TCP"
+ fields_desc = [ ShortEnumField("sport", 20, TCP_SERVICES),
+ ShortEnumField("dport", 80, TCP_SERVICES),
+ IntField("seq", 0),
+ IntField("ack", 0),
+ BitField("dataofs", None, 4),
+ BitField("reserved", 0, 4),
+ FlagsField("flags", 0x2, 8, "FSRPAUEC"),
+ ShortField("window", 8192),
+ XShortField("chksum", None),
+ ShortField("urgptr", 0),
+ TCPOptionsField("options", {}) ]
+ def post_build(self, p, pay):
+ p += pay
+ dataofs = self.dataofs
+ if dataofs is None:
+ dataofs = 5+((len(self.get_field("options").i2m(self,self.options))+3)/4)
+ p = p[:12]+chr((dataofs << 4) | ord(p[12])&0x0f)+p[13:]
+ if self.chksum is None:
+ if isinstance(self.underlayer, IP):
+ if self.underlayer.len is not None:
+ ln = self.underlayer.len-20
+ else:
+ ln = len(p)
+ psdhdr = struct.pack("!4s4sHH",
+ inet_aton(self.underlayer.src),
+ inet_aton(self.underlayer.dst),
+ self.underlayer.proto,
+ ln)
+ ck=checksum(psdhdr+p)
+ p = p[:16]+struct.pack("!H", ck)+p[18:]
+ elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
+ ck = in6_chksum(socket.IPPROTO_TCP, self.underlayer, p)
+ p = p[:16]+struct.pack("!H", ck)+p[18:]
+ else:
+ warning("No IP underlayer to compute checksum. Leaving null.")
+ return p
+ def hashret(self):
+ if conf.checkIPsrc:
+ return struct.pack("H",self.sport ^ self.dport)+self.payload.hashret()
+ else:
+ return self.payload.hashret()
+ def answers(self, other):
+ if not isinstance(other, TCP):
+ return 0
+ if conf.checkIPsrc:
+ if not ((self.sport == other.dport) and
+ (self.dport == other.sport)):
+ return 0
+ if (abs(other.seq-self.ack) > 2+len(other.payload)):
+ return 0
+ return 1
+ def mysummary(self):
+ if isinstance(self.underlayer, IP):
+ return self.underlayer.sprintf("TCP %IP.src%:%TCP.sport% > %IP.dst%:%TCP.dport% %TCP.flags%")
+ elif isinstance(self.underlayer, IPv6):
+ return self.underlayer.sprintf("TCP %IPv6.src%:%TCP.sport% > %IPv6.dst%:%TCP.dport% %TCP.flags%")
+ else:
+ return self.sprintf("TCP %TCP.sport% > %TCP.dport% %TCP.flags%")
+
+class UDP(Packet):
+ name = "UDP"
+ fields_desc = [ ShortEnumField("sport", 53, UDP_SERVICES),
+ ShortEnumField("dport", 53, UDP_SERVICES),
+ ShortField("len", None),
+ XShortField("chksum", None), ]
+ def post_build(self, p, pay):
+ p += pay
+ l = self.len
+ if l is None:
+ l = len(p)
+ p = p[:4]+struct.pack("!H",l)+p[6:]
+ if self.chksum is None:
+ if isinstance(self.underlayer, IP):
+ if self.underlayer.len is not None:
+ ln = self.underlayer.len-20
+ else:
+ ln = len(p)
+ psdhdr = struct.pack("!4s4sHH",
+ inet_aton(self.underlayer.src),
+ inet_aton(self.underlayer.dst),
+ self.underlayer.proto,
+ ln)
+ ck=checksum(psdhdr+p)
+ p = p[:6]+struct.pack("!H", ck)+p[8:]
+ elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
+ ck = in6_chksum(socket.IPPROTO_UDP, self.underlayer, p)
+ p = p[:6]+struct.pack("!H", ck)+p[8:]
+ else:
+ warning("No IP underlayer to compute checksum. Leaving null.")
+ return p
+ def extract_padding(self, s):
+ l = self.len - 8
+ return s[:l],s[l:]
+ def hashret(self):
+ return self.payload.hashret()
+ def answers(self, other):
+ if not isinstance(other, UDP):
+ return 0
+ if conf.checkIPsrc:
+ if self.dport != other.sport:
+ return 0
+ return self.payload.answers(other.payload)
+ def mysummary(self):
+ if isinstance(self.underlayer, IP):
+ return self.underlayer.sprintf("UDP %IP.src%:%UDP.sport% > %IP.dst%:%UDP.dport%")
+ elif isinstance(self.underlayer, IPv6):
+ return self.underlayer.sprintf("UDP %IPv6.src%:%UDP.sport% > %IPv6.dst%:%UDP.dport%")
+ else:
+ return self.sprintf("UDP %UDP.sport% > %UDP.dport%")
+
+icmptypes = { 0 : "echo-reply",
+ 3 : "dest-unreach",
+ 4 : "source-quench",
+ 5 : "redirect",
+ 8 : "echo-request",
+ 9 : "router-advertisement",
+ 10 : "router-solicitation",
+ 11 : "time-exceeded",
+ 12 : "parameter-problem",
+ 13 : "timestamp-request",
+ 14 : "timestamp-reply",
+ 15 : "information-request",
+ 16 : "information-response",
+ 17 : "address-mask-request",
+ 18 : "address-mask-reply" }
+
+class ICMP(Packet):
+ name = "ICMP"
+ fields_desc = [ ByteEnumField("type",8, icmptypes),
+ ByteField("code",0),
+ XShortField("chksum", None),
+ XShortField("id",0),
+ XShortField("seq",0) ]
+ def post_build(self, p, pay):
+ p += pay
+ if self.chksum is None:
+ ck = checksum(p)
+ p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
+ return p
+
+ def hashret(self):
+ return struct.pack("HH",self.id,self.seq)+self.payload.hashret()
+ def answers(self, other):
+ if not isinstance(other,ICMP):
+ return 0
+ if ( (other.type,self.type) in [(8,0),(13,14),(15,16),(17,18)] and
+ self.id == other.id and
+ self.seq == other.seq ):
+ return 1
+ return 0
+
+ def guess_payload_class(self, payload):
+ if self.type in [3,4,5,11,12]:
+ return IPerror
+ else:
+ return None
+ def mysummary(self):
+ if isinstance(self.underlayer, IP):
+ return self.underlayer.sprintf("ICMP %IP.src% > %IP.dst% %ICMP.type% %ICMP.code%")
+ else:
+ return self.sprintf("ICMP %ICMP.type% %ICMP.code%")
+
+
+
+
+
+class IPerror(IP):
+ name = "IP in ICMP"
+ def answers(self, other):
+ if not isinstance(other, IP):
+ return 0
+ if not ( ((conf.checkIPsrc == 0) or (self.dst == other.dst)) and
+ (self.src == other.src) and
+ ( ((conf.checkIPID == 0)
+ or (self.id == other.id)
+ or (conf.checkIPID == 1 and self.id == socket.htons(other.id)))) and
+ (self.proto == other.proto) ):
+ return 0
+ return self.payload.answers(other.payload)
+ def mysummary(self):
+ return Packet.mysummary(self)
+
+
+class TCPerror(TCP):
+ name = "TCP in ICMP"
+ def answers(self, other):
+ if not isinstance(other, TCP):
+ return 0
+ if conf.checkIPsrc:
+ if not ((self.sport == other.sport) and
+ (self.dport == other.dport)):
+ return 0
+ if conf.check_TCPerror_seqack:
+ if self.seq is not None:
+ if self.seq != other.seq:
+ return 0
+ if self.ack is not None:
+ if self.ack != other.ack:
+ return 0
+ return 1
+ def mysummary(self):
+ return Packet.mysummary(self)
+
+
+class UDPerror(UDP):
+ name = "UDP in ICMP"
+ def answers(self, other):
+ if not isinstance(other, UDP):
+ return 0
+ if conf.checkIPsrc:
+ if not ((self.sport == other.sport) and
+ (self.dport == other.dport)):
+ return 0
+ return 1
+ def mysummary(self):
+ return Packet.mysummary(self)
+
+
+
+class ICMPerror(ICMP):
+ name = "ICMP in ICMP"
+ def answers(self, other):
+ if not isinstance(other,ICMP):
+ return 0
+ if not ((self.type == other.type) and
+ (self.code == other.code)):
+ return 0
+ if self.code in [0,8,13,14,17,18]:
+ if (self.id == other.id and
+ self.seq == other.seq):
+ return 1
+ else:
+ return 0
+ else:
+ return 1
+ def mysummary(self):
+ return Packet.mysummary(self)
+
+class IPv6(Packet):
+ """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
+ name = "IPv6 not implemented here."
+ def __init__(self, *args, **kargs):
+ log_interactive.error(self.name)
+ def __repr__(self):
+ return "<IPv6: ERROR not implemented>"
+
+class _IPv6OptionHeader(Packet):
+ """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
+ name = "IPv6 not implemented here."
+ def __init__(self, *args, **kargs):
+ log_interactive.error(self.name)
+ def __repr__(self):
+ return "<IPv6: ERROR not implemented>"
+
+class PPP(Packet):
+ name = "PPP Link Layer"
+ fields_desc = [ ShortEnumField("proto", 0x0021, {0x0021: "IP",
+ 0xc021: "LCP"} ) ]
+
+
+class DNS(Packet):
+ name = "DNS"
+ fields_desc = [ ShortField("id",0),
+ BitField("qr",0, 1),
+ BitEnumField("opcode", 0, 4, {0:"QUERY",1:"IQUERY",2:"STATUS"}),
+ BitField("aa", 0, 1),
+ BitField("tc", 0, 1),
+ BitField("rd", 0, 1),
+ BitField("ra", 0 ,1),
+ BitField("z", 0, 3),
+ BitEnumField("rcode", 0, 4, {0:"ok", 1:"format-error", 2:"server-failure", 3:"name-error", 4:"not-implemented", 5:"refused"}),
+ DNSRRCountField("qdcount", None, "qd"),
+ DNSRRCountField("ancount", None, "an"),
+ DNSRRCountField("nscount", None, "ns"),
+ DNSRRCountField("arcount", None, "ar"),
+ DNSQRField("qd", "qdcount"),
+ DNSRRField("an", "ancount"),
+ DNSRRField("ns", "nscount"),
+ DNSRRField("ar", "arcount",0) ]
+ def answers(self, other):
+ return (isinstance(other, DNS)
+ and self.id == other.id
+ and self.qr == 1
+ and other.qr == 0)
+
+ def mysummary(self):
+ type = ["Qry","Ans"][self.qr]
+ name = ""
+ if self.qr:
+ type = "Ans"
+ if self.ancount > 0 and isinstance(self.an, DNSRR):
+ name = ' "%s"' % self.an.rdata
+ else:
+ type = "Qry"
+ if self.qdcount > 0 and isinstance(self.qd, DNSQR):
+ name = ' "%s"' % self.qd.qname
+ return 'DNS %s%s ' % (type, name)
+
+dnstypes = { 0:"ANY", 255:"ALL",
+ 1:"A", 2:"NS", 3:"MD", 4:"MD", 5:"CNAME", 6:"SOA", 7: "MB", 8:"MG",
+ 9:"MR",10:"NULL",11:"WKS",12:"PTR",13:"HINFO",14:"MINFO",15:"MX",16:"TXT",
+ 17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME"}
+
+dnsqtypes = {251:"IXFR",252:"AXFR",253:"MAILB",254:"MAILA",255:"ALL"}
+dnsqtypes.update(dnstypes)
+dnsclasses = {1: 'IN', 2: 'CS', 3: 'CH', 4: 'HS', 255: 'ANY'}
+
+
+class DNSQR(Packet):
+ name = "DNS Question Record"
+ show_indent=0
+ fields_desc = [ DNSStrField("qname",""),
+ ShortEnumField("qtype", 1, dnsqtypes),
+ ShortEnumField("qclass", 1, dnsclasses) ]
+
+
+
+class DNSRR(Packet):
+ name = "DNS Resource Record"
+ show_indent=0
+ fields_desc = [ DNSStrField("rrname",""),
+ ShortEnumField("type", 1, dnstypes),
+ ShortEnumField("rclass", 1, dnsclasses),
+ IntField("ttl", 0),
+ RDLenField("rdlen"),
+ RDataField("rdata", "", length_from=lambda pkt:pkt.rdlen) ]
+
+dhcpmagic="c\x82Sc"
+
+
+class BOOTP(Packet):
+ name = "BOOTP"
+ fields_desc = [ ByteEnumField("op",1, {1:"BOOTREQUEST", 2:"BOOTREPLY"}),
+ ByteField("htype",1),
+ ByteField("hlen",6),
+ ByteField("hops",0),
+ IntField("xid",0),
+ ShortField("secs",0),
+ FlagsField("flags", 0, 16, "???????????????B"),
+ IPField("ciaddr","0.0.0.0"),
+ IPField("yiaddr","0.0.0.0"),
+ IPField("siaddr","0.0.0.0"),
+ IPField("giaddr","0.0.0.0"),
+ Field("chaddr","", "16s"),
+ Field("sname","","64s"),
+ Field("file","","128s"),
+ StrField("options","") ]
+ def guess_payload_class(self, payload):
+ if self.options[:len(dhcpmagic)] == dhcpmagic:
+ return DHCP
+ else:
+ return Packet.guess_payload_class(self, payload)
+ def extract_padding(self,s):
+ if self.options[:len(dhcpmagic)] == dhcpmagic:
+ # set BOOTP options to DHCP magic cookie and make rest a payload of DHCP options
+ payload = self.options[len(dhcpmagic):]
+ self.options = self.options[:len(dhcpmagic)]
+ return payload, None
+ else:
+ return "", None
+ def hashret(self):
+ return struct.pack("L", self.xid)
+ def answers(self, other):
+ if not isinstance(other, BOOTP):
+ return 0
+ return self.xid == other.xid
+
+
+
+#DHCP_UNKNOWN, DHCP_IP, DHCP_IPLIST, DHCP_TYPE \
+#= range(4)
+#
+
+DHCPTypes = {
+ 1: "discover",
+ 2: "offer",
+ 3: "request",
+ 4: "decline",
+ 5: "ack",
+ 6: "nak",
+ 7: "release",
+ 8: "inform",
+ 9: "force_renew",
+ 10:"lease_query",
+ 11:"lease_unassigned",
+ 12:"lease_unknown",
+ 13:"lease_active",
+ }
+
+DHCPOptions = {
+ 0: "pad",
+ 1: IPField("subnet_mask", "0.0.0.0"),
+ 2: "time_zone",
+ 3: IPField("router","0.0.0.0"),
+ 4: IPField("time_server","0.0.0.0"),
+ 5: IPField("IEN_name_server","0.0.0.0"),
+ 6: IPField("name_server","0.0.0.0"),
+ 7: IPField("log_server","0.0.0.0"),
+ 8: IPField("cookie_server","0.0.0.0"),
+ 9: IPField("lpr_server","0.0.0.0"),
+ 12: "hostname",
+ 14: "dump_path",
+ 15: "domain",
+ 17: "root_disk_path",
+ 22: "max_dgram_reass_size",
+ 23: "default_ttl",
+ 24: "pmtu_timeout",
+ 28: IPField("broadcast_address","0.0.0.0"),
+ 35: "arp_cache_timeout",
+ 36: "ether_or_dot3",
+ 37: "tcp_ttl",
+ 38: "tcp_keepalive_interval",
+ 39: "tcp_keepalive_garbage",
+ 40: "NIS_domain",
+ 41: IPField("NIS_server","0.0.0.0"),
+ 42: IPField("NTP_server","0.0.0.0"),
+ 43: "vendor_specific",
+ 44: IPField("NetBIOS_server","0.0.0.0"),
+ 45: IPField("NetBIOS_dist_server","0.0.0.0"),
+ 50: IPField("requested_addr","0.0.0.0"),
+ 51: IntField("lease_time", 43200),
+ 54: IPField("server_id","0.0.0.0"),
+ 55: "param_req_list",
+ 57: ShortField("max_dhcp_size", 1500),
+ 58: IntField("renewal_time", 21600),
+ 59: IntField("rebinding_time", 37800),
+ 60: "vendor_class_id",
+ 61: "client_id",
+
+ 64: "NISplus_domain",
+ 65: IPField("NISplus_server","0.0.0.0"),
+ 69: IPField("SMTP_server","0.0.0.0"),
+ 70: IPField("POP3_server","0.0.0.0"),
+ 71: IPField("NNTP_server","0.0.0.0"),
+ 72: IPField("WWW_server","0.0.0.0"),
+ 73: IPField("Finger_server","0.0.0.0"),
+ 74: IPField("IRC_server","0.0.0.0"),
+ 75: IPField("StreetTalk_server","0.0.0.0"),
+ 76: "StreetTalk_Dir_Assistance",
+ 82: "relay_agent_Information",
+ 53: ByteEnumField("message-type", 1, DHCPTypes),
+ # 55: DHCPRequestListField("request-list"),
+ 255: "end"
+ }
+
+DHCPRevOptions = {}
+
+for k,v in DHCPOptions.iteritems():
+ if type(v) is str:
+ n = v
+ v = None
+ else:
+ n = v.name
+ DHCPRevOptions[n] = (k,v)
+del(n)
+del(v)
+del(k)
+
+
+
+
+
+class DHCPOptionsField(StrField):
+ islist=1
+ def i2repr(self,pkt,x):
+ s = []
+ for v in x:
+ if type(v) is tuple and len(v) == 2:
+ if DHCPRevOptions.has_key(v[0]) and isinstance(DHCPRevOptions[v[0]][1],Field):
+ f = DHCPRevOptions[v[0]][1]
+ vv = f.i2repr(pkt,v[1])
+ else:
+ vv = repr(v[1])
+ s.append("%s=%s" % (v[0],vv))
+ else:
+ s.append(str(v))
+ return "[%s]" % (" ".join(s))
+
+ def getfield(self, pkt, s):
+ return "", self.m2i(pkt, s)
+ def m2i(self, pkt, x):
+ opt = []
+ while x:
+ o = ord(x[0])
+ if o == 255:
+ opt.append("end")
+ x = x[1:]
+ continue
+ if o == 0:
+ opt.append("pad")
+ x = x[1:]
+ continue
+ if DHCPOptions.has_key(o):
+ f = DHCPOptions[o]
+
+ if isinstance(f, str):
+ olen = ord(x[1])
+ opt.append( (f,x[2:olen+2]) )
+ x = x[olen+2:]
+ else:
+ olen = ord(x[1])
+ left, val = f.getfield(pkt,x[2:olen+2])
+# val = f.m2i(pkt,val)
+# if left:
+# print "m2i data left left=%s" % left
+ opt.append((f.name, val))
+ x = x[olen+2:]
+ else:
+ olen = ord(x[1])
+ opt.append((o, x[2:olen+2]))
+ x = x[olen+2:]
+ return opt
+ def i2m(self, pkt, x):
+ #print "i2m x=%s" % x
+ s = ""
+ for o in x:
+ if type(o) is tuple and len(o) == 2:
+ name, val = o
+
+ if isinstance(name, int):
+ onum, oval = name, val
+ elif DHCPRevOptions.has_key(name):
+ onum, f = DHCPRevOptions[name]
+ if f is None:
+ oval = val
+ else:
+# oval = f.addfield(pkt,"",f.i2m(pkt,f.any2i(pkt,val)))
+ oval = f.addfield(pkt,"",f.any2i(pkt,val))
+
+ else:
+ warning("Unknown field option %s" % name)
+ continue
+
+ s += chr(onum)
+ s += chr(len(oval))
+ s += oval
+
+ elif (type(o) is str and DHCPRevOptions.has_key(o) and
+ DHCPRevOptions[o][1] == None):
+ s += chr(DHCPRevOptions[o][0])
+ elif type(o) is int:
+ s += chr(o)
+ else:
+ warning("Malformed option %s" % o)
+ return s
+
+
+class DHCP(Packet):
+ name = "DHCP options"
+ fields_desc = [ DHCPOptionsField("options","") ]
+
+
+class Dot11(Packet):
+ name = "802.11"
+ fields_desc = [
+ BitField("subtype", 0, 4),
+ BitEnumField("type", 0, 2, ["Management", "Control", "Data", "Reserved"]),
+ BitField("proto", 0, 2),
+ FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry", "pw-mgt", "MD", "wep", "order"]),
+ ShortField("ID",0),
+ MACField("addr1", ETHER_ANY),
+ Dot11Addr2MACField("addr2", ETHER_ANY),
+ Dot11Addr3MACField("addr3", ETHER_ANY),
+ Dot11SCField("SC", 0),
+ Dot11Addr4MACField("addr4", ETHER_ANY)
+ ]
+ def mysummary(self):
+ return self.sprintf("802.11 %Dot11.type% %Dot11.subtype% %Dot11.addr2% > %Dot11.addr1%")
+ def guess_payload_class(self, payload):
+ if self.FCfield & 0x40:
+ return Dot11WEP
+ else:
+ return Packet.guess_payload_class(self, payload)
+ def answers(self, other):
+ if isinstance(other,Dot11):
+ if self.type == 0: # management
+ if self.addr1.lower() != other.addr2.lower(): # check resp DA w/ req SA
+ return 0
+ if (other.subtype,self.subtype) in [(0,1),(2,3),(4,5)]:
+ return 1
+ if self.subtype == other.subtype == 11: # auth
+ return self.payload.answers(other.payload)
+ elif self.type == 1: # control
+ return 0
+ elif self.type == 2: # data
+ return self.payload.answers(other.payload)
+ elif self.type == 3: # reserved
+ return 0
+ return 0
+ def unwep(self, key=None, warn=1):
+ if self.FCfield & 0x40 == 0:
+ if warn:
+ warning("No WEP to remove")
+ return
+ if isinstance(self.payload.payload, NoPayload):
+ if key or conf.wepkey:
+ self.payload.decrypt(key)
+ if isinstance(self.payload.payload, NoPayload):
+ if warn:
+ warning("Dot11 can't be decrypted. Check conf.wepkey.")
+ return
+ self.FCfield &= ~0x40
+ self.payload=self.payload.payload
+
+
+capability_list = [ "res8", "res9", "short-slot", "res11",
+ "res12", "DSSS-OFDM", "res14", "res15",
+ "ESS", "IBSS", "CFP", "CFP-req",
+ "privacy", "short-preamble", "PBCC", "agility"]
+
+reason_code = {0:"reserved",1:"unspec", 2:"auth-expired",
+ 3:"deauth-ST-leaving",
+ 4:"inactivity", 5:"AP-full", 6:"class2-from-nonauth",
+ 7:"class3-from-nonass", 8:"disas-ST-leaving",
+ 9:"ST-not-auth"}
+
+status_code = {0:"success", 1:"failure", 10:"cannot-support-all-cap",
+ 11:"inexist-asso", 12:"asso-denied", 13:"algo-unsupported",
+ 14:"bad-seq-num", 15:"challenge-failure",
+ 16:"timeout", 17:"AP-full",18:"rate-unsupported" }
+
+class Dot11Beacon(Packet):
+ name = "802.11 Beacon"
+ fields_desc = [ LELongField("timestamp", 0),
+ LEShortField("beacon_interval", 0x0064),
+ FlagsField("cap", 0, 16, capability_list) ]
+
+
+class Dot11Elt(Packet):
+ name = "802.11 Information Element"
+ fields_desc = [ ByteEnumField("ID", 0, {0:"SSID", 1:"Rates", 2: "FHset", 3:"DSset", 4:"CFset", 5:"TIM", 6:"IBSSset", 16:"challenge",
+ 42:"ERPinfo", 47:"ERPinfo", 48:"RSNinfo", 50:"ESRates",221:"vendor",68:"reserved"}),
+ FieldLenField("len", None, "info", "B"),
+ StrLenField("info", "", length_from=lambda x:x.len) ]
+ def mysummary(self):
+ if self.ID == 0:
+ return "SSID=%s"%repr(self.info),[Dot11]
+ else:
+ return ""
+
+class Dot11ATIM(Packet):
+ name = "802.11 ATIM"
+
+class Dot11Disas(Packet):
+ name = "802.11 Disassociation"
+ fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
+
+class Dot11AssoReq(Packet):
+ name = "802.11 Association Request"
+ fields_desc = [ FlagsField("cap", 0, 16, capability_list),
+ LEShortField("listen_interval", 0x00c8) ]
+
+
+class Dot11AssoResp(Packet):
+ name = "802.11 Association Response"
+ fields_desc = [ FlagsField("cap", 0, 16, capability_list),
+ LEShortField("status", 0),
+ LEShortField("AID", 0) ]
+
+class Dot11ReassoReq(Packet):
+ name = "802.11 Reassociation Request"
+ fields_desc = [ FlagsField("cap", 0, 16, capability_list),
+ MACField("current_AP", ETHER_ANY),
+ LEShortField("listen_interval", 0x00c8) ]
+
+
+class Dot11ReassoResp(Dot11AssoResp):
+ name = "802.11 Reassociation Response"
+
+class Dot11ProbeReq(Packet):
+ name = "802.11 Probe Request"
+
+class Dot11ProbeResp(Packet):
+ name = "802.11 Probe Response"
+ fields_desc = [ LELongField("timestamp", 0),
+ LEShortField("beacon_interval", 0x0064),
+ FlagsField("cap", 0, 16, capability_list) ]
+
+class Dot11Auth(Packet):
+ name = "802.11 Authentication"
+ fields_desc = [ LEShortEnumField("algo", 0, ["open", "sharedkey"]),
+ LEShortField("seqnum", 0),
+ LEShortEnumField("status", 0, status_code) ]
+ def answers(self, other):
+ if self.seqnum == other.seqnum+1:
+ return 1
+ return 0
+
+class Dot11Deauth(Packet):
+ name = "802.11 Deauthentication"
+ fields_desc = [ LEShortEnumField("reason", 1, reason_code) ]
+
+
+
+class Dot11WEP(Packet):
+ name = "802.11 WEP packet"
+ fields_desc = [ StrFixedLenField("iv", "\0\0\0", 3),
+ ByteField("keyid", 0),
+ StrField("wepdata",None,remain=4),
+ IntField("icv",None) ]
+
+ def post_dissect(self, s):
+# self.icv, = struct.unpack("!I",self.wepdata[-4:])
+# self.wepdata = self.wepdata[:-4]
+ self.decrypt()
+
+ def build_payload(self):
+ if self.wepdata is None:
+ return Packet.build_payload(self)
+ return ""
+
+ def post_build(self, p, pay):
+ if self.wepdata is None:
+ key = conf.wepkey
+ if key:
+ if self.icv is None:
+ pay += struct.pack("<I",crc32(pay))
+ icv = ""
+ else:
+ icv = p[4:8]
+ c = ARC4.new(self.iv+key)
+ p = p[:4]+c.encrypt(pay)+icv
+ else:
+ warning("No WEP key set (conf.wepkey).. strange results expected..")
+ return p
+
+
+ def decrypt(self,key=None):
+ if key is None:
+ key = conf.wepkey
+ if key:
+ c = ARC4.new(self.iv+key)
+ self.add_payload(LLC(c.decrypt(self.wepdata)))
+
+
+
+class PrismHeader(Packet):
+ """ iwpriv wlan0 monitor 3 """
+ name = "Prism header"
+ fields_desc = [ LEIntField("msgcode",68),
+ LEIntField("len",144),
+ StrFixedLenField("dev","",16),
+ LEIntField("hosttime_did",0),
+ LEShortField("hosttime_status",0),
+ LEShortField("hosttime_len",0),
+ LEIntField("hosttime",0),
+ LEIntField("mactime_did",0),
+ LEShortField("mactime_status",0),
+ LEShortField("mactime_len",0),
+ LEIntField("mactime",0),
+ LEIntField("channel_did",0),
+ LEShortField("channel_status",0),
+ LEShortField("channel_len",0),
+ LEIntField("channel",0),
+ LEIntField("rssi_did",0),
+ LEShortField("rssi_status",0),
+ LEShortField("rssi_len",0),
+ LEIntField("rssi",0),
+ LEIntField("sq_did",0),
+ LEShortField("sq_status",0),
+ LEShortField("sq_len",0),
+ LEIntField("sq",0),
+ LEIntField("signal_did",0),
+ LEShortField("signal_status",0),
+ LEShortField("signal_len",0),
+ LESignedIntField("signal",0),
+ LEIntField("noise_did",0),
+ LEShortField("noise_status",0),
+ LEShortField("noise_len",0),
+ LEIntField("noise",0),
+ LEIntField("rate_did",0),
+ LEShortField("rate_status",0),
+ LEShortField("rate_len",0),
+ LEIntField("rate",0),
+ LEIntField("istx_did",0),
+ LEShortField("istx_status",0),
+ LEShortField("istx_len",0),
+ LEIntField("istx",0),
+ LEIntField("frmlen_did",0),
+ LEShortField("frmlen_status",0),
+ LEShortField("frmlen_len",0),
+ LEIntField("frmlen",0),
+ ]
+ def answers(self, other):
+ if isinstance(other, PrismHeader):
+ return self.payload.answers(other.payload)
+ else:
+ return self.payload.answers(other)
+
+
+
+class HSRP(Packet):
+ name = "HSRP"
+ fields_desc = [
+ ByteField("version", 0),
+ ByteEnumField("opcode", 0, { 0:"Hello"}),
+ ByteEnumField("state", 16, { 16:"Active"}),
+ ByteField("hellotime", 3),
+ ByteField("holdtime", 10),
+ ByteField("priority", 120),
+ ByteField("group", 1),
+ ByteField("reserved", 0),
+ StrFixedLenField("auth","cisco",8),
+ IPField("virtualIP","192.168.1.1") ]
+
+
+
+
+
+
+
+class NTP(Packet):
+ # RFC 1769
+ name = "NTP"
+ fields_desc = [
+ BitEnumField('leap', 0, 2,
+ { 0: 'nowarning',
+ 1: 'longminute',
+ 2: 'shortminute',
+ 3: 'notsync'}),
+ BitField('version', 3, 3),
+ BitEnumField('mode', 3, 3,
+ { 0: 'reserved',
+ 1: 'sym_active',
+ 2: 'sym_passive',
+ 3: 'client',
+ 4: 'server',
+ 5: 'broadcast',
+ 6: 'control',
+ 7: 'private'}),
+ BitField('stratum', 2, 8),
+ BitField('poll', 0xa, 8), ### XXX : it's a signed int
+ BitField('precision', 0, 8), ### XXX : it's a signed int
+ FloatField('delay', 0, 32),
+ FloatField('dispersion', 0, 32),
+ IPField('id', "127.0.0.1"),
+ TimeStampField('ref', 0, 64),
+ TimeStampField('orig', -1, 64), # -1 means current time
+ TimeStampField('recv', 0, 64),
+ TimeStampField('sent', -1, 64)
+ ]
+ def mysummary(self):
+ return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%")
+
+
+class GRE(Packet):
+ name = "GRE"
+ fields_desc = [ BitField("chksumpresent",0,1),
+ BitField("reserved0",0,12),
+ BitField("version",0,3),
+ XShortEnumField("proto", 0x0000, ETHER_TYPES),
+ ConditionalField(XShortField("chksum",None),lambda pkt:pkt.chksumpresent==1),
+ ConditionalField(XShortField("reserved1",None),lambda pkt:pkt.chksumpresent==1),
+ ]
+ def post_build(self, p, pay):
+ p += pay
+ if self.chksumpresent and self.chksum is None:
+ c = checksum(p)
+ p = p[:4]+chr((c>>8)&0xff)+chr(c&0xff)+p[6:]
+ return p
+
+
+class Radius(Packet):
+ name = "Radius"
+ fields_desc = [ ByteEnumField("code", 1, {1: "Access-Request",
+ 2: "Access-Accept",
+ 3: "Access-Reject",
+ 4: "Accounting-Request",
+ 5: "Accounting-Accept",
+ 6: "Accounting-Status",
+ 7: "Password-Request",
+ 8: "Password-Ack",
+ 9: "Password-Reject",
+ 10: "Accounting-Message",
+ 11: "Access-Challenge",
+ 12: "Status-Server",
+ 13: "Status-Client",
+ 21: "Resource-Free-Request",
+ 22: "Resource-Free-Response",
+ 23: "Resource-Query-Request",
+ 24: "Resource-Query-Response",
+ 25: "Alternate-Resource-Reclaim-Request",
+ 26: "NAS-Reboot-Request",
+ 27: "NAS-Reboot-Response",
+ 29: "Next-Passcode",
+ 30: "New-Pin",
+ 31: "Terminate-Session",
+ 32: "Password-Expired",
+ 33: "Event-Request",
+ 34: "Event-Response",
+ 40: "Disconnect-Request",
+ 41: "Disconnect-ACK",
+ 42: "Disconnect-NAK",
+ 43: "CoA-Request",
+ 44: "CoA-ACK",
+ 45: "CoA-NAK",
+ 50: "IP-Address-Allocate",
+ 51: "IP-Address-Release",
+ 253: "Experimental-use",
+ 254: "Reserved",
+ 255: "Reserved"} ),
+ ByteField("id", 0),
+ ShortField("len", None),
+ StrFixedLenField("authenticator","",16) ]
+ def post_build(self, p, pay):
+ p += pay
+ l = self.len
+ if l is None:
+ l = len(p)
+ p = p[:2]+struct.pack("!H",l)+p[4:]
+ return p
+
+
+
+
+class RIP(Packet):
+ name = "RIP header"
+ fields_desc = [
+ ByteEnumField("command",1,{1:"req",2:"resp",3:"traceOn",4:"traceOff",5:"sun",
+ 6:"trigReq",7:"trigResp",8:"trigAck",9:"updateReq",
+ 10:"updateResp",11:"updateAck"}),
+ ByteField("version",1),
+ ShortField("null",0),
+ ]
+
+class RIPEntry(Packet):
+ name = "RIP entry"
+ fields_desc = [
+ ShortEnumField("AF",2,{2:"IP"}),
+ ShortField("RouteTag",0),
+ IPField("addr","0.0.0.0"),
+ IPField("mask","0.0.0.0"),
+ IPField("nextHop","0.0.0.0"),
+ IntEnumField("metric",1,{16:"Unreach"}),
+ ]
+
+
+
+
+ISAKMP_payload_type = ["None","SA","Proposal","Transform","KE","ID","CERT","CR","Hash",
+ "SIG","Nonce","Notification","Delete","VendorID"]
+
+ISAKMP_exchange_type = ["None","base","identity prot.",
+ "auth only", "aggressive", "info"]
+
+
+class ISAKMP_class(Packet):
+ def guess_payload_class(self, payload):
+ np = self.next_payload
+ if np == 0:
+ return Raw
+ elif np < len(ISAKMP_payload_type):
+ pt = ISAKMP_payload_type[np]
+ return globals().get("ISAKMP_payload_%s" % pt, ISAKMP_payload)
+ else:
+ return ISAKMP_payload
+
+
+class ISAKMP(ISAKMP_class): # rfc2408
+ name = "ISAKMP"
+ fields_desc = [
+ StrFixedLenField("init_cookie","",8),
+ StrFixedLenField("resp_cookie","",8),
+ ByteEnumField("next_payload",0,ISAKMP_payload_type),
+ XByteField("version",0x10),
+ ByteEnumField("exch_type",0,ISAKMP_exchange_type),
+ FlagsField("flags",0, 8, ["encryption","commit","auth_only","res3","res4","res5","res6","res7"]), # XXX use a Flag field
+ IntField("id",0),
+ IntField("length",None)
+ ]
+
+ def guess_payload_class(self, payload):
+ if self.flags & 1:
+ return Raw
+ return ISAKMP_class.guess_payload_class(self, payload)
+
+ def answers(self, other):
+ if isinstance(other, ISAKMP):
+ if other.init_cookie == self.init_cookie:
+ return 1
+ return 0
+ def post_build(self, p, pay):
+ p += pay
+ if self.length is None:
+ p = p[:24]+struct.pack("!I",len(p))+p[28:]
+ return p
+
+
+
+
+class ISAKMP_payload_Transform(ISAKMP_class):
+ name = "IKE Transform"
+ fields_desc = [
+ ByteEnumField("next_payload",None,ISAKMP_payload_type),
+ ByteField("res",0),
+# ShortField("len",None),
+ ShortField("length",None),
+ ByteField("num",None),
+ ByteEnumField("id",1,{1:"KEY_IKE"}),
+ ShortField("res2",0),
+ ISAKMPTransformSetField("transforms",None,length_from=lambda x:x.length-8)
+# XIntField("enc",0x80010005L),
+# XIntField("hash",0x80020002L),
+# XIntField("auth",0x80030001L),
+# XIntField("group",0x80040002L),
+# XIntField("life_type",0x800b0001L),
+# XIntField("durationh",0x000c0004L),
+# XIntField("durationl",0x00007080L),
+ ]
+ def post_build(self, p, pay):
+ if self.length is None:
+ l = len(p)
+ p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
+ p += pay
+ return p
+
+
+
+
+class ISAKMP_payload_Proposal(ISAKMP_class):
+ name = "IKE proposal"
+# ISAKMP_payload_type = 0
+ fields_desc = [
+ ByteEnumField("next_payload",None,ISAKMP_payload_type),
+ ByteField("res",0),
+ FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8),
+ ByteField("proposal",1),
+ ByteEnumField("proto",1,{1:"ISAKMP"}),
+ FieldLenField("SPIsize",None,"SPI","B"),
+ ByteField("trans_nb",None),
+ StrLenField("SPI","",length_from=lambda x:x.SPIsize),
+ PacketLenField("trans",Raw(),ISAKMP_payload_Transform,length_from=lambda x:x.length-8),
+ ]
+
+
+class ISAKMP_payload(ISAKMP_class):
+ name = "ISAKMP payload"
+ fields_desc = [
+ ByteEnumField("next_payload",None,ISAKMP_payload_type),
+ ByteField("res",0),
+ FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
+ StrLenField("load","",length_from=lambda x:x.length-4),
+ ]
+
+
+class ISAKMP_payload_VendorID(ISAKMP_class):
+ name = "ISAKMP Vendor ID"
+ overload_fields = { ISAKMP: { "next_payload":13 }}
+ fields_desc = [
+ ByteEnumField("next_payload",None,ISAKMP_payload_type),
+ ByteField("res",0),
+ FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
+ StrLenField("vendorID","",length_from=lambda x:x.length-4),
+ ]
+
+class ISAKMP_payload_SA(ISAKMP_class):
+ name = "ISAKMP SA"
+ overload_fields = { ISAKMP: { "next_payload":1 }}
+ fields_desc = [
+ ByteEnumField("next_payload",None,ISAKMP_payload_type),
+ ByteField("res",0),
+ FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+12),
+ IntEnumField("DOI",1,{1:"IPSEC"}),
+ IntEnumField("situation",1,{1:"identity"}),
+ PacketLenField("prop",Raw(),ISAKMP_payload_Proposal,length_from=lambda x:x.length-12),
+ ]
+
+class ISAKMP_payload_Nonce(ISAKMP_class):
+ name = "ISAKMP Nonce"
+ overload_fields = { ISAKMP: { "next_payload":10 }}
+ fields_desc = [
+ ByteEnumField("next_payload",None,ISAKMP_payload_type),
+ ByteField("res",0),
+ FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
+ StrLenField("load","",length_from=lambda x:x.length-4),
+ ]
+
+class ISAKMP_payload_KE(ISAKMP_class):
+ name = "ISAKMP Key Exchange"
+ overload_fields = { ISAKMP: { "next_payload":4 }}
+ fields_desc = [
+ ByteEnumField("next_payload",None,ISAKMP_payload_type),
+ ByteField("res",0),
+ FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
+ StrLenField("load","",length_from=lambda x:x.length-4),
+ ]
+
+class ISAKMP_payload_ID(ISAKMP_class):
+ name = "ISAKMP Identification"
+ overload_fields = { ISAKMP: { "next_payload":5 }}
+ fields_desc = [
+ ByteEnumField("next_payload",None,ISAKMP_payload_type),
+ ByteField("res",0),
+ FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
+ ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
+ ByteEnumField("ProtoID",0,{0:"Unused"}),
+ ShortEnumField("Port",0,{0:"Unused"}),
+# IPField("IdentData","127.0.0.1"),
+ StrLenField("load","",length_from=lambda x:x.length-8),
+ ]
+
+
+
+class ISAKMP_payload_Hash(ISAKMP_class):
+ name = "ISAKMP Hash"
+ overload_fields = { ISAKMP: { "next_payload":8 }}
+ fields_desc = [
+ ByteEnumField("next_payload",None,ISAKMP_payload_type),
+ ByteField("res",0),
+ FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4),
+ StrLenField("load","",length_from=lambda x:x.length-4),
+ ]
+
+
+
+ISAKMP_payload_type_overload = {}
+for i in range(len(ISAKMP_payload_type)):
+ name = "ISAKMP_payload_%s" % ISAKMP_payload_type[i]
+ if name in globals():
+ ISAKMP_payload_type_overload[globals()[name]] = {"next_payload":i}
+
+del(i)
+del(name)
+ISAKMP_class.overload_fields = ISAKMP_payload_type_overload.copy()
+
+
+
+
+# Cisco Skinny protocol
+
+# shamelessly ripped from Ethereal dissector
+skinny_messages = {
+# Station -> Callmanager
+ 0x0000: "KeepAliveMessage",
+ 0x0001: "RegisterMessage",
+ 0x0002: "IpPortMessage",
+ 0x0003: "KeypadButtonMessage",
+ 0x0004: "EnblocCallMessage",
+ 0x0005: "StimulusMessage",
+ 0x0006: "OffHookMessage",
+ 0x0007: "OnHookMessage",
+ 0x0008: "HookFlashMessage",
+ 0x0009: "ForwardStatReqMessage",
+ 0x000A: "SpeedDialStatReqMessage",
+ 0x000B: "LineStatReqMessage",
+ 0x000C: "ConfigStatReqMessage",
+ 0x000D: "TimeDateReqMessage",
+ 0x000E: "ButtonTemplateReqMessage",
+ 0x000F: "VersionReqMessage",
+ 0x0010: "CapabilitiesResMessage",
+ 0x0011: "MediaPortListMessage",
+ 0x0012: "ServerReqMessage",
+ 0x0020: "AlarmMessage",
+ 0x0021: "MulticastMediaReceptionAck",
+ 0x0022: "OpenReceiveChannelAck",
+ 0x0023: "ConnectionStatisticsRes",
+ 0x0024: "OffHookWithCgpnMessage",
+ 0x0025: "SoftKeySetReqMessage",
+ 0x0026: "SoftKeyEventMessage",
+ 0x0027: "UnregisterMessage",
+ 0x0028: "SoftKeyTemplateReqMessage",
+ 0x0029: "RegisterTokenReq",
+ 0x002A: "MediaTransmissionFailure",
+ 0x002B: "HeadsetStatusMessage",
+ 0x002C: "MediaResourceNotification",
+ 0x002D: "RegisterAvailableLinesMessage",
+ 0x002E: "DeviceToUserDataMessage",
+ 0x002F: "DeviceToUserDataResponseMessage",
+ 0x0030: "UpdateCapabilitiesMessage",
+ 0x0031: "OpenMultiMediaReceiveChannelAckMessage",
+ 0x0032: "ClearConferenceMessage",
+ 0x0033: "ServiceURLStatReqMessage",
+ 0x0034: "FeatureStatReqMessage",
+ 0x0035: "CreateConferenceResMessage",
+ 0x0036: "DeleteConferenceResMessage",
+ 0x0037: "ModifyConferenceResMessage",
+ 0x0038: "AddParticipantResMessage",
+ 0x0039: "AuditConferenceResMessage",
+ 0x0040: "AuditParticipantResMessage",
+ 0x0041: "DeviceToUserDataVersion1Message",
+# Callmanager -> Station */
+ 0x0081: "RegisterAckMessage",
+ 0x0082: "StartToneMessage",
+ 0x0083: "StopToneMessage",
+ 0x0085: "SetRingerMessage",
+ 0x0086: "SetLampMessage",
+ 0x0087: "SetHkFDetectMessage",
+ 0x0088: "SetSpeakerModeMessage",
+ 0x0089: "SetMicroModeMessage",
+ 0x008A: "StartMediaTransmission",
+ 0x008B: "StopMediaTransmission",
+ 0x008C: "StartMediaReception",
+ 0x008D: "StopMediaReception",
+ 0x008F: "CallInfoMessage",
+ 0x0090: "ForwardStatMessage",
+ 0x0091: "SpeedDialStatMessage",
+ 0x0092: "LineStatMessage",
+ 0x0093: "ConfigStatMessage",
+ 0x0094: "DefineTimeDate",
+ 0x0095: "StartSessionTransmission",
+ 0x0096: "StopSessionTransmission",
+ 0x0097: "ButtonTemplateMessage",
+ 0x0098: "VersionMessage",
+ 0x0099: "DisplayTextMessage",
+ 0x009A: "ClearDisplay",
+ 0x009B: "CapabilitiesReqMessage",
+ 0x009C: "EnunciatorCommandMessage",
+ 0x009D: "RegisterRejectMessage",
+ 0x009E: "ServerResMessage",
+ 0x009F: "Reset",
+ 0x0100: "KeepAliveAckMessage",
+ 0x0101: "StartMulticastMediaReception",
+ 0x0102: "StartMulticastMediaTransmission",
+ 0x0103: "StopMulticastMediaReception",
+ 0x0104: "StopMulticastMediaTransmission",
+ 0x0105: "OpenReceiveChannel",
+ 0x0106: "CloseReceiveChannel",
+ 0x0107: "ConnectionStatisticsReq",
+ 0x0108: "SoftKeyTemplateResMessage",
+ 0x0109: "SoftKeySetResMessage",
+ 0x0110: "SelectSoftKeysMessage",
+ 0x0111: "CallStateMessage",
+ 0x0112: "DisplayPromptStatusMessage",
+ 0x0113: "ClearPromptStatusMessage",
+ 0x0114: "DisplayNotifyMessage",
+ 0x0115: "ClearNotifyMessage",
+ 0x0116: "ActivateCallPlaneMessage",
+ 0x0117: "DeactivateCallPlaneMessage",
+ 0x0118: "UnregisterAckMessage",
+ 0x0119: "BackSpaceReqMessage",
+ 0x011A: "RegisterTokenAck",
+ 0x011B: "RegisterTokenReject",
+ 0x0042: "DeviceToUserDataResponseVersion1Message",
+ 0x011C: "StartMediaFailureDetection",
+ 0x011D: "DialedNumberMessage",
+ 0x011E: "UserToDeviceDataMessage",
+ 0x011F: "FeatureStatMessage",
+ 0x0120: "DisplayPriNotifyMessage",
+ 0x0121: "ClearPriNotifyMessage",
+ 0x0122: "StartAnnouncementMessage",
+ 0x0123: "StopAnnouncementMessage",
+ 0x0124: "AnnouncementFinishMessage",
+ 0x0127: "NotifyDtmfToneMessage",
+ 0x0128: "SendDtmfToneMessage",
+ 0x0129: "SubscribeDtmfPayloadReqMessage",
+ 0x012A: "SubscribeDtmfPayloadResMessage",
+ 0x012B: "SubscribeDtmfPayloadErrMessage",
+ 0x012C: "UnSubscribeDtmfPayloadReqMessage",
+ 0x012D: "UnSubscribeDtmfPayloadResMessage",
+ 0x012E: "UnSubscribeDtmfPayloadErrMessage",
+ 0x012F: "ServiceURLStatMessage",
+ 0x0130: "CallSelectStatMessage",
+ 0x0131: "OpenMultiMediaChannelMessage",
+ 0x0132: "StartMultiMediaTransmission",
+ 0x0133: "StopMultiMediaTransmission",
+ 0x0134: "MiscellaneousCommandMessage",
+ 0x0135: "FlowControlCommandMessage",
+ 0x0136: "CloseMultiMediaReceiveChannel",
+ 0x0137: "CreateConferenceReqMessage",
+ 0x0138: "DeleteConferenceReqMessage",
+ 0x0139: "ModifyConferenceReqMessage",
+ 0x013A: "AddParticipantReqMessage",
+ 0x013B: "DropParticipantReqMessage",
+ 0x013C: "AuditConferenceReqMessage",
+ 0x013D: "AuditParticipantReqMessage",
+ 0x013F: "UserToDeviceDataVersion1Message",
+ }
+
+
+
+class Skinny(Packet):
+ name="Skinny"
+ fields_desc = [ LEIntField("len",0),
+ LEIntField("res",0),
+ LEIntEnumField("msg",0,skinny_messages) ]
+
+_rtp_payload_types = {
+ # http://www.iana.org/assignments/rtp-parameters
+ 0: 'G.711 PCMU', 3: 'GSM',
+ 4: 'G723', 5: 'DVI4',
+ 6: 'DVI4', 7: 'LPC',
+ 8: 'PCMA', 9: 'G722',
+ 10: 'L16', 11: 'L16',
+ 12: 'QCELP', 13: 'CN',
+ 14: 'MPA', 15: 'G728',
+ 16: 'DVI4', 17: 'DVI4',
+ 18: 'G729', 25: 'CelB',
+ 26: 'JPEG', 28: 'nv',
+ 31: 'H261', 32: 'MPV',
+ 33: 'MP2T', 34: 'H263' }
+
+class RTP(Packet):
+ name="RTP"
+ fields_desc = [ BitField('version', 2, 2),
+ BitField('padding', 0, 1),
+ BitField('extension', 0, 1),
+ BitFieldLenField('numsync', None, 4, count_of='sync'),
+ BitField('marker', 0, 1),
+ BitEnumField('payload', 0, 7, _rtp_payload_types),
+ ShortField('sequence', 0),
+ IntField('timestamp', 0),
+ IntField('sourcesync', 0),
+ FieldListField('sync', [], IntField("id",0), count_from=lambda pkt:pkt.numsync) ]
+
+### SEBEK
+
+
+class SebekHead(Packet):
+ name = "Sebek header"
+ fields_desc = [ XIntField("magic", 0xd0d0d0),
+ ShortField("version", 1),
+ ShortEnumField("type", 0, {"read":0, "write":1,
+ "socket":2, "open":3}),
+ IntField("counter", 0),
+ IntField("time_sec", 0),
+ IntField("time_usec", 0) ]
+ def mysummary(self):
+ return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%")
+
+# we need this because Sebek headers differ between v1 and v3, and
+# between v3 type socket and v3 others
+
+class SebekV1(Packet):
+ name = "Sebek v1"
+ fields_desc = [ IntField("pid", 0),
+ IntField("uid", 0),
+ IntField("fd", 0),
+ StrFixedLenField("command", "", 12),
+ FieldLenField("data_length", None, "data",fmt="I"),
+ StrLenField("data", "", length_from=lambda x:x.data_length) ]
+ def mysummary(self):
+ if isinstance(self.underlayer, SebekHead):
+ return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.command%)")
+ else:
+ return self.sprintf("Sebek v1 (%SebekV1.command%)")
+
+class SebekV3(Packet):
+ name = "Sebek v3"
+ fields_desc = [ IntField("parent_pid", 0),
+ IntField("pid", 0),
+ IntField("uid", 0),
+ IntField("fd", 0),
+ IntField("inode", 0),
+ StrFixedLenField("command", "", 12),
+ FieldLenField("data_length", None, "data",fmt="I"),
+ StrLenField("data", "", length_from=lambda x:x.data_length) ]
+ def mysummary(self):
+ if isinstance(self.underlayer, SebekHead):
+ return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.command%)")
+ else:
+ return self.sprintf("Sebek v3 (%SebekV3.command%)")
+
+class SebekV2(SebekV3):
+ def mysummary(self):
+ if isinstance(self.underlayer, SebekHead):
+ return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.command%)")
+ else:
+ return self.sprintf("Sebek v2 (%SebekV2.command%)")
+
+class SebekV3Sock(Packet):
+ name = "Sebek v2 socket"
+ fields_desc = [ IntField("parent_pid", 0),
+ IntField("pid", 0),
+ IntField("uid", 0),
+ IntField("fd", 0),
+ IntField("inode", 0),
+ StrFixedLenField("command", "", 12),
+ IntField("data_length", 15),
+ IPField("dip", "127.0.0.1"),
+ ShortField("dport", 0),
+ IPField("sip", "127.0.0.1"),
+ ShortField("sport", 0),
+ ShortEnumField("call", 0, { "bind":2,
+ "connect":3, "listen":4,
+ "accept":5, "sendmsg":16,
+ "recvmsg":17, "sendto":11,
+ "recvfrom":12}),
+ ByteEnumField("proto", 0, IP_PROTOS) ]
+ def mysummary(self):
+ if isinstance(self.underlayer, SebekHead):
+ return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.command%)")
+ else:
+ return self.sprintf("Sebek v3 socket (%SebekV3Sock.command%)")
+
+class SebekV2Sock(SebekV3Sock):
+ def mysummary(self):
+ if isinstance(self.underlayer, SebekHead):
+ return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.command%)")
+ else:
+ return self.sprintf("Sebek v2 socket (%SebekV2Sock.command%)")
+
+class MGCP(Packet):
+ name = "MGCP"
+ longname = "Media Gateway Control Protocol"
+ fields_desc = [ StrStopField("verb","AUEP"," ", -1),
+ StrFixedLenField("sep1"," ",1),
+ StrStopField("transaction_id","1234567"," ", -1),
+ StrFixedLenField("sep2"," ",1),
+ StrStopField("endpoint","dummy@dummy.net"," ", -1),
+ StrFixedLenField("sep3"," ",1),
+ StrStopField("version","MGCP 1.0 NCS 1.0","\x0a", -1),
+ StrFixedLenField("sep4","\x0a",1),
+ ]
+
+
+#class MGCP(Packet):
+# name = "MGCP"
+# longname = "Media Gateway Control Protocol"
+# fields_desc = [ ByteEnumField("type",0, ["request","response","others"]),
+# ByteField("code0",0),
+# ByteField("code1",0),
+# ByteField("code2",0),
+# ByteField("code3",0),
+# ByteField("code4",0),
+# IntField("trasid",0),
+# IntField("req_time",0),
+# ByteField("is_duplicate",0),
+# ByteField("req_available",0) ]
+#
+class GPRS(Packet):
+ name = "GPRSdummy"
+ fields_desc = [
+ StrStopField("dummy","","\x65\x00\x00",1)
+ ]
+
+
+class HCI_Hdr(Packet):
+ name = "HCI header"
+ fields_desc = [ ByteEnumField("type",2,{1:"command",2:"ACLdata",3:"SCOdata",4:"event",5:"vendor"}),]
+
+ def mysummary(self):
+ return self.sprintf("HCI %type%")
+
+class HCI_ACL_Hdr(Packet):
+ name = "HCI ACL header"
+ fields_desc = [ ByteField("handle",0), # Actually, handle is 12 bits and flags is 4.
+ ByteField("flags",0), # I wait to write a LEBitField
+ LEShortField("len",None), ]
+ def post_build(self, p, pay):
+ p += pay
+ if self.len is None:
+ l = len(p)-4
+ p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
+ return p
+
+
+class L2CAP_Hdr(Packet):
+ name = "L2CAP header"
+ fields_desc = [ LEShortField("len",None),
+ LEShortEnumField("cid",0,{1:"control"}),]
+
+ def post_build(self, p, pay):
+ p += pay
+ if self.len is None:
+ l = len(p)-4
+ p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
+ return p
+
+
+
+class L2CAP_CmdHdr(Packet):
+ name = "L2CAP command header"
+ fields_desc = [
+ ByteEnumField("code",8,{1:"rej",2:"conn_req",3:"conn_resp",
+ 4:"conf_req",5:"conf_resp",6:"disconn_req",
+ 7:"disconn_resp",8:"echo_req",9:"echo_resp",
+ 10:"info_req",11:"info_resp"}),
+ ByteField("id",0),
+ LEShortField("len",None) ]
+ def post_build(self, p, pay):
+ p += pay
+ if self.len is None:
+ l = len(p)-4
+ p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
+ return p
+ def answers(self, other):
+ if other.id == self.id:
+ if self.code == 1:
+ return 1
+ if other.code in [2,4,6,8,10] and self.code == other.code+1:
+ if other.code == 8:
+ return 1
+ return self.payload.answers(other.payload)
+ return 0
+
+class L2CAP_ConnReq(Packet):
+ name = "L2CAP Conn Req"
+ fields_desc = [ LEShortEnumField("psm",0,{1:"SDP",3:"RFCOMM",5:"telephony control"}),
+ LEShortField("scid",0),
+ ]
+
+class L2CAP_ConnResp(Packet):
+ name = "L2CAP Conn Resp"
+ fields_desc = [ LEShortField("dcid",0),
+ LEShortField("scid",0),
+ LEShortEnumField("result",0,["no_info","authen_pend","author_pend"]),
+ LEShortEnumField("status",0,["success","pend","bad_psm",
+ "cr_sec_block","cr_no_mem"]),
+ ]
+ def answers(self, other):
+ return self.scid == other.scid
+
+class L2CAP_CmdRej(Packet):
+ name = "L2CAP Command Rej"
+ fields_desc = [ LEShortField("reason",0),
+ ]
+
+
+class L2CAP_ConfReq(Packet):
+ name = "L2CAP Conf Req"
+ fields_desc = [ LEShortField("dcid",0),
+ LEShortField("flags",0),
+ ]
+
+class L2CAP_ConfResp(Packet):
+ name = "L2CAP Conf Resp"
+ fields_desc = [ LEShortField("scid",0),
+ LEShortField("flags",0),
+ LEShortEnumField("result",0,["success","unaccept","reject","unknown"]),
+ ]
+ def answers(self, other):
+ return self.scid == other.scid
+
+
+class L2CAP_DisconnReq(Packet):
+ name = "L2CAP Disconn Req"
+ fields_desc = [ LEShortField("dcid",0),
+ LEShortField("scid",0), ]
+
+class L2CAP_DisconnResp(Packet):
+ name = "L2CAP Disconn Resp"
+ fields_desc = [ LEShortField("dcid",0),
+ LEShortField("scid",0), ]
+ def answers(self, other):
+ return self.scid == other.scid
+
+
+
+class L2CAP_InfoReq(Packet):
+ name = "L2CAP Info Req"
+ fields_desc = [ LEShortEnumField("type",0,{1:"CL_MTU",2:"FEAT_MASK"}),
+ StrField("data","")
+ ]
+
+
+class L2CAP_InfoResp(Packet):
+ name = "L2CAP Info Resp"
+ fields_desc = [ LEShortField("type",0),
+ LEShortEnumField("result",0,["success","not_supp"]),
+ StrField("data",""), ]
+ def answers(self, other):
+ return self.type == other.type
+
+
+
+
+class NetBIOS_DS(Packet):
+ name = "NetBIOS datagram service"
+ fields_desc = [
+ ByteEnumField("type",17, {17:"direct_group"}),
+ ByteField("flags",0),
+ XShortField("id",0),
+ IPField("src","127.0.0.1"),
+ ShortField("sport",138),
+ ShortField("len",None),
+ ShortField("ofs",0),
+ NetBIOSNameField("srcname",""),
+ NetBIOSNameField("dstname",""),
+ ]
+ def post_build(self, p, pay):
+ p += pay
+ if self.len is None:
+ l = len(p)-14
+ p = p[:10]+struct.pack("!H", l)+p[12:]
+ return p
+
+# ShortField("length",0),
+# ShortField("Delimitor",0),
+# ByteField("command",0),
+# ByteField("data1",0),
+# ShortField("data2",0),
+# ShortField("XMIt",0),
+# ShortField("RSPCor",0),
+# StrFixedLenField("dest","",16),
+# StrFixedLenField("source","",16),
+#
+# ]
+#
+
+# IR
+
+class IrLAPHead(Packet):
+ name = "IrDA Link Access Protocol Header"
+ fields_desc = [ XBitField("Address", 0x7f, 7),
+ BitEnumField("Type", 1, 1, {"Response":0,
+ "Command":1})]
+
+class IrLAPCommand(Packet):
+ name = "IrDA Link Access Protocol Command"
+ fields_desc = [ XByteField("Control", 0),
+ XByteField("Format identifier", 0),
+ XIntField("Source address", 0),
+ XIntField("Destination address", 0xffffffffL),
+ XByteField("Discovery flags", 0x1),
+ ByteEnumField("Slot number", 255, {"final":255}),
+ XByteField("Version", 0)]
+
+
+class IrLMP(Packet):
+ name = "IrDA Link Management Protocol"
+ fields_desc = [ XShortField("Service hints", 0),
+ XByteField("Character set", 0),
+ StrField("Device name", "") ]
+
+
+#NetBIOS
+
+
+# Name Query Request
+# Node Status Request
+class NBNSQueryRequest(Packet):
+ name="NBNS query request"
+ fields_desc = [ShortField("NAME_TRN_ID",0),
+ ShortField("FLAGS", 0x0110),
+ ShortField("QDCOUNT",1),
+ ShortField("ANCOUNT",0),
+ ShortField("NSCOUNT",0),
+ ShortField("ARCOUNT",0),
+ NetBIOSNameField("QUESTION_NAME","windows"),
+ ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
+ ByteField("NULL",0),
+ ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+ ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"})]
+
+# Name Registration Request
+# Name Refresh Request
+# Name Release Request or Demand
+class NBNSRequest(Packet):
+ name="NBNS request"
+ fields_desc = [ShortField("NAME_TRN_ID",0),
+ ShortField("FLAGS", 0x2910),
+ ShortField("QDCOUNT",1),
+ ShortField("ANCOUNT",0),
+ ShortField("NSCOUNT",0),
+ ShortField("ARCOUNT",1),
+ NetBIOSNameField("QUESTION_NAME","windows"),
+ ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
+ ByteField("NULL",0),
+ ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+ ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
+ ShortEnumField("RR_NAME",0xC00C,{0xC00C:"Label String Pointer to QUESTION_NAME"}),
+ ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+ ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
+ IntField("TTL", 0),
+ ShortField("RDLENGTH", 6),
+ BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
+ BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
+ BitEnumField("UNUSED",0,13,{0:"Unused"}),
+ IPField("NB_ADDRESS", "127.0.0.1")]
+
+# Name Query Response
+# Name Registration Response
+class NBNSQueryResponse(Packet):
+ name="NBNS query response"
+ fields_desc = [ShortField("NAME_TRN_ID",0),
+ ShortField("FLAGS", 0x8500),
+ ShortField("QDCOUNT",0),
+ ShortField("ANCOUNT",1),
+ ShortField("NSCOUNT",0),
+ ShortField("ARCOUNT",0),
+ NetBIOSNameField("RR_NAME","windows"),
+ ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
+ ByteField("NULL",0),
+ ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+ ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
+ IntField("TTL", 0x493e0),
+ ShortField("RDLENGTH", 6),
+ ShortField("NB_FLAGS", 0),
+ IPField("NB_ADDRESS", "127.0.0.1")]
+
+# Name Query Response (negative)
+# Name Release Response
+class NBNSQueryResponseNegative(Packet):
+ name="NBNS query response (negative)"
+ fields_desc = [ShortField("NAME_TRN_ID",0),
+ ShortField("FLAGS", 0x8506),
+ ShortField("QDCOUNT",0),
+ ShortField("ANCOUNT",1),
+ ShortField("NSCOUNT",0),
+ ShortField("ARCOUNT",0),
+ NetBIOSNameField("RR_NAME","windows"),
+ ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
+ ByteField("NULL",0),
+ ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+ ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
+ IntField("TTL",0),
+ ShortField("RDLENGTH",6),
+ BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
+ BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
+ BitEnumField("UNUSED",0,13,{0:"Unused"}),
+ IPField("NB_ADDRESS", "127.0.0.1")]
+
+# Node Status Response
+class NBNSNodeStatusResponse(Packet):
+ name="NBNS Node Status Response"
+ fields_desc = [ShortField("NAME_TRN_ID",0),
+ ShortField("FLAGS", 0x8500),
+ ShortField("QDCOUNT",0),
+ ShortField("ANCOUNT",1),
+ ShortField("NSCOUNT",0),
+ ShortField("ARCOUNT",0),
+ NetBIOSNameField("RR_NAME","windows"),
+ ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
+ ByteField("NULL",0),
+ ShortEnumField("RR_TYPE",0x21, {0x20:"NB",0x21:"NBSTAT"}),
+ ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
+ IntField("TTL",0),
+ ShortField("RDLENGTH",83),
+ ByteField("NUM_NAMES",1)]
+
+# Service for Node Status Response
+class NBNSNodeStatusResponseService(Packet):
+ name="NBNS Node Status Response Service"
+ fields_desc = [StrFixedLenField("NETBIOS_NAME","WINDOWS ",15),
+ ByteEnumField("SUFFIX",0,{0:"workstation",0x03:"messenger service",0x20:"file server service",0x1b:"domain master browser",0x1c:"domain controller", 0x1e:"browser election service"}),
+ ByteField("NAME_FLAGS",0x4),
+ ByteEnumField("UNUSED",0,{0:"unused"})]
+
+# End of Node Status Response packet
+class NBNSNodeStatusResponseEnd(Packet):
+ name="NBNS Node Status Response"
+ fields_desc = [SourceMACField("MAC_ADDRESS"),
+ BitField("STATISTICS",0,57*8)]
+
+# Wait for Acknowledgement Response
+class NBNSWackResponse(Packet):
+ name="NBNS Wait for Acknowledgement Response"
+ fields_desc = [ShortField("NAME_TRN_ID",0),
+ ShortField("FLAGS", 0xBC07),
+ ShortField("QDCOUNT",0),
+ ShortField("ANCOUNT",1),
+ ShortField("NSCOUNT",0),
+ ShortField("ARCOUNT",0),
+ NetBIOSNameField("RR_NAME","windows"),
+ ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
+ ByteField("NULL",0),
+ ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
+ ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
+ IntField("TTL", 2),
+ ShortField("RDLENGTH",2),
+ BitField("RDATA",10512,16)] #10512=0010100100010000
+
+class NBTDatagram(Packet):
+ name="NBT Datagram Packet"
+ fields_desc= [ByteField("Type", 0x10),
+ ByteField("Flags", 0x02),
+ ShortField("ID", 0),
+ IPField("SourceIP", "127.0.0.1"),
+ ShortField("SourcePort", 138),
+ ShortField("Length", 272),
+ ShortField("Offset", 0),
+ NetBIOSNameField("SourceName","windows"),
+ ShortEnumField("SUFFIX1",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
+ ByteField("NULL",0),
+ NetBIOSNameField("DestinationName","windows"),
+ ShortEnumField("SUFFIX2",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
+ ByteField("NULL",0)]
+
+
+class NBTSession(Packet):
+ name="NBT Session Packet"
+ fields_desc= [ByteEnumField("TYPE",0,{0x00:"Session Message",0x81:"Session Request",0x82:"Positive Session Response",0x83:"Negative Session Response",0x84:"Retarget Session Response",0x85:"Session Keepalive"}),
+ BitField("RESERVED",0x00,7),
+ BitField("LENGTH",0,17)]
+
+
+# SMB NetLogon Response Header
+class SMBNetlogon_Protocol_Response_Header(Packet):
+ name="SMBNetlogon Protocol Response Header"
+ fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+ ByteEnumField("Command",0x25,{0x25:"Trans"}),
+ ByteField("Error_Class",0x02),
+ ByteField("Reserved",0),
+ LEShortField("Error_code",4),
+ ByteField("Flags",0),
+ LEShortField("Flags2",0x0000),
+ LEShortField("PIDHigh",0x0000),
+ LELongField("Signature",0x0),
+ LEShortField("Unused",0x0),
+ LEShortField("TID",0),
+ LEShortField("PID",0),
+ LEShortField("UID",0),
+ LEShortField("MID",0),
+ ByteField("WordCount",17),
+ LEShortField("TotalParamCount",0),
+ LEShortField("TotalDataCount",112),
+ LEShortField("MaxParamCount",0),
+ LEShortField("MaxDataCount",0),
+ ByteField("MaxSetupCount",0),
+ ByteField("unused2",0),
+ LEShortField("Flags3",0),
+ ByteField("TimeOut1",0xe8),
+ ByteField("TimeOut2",0x03),
+ LEShortField("unused3",0),
+ LEShortField("unused4",0),
+ LEShortField("ParamCount2",0),
+ LEShortField("ParamOffset",0),
+ LEShortField("DataCount",112),
+ LEShortField("DataOffset",92),
+ ByteField("SetupCount", 3),
+ ByteField("unused5", 0)]
+
+# SMB MailSlot Protocol
+class SMBMailSlot(Packet):
+ name = "SMB Mail Slot Protocol"
+ fields_desc = [LEShortField("opcode", 1),
+ LEShortField("priority", 1),
+ LEShortField("class", 2),
+ LEShortField("size", 135),
+ StrNullField("name","\MAILSLOT\NET\GETDC660")]
+
+# SMB NetLogon Protocol Response Tail SAM
+class SMBNetlogon_Protocol_Response_Tail_SAM(Packet):
+ name = "SMB Netlogon Protocol Response Tail SAM"
+ fields_desc = [ByteEnumField("Command", 0x17, {0x12:"SAM logon request", 0x17:"SAM Active directory Response"}),
+ ByteField("unused", 0),
+ ShortField("Data1", 0),
+ ShortField("Data2", 0xfd01),
+ ShortField("Data3", 0),
+ ShortField("Data4", 0xacde),
+ ShortField("Data5", 0x0fe5),
+ ShortField("Data6", 0xd10a),
+ ShortField("Data7", 0x374c),
+ ShortField("Data8", 0x83e2),
+ ShortField("Data9", 0x7dd9),
+ ShortField("Data10", 0x3a16),
+ ShortField("Data11", 0x73ff),
+ ByteField("Data12", 0x04),
+ StrFixedLenField("Data13", "rmff", 4),
+ ByteField("Data14", 0x0),
+ ShortField("Data16", 0xc018),
+ ByteField("Data18", 0x0a),
+ StrFixedLenField("Data20", "rmff-win2k", 10),
+ ByteField("Data21", 0xc0),
+ ShortField("Data22", 0x18c0),
+ ShortField("Data23", 0x180a),
+ StrFixedLenField("Data24", "RMFF-WIN2K", 10),
+ ShortField("Data25", 0),
+ ByteField("Data26", 0x17),
+ StrFixedLenField("Data27", "Default-First-Site-Name", 23),
+ ShortField("Data28", 0x00c0),
+ ShortField("Data29", 0x3c10),
+ ShortField("Data30", 0x00c0),
+ ShortField("Data31", 0x0200),
+ ShortField("Data32", 0x0),
+ ShortField("Data33", 0xac14),
+ ShortField("Data34", 0x0064),
+ ShortField("Data35", 0x0),
+ ShortField("Data36", 0x0),
+ ShortField("Data37", 0x0),
+ ShortField("Data38", 0x0),
+ ShortField("Data39", 0x0d00),
+ ShortField("Data40", 0x0),
+ ShortField("Data41", 0xffff)]
+
+# SMB NetLogon Protocol Response Tail LM2.0
+class SMBNetlogon_Protocol_Response_Tail_LM20(Packet):
+ name = "SMB Netlogon Protocol Response Tail LM20"
+ fields_desc = [ByteEnumField("Command",0x06,{0x06:"LM 2.0 Response to logon request"}),
+ ByteField("unused", 0),
+ StrFixedLenField("DblSlash", "\\\\", 2),
+ StrNullField("ServerName","WIN"),
+ LEShortField("LM20Token", 0xffff)]
+
+# SMBNegociate Protocol Request Header
+class SMBNegociate_Protocol_Request_Header(Packet):
+ name="SMBNegociate Protocol Request Header"
+ fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+ ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
+ ByteField("Error_Class",0),
+ ByteField("Reserved",0),
+ LEShortField("Error_code",0),
+ ByteField("Flags",0x18),
+ LEShortField("Flags2",0x0000),
+ LEShortField("PIDHigh",0x0000),
+ LELongField("Signature",0x0),
+ LEShortField("Unused",0x0),
+ LEShortField("TID",0),
+ LEShortField("PID",1),
+ LEShortField("UID",0),
+ LEShortField("MID",2),
+ ByteField("WordCount",0),
+ LEShortField("ByteCount",12)]
+
+# SMB Negociate Protocol Request Tail
+class SMBNegociate_Protocol_Request_Tail(Packet):
+ name="SMB Negociate Protocol Request Tail"
+ fields_desc=[ByteField("BufferFormat",0x02),
+ StrNullField("BufferData","NT LM 0.12")]
+
+# SMBNegociate Protocol Response Advanced Security
+class SMBNegociate_Protocol_Response_Advanced_Security(Packet):
+ name="SMBNegociate Protocol Response Advanced Security"
+ fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+ ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
+ ByteField("Error_Class",0),
+ ByteField("Reserved",0),
+ LEShortField("Error_Code",0),
+ ByteField("Flags",0x98),
+ LEShortField("Flags2",0x0000),
+ LEShortField("PIDHigh",0x0000),
+ LELongField("Signature",0x0),
+ LEShortField("Unused",0x0),
+ LEShortField("TID",0),
+ LEShortField("PID",1),
+ LEShortField("UID",0),
+ LEShortField("MID",2),
+ ByteField("WordCount",17),
+ LEShortField("DialectIndex",7),
+ ByteField("SecurityMode",0x03),
+ LEShortField("MaxMpxCount",50),
+ LEShortField("MaxNumberVC",1),
+ LEIntField("MaxBufferSize",16144),
+ LEIntField("MaxRawSize",65536),
+ LEIntField("SessionKey",0x0000),
+ LEShortField("ServerCapabilities",0xf3f9),
+ BitField("UnixExtensions",0,1),
+ BitField("Reserved2",0,7),
+ BitField("ExtendedSecurity",1,1),
+ BitField("CompBulk",0,2),
+ BitField("Reserved3",0,5),
+# There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
+ LEIntField("ServerTimeHigh",0xD6228000L),
+ LEIntField("ServerTimeLow",0x1C4EF94),
+ LEShortField("ServerTimeZone",0x3c),
+ ByteField("EncryptionKeyLength",0),
+ LEFieldLenField("ByteCount", None, "SecurityBlob", adjust=lambda pkt,x:x-16),
+ BitField("GUID",0,128),
+ StrLenField("SecurityBlob", "", length_from=lambda x:x.ByteCount+16)]
+
+# SMBNegociate Protocol Response No Security
+# When using no security, with EncryptionKeyLength=8, you must have an EncryptionKey before the DomainName
+class SMBNegociate_Protocol_Response_No_Security(Packet):
+ name="SMBNegociate Protocol Response No Security"
+ fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+ ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
+ ByteField("Error_Class",0),
+ ByteField("Reserved",0),
+ LEShortField("Error_Code",0),
+ ByteField("Flags",0x98),
+ LEShortField("Flags2",0x0000),
+ LEShortField("PIDHigh",0x0000),
+ LELongField("Signature",0x0),
+ LEShortField("Unused",0x0),
+ LEShortField("TID",0),
+ LEShortField("PID",1),
+ LEShortField("UID",0),
+ LEShortField("MID",2),
+ ByteField("WordCount",17),
+ LEShortField("DialectIndex",7),
+ ByteField("SecurityMode",0x03),
+ LEShortField("MaxMpxCount",50),
+ LEShortField("MaxNumberVC",1),
+ LEIntField("MaxBufferSize",16144),
+ LEIntField("MaxRawSize",65536),
+ LEIntField("SessionKey",0x0000),
+ LEShortField("ServerCapabilities",0xf3f9),
+ BitField("UnixExtensions",0,1),
+ BitField("Reserved2",0,7),
+ BitField("ExtendedSecurity",0,1),
+ FlagsField("CompBulk",0,2,"CB"),
+ BitField("Reserved3",0,5),
+ # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
+ LEIntField("ServerTimeHigh",0xD6228000L),
+ LEIntField("ServerTimeLow",0x1C4EF94),
+ LEShortField("ServerTimeZone",0x3c),
+ ByteField("EncryptionKeyLength",8),
+ LEShortField("ByteCount",24),
+ BitField("EncryptionKey",0,64),
+ StrNullField("DomainName","WORKGROUP"),
+ StrNullField("ServerName","RMFF1")]
+
+# SMBNegociate Protocol Response No Security No Key
+class SMBNegociate_Protocol_Response_No_Security_No_Key(Packet):
+ namez="SMBNegociate Protocol Response No Security No Key"
+ fields_desc = [StrFixedLenField("Start","\xffSMB",4),
+ ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
+ ByteField("Error_Class",0),
+ ByteField("Reserved",0),
+ LEShortField("Error_Code",0),
+ ByteField("Flags",0x98),
+ LEShortField("Flags2",0x0000),
+ LEShortField("PIDHigh",0x0000),
+ LELongField("Signature",0x0),
+ LEShortField("Unused",0x0),
+ LEShortField("TID",0),
+ LEShortField("PID",1),
+ LEShortField("UID",0),
+ LEShortField("MID",2),
+ ByteField("WordCount",17),
+ LEShortField("DialectIndex",7),
+ ByteField("SecurityMode",0x03),
+ LEShortField("MaxMpxCount",50),
+ LEShortField("MaxNumberVC",1),
+ LEIntField("MaxBufferSize",16144),
+ LEIntField("MaxRawSize",65536),
+ LEIntField("SessionKey",0x0000),
+ LEShortField("ServerCapabilities",0xf3f9),
+ BitField("UnixExtensions",0,1),
+ BitField("Reserved2",0,7),
+ BitField("ExtendedSecurity",0,1),
+ FlagsField("CompBulk",0,2,"CB"),
+ BitField("Reserved3",0,5),
+ # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
+ LEIntField("ServerTimeHigh",0xD6228000L),
+ LEIntField("ServerTimeLow",0x1C4EF94),
+ LEShortField("ServerTimeZone",0x3c),
+ ByteField("EncryptionKeyLength",0),
+ LEShortField("ByteCount",16),
+ StrNullField("DomainName","WORKGROUP"),
+ StrNullField("ServerName","RMFF1")]
+
+# Session Setup AndX Request
+class SMBSession_Setup_AndX_Request(Packet):
+ name="Session Setup AndX Request"
+ fields_desc=[StrFixedLenField("Start","\xffSMB",4),
+ ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
+ ByteField("Error_Class",0),
+ ByteField("Reserved",0),
+ LEShortField("Error_Code",0),
+ ByteField("Flags",0x18),
+ LEShortField("Flags2",0x0001),
+ LEShortField("PIDHigh",0x0000),
+ LELongField("Signature",0x0),
+ LEShortField("Unused",0x0),
+ LEShortField("TID",0),
+ LEShortField("PID",1),
+ LEShortField("UID",0),
+ LEShortField("MID",2),
+ ByteField("WordCount",13),
+ ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
+ ByteField("Reserved2",0),
+ LEShortField("AndXOffset",96),
+ LEShortField("MaxBufferS",2920),
+ LEShortField("MaxMPXCount",50),
+ LEShortField("VCNumber",0),
+ LEIntField("SessionKey",0),
+ LEFieldLenField("ANSIPasswordLength",None,"ANSIPassword"),
+ LEShortField("UnicodePasswordLength",0),
+ LEIntField("Reserved3",0),
+ LEShortField("ServerCapabilities",0x05),
+ BitField("UnixExtensions",0,1),
+ BitField("Reserved4",0,7),
+ BitField("ExtendedSecurity",0,1),
+ BitField("CompBulk",0,2),
+ BitField("Reserved5",0,5),
+ LEShortField("ByteCount",35),
+ StrLenField("ANSIPassword", "Pass",length_from=lambda x:x.ANSIPasswordLength),
+ StrNullField("Account","GUEST"),
+ StrNullField("PrimaryDomain", ""),
+ StrNullField("NativeOS","Windows 4.0"),
+ StrNullField("NativeLanManager","Windows 4.0"),
+ ByteField("WordCount2",4),
+ ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
+ ByteField("Reserved6",0),
+ LEShortField("AndXOffset2",0),
+ LEShortField("Flags3",0x2),
+ LEShortField("PasswordLength",0x1),
+ LEShortField("ByteCount2",18),
+ ByteField("Password",0),
+ StrNullField("Path","\\\\WIN2K\\IPC$"),
+ StrNullField("Service","IPC")]
+
+# Session Setup AndX Response
+class SMBSession_Setup_AndX_Response(Packet):
+ name="Session Setup AndX Response"
+ fields_desc=[StrFixedLenField("Start","\xffSMB",4),
+ ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
+ ByteField("Error_Class",0),
+ ByteField("Reserved",0),
+ LEShortField("Error_Code",0),
+ ByteField("Flags",0x90),
+ LEShortField("Flags2",0x1001),
+ LEShortField("PIDHigh",0x0000),
+ LELongField("Signature",0x0),
+ LEShortField("Unused",0x0),
+ LEShortField("TID",0),
+ LEShortField("PID",1),
+ LEShortField("UID",0),
+ LEShortField("MID",2),
+ ByteField("WordCount",3),
+ ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
+ ByteField("Reserved2",0),
+ LEShortField("AndXOffset",66),
+ LEShortField("Action",0),
+ LEShortField("ByteCount",25),
+ StrNullField("NativeOS","Windows 4.0"),
+ StrNullField("NativeLanManager","Windows 4.0"),
+ StrNullField("PrimaryDomain",""),
+ ByteField("WordCount2",3),
+ ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
+ ByteField("Reserved3",0),
+ LEShortField("AndXOffset2",80),
+ LEShortField("OptionalSupport",0x01),
+ LEShortField("ByteCount2",5),
+ StrNullField("Service","IPC"),
+ StrNullField("NativeFileSystem","")]
+
+class MobileIP(Packet):
+ name = "Mobile IP (RFC3344)"
+ fields_desc = [ ByteEnumField("type", 1, {1:"RRQ", 3:"RRP"}) ]
+
+class MobileIPRRQ(Packet):
+ name = "Mobile IP Registration Request (RFC3344)"
+ fields_desc = [ XByteField("flags", 0),
+ ShortField("lifetime", 180),
+ IPField("homeaddr", "0.0.0.0"),
+ IPField("haaddr", "0.0.0.0"),
+ IPField("coaddr", "0.0.0.0"),
+ Field("id", "", "64s") ]
+
+class MobileIPRRP(Packet):
+ name = "Mobile IP Registration Reply (RFC3344)"
+ fields_desc = [ ByteField("code", 0),
+ ShortField("lifetime", 180),
+ IPField("homeaddr", "0.0.0.0"),
+ IPField("haaddr", "0.0.0.0"),
+ Field("id", "", "64s") ]
+
+class MobileIPTunnelData(Packet):
+ name = "Mobile IP Tunnel Data Message (RFC3519)"
+ fields_desc = [ ByteField("nexthdr", 4),
+ ShortField("res", 0) ]
+
+
+# Cisco Netflow Protocol version 1
+class NetflowHeader(Packet):
+ name = "Netflow Header"
+ fields_desc = [ ShortField("version", 1) ]
+
+class NetflowHeaderV1(Packet):
+ name = "Netflow Header V1"
+ fields_desc = [ ShortField("count", 0),
+ IntField("sysUptime", 0),
+ IntField("unixSecs", 0),
+ IntField("unixNanoSeconds", 0) ]
+
+
+class NetflowRecordV1(Packet):
+ name = "Netflow Record"
+ fields_desc = [ IPField("ipsrc", "0.0.0.0"),
+ IPField("ipdst", "0.0.0.0"),
+ IPField("nexthop", "0.0.0.0"),
+ ShortField("inputIfIndex", 0),
+ ShortField("outpuIfIndex", 0),
+ IntField("dpkts", 0),
+ IntField("dbytes", 0),
+ IntField("starttime", 0),
+ IntField("endtime", 0),
+ ShortField("srcport", 0),
+ ShortField("dstport", 0),
+ ShortField("padding", 0),
+ ByteField("proto", 0),
+ ByteField("tos", 0),
+ IntField("padding1", 0),
+ IntField("padding2", 0) ]
+
+
+TFTP_operations = { 1:"RRQ",2:"WRQ",3:"DATA",4:"ACK",5:"ERROR",6:"OACK" }
+
+
+class TFTP(Packet):
+ name = "TFTP opcode"
+ fields_desc = [ ShortEnumField("op", 1, TFTP_operations), ]
+
+
+
+class TFTP_RRQ(Packet):
+ name = "TFTP Read Request"
+ fields_desc = [ StrNullField("filename", ""),
+ StrNullField("mode", "octet") ]
+ def answers(self, other):
+ return 0
+ def mysummary(self):
+ return self.sprintf("RRQ %filename%"),[UDP]
+
+
+class TFTP_WRQ(Packet):
+ name = "TFTP Write Request"
+ fields_desc = [ StrNullField("filename", ""),
+ StrNullField("mode", "octet") ]
+ def answers(self, other):
+ return 0
+ def mysummary(self):
+ return self.sprintf("WRQ %filename%"),[UDP]
+
+class TFTP_DATA(Packet):
+ name = "TFTP Data"
+ fields_desc = [ ShortField("block", 0) ]
+ def answers(self, other):
+ return self.block == 1 and isinstance(other, TFTP_RRQ)
+ def mysummary(self):
+ return self.sprintf("DATA %block%"),[UDP]
+
+class TFTP_Option(Packet):
+ fields_desc = [ StrNullField("oname",""),
+ StrNullField("value","") ]
+ def extract_padding(self, pkt):
+ return "",pkt
+
+class TFTP_Options(Packet):
+ fields_desc = [ PacketListField("options", [], TFTP_Option, length_from=lambda x:None) ]
+
+
+class TFTP_ACK(Packet):
+ name = "TFTP Ack"
+ fields_desc = [ ShortField("block", 0) ]
+ def answers(self, other):
+ if isinstance(other, TFTP_DATA):
+ return self.block == other.block
+ elif isinstance(other, TFTP_RRQ) or isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_OACK):
+ return self.block == 0
+ return 0
+ def mysummary(self):
+ return self.sprintf("ACK %block%"),[UDP]
+
+TFTP_Error_Codes = { 0: "Not defined",
+ 1: "File not found",
+ 2: "Access violation",
+ 3: "Disk full or allocation exceeded",
+ 4: "Illegal TFTP operation",
+ 5: "Unknown transfer ID",
+ 6: "File already exists",
+ 7: "No such user",
+ 8: "Terminate transfer due to option negotiation",
+ }
+
+class TFTP_ERROR(Packet):
+ name = "TFTP Error"
+ fields_desc = [ ShortEnumField("errorcode", 0, TFTP_Error_Codes),
+ StrNullField("errormsg", "")]
+ def answers(self, other):
+ return (isinstance(other, TFTP_DATA) or
+ isinstance(other, TFTP_RRQ) or
+ isinstance(other, TFTP_WRQ) or
+ isinstance(other, TFTP_ACK))
+ def mysummary(self):
+ return self.sprintf("ERROR %errorcode%: %errormsg%"),[UDP]
+
+
+class TFTP_OACK(Packet):
+ name = "TFTP Option Ack"
+ fields_desc = [ ]
+ def answers(self, other):
+ return isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_RRQ)
+
+
+##########
+## SNMP ##
+##########
+
+######[ ASN1 class ]######
+
+class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL):
+ name="SNMP"
+ PDU_GET = 0xa0
+ PDU_NEXT = 0xa1
+ PDU_RESPONSE = 0xa2
+ PDU_SET = 0xa3
+ PDU_TRAPv1 = 0xa4
+ PDU_BULK = 0xa5
+ PDU_INFORM = 0xa6
+ PDU_TRAPv2 = 0xa7
+
+
+class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_GET
+
+class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_NEXT
+
+class ASN1_SNMP_PDU_RESPONSE(ASN1_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_RESPONSE
+
+class ASN1_SNMP_PDU_SET(ASN1_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_SET
+
+class ASN1_SNMP_PDU_TRAPv1(ASN1_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_TRAPv1
+
+class ASN1_SNMP_PDU_BULK(ASN1_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_BULK
+
+class ASN1_SNMP_PDU_INFORM(ASN1_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_INFORM
+
+class ASN1_SNMP_PDU_TRAPv2(ASN1_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_TRAPv2
+
+
+######[ BER codecs ]#######
+
+class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_GET
+
+class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_NEXT
+
+class BERcodec_SNMP_PDU_RESPONSE(BERcodec_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_RESPONSE
+
+class BERcodec_SNMP_PDU_SET(BERcodec_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_SET
+
+class BERcodec_SNMP_PDU_TRAPv1(BERcodec_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_TRAPv1
+
+class BERcodec_SNMP_PDU_BULK(BERcodec_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_BULK
+
+class BERcodec_SNMP_PDU_INFORM(BERcodec_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_INFORM
+
+class BERcodec_SNMP_PDU_TRAPv2(BERcodec_SEQUENCE):
+ tag = ASN1_Class_SNMP.PDU_TRAPv2
+
+
+
+######[ ASN1 fields ]######
+
+class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE):
+ ASN1_tag = ASN1_Class_SNMP.PDU_GET
+
+class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE):
+ ASN1_tag = ASN1_Class_SNMP.PDU_NEXT
+
+class ASN1F_SNMP_PDU_RESPONSE(ASN1F_SEQUENCE):
+ ASN1_tag = ASN1_Class_SNMP.PDU_RESPONSE
+
+class ASN1F_SNMP_PDU_SET(ASN1F_SEQUENCE):
+ ASN1_tag = ASN1_Class_SNMP.PDU_SET
+
+class ASN1F_SNMP_PDU_TRAPv1(ASN1F_SEQUENCE):
+ ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv1
+
+class ASN1F_SNMP_PDU_BULK(ASN1F_SEQUENCE):
+ ASN1_tag = ASN1_Class_SNMP.PDU_BULK
+
+class ASN1F_SNMP_PDU_INFORM(ASN1F_SEQUENCE):
+ ASN1_tag = ASN1_Class_SNMP.PDU_INFORM
+
+class ASN1F_SNMP_PDU_TRAPv2(ASN1F_SEQUENCE):
+ ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv2
+
+
+
+######[ SNMP Packet ]######
+
+SNMP_error = { 0: "no_error",
+ 1: "too_big",
+ 2: "no_such_name",
+ 3: "bad_value",
+ 4: "read_only",
+ 5: "generic_error",
+ 6: "no_access",
+ 7: "wrong_type",
+ 8: "wrong_length",
+ 9: "wrong_encoding",
+ 10: "wrong_value",
+ 11: "no_creation",
+ 12: "inconsistent_value",
+ 13: "ressource_unavailable",
+ 14: "commit_failed",
+ 15: "undo_failed",
+ 16: "authorization_error",
+ 17: "not_writable",
+ 18: "inconsistent_name",
+ }
+
+SNMP_trap_types = { 0: "cold_start",
+ 1: "warm_start",
+ 2: "link_down",
+ 3: "link_up",
+ 4: "auth_failure",
+ 5: "egp_neigh_loss",
+ 6: "enterprise_specific",
+ }
+
+class SNMPvarbind(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"),
+ ASN1F_field("value",ASN1_NULL(0))
+ )
+
+
+class SNMPget(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0),
+ ASN1F_enum_INTEGER("error",0, SNMP_error),
+ ASN1F_INTEGER("error_index",0),
+ ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+ )
+
+class SNMPnext(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0),
+ ASN1F_enum_INTEGER("error",0, SNMP_error),
+ ASN1F_INTEGER("error_index",0),
+ ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+ )
+
+class SNMPresponse(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SNMP_PDU_RESPONSE( ASN1F_INTEGER("id",0),
+ ASN1F_enum_INTEGER("error",0, SNMP_error),
+ ASN1F_INTEGER("error_index",0),
+ ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+ )
+
+class SNMPset(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SNMP_PDU_SET( ASN1F_INTEGER("id",0),
+ ASN1F_enum_INTEGER("error",0, SNMP_error),
+ ASN1F_INTEGER("error_index",0),
+ ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+ )
+
+class SNMPtrapv1(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_INTEGER("id",0),
+ ASN1F_OID("enterprise", "1.3"),
+ ASN1F_STRING("agent_addr",""),
+ ASN1F_enum_INTEGER("generic_trap", 0, SNMP_trap_types),
+ ASN1F_INTEGER("specific_trap", 0),
+ ASN1F_INTEGER("time_stamp", IntAutoTime()),
+ ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+ )
+
+class SNMPbulk(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SNMP_PDU_BULK( ASN1F_INTEGER("id",0),
+ ASN1F_INTEGER("non_repeaters",0),
+ ASN1F_INTEGER("max_repetitions",0),
+ ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+ )
+
+class SNMPinform(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SNMP_PDU_INFORM( ASN1F_INTEGER("id",0),
+ ASN1F_enum_INTEGER("error",0, SNMP_error),
+ ASN1F_INTEGER("error_index",0),
+ ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+ )
+
+class SNMPtrapv2(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SNMP_PDU_TRAPv2( ASN1F_INTEGER("id",0),
+ ASN1F_enum_INTEGER("error",0, SNMP_error),
+ ASN1F_INTEGER("error_index",0),
+ ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind)
+ )
+
+
+class SNMP(ASN1_Packet):
+ ASN1_codec = ASN1_Codecs.BER
+ ASN1_root = ASN1F_SEQUENCE(
+ ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}),
+ ASN1F_STRING("community","public"),
+ ASN1F_CHOICE("PDU", SNMPget(),
+ SNMPget, SNMPnext, SNMPresponse, SNMPset,
+ SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2)
+ )
+ def answers(self, other):
+ return ( isinstance(self.PDU, SNMPresponse) and
+ ( isinstance(other.PDU, SNMPget) or
+ isinstance(other.PDU, SNMPnext) or
+ isinstance(other.PDU, SNMPset) ) and
+ self.PDU.id == other.PDU.id )
+
+
+
+#################
+## Bind layers ##
+#################
+
+
+def bind_bottom_up(lower, upper, __fval=None, **fval):
+ if __fval is not None:
+ fval.update(__fval)
+ lower.payload_guess = lower.payload_guess[:]
+ lower.payload_guess.append((fval, upper))
+
+
+def bind_top_down(lower, upper, __fval=None, **fval):
+ if __fval is not None:
+ fval.update(__fval)
+ upper.overload_fields = upper.overload_fields.copy()
+ upper.overload_fields[lower] = fval
+
+def bind_layers(lower, upper, __fval=None, **fval):
+ if __fval is not None:
+ fval.update(__fval)
+ bind_top_down(lower, upper, **fval)
+ bind_bottom_up(lower, upper, **fval)
+
+def split_bottom_up(lower, upper, __fval=None, **fval):
+ if __fval is not None:
+ fval.update(__fval)
+ def do_filter((f,u),upper=upper,fval=fval):
+ if u != upper:
+ return True
+ for k in fval:
+ if k not in f or f[k] != fval[k]:
+ return True
+ return False
+ lower.payload_guess = filter(do_filter, lower.payload_guess)
+
+def split_top_down(lower, upper, __fval=None, **fval):
+ if __fval is not None:
+ fval.update(__fval)
+ if lower in upper.overload_fields:
+ ofval = upper.overload_fields[lower]
+ for k in fval:
+ if k not in ofval or ofval[k] != fval[k]:
+ return
+ upper.overload_fields = upper.overload_fields.copy()
+ del(upper.overload_fields[lower])
+
+def split_layers(lower, upper, __fval=None, **fval):
+ if __fval is not None:
+ fval.update(__fval)
+ split_bottom_up(lower, upper, **fval)
+ split_top_down(lower, upper, **fval)
+
+
+bind_layers( Dot3, LLC, )
+bind_layers( GPRS, IP, )
+bind_layers( PrismHeader, Dot11, )
+bind_layers( RadioTap, Dot11, )
+bind_layers( Dot11, LLC, type=2)
+bind_layers( PPP, IP, proto=33)
+bind_layers( Ether, LLC, type=122)
+bind_layers( Ether, Dot1Q, type=33024)
+bind_layers( Ether, Ether, type=1)
+bind_layers( Ether, ARP, type=2054)
+bind_layers( Ether, IP, type=2048)
+bind_layers( Ether, EAPOL, type=34958)
+bind_layers( Ether, EAPOL, dst='01:80:c2:00:00:03', type=34958)
+bind_layers( Ether, PPPoED, type=34915)
+bind_layers( Ether, PPPoE, type=34916)
+bind_layers( CookedLinux, LLC, proto=122)
+bind_layers( CookedLinux, Dot1Q, proto=33024)
+bind_layers( CookedLinux, Ether, proto=1)
+bind_layers( CookedLinux, ARP, proto=2054)
+bind_layers( CookedLinux, IP, proto=2048)
+bind_layers( CookedLinux, EAPOL, proto=34958)
+bind_layers( CookedLinux, PPPoED, proto=34915)
+bind_layers( CookedLinux, PPPoE, proto=34916)
+bind_layers( GRE, LLC, proto=122)
+bind_layers( GRE, Dot1Q, proto=33024)
+bind_layers( GRE, Ether, proto=1)
+bind_layers( GRE, ARP, proto=2054)
+bind_layers( GRE, IP, proto=2048)
+bind_layers( GRE, EAPOL, proto=34958)
+bind_layers( PPPoE, PPP, code=0)
+bind_layers( EAPOL, EAP, type=0)
+bind_layers( LLC, STP, dsap=66, ssap=66, ctrl=3)
+bind_layers( LLC, SNAP, dsap=170, ssap=170, ctrl=3)
+bind_layers( SNAP, Dot1Q, code=33024)
+bind_layers( SNAP, Ether, code=1)
+bind_layers( SNAP, ARP, code=2054)
+bind_layers( SNAP, IP, code=2048)
+bind_layers( SNAP, EAPOL, code=34958)
+bind_layers( SNAP, STP, code=267)
+bind_layers( IPerror, IPerror, frag=0, proto=4)
+bind_layers( IPerror, ICMPerror, frag=0, proto=1)
+bind_layers( IPerror, TCPerror, frag=0, proto=6)
+bind_layers( IPerror, UDPerror, frag=0, proto=17)
+bind_layers( IP, IP, frag=0, proto=4)
+bind_layers( IP, ICMP, frag=0, proto=1)
+bind_layers( IP, TCP, frag=0, proto=6)
+bind_layers( IP, UDP, frag=0, proto=17)
+bind_layers( IP, GRE, frag=0, proto=47)
+bind_layers( UDP, SNMP, sport=161)
+bind_layers( UDP, SNMP, dport=161)
+bind_layers( UDP, MGCP, dport=2727)
+bind_layers( UDP, MGCP, sport=2727)
+bind_layers( UDP, DNS, dport=53)
+bind_layers( UDP, DNS, sport=53)
+bind_layers( UDP, ISAKMP, dport=500, sport=500)
+bind_layers( UDP, HSRP, dport=1985, sport=1985)
+bind_layers( UDP, NTP, dport=123, sport=123)
+bind_layers( UDP, BOOTP, dport=67, sport=68)
+bind_layers( UDP, BOOTP, dport=68, sport=67)
+bind_layers( BOOTP, DHCP, options='c\x82Sc')
+bind_layers( UDP, RIP, sport=520)
+bind_layers( UDP, RIP, dport=520)
+bind_layers( RIP, RIPEntry, )
+bind_layers( RIPEntry, RIPEntry, )
+bind_layers( Dot11, Dot11AssoReq, subtype=0, type=0)
+bind_layers( Dot11, Dot11AssoResp, subtype=1, type=0)
+bind_layers( Dot11, Dot11ReassoReq, subtype=2, type=0)
+bind_layers( Dot11, Dot11ReassoResp, subtype=3, type=0)
+bind_layers( Dot11, Dot11ProbeReq, subtype=4, type=0)
+bind_layers( Dot11, Dot11ProbeResp, subtype=5, type=0)
+bind_layers( Dot11, Dot11Beacon, subtype=8, type=0)
+bind_layers( Dot11, Dot11ATIM, subtype=9, type=0)
+bind_layers( Dot11, Dot11Disas, subtype=10, type=0)
+bind_layers( Dot11, Dot11Auth, subtype=11, type=0)
+bind_layers( Dot11, Dot11Deauth, subtype=12, type=0)
+bind_layers( Dot11Beacon, Dot11Elt, )
+bind_layers( Dot11AssoReq, Dot11Elt, )
+bind_layers( Dot11AssoResp, Dot11Elt, )
+bind_layers( Dot11ReassoReq, Dot11Elt, )
+bind_layers( Dot11ReassoResp, Dot11Elt, )
+bind_layers( Dot11ProbeReq, Dot11Elt, )
+bind_layers( Dot11ProbeResp, Dot11Elt, )
+bind_layers( Dot11Auth, Dot11Elt, )
+bind_layers( Dot11Elt, Dot11Elt, )
+bind_layers( TCP, Skinny, dport=2000)
+bind_layers( TCP, Skinny, sport=2000)
+bind_layers( UDP, SebekHead, sport=1101)
+bind_layers( UDP, SebekHead, dport=1101)
+bind_layers( UDP, SebekHead, dport=1101, sport=1101)
+bind_layers( SebekHead, SebekV1, version=1)
+bind_layers( SebekHead, SebekV2Sock, version=2, type=2)
+bind_layers( SebekHead, SebekV2, version=2)
+bind_layers( SebekHead, SebekV3Sock, version=3, type=2)
+bind_layers( SebekHead, SebekV3, version=3)
+bind_layers( CookedLinux, IrLAPHead, proto=23)
+bind_layers( IrLAPHead, IrLAPCommand, Type=1)
+bind_layers( IrLAPCommand, IrLMP, )
+bind_layers( UDP, NBNSQueryRequest, dport=137)
+bind_layers( UDP, NBNSRequest, dport=137)
+bind_layers( UDP, NBNSQueryResponse, sport=137)
+bind_layers( UDP, NBNSQueryResponseNegative, sport=137)
+bind_layers( UDP, NBNSNodeStatusResponse, sport=137)
+bind_layers( NBNSNodeStatusResponse, NBNSNodeStatusResponseService, )
+bind_layers( NBNSNodeStatusResponse, NBNSNodeStatusResponseService, )
+bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseService, )
+bind_layers( NBNSNodeStatusResponseService, NBNSNodeStatusResponseEnd, )
+bind_layers( UDP, NBNSWackResponse, sport=137)
+bind_layers( UDP, NBTDatagram, dport=138)
+bind_layers( TCP, NBTSession, dport=139)
+bind_layers( NBTSession, SMBNegociate_Protocol_Request_Header, )
+bind_layers( SMBNegociate_Protocol_Request_Header, SMBNegociate_Protocol_Request_Tail, )
+bind_layers( SMBNegociate_Protocol_Request_Tail, SMBNegociate_Protocol_Request_Tail, )
+bind_layers( NBTSession, SMBNegociate_Protocol_Response_Advanced_Security, ExtendedSecurity=1)
+bind_layers( NBTSession, SMBNegociate_Protocol_Response_No_Security, ExtendedSecurity=0, EncryptionKeyLength=8)
+bind_layers( NBTSession, SMBNegociate_Protocol_Response_No_Security_No_Key, ExtendedSecurity=0, EncryptionKeyLength=0)
+bind_layers( NBTSession, SMBSession_Setup_AndX_Request, )
+bind_layers( NBTSession, SMBSession_Setup_AndX_Response, )
+bind_layers( HCI_Hdr, HCI_ACL_Hdr, type=2)
+bind_layers( HCI_Hdr, Raw, )
+bind_layers( HCI_ACL_Hdr, L2CAP_Hdr, )
+bind_layers( L2CAP_Hdr, L2CAP_CmdHdr, cid=1)
+bind_layers( L2CAP_CmdHdr, L2CAP_CmdRej, code=1)
+bind_layers( L2CAP_CmdHdr, L2CAP_ConnReq, code=2)
+bind_layers( L2CAP_CmdHdr, L2CAP_ConnResp, code=3)
+bind_layers( L2CAP_CmdHdr, L2CAP_ConfReq, code=4)
+bind_layers( L2CAP_CmdHdr, L2CAP_ConfResp, code=5)
+bind_layers( L2CAP_CmdHdr, L2CAP_DisconnReq, code=6)
+bind_layers( L2CAP_CmdHdr, L2CAP_DisconnResp, code=7)
+bind_layers( L2CAP_CmdHdr, L2CAP_InfoReq, code=10)
+bind_layers( L2CAP_CmdHdr, L2CAP_InfoResp, code=11)
+bind_layers( UDP, MobileIP, sport=434)
+bind_layers( UDP, MobileIP, dport=434)
+bind_layers( MobileIP, MobileIPRRQ, type=1)
+bind_layers( MobileIP, MobileIPRRP, type=3)
+bind_layers( MobileIP, MobileIPTunnelData, type=4)
+bind_layers( MobileIPTunnelData, IP, nexthdr=4)
+bind_layers( NetflowHeader, NetflowHeaderV1, version=1)
+bind_layers( NetflowHeaderV1, NetflowRecordV1, )
+
+bind_layers(UDP, TFTP, dport=69)
+bind_layers(TFTP, TFTP_RRQ, op=1)
+bind_layers(TFTP, TFTP_WRQ, op=2)
+bind_layers(TFTP, TFTP_DATA, op=3)
+bind_layers(TFTP, TFTP_ACK, op=4)
+bind_layers(TFTP, TFTP_ERROR, op=5)
+bind_layers(TFTP, TFTP_OACK, op=6)
+bind_layers(TFTP_RRQ, TFTP_Options)
+bind_layers(TFTP_WRQ, TFTP_Options)
+bind_layers(TFTP_OACK, TFTP_Options)
+
+
+###################
+## Fragmentation ##
+###################
+
+def fragment(pkt, fragsize=1480):
+ fragsize = (fragsize+7)/8*8
+ lst = []
+ for p in pkt:
+ s = str(p[IP].payload)
+ nb = (len(s)+fragsize-1)/fragsize
+ for i in range(nb):
+ q = p.copy()
+ del(q[IP].payload)
+ del(q[IP].chksum)
+ del(q[IP].len)
+ if i == nb-1:
+ q[IP].flags &= ~1
+ else:
+ q[IP].flags |= 1
+ q[IP].frag = i*fragsize/8
+ r = Raw(load=s[i*fragsize:(i+1)*fragsize])
+ r.overload_fields = p[IP].payload.overload_fields.copy()
+ q.add_payload(r)
+ lst.append(q)
+ return lst
+
+def overlap_frag(p, overlap, fragsize=8, overlap_fragsize=None):
+ if overlap_fragsize is None:
+ overlap_fragsize = fragsize
+ q = p.copy()
+ del(q[IP].payload)
+ q[IP].add_payload(overlap)
+
+ qfrag = fragment(q, overlap_fragsize)
+ qfrag[-1][IP].flags |= 1
+ return qfrag+fragment(p, fragsize)
+
+def defrag(plist):
+ """defrag(plist) -> ([not fragmented], [defragmented],
+ [ [bad fragments], [bad fragments], ... ])"""
+ frags = {}
+ nofrag = PacketList()
+ for p in plist:
+ ip = p[IP]
+ if IP not in p:
+ nofrag.append(p)
+ continue
+ if ip.frag == 0 and ip.flags & 1 == 0:
+ nofrag.append(p)
+ continue
+ uniq = (ip.id,ip.src,ip.dst,ip.proto)
+ if uniq in frags:
+ frags[uniq].append(p)
+ else:
+ frags[uniq] = PacketList([p])
+ defrag = []
+ missfrag = []
+ for lst in frags.itervalues():
+ lst.sort(lambda x,y:cmp(x.frag, y.frag))
+ p = lst[0]
+ if p.frag > 0:
+ missfrag.append(lst)
+ continue
+ p = p.copy()
+ if Padding in p:
+ del(p[Padding].underlayer.payload)
+ ip = p[IP]
+ if ip.len is None or ip.ihl is None:
+ clen = len(ip.payload)
+ else:
+ clen = ip.len - (ip.ihl<<2)
+ txt = Raw()
+ for q in lst[1:]:
+ if clen != q.frag<<3:
+ if clen > q.frag<<3:
+ warning("Fragment overlap (%i > %i) %r || %r || %r" % (clen, q.frag<<3, p,txt,q))
+ missfrag.append(lst)
+ txt = None
+ break
+ if q[IP].len is None or q[IP].ihl is None:
+ clen += len(q[IP].payload)
+ else:
+ clen += q[IP].len - (q[IP].ihl<<2)
+ if Padding in q:
+ del(q[Padding].underlayer.payload)
+ txt.add_payload(q[IP].payload.copy())
+
+ if txt is None:
+ continue
+
+ ip.flags &= ~1 # !MF
+ del(ip.chksum)
+ del(ip.len)
+ p = p/txt
+ defrag.append(p)
+ defrag2=PacketList()
+ for p in defrag:
+ defrag2.append(p.__class__(str(p)))
+ return nofrag,defrag2,missfrag
+
+def defragment(plist):
+ """defrag(plist) -> plist defragmented as much as possible """
+ frags = {}
+ final = []
+
+ pos = 0
+ for p in plist:
+ p._defrag_pos = pos
+ pos += 1
+ if IP in p:
+ ip = p[IP]
+ if ip.frag != 0 or ip.flags & 1:
+ ip = p[IP]
+ uniq = (ip.id,ip.src,ip.dst,ip.proto)
+ if uniq in frags:
+ frags[uniq].append(p)
+ else:
+ frags[uniq] = [p]
+ continue
+ final.append(p)
+
+ defrag = []
+ missfrag = []
+ for lst in frags.itervalues():
+ lst.sort(lambda x,y:cmp(x.frag, y.frag))
+ p = lst[0]
+ if p.frag > 0:
+ missfrag += lst
+ continue
+ p = p.copy()
+ if Padding in p:
+ del(p[Padding].underlayer.payload)
+ ip = p[IP]
+ if ip.len is None or ip.ihl is None:
+ clen = len(ip.payload)
+ else:
+ clen = ip.len - (ip.ihl<<2)
+ txt = Raw()
+ for q in lst[1:]:
+ if clen != q.frag<<3:
+ if clen > q.frag<<3:
+ warning("Fragment overlap (%i > %i) %r || %r || %r" % (clen, q.frag<<3, p,txt,q))
+ missfrag += lst
+ txt = None
+ break
+ if q[IP].len is None or q[IP].ihl is None:
+ clen += len(q[IP].payload)
+ else:
+ clen += q[IP].len - (q[IP].ihl<<2)
+ if Padding in q:
+ del(q[Padding].underlayer.payload)
+ txt.add_payload(q[IP].payload.copy())
+
+ if txt is None:
+ continue
+
+ ip.flags &= ~1 # !MF
+ del(ip.chksum)
+ del(ip.len)
+ p = p/txt
+ p._defrag_pos = lst[-1]._defrag_pos
+ defrag.append(p)
+ defrag2=[]
+ for p in defrag:
+ q = p.__class__(str(p))
+ q._defrag_pos = p._defrag_pos
+ defrag2.append(q)
+ final += defrag2
+ final += missfrag
+ final.sort(lambda x,y: cmp(x._defrag_pos, y._defrag_pos))
+ for p in final:
+ del(p._defrag_pos)
+
+ if hasattr(plist, "listname"):
+ name = "Defragmented %s" % plist.listname
+ else:
+ name = "Defragmented"
+
+
+ return PacketList(final, name=name)
+
+
+
+
+
+
+###################
+## Super sockets ##
+###################
+
+def Ether_Dot3_Dispatcher(pkt=None, **kargs):
+ if type(pkt) is str and len(pkt) >= 14 and struct.unpack("!H", pkt[12:14])[0] <= 1500:
+ return Dot3(pkt, **kargs)
+ return Ether(pkt, **kargs)
+
+# According to libdnet
+LLTypes = { ARPHDR_ETHER : Ether_Dot3_Dispatcher,
+ ARPHDR_METRICOM : Ether_Dot3_Dispatcher,
+ ARPHDR_LOOPBACK : Ether_Dot3_Dispatcher,
+ 12 : IP,
+ 101 : IP,
+ 801 : Dot11,
+ 802 : PrismHeader,
+ 803 : RadioTap,
+ 105 : Dot11,
+ 113 : CookedLinux,
+ 119 : PrismHeader, # for atheros
+ 127 : RadioTap,
+ 144 : CookedLinux, # called LINUX_IRDA, similar to CookedLinux
+ 783 : IrLAPHead,
+ 0xB1E70073L : HCI_Hdr, # I invented this one
+ }
+
+LLNumTypes = { Ether : ARPHDR_ETHER,
+ IP : 12,
+ IP : 101,
+ Dot11 : 801,
+ PrismHeader : 802,
+ RadioTap : 803,
+ RadioTap : 127,
+ Dot11 : 105,
+ CookedLinux : 113,
+ CookedLinux : 144,
+ IrLAPHead : 783
+ }
+
+L3Types = { ETH_P_IP : IP,
+ ETH_P_ARP : ARP,
+ ETH_P_ALL : IP
+ }
+
+
+
+class SuperSocket:
+ closed=0
+ def __init__(self, family=socket.AF_INET,type=socket.SOCK_STREAM, proto=0):
+ self.ins = socket.socket(family, type, proto)
+ self.outs = self.ins
+ self.promisc=None
+ def send(self, x):
+ return self.outs.send(str(x))
+ def recv(self, x):
+ return Raw(self.ins.recv(x))
+ def fileno(self):
+ return self.ins.fileno()
+ def close(self):
+ if self.closed:
+ return
+ self.closed=1
+ if self.ins != self.outs:
+ if self.outs and self.outs.fileno() != -1:
+ self.outs.close()
+ if self.ins and self.ins.fileno() != -1:
+ self.ins.close()
+ def bind_in(self, addr):
+ self.ins.bind(addr)
+ def bind_out(self, addr):
+ self.outs.bind(addr)
+
+
+class L3RawSocket(SuperSocket):
+ def __init__(self, type = ETH_P_IP, filter=None, iface=None, promisc=None, nofilter=0):
+ self.outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
+ self.outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
+ self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+ def recv(self, x):
+ return Ether(self.ins.recv(x)).payload
+ def send(self, x):
+ try:
+ self.outs.sendto(str(x),(x.dst,0))
+ except socket.error,msg:
+ log_runtime.error(msg)
+
+
+
+class L3PacketSocket(SuperSocket):
+ def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
+ self.type = type
+ self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+ self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
+ if not nofilter:
+ if conf.except_filter:
+ if filter:
+ filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+ else:
+ filter = "not (%s)" % conf.except_filter
+ if filter is not None:
+ attach_filter(self.ins, filter)
+ self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
+ self.outs = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+ self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
+ if promisc is None:
+ promisc = conf.promisc
+ self.promisc = promisc
+ if self.promisc:
+ if iface is None:
+ self.iff = get_if_list()
+ else:
+ if iface.__class__ is list:
+ self.iff = iface
+ else:
+ self.iff = [iface]
+ for i in self.iff:
+ set_promisc(self.ins, i)
+ def close(self):
+ if self.closed:
+ return
+ self.closed=1
+ if self.promisc:
+ for i in self.iff:
+ set_promisc(self.ins, i, 0)
+ SuperSocket.close(self)
+ def recv(self, x):
+ pkt, sa_ll = self.ins.recvfrom(x)
+ if sa_ll[2] == socket.PACKET_OUTGOING:
+ return None
+ if LLTypes.has_key(sa_ll[3]):
+ cls = LLTypes[sa_ll[3]]
+ lvl = 2
+ elif L3Types.has_key(sa_ll[1]):
+ cls = L3Types[sa_ll[1]]
+ lvl = 3
+ else:
+ warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
+ cls = Ether
+ lvl = 2
+
+ try:
+ pkt = cls(pkt)
+ except KeyboardInterrupt:
+ raise
+ except:
+ if conf.debug_dissector:
+ raise
+ pkt = Raw(pkt)
+ if lvl == 2:
+ pkt = pkt.payload
+ return pkt
+
+ def send(self, x):
+ if isinstance(x, IPv6):
+ iff,a,gw = conf.route6.route(x.dst)
+ elif hasattr(x,"dst"):
+ iff,a,gw = conf.route.route(x.dst)
+ else:
+ iff = conf.iface
+ sdto = (iff, self.type)
+ self.outs.bind(sdto)
+ sn = self.outs.getsockname()
+ ll = lambda x:x
+ if sn[3] in (ARPHDR_PPP,ARPHDR_TUN):
+ sdto = (iff, ETH_P_IP)
+ if LLTypes.has_key(sn[3]):
+ ll = lambda x:LLTypes[sn[3]]()/x
+ try:
+ self.outs.sendto(str(ll(x)), sdto)
+ except socket.error,msg:
+ if conf.auto_fragment and msg[0] == 90:
+ for p in fragment(x):
+ self.outs.sendto(str(ll(p)), sdto)
+ else:
+ raise
+
+
+
+
+class L2Socket(SuperSocket):
+ def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
+ if iface is None:
+ iface = conf.iface
+ self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+ self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
+ if not nofilter:
+ if conf.except_filter:
+ if filter:
+ filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+ else:
+ filter = "not (%s)" % conf.except_filter
+ if filter is not None:
+ attach_filter(self.ins, filter)
+ self.ins.bind((iface, type))
+ self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
+ self.outs = self.ins
+ self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
+ sa_ll = self.outs.getsockname()
+ if LLTypes.has_key(sa_ll[3]):
+ self.LL = LLTypes[sa_ll[3]]
+ elif L3Types.has_key(sa_ll[1]):
+ self.LL = L3Types[sa_ll[1]]
+ else:
+ warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
+ self.LL = Ether
+
+ def recv(self, x):
+ pkt, sa_ll = self.ins.recvfrom(x)
+ if sa_ll[2] == socket.PACKET_OUTGOING:
+ return None
+ try:
+ q = self.LL(pkt)
+ except KeyboardInterrupt:
+ raise
+ except:
+ if conf.debug_dissector:
+ raise
+ q = Raw(pkt)
+ return q
+
+
+class L2ListenSocket(SuperSocket):
+ def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None, nofilter=0):
+ self.type = type
+ self.outs = None
+ self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
+ self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
+ if iface is not None:
+ self.ins.bind((iface, type))
+ if not nofilter:
+ if conf.except_filter:
+ if filter:
+ filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+ else:
+ filter = "not (%s)" % conf.except_filter
+ if filter is not None:
+ attach_filter(self.ins, filter)
+ if promisc is None:
+ promisc = conf.sniff_promisc
+ self.promisc = promisc
+ if iface is None:
+ self.iff = get_if_list()
+ else:
+ if iface.__class__ is list:
+ self.iff = iface
+ else:
+ self.iff = [iface]
+ if self.promisc:
+ for i in self.iff:
+ set_promisc(self.ins, i)
+ self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
+ def close(self):
+ if self.promisc:
+ for i in self.iff:
+ set_promisc(self.ins, i, 0)
+ SuperSocket.close(self)
+
+ def recv(self, x):
+ pkt, sa_ll = self.ins.recvfrom(x)
+ if LLTypes.has_key(sa_ll[3]):
+ cls = LLTypes[sa_ll[3]]
+ elif L3Types.has_key(sa_ll[1]):
+ cls = L3Types[sa_ll[1]]
+ else:
+ warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
+ cls = Ether
+
+ try:
+ pkt = cls(pkt)
+ except KeyboardInterrupt:
+ raise
+ except:
+ if conf.debug_dissector:
+ raise
+ pkt = Raw(pkt)
+ return pkt
+
+ def send(self, x):
+ raise Scapy_Exception("Can't send anything with L2ListenSocket")
+
+
+
+class L3dnetSocket(SuperSocket):
+ def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
+ self.iflist = {}
+ self.ins = pcap.pcapObject()
+ if iface is None:
+ iface = conf.iface
+ self.iface = iface
+ self.ins.open_live(iface, 1600, 0, 100)
+ try:
+ ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
+ except:
+ pass
+ if nofilter:
+ if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
+ filter = "ether proto %i" % type
+ else:
+ filter = None
+ else:
+ if conf.except_filter:
+ if filter:
+ filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+ else:
+ filter = "not (%s)" % conf.except_filter
+ if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
+ if filter:
+ filter = "(ether proto %i) and (%s)" % (type,filter)
+ else:
+ filter = "ether proto %i" % type
+ if filter:
+ self.ins.setfilter(filter, 0, 0)
+ def send(self, x):
+ if isinstance(x, IPv6):
+ iff,a,gw = conf.route6.route(x.dst)
+ elif hasattr(x,"dst"):
+ iff,a,gw = conf.route.route(x.dst)
+ else:
+ iff = conf.iface
+ ifs = self.iflist.get(iff)
+ if ifs is None:
+ self.iflist[iff] = ifs = dnet.eth(iff)
+ ifs.send(str(Ether()/x))
+ def recv(self,x=MTU):
+ ll = self.ins.datalink()
+ if LLTypes.has_key(ll):
+ cls = LLTypes[ll]
+ else:
+ warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
+ cls = Ether
+
+ pkt = self.ins.next()
+ if pkt is not None:
+ pkt = pkt[1]
+ if pkt is None:
+ return
+
+ try:
+ pkt = cls(pkt)
+ except KeyboardInterrupt:
+ raise
+ except:
+ if conf.debug_dissector:
+ raise
+ pkt = Raw(pkt)
+ return pkt.payload
+
+ def nonblock_recv(self):
+ self.ins.setnonblock(1)
+ p = self.recv()
+ self.ins.setnonblock(0)
+ return p
+
+ def close(self):
+ if hasattr(self, "ins"):
+ del(self.ins)
+ if hasattr(self, "outs"):
+ del(self.outs)
+
+class L2dnetSocket(SuperSocket):
+ def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
+ if iface is None:
+ iface = conf.iface
+ self.iface = iface
+ self.ins = pcap.pcapObject()
+ self.ins.open_live(iface, 1600, 0, 100)
+ try:
+ ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
+ except:
+ pass
+ if nofilter:
+ if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
+ filter = "ether proto %i" % type
+ else:
+ filter = None
+ else:
+ if conf.except_filter:
+ if filter:
+ filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+ else:
+ filter = "not (%s)" % conf.except_filter
+ if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
+ if filter:
+ filter = "(ether proto %i) and (%s)" % (type,filter)
+ else:
+ filter = "ether proto %i" % type
+ if filter:
+ self.ins.setfilter(filter, 0, 0)
+ self.outs = dnet.eth(iface)
+ def recv(self,x):
+ ll = self.ins.datalink()
+ if LLTypes.has_key(ll):
+ cls = LLTypes[ll]
+ else:
+ warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
+ cls = Ether
+
+ pkt = self.ins.next()
+ if pkt is not None:
+ pkt = pkt[1]
+ if pkt is None:
+ return
+
+ try:
+ pkt = cls(pkt)
+ except KeyboardInterrupt:
+ raise
+ except:
+ if conf.debug_dissector:
+ raise
+ pkt = Raw(pkt)
+ return pkt
+
+ def nonblock_recv(self):
+ self.ins.setnonblock(1)
+ p = self.recv(MTU)
+ self.ins.setnonblock(0)
+ return p
+
+ def close(self):
+ if hasattr(self, "ins"):
+ del(self.ins)
+ if hasattr(self, "outs"):
+ del(self.outs)
+
+
+
+
+
+class L2pcapListenSocket(SuperSocket):
+ def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None):
+ self.type = type
+ self.outs = None
+ self.ins = pcap.pcapObject()
+ self.iface = iface
+ if iface is None:
+ iface = conf.iface
+ if promisc is None:
+ promisc = conf.sniff_promisc
+ self.promisc = promisc
+ self.ins.open_live(iface, 1600, self.promisc, 100)
+ try:
+ ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
+ except:
+ pass
+ if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given
+ if conf.except_filter:
+ if filter:
+ filter = "(%s) and not (%s)" % (filter, conf.except_filter)
+ else:
+ filter = "not (%s)" % conf.except_filter
+ if filter:
+ self.ins.setfilter(filter, 0, 0)
+
+ def close(self):
+ del(self.ins)
+
+ def recv(self, x):
+ ll = self.ins.datalink()
+ if LLTypes.has_key(ll):
+ cls = LLTypes[ll]
+ else:
+ warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
+ cls = Ether
+
+ pkt = None
+ while pkt is None:
+ pkt = self.ins.next()
+ if pkt is not None:
+ pkt = pkt[1]
+
+ try:
+ pkt = cls(pkt)
+ except KeyboardInterrupt:
+ raise
+ except:
+ if conf.debug_dissector:
+ raise
+ pkt = Raw(pkt)
+ return pkt
+
+ def send(self, x):
+ raise Scapy_Exception("Can't send anything with L2pcapListenSocket")
+
+
+class SimpleSocket(SuperSocket):
+ def __init__(self, sock):
+ self.ins = sock
+ self.outs = sock
+
+
+class StreamSocket(SimpleSocket):
+ def __init__(self, sock, basecls=Raw):
+ SimpleSocket.__init__(self, sock)
+ self.basecls = basecls
+
+ def recv(self, x=MTU):
+ pkt = self.ins.recv(x, socket.MSG_PEEK)
+ x = len(pkt)
+ pkt = self.basecls(pkt)
+ pad = pkt[Padding]
+ if pad is not None and pad.underlayer is not None:
+ del(pad.underlayer.payload)
+ while pad is not None and not isinstance(pad, NoPayload):
+ x -= len(pad.load)
+ pad = pad.payload
+ self.ins.recv(x)
+ return pkt
+
+
+class BluetoothL2CAPSocket(SuperSocket):
+ def __init__(self, peer):
+ s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
+ socket.BTPROTO_L2CAP)
+ s.connect((peer,0))
+
+ self.ins = self.outs = s
+
+ def recv(self, x):
+ return L2CAP_CmdHdr(self.ins.recv(x))
+
+
+class BluetoothHCISocket(SuperSocket):
+ def __init__(self, iface=0x10000, type=None):
+ s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
+ s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR,1)
+ s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP,1)
+ s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffffL,0xffffffffL,0xffffffffL,0)) #type mask, event mask, event mask, opcode
+ s.bind((iface,))
+ self.ins = self.outs = s
+# s.connect((peer,0))
+
+
+ def recv(self, x):
+ return HCI_Hdr(self.ins.recv(x))
+
+
+
+####################
+## Send / Receive ##
+####################
+
+
+
+
+def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
+ if not isinstance(pkt, Gen):
+ pkt = SetGen(pkt)
+
+ if verbose is None:
+ verbose = conf.verb
+ debug.recv = PacketList([],"Unanswered")
+ debug.sent = PacketList([],"Sent")
+ debug.match = SndRcvList([])
+ nbrecv=0
+ ans = []
+ # do it here to fix random fields, so that parent and child have the same
+ tobesent = [p for p in pkt]
+ notans = len(tobesent)
+
+ hsent={}
+ for i in tobesent:
+ h = i.hashret()
+ if h in hsent:
+ hsent[h].append(i)
+ else:
+ hsent[h] = [i]
+ if retry < 0:
+ retry = -retry
+ autostop=retry
+ else:
+ autostop=0
+
+
+ while retry >= 0:
+ found=0
+
+ if timeout < 0:
+ timeout = None
+
+ rdpipe,wrpipe = os.pipe()
+ rdpipe=os.fdopen(rdpipe)
+ wrpipe=os.fdopen(wrpipe,"w")
+
+ pid = os.fork()
+ if pid == 0:
+ sys.stdin.close()
+ rdpipe.close()
+ try:
+ i = 0
+ if verbose:
+ print "Begin emission:"
+ for p in tobesent:
+ pks.send(p)
+ i += 1
+ time.sleep(inter)
+ if verbose:
+ print "Finished to send %i packets." % i
+ except SystemExit:
+ pass
+ except KeyboardInterrupt:
+ pass
+ except:
+ log_runtime.exception("--- Error in child %i" % os.getpid())
+ log_runtime.info("--- Error in child %i" % os.getpid())
+ os._exit(0)
+ else:
+ cPickle.dump(arp_cache, wrpipe)
+ wrpipe.close()
+ os._exit(0)
+ elif pid < 0:
+ log_runtime.error("fork error")
+ else:
+ wrpipe.close()
+ stoptime = 0
+ remaintime = None
+ inmask = [rdpipe,pks]
+ try:
+ while 1:
+ if stoptime:
+ remaintime = stoptime-time.time()
+ if remaintime <= 0:
+ break
+ r = None
+ if FREEBSD or DARWIN:
+ inp, out, err = select(inmask,[],[], 0.05)
+ if len(inp) == 0 or pks in inp:
+ r = pks.nonblock_recv()
+ else:
+ inp, out, err = select(inmask,[],[], remaintime)
+ if len(inp) == 0:
+ break
+ if pks in inp:
+ r = pks.recv(MTU)
+ if rdpipe in inp:
+ if timeout:
+ stoptime = time.time()+timeout
+ del(inmask[inmask.index(rdpipe)])
+ if r is None:
+ continue
+ ok = 0
+ h = r.hashret()
+ if h in hsent:
+ hlst = hsent[h]
+ for i in range(len(hlst)):
+ if r.answers(hlst[i]):
+ ans.append((hlst[i],r))
+ if verbose > 1:
+ os.write(1, "*")
+ ok = 1
+ if not multi:
+ del(hlst[i])
+ notans -= 1;
+ else:
+ if not hasattr(hlst[i], '_answered'):
+ notans -= 1;
+ hlst[i]._answered = 1;
+ break
+ if notans == 0 and not multi:
+ break
+ if not ok:
+ if verbose > 1:
+ os.write(1, ".")
+ nbrecv += 1
+ if conf.debug_match:
+ debug.recv.append(r)
+ except KeyboardInterrupt:
+ if chainCC:
+ raise
+
+ try:
+ ac = cPickle.load(rdpipe)
+ except EOFError:
+ warning("Child died unexpectedly. Packets may have not been sent")
+ else:
+ arp_cache.update(ac)
+ os.waitpid(pid,0)
+
+ remain = reduce(list.__add__, hsent.values(), [])
+ if multi:
+ remain = filter(lambda p: not hasattr(p, '_answered'), remain);
+
+ if autostop and len(remain) > 0 and len(remain) != len(tobesent):
+ retry = autostop
+
+ tobesent = remain
+ if len(tobesent) == 0:
+ break
+ retry -= 1
+
+ if conf.debug_match:
+ debug.sent=PacketList(remain[:],"Sent")
+ debug.match=SndRcvList(ans[:])
+
+ #clean the ans list to delete the field _answered
+ if (multi):
+ for s,r in ans:
+ if hasattr(s, '_answered'):
+ del(s._answered)
+
+ if verbose:
+ print "\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans)
+ return SndRcvList(ans),PacketList(remain,"Unanswered"),debug.recv
+
+
+def __gen_send(s, x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
+ if not isinstance(x, Gen):
+ x = SetGen(x)
+ if verbose is None:
+ verbose = conf.verb
+ n = 0
+ if count is not None:
+ loop = -count
+ elif not loop:
+ loop=-1
+ try:
+ while loop:
+ for p in x:
+ s.send(p)
+ n += 1
+ if verbose:
+ os.write(1,".")
+ time.sleep(inter)
+ if loop < 0:
+ loop += 1
+ except KeyboardInterrupt:
+ pass
+ s.close()
+ if verbose:
+ print "\nSent %i packets." % n
+
+def send(x, inter=0, loop=0, count=None, verbose=None, *args, **kargs):
+ """Send packets at layer 3
+send(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
+ __gen_send(conf.L3socket(*args, **kargs), x, inter=inter, loop=loop, count=count,verbose=verbose)
+
+def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, count=None, verbose=None, *args, **kargs):
+ """Send packets at layer 2
+send(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
+ if iface is None and iface_hint is not None:
+ iface = conf.route.route(iface_hint)[0]
+ __gen_send(conf.L2socket(iface=iface, *args, **kargs), x, inter=inter, loop=loop, count=count, verbose=verbose)
+
+def sendpfast(x, pps=None, mbps=None, realtime=None, loop=0, iface=None):
+ """Send packets at layer 2 using tcpreplay for performance
+ pps: packets per second
+ mpbs: MBits per second
+ realtime: use packet's timestamp, bending time with realtime value
+ loop: number of times to process the packet list
+ iface: output interface """
+ if iface is None:
+ iface = conf.iface
+ options = ["--intf1=%s" % iface ]
+ if pps is not None:
+ options.append("--pps=%i" % pps)
+ elif mbps is not None:
+ options.append("--mbps=%i" % mbps)
+ elif realtime is not None:
+ options.append("--multiplier=%i" % realtime)
+ else:
+ options.append("--topspeed")
+
+ if loop:
+ options.append("--loop=%i" % loop)
+
+ f = os.tempnam("scapy")
+ options.append(f)
+ wrpcap(f, x)
+ try:
+ try:
+ os.spawnlp(os.P_WAIT, conf.prog.tcpreplay, conf.prog.tcpreplay, *options)
+ except KeyboardInterrupt:
+ log_interactive.info("Interrupted by user")
+ finally:
+ os.unlink(f)
+
+
+
+
+
+def sr(x,filter=None, iface=None, nofilter=0, *args,**kargs):
+ """Send and receive packets at layer 3
+nofilter: put 1 to avoid use of bpf filters
+retry: if positive, how many times to resend unanswered packets
+ if negative, how many times to retry when no more packets are answered
+timeout: how much time to wait after the last packet has been sent
+verbose: set verbosity level
+multi: whether to accept multiple answers for the same stimulus
+filter: provide a BPF filter
+iface: listen answers only on the given interface"""
+ if not kargs.has_key("timeout"):
+ kargs["timeout"] = -1
+ s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
+ a,b,c=sndrcv(s,x,*args,**kargs)
+ s.close()
+ return a,b
+
+def sr1(x,filter=None,iface=None, nofilter=0, *args,**kargs):
+ """Send packets at layer 3 and return only the first answer
+nofilter: put 1 to avoid use of bpf filters
+retry: if positive, how many times to resend unanswered packets
+ if negative, how many times to retry when no more packets are answered
+timeout: how much time to wait after the last packet has been sent
+verbose: set verbosity level
+multi: whether to accept multiple answers for the same stimulus
+filter: provide a BPF filter
+iface: listen answers only on the given interface"""
+ if not kargs.has_key("timeout"):
+ kargs["timeout"] = -1
+ s=conf.L3socket(filter=filter, nofilter=nofilter, iface=iface)
+ a,b,c=sndrcv(s,x,*args,**kargs)
+ s.close()
+ if len(a) > 0:
+ return a[0][1]
+ else:
+ return None
+
+def srp(x,iface=None, iface_hint=None, filter=None, nofilter=0, type=ETH_P_ALL, *args,**kargs):
+ """Send and receive packets at layer 2
+nofilter: put 1 to avoid use of bpf filters
+retry: if positive, how many times to resend unanswered packets
+ if negative, how many times to retry when no more packets are answered
+timeout: how much time to wait after the last packet has been sent
+verbose: set verbosity level
+multi: whether to accept multiple answers for the same stimulus
+filter: provide a BPF filter
+iface: work only on the given interface"""
+ if not kargs.has_key("timeout"):
+ kargs["timeout"] = -1
+ if iface is None and iface_hint is not None:
+ iface = conf.route.route(iface_hint)[0]
+ a,b,c=sndrcv(conf.L2socket(iface=iface, filter=filter, nofilter=nofilter, type=type),x,*args,**kargs)
+ return a,b
+
+def srp1(*args,**kargs):
+ """Send and receive packets at layer 2 and return only the first answer
+nofilter: put 1 to avoid use of bpf filters
+retry: if positive, how many times to resend unanswered packets
+ if negative, how many times to retry when no more packets are answered
+timeout: how much time to wait after the last packet has been sent
+verbose: set verbosity level
+multi: whether to accept multiple answers for the same stimulus
+filter: provide a BPF filter
+iface: work only on the given interface"""
+ if not kargs.has_key("timeout"):
+ kargs["timeout"] = -1
+ a,b=srp(*args,**kargs)
+ if len(a) > 0:
+ return a[0][1]
+ else:
+ return None
+
+def __sr_loop(srfunc, pkts, prn=lambda x:x[1].summary(), prnfail=lambda x:x.summary(), inter=1, timeout=None, count=None, verbose=0, store=1, *args, **kargs):
+ n = 0
+ r = 0
+ ct = conf.color_theme
+ parity = 0
+ ans=[]
+ unans=[]
+ if timeout is None:
+ timeout = min(2*inter, 5)
+ try:
+ while 1:
+ parity ^= 1
+ col = [ct.even,ct.odd][parity]
+ if count is not None:
+ if count == 0:
+ break
+ count -= 1
+ start = time.time()
+ print "\rsend...\r",
+ res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=1, *args, **kargs)
+ n += len(res[0])+len(res[1])
+ r += len(res[0])
+ if prn and len(res[0]) > 0:
+ msg = "RECV %i:" % len(res[0])
+ print "\r"+ct.success(msg),
+ for p in res[0]:
+ print col(prn(p))
+ print " "*len(msg),
+ if prnfail and len(res[1]) > 0:
+ msg = "fail %i:" % len(res[1])
+ print "\r"+ct.fail(msg),
+ for p in res[1]:
+ print col(prnfail(p))
+ print " "*len(msg),
+ if not (prn or prnfail):
+ print "recv:%i fail:%i" % tuple(map(len, res[:2]))
+ if store:
+ ans += res[0]
+ unans += res[1]
+ end=time.time()
+ if end-start < inter:
+ time.sleep(inter+start-end)
+ except KeyboardInterrupt:
+ pass
+
+ if n>0:
+ print "%s\nSent %i packets, received %i packets. %3.1f%% hits." % (Color.normal,n,r,100.0*r/n)
+
+ return SndRcvList(ans),PacketList(unans)
+
+def srloop(pkts, *args, **kargs):
+ """Send a packet at layer 3 in loop and print the answer each time
+srloop(pkts, [prn], [inter], [count], ...) --> None"""
+ return __sr_loop(sr, pkts, *args, **kargs)
+
+def srploop(pkts, *args, **kargs):
+ """Send a packet at layer 2 in loop and print the answer each time
+srloop(pkts, [prn], [inter], [count], ...) --> None"""
+ return __sr_loop(srp, pkts, *args, **kargs)
+
+
+def sndrcvflood(pks, pkt, prn=lambda (s,r):r.summary(), chainCC=0, store=1, unique=0):
+ if not isinstance(pkt, Gen):
+ pkt = SetGen(pkt)
+ tobesent = [p for p in pkt]
+ received = SndRcvList()
+ seen = {}
+
+ hsent={}
+ for i in tobesent:
+ h = i.hashret()
+ if h in hsent:
+ hsent[h].append(i)
+ else:
+ hsent[h] = [i]
+
+ def send_in_loop(tobesent):
+ while 1:
+ for p in tobesent:
+ yield p
+
+ packets_to_send = send_in_loop(tobesent)
+
+ ssock = rsock = pks.fileno()
+
+ try:
+ while 1:
+ readyr,readys,_ = select([rsock],[ssock],[])
+ if ssock in readys:
+ pks.send(packets_to_send.next())
+
+ if rsock in readyr:
+ p = pks.recv(MTU)
+ if p is None:
+ continue
+ h = p.hashret()
+ if h in hsent:
+ hlst = hsent[h]
+ for i in hlst:
+ if p.answers(i):
+ res = prn((i,p))
+ if unique:
+ if res in seen:
+ continue
+ seen[res] = None
+ if res is not None:
+ print res
+ if store:
+ received.append((i,p))
+ except KeyboardInterrupt:
+ if chainCC:
+ raise
+ return received
+
+def srflood(x,filter=None, iface=None, nofilter=None, *args,**kargs):
+ """Flood and receive packets at layer 3
+prn: function applied to packets received. Ret val is printed if not None
+store: if 1 (default), store answers and return them
+unique: only consider packets whose print
+nofilter: put 1 to avoid use of bpf filters
+filter: provide a BPF filter
+iface: listen answers only on the given interface"""
+ s = conf.L3socket(filter=filter, iface=iface, nofilter=nofilter)
+ r=sndrcvflood(s,x,*args,**kargs)
+ s.close()
+ return r
+
+def srpflood(x,filter=None, iface=None, iface_hint=None, nofilter=None, *args,**kargs):
+ """Flood and receive packets at layer 2
+prn: function applied to packets received. Ret val is printed if not None
+store: if 1 (default), store answers and return them
+unique: only consider packets whose print
+nofilter: put 1 to avoid use of bpf filters
+filter: provide a BPF filter
+iface: listen answers only on the given interface"""
+ if iface is None and iface_hint is not None:
+ iface = conf.route.route(iface_hint)[0]
+ s = conf.L2socket(filter=filter, iface=iface, nofilter=nofilter)
+ r=sndrcvflood(s,x,*args,**kargs)
+ s.close()
+ return r
+
+
+## Bluetooth
+
+
+def srbt(peer, pkts, inter=0.1, *args, **kargs):
+ s = conf.BTsocket(peer=peer)
+ a,b,c=sndrcv(s,pkts,inter=inter,*args,**kargs)
+ s.close()
+ return a,b
+
+def srbt1(peer, pkts, *args, **kargs):
+ a,b = srbt(peer, pkts, *args, **kargs)
+ if len(a) > 0:
+ return a[0][1]
+
+
+
+
+
+#############################
+## pcap capture file stuff ##
+#############################
+
+def wrpcap(filename, pkt, *args, **kargs):
+ """Write a list of packets to a pcap file
+gz: set to 1 to save a gzipped capture
+linktype: force linktype value
+endianness: "<" or ">", force endianness"""
+ PcapWriter(filename, *args, **kargs).write(pkt)
+
+def rdpcap(filename, count=-1):
+ """Read a pcap file and return a packet list
+count: read only <count> packets"""
+ return PcapReader(filename).read_all(count=count)
+
+class PcapReader:
+ """A stateful pcap reader
+
+ Based entirely on scapy.rdpcap(), this class allows for packets
+ to be dispatched without having to be loaded into memory all at
+ once
+ """
+
+ def __init__(self, filename):
+ self.filename = filename
+ try:
+ self.f = gzip.open(filename,"rb")
+ magic = self.f.read(4)
+ except IOError:
+ self.f = open(filename,"rb")
+ magic = self.f.read(4)
+ if magic == "\xa1\xb2\xc3\xd4": #big endian
+ self.endian = ">"
+ elif magic == "\xd4\xc3\xb2\xa1": #little endian
+ self.endian = "<"
+ else:
+ raise RuntimeWarning, "Not a pcap capture file (bad magic)"
+ hdr = self.f.read(20)
+ if len(hdr)<20:
+ raise RuntimeWarning, "Invalid pcap file (too short)"
+ vermaj,vermin,tz,sig,snaplen,linktype = struct.unpack(self.endian+"HHIIII",hdr)
+ self.LLcls = LLTypes.get(linktype, Raw)
+ if self.LLcls == Raw:
+ warning("PcapReader: unkonwon LL type [%i]/[%#x]. Using Raw packets" % (linktype,linktype))
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ """impliment the iterator protocol on a set of packets in a
+ pcap file
+ """
+ pkt = self.read_packet()
+ if pkt == None:
+ raise StopIteration
+ return pkt
+
+
+ def read_packet(self):
+ """return a single packet read from the file
+
+ returns None when no more packets are available
+ """
+ hdr = self.f.read(16)
+ if len(hdr) < 16:
+ return None
+ sec,usec,caplen,olen = struct.unpack(self.endian+"IIII", hdr)
+ s = self.f.read(caplen)
+ try:
+ p = self.LLcls(s)
+ except KeyboardInterrupt:
+ raise
+ except:
+ if conf.debug_dissector:
+ raise
+ p = Raw(s)
+ p.time = sec+0.000001*usec
+ return p
+
+ def dispatch(self, callback):
+ """call the specified callback routine for each packet read
+
+ This is just a convienience function for the main loop
+ that allows for easy launching of packet processing in a
+ thread.
+ """
+ p = self.read_packet()
+ while p != None:
+ callback(p)
+ p = self.read_packet()
+
+ def read_all(self,count=-1):
+ """return a list of all packets in the pcap file
+ """
+ res=[]
+ while count != 0:
+ count -= 1
+ p = self.read_packet()
+ if p is None:
+ break
+ res.append(p)
+ return PacketList(res,name = os.path.basename(self.filename))
+
+ def recv(self, size):
+ """ Emulate a socket
+ """
+ return self.read_packet()
+
+ def fileno(self):
+ return self.f.fileno()
+
+
+
+class PcapWriter:
+ """A pcap writer with more control than wrpcap()
+
+ This routine is based entirely on scapy.wrpcap(), but adds capability
+ of writing one packet at a time in a streaming manner.
+ """
+ def __init__(self, filename, linktype=None, gz=0, endianness=""):
+ self.linktype = linktype
+ self.header_done = 0
+ if gz:
+ self.f = gzip.open(filename,"wb")
+ else:
+ self.f = open(filename,"wb")
+ self.endian = endianness
+
+ def fileno(self):
+ return self.f.fileno()
+
+ def write(self, pkt):
+ """accepts a either a single packet or a list of packets
+ to be written to the dumpfile
+ """
+
+ if self.header_done == 0:
+ if self.linktype == None:
+ if isinstance(pkt,Packet):
+ linktype = LLNumTypes.get(pkt.__class__,1)
+ else:
+ linktype = LLNumTypes.get(pkt[0].__class__,1)
+
+ self.f.write(struct.pack(self.endian+"IHHIIII", 0xa1b2c3d4L,
+ 2, 4, 0, 0, MTU, linktype))
+ self.header_done = 1
+
+ for p in pkt:
+ self._write_packet(p)
+
+ def _write_packet(self, packet):
+ """writes a single packet to the pcap file
+ """
+ s = str(packet)
+ l = len(s)
+ sec = int(packet.time)
+ usec = int((packet.time-sec)*1000000)
+ self.f.write(struct.pack(self.endian+"IIII", sec, usec, l, l))
+ self.f.write(s)
+
+re_extract_hexcap = re.compile("^(0x[0-9a-fA-F]{2,}[ :\t]|(0x)?[0-9a-fA-F]{2,}:|(0x)?[0-9a-fA-F]{3,}[: \t]|) *(([0-9a-fA-F]{2} {,2}){,16})")
+
+def import_hexcap():
+ p = ""
+ try:
+ while 1:
+ l = raw_input().strip()
+ try:
+ p += re_extract_hexcap.match(l).groups()[3]
+ except:
+ warning("Parsing error during hexcap")
+ continue
+ except EOFError:
+ pass
+
+ p = p.replace(" ","")
+ p2=""
+ for i in range(len(p)/2):
+ p2 += chr(int(p[2*i:2*i+2],16))
+ return p2
+
+
+
+def wireshark(pktlist):
+ f = os.tempnam("scapy")
+ wrpcap(f, pktlist)
+ os.spawnlp(os.P_NOWAIT, conf.prog.wireshark, conf.prog.wireshark, "-r", f)
+
+def hexedit(x):
+ x = str(x)
+ f = os.tempnam("scapy")
+ open(f,"w").write(x)
+ os.spawnlp(os.P_WAIT, conf.prog.hexedit, conf.prog.hexedit, f)
+ x = open(f).read()
+ os.unlink(f)
+ return x
+
+
+#####################
+## knowledge bases ##
+#####################
+
+class KnowledgeBase:
+ def __init__(self, filename):
+ self.filename = filename
+ self.base = None
+
+ def lazy_init(self):
+ self.base = ""
+
+ def reload(self, filename = None):
+ if filename is not None:
+ self.filename = filename
+ oldbase = self.base
+ self.base = None
+ self.lazy_init()
+ if self.base is None:
+ self.base = oldbase
+
+ def get_base(self):
+ if self.base is None:
+ self.lazy_init()
+ return self.base
+
+
+
+##########################
+## IP location database ##
+##########################
+
+class IPCountryKnowledgeBase(KnowledgeBase):
+ """
+How to generate the base :
+db = []
+for l in open("GeoIPCountryWhois.csv").readlines():
+ s,e,c = l.split(",")[2:5]
+ db.append((int(s[1:-1]),int(e[1:-1]),c[1:-1]))
+cPickle.dump(gzip.open("xxx","w"),db)
+"""
+ def lazy_init(self):
+ self.base = load_object(self.filename)
+
+
+class CountryLocKnowledgeBase(KnowledgeBase):
+ def lazy_init(self):
+ f=open(self.filename)
+ self.base = {}
+ while 1:
+ l = f.readline()
+ if not l:
+ break
+ l = l.strip().split(",")
+ if len(l) != 3:
+ continue
+ c,lat,long = l
+
+ self.base[c] = (float(long),float(lat))
+ f.close()
+
+
+
+
+def locate_ip(ip):
+ ip=map(int,ip.split("."))
+ ip = ip[3]+(ip[2]<<8L)+(ip[1]<<16L)+(ip[0]<<24L)
+
+ cloc = country_loc_kdb.get_base()
+ db = IP_country_kdb.get_base()
+
+ d=0
+ f=len(db)-1
+ while (f-d) > 1:
+ guess = (d+f)/2
+ if ip > db[guess][0]:
+ d = guess
+ else:
+ f = guess
+ s,e,c = db[guess]
+ if s <= ip and ip <= e:
+ return cloc.get(c,None)
+
+
+
+
+###############
+## p0f stuff ##
+###############
+
+# File format (according to p0f.fp) :
+#
+# wwww:ttt:D:ss:OOO...:QQ:OS:Details
+#
+# wwww - window size
+# ttt - initial TTL
+# D - don't fragment bit (0=unset, 1=set)
+# ss - overall SYN packet size
+# OOO - option value and order specification
+# QQ - quirks list
+# OS - OS genre
+# details - OS description
+
+
+
+class p0fKnowledgeBase(KnowledgeBase):
+ def __init__(self, filename):
+ KnowledgeBase.__init__(self, filename)
+ #self.ttl_range=[255]
+ def lazy_init(self):
+ try:
+ f=open(self.filename)
+ except IOError:
+ warning("Can't open base %s" % self.filename)
+ return
+ try:
+ self.base = []
+ for l in f:
+ if l[0] in ["#","\n"]:
+ continue
+ l = tuple(l.split(":"))
+ if len(l) < 8:
+ continue
+ li = map(int,l[1:4])
+ #if li[0] not in self.ttl_range:
+ # self.ttl_range.append(li[0])
+ # self.ttl_range.sort()
+ self.base.append((l[0], li[0], li[1], li[2], l[4], l[5], l[6], l[7][:-1]))
+ except:
+ warning("Can't parse p0f database (new p0f version ?)")
+ self.base = None
+ f.close()
+
+
+def packet2p0f(pkt):
+ while pkt.haslayer(IP) and pkt.haslayer(TCP):
+ pkt = pkt.getlayer(IP)
+ if isinstance(pkt.payload, TCP):
+ break
+ pkt = pkt.payload
+
+ if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP):
+ raise TypeError("Not a TCP/IP packet")
+ if pkt.payload.flags & 0x13 != 0x02: #S,!A,!F
+ raise TypeError("Not a syn packet")
+
+ #t = p0f_kdb.ttl_range[:]
+ #t += [pkt.ttl]
+ #t.sort()
+ #ttl=t[t.index(pkt.ttl)+1]
+ ttl = pkt.ttl
+
+ df = (pkt.flags & 2) / 2
+ ss = len(pkt)
+ # from p0f/config.h : PACKET_BIG = 100
+ if ss > 100:
+ ss = 0
+
+ ooo = ""
+ mss = -1
+ qqT = False
+ qqP = False
+ #qqBroken = False
+ ilen = (pkt[TCP].dataofs << 2) - 20 # from p0f.c
+ for option in pkt.payload.options:
+ ilen -= 1
+ if option[0] == "MSS":
+ ooo += "M" + str(option[1]) + ","
+ mss = option[1]
+ # FIXME: qqBroken
+ ilen -= 3
+ elif option[0] == "WScale":
+ ooo += "W" + str(option[1]) + ","
+ # FIXME: qqBroken
+ ilen -= 2
+ elif option[0] == "Timestamp":
+ if option[1][0] == 0:
+ ooo += "T0,"
+ else:
+ ooo += "T,"
+ if option[1][1] != 0:
+ qqT = True
+ ilen -= 9
+ elif option[0] == "SAckOK":
+ ooo += "S,"
+ ilen -= 1
+ elif option[0] == "NOP":
+ ooo += "N,"
+ elif option[0] == "EOL":
+ ooo += "E,"
+ if ilen > 0:
+ qqP = True
+ else:
+ ooo += "?,"
+ # FIXME: ilen
+ ooo = ooo[:-1]
+ if ooo == "": ooo = "."
+
+ win = pkt.payload.window
+ if mss != -1:
+ if win % mss == 0:
+ win = "S" + str(win/mss)
+ elif win % (mss + 40) == 0:
+ win = "T" + str(win/(mss+40))
+ win = str(win)
+
+ qq = ""
+
+ if qqP:
+ qq += "P"
+ if pkt[IP].id == 0:
+ qq += "Z"
+ if pkt[IP].options != '':
+ qq += "I"
+ if pkt[TCP].urgptr != 0:
+ qq += "U"
+ if pkt[TCP].reserved != 0:
+ qq += "X"
+ if pkt[TCP].ack != 0:
+ qq += "A"
+ if qqT:
+ qq += "T"
+ if pkt[TCP].flags & 40 != 0:
+ # U or P
+ qq += "F"
+ if not isinstance(pkt[TCP].payload, NoPayload):
+ qq += "D"
+ # FIXME : "!" - broken options segment
+
+ if qq == "":
+ qq = "."
+
+ return (win,
+ ttl,
+ df,
+ ss,
+ ooo,
+ qq)
+
+def p0f_correl(x,y):
+ d = 0
+ # wwww can be "*" or "%nn"
+ d += (x[0] == y[0] or y[0] == "*" or (y[0][0] == "%" and x[0].isdigit() and (int(x[0]) % int(y[0][1:])) == 0))
+ # ttl
+ d += (y[1] >= x[1] and y[1] - x[1] < 32)
+ for i in [2, 3, 5]:
+ d += (x[i] == y[i])
+ xopt = x[4].split(",")
+ yopt = y[4].split(",")
+ if len(xopt) == len(yopt):
+ same = True
+ for i in range(len(xopt)):
+ if not (xopt[i] == yopt[i] or
+ (len(yopt[i]) == 2 and len(xopt[i]) > 1 and
+ yopt[i][1] == "*" and xopt[i][0] == yopt[i][0]) or
+ (len(yopt[i]) > 2 and len(xopt[i]) > 1 and
+ yopt[i][1] == "%" and xopt[i][0] == yopt[i][0] and
+ int(xopt[i][1:]) % int(yopt[i][2:]) == 0)):
+ same = False
+ break
+ if same:
+ d += len(xopt)
+ return d
+
+
+def p0f(pkt):
+ """Passive OS fingerprinting: which OS emitted this TCP SYN ?
+p0f(packet) -> accuracy, [list of guesses]
+"""
+ pb = p0f_kdb.get_base()
+ if not pb:
+ warning("p0f base empty.")
+ return []
+ s = len(pb[0][0])
+ r = []
+ sig = packet2p0f(pkt)
+ max = len(sig[4].split(",")) + 5
+ for b in pb:
+ d = p0f_correl(sig,b)
+ if d == max:
+ r.append((b[6], b[7], b[1] - pkt[IP].ttl))
+ return r
+
+
+def prnp0f(pkt):
+ try:
+ r = p0f(pkt)
+ except:
+ return
+ if r == []:
+ r = ("UNKNOWN", "[" + ":".join(map(str, packet2p0f(pkt))) + ":?:?]", None)
+ else:
+ r = r[0]
+ uptime = None
+ try:
+ uptime = pkt2uptime(pkt)
+ except:
+ pass
+ if uptime == 0:
+ uptime = None
+ res = pkt.sprintf("%IP.src%:%TCP.sport% - " + r[0] + " " + r[1])
+ if uptime is not None:
+ res += pkt.sprintf(" (up: " + str(uptime/3600) + " hrs)\n -> %IP.dst%:%TCP.dport%")
+ else:
+ res += pkt.sprintf("\n -> %IP.dst%:%TCP.dport%")
+ if r[2] is not None:
+ res += " (distance " + str(r[2]) + ")"
+ print res
+
+
+def pkt2uptime(pkt, HZ=100):
+ """Calculate the date the machine which emitted the packet booted using TCP timestamp
+pkt2uptime(pkt, [HZ=100])"""
+ if not isinstance(pkt, Packet):
+ raise TypeError("Not a TCP packet")
+ if isinstance(pkt,NoPayload):
+ raise TypeError("Not a TCP packet")
+ if not isinstance(pkt, TCP):
+ return pkt2uptime(pkt.payload)
+ for opt in pkt.options:
+ if opt[0] == "Timestamp":
+ #t = pkt.time - opt[1][0] * 1.0/HZ
+ #return time.ctime(t)
+ t = opt[1][0] / HZ
+ return t
+ raise TypeError("No timestamp option")
+
+
+
+#################
+## Queso stuff ##
+#################
+
+
+def quesoTCPflags(flags):
+ if flags == "-":
+ return "-"
+ flv = "FSRPAUXY"
+ v = 0
+ for i in flags:
+ v |= 2**flv.index(i)
+ return "%x" % v
+
+class QuesoKnowledgeBase(KnowledgeBase):
+ def lazy_init(self):
+ try:
+ f = open(self.filename)
+ except IOError:
+ return
+ self.base = {}
+ p = None
+ try:
+ for l in f:
+ l = l.strip()
+ if not l or l[0] == ';':
+ continue
+ if l[0] == '*':
+ if p is not None:
+ p[""] = name
+ name = l[1:].strip()
+ p = self.base
+ continue
+ if l[0] not in list("0123456"):
+ continue
+ res = l[2:].split()
+ res[-1] = quesoTCPflags(res[-1])
+ res = " ".join(res)
+ if not p.has_key(res):
+ p[res] = {}
+ p = p[res]
+ if p is not None:
+ p[""] = name
+ except:
+ self.base = None
+ warning("Can't load queso base [%s]", self.filename)
+ f.close()
+
+
+
+
+def queso_sig(target, dport=80, timeout=3):
+ p = queso_kdb.get_base()
+ ret = []
+ for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]:
+ ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()),
+ timeout=timeout, verbose=0)
+ if len(ans) == 0:
+ rs = "- - - -"
+ else:
+ s,r = ans[0]
+ rs = "%i" % (r.seq != 0)
+ if not r.ack:
+ r += " 0"
+ elif r.ack-s.seq > 666:
+ rs += " R" % 0
+ else:
+ rs += " +%i" % (r.ack-s.seq)
+ rs += " %X" % r.window
+ rs += " %x" % r.payload.flags
+ ret.append(rs)
+ return ret
+
+def queso_search(sig):
+ p = queso_kdb.get_base()
+ sig.reverse()
+ ret = []
+ try:
+ while sig:
+ s = sig.pop()
+ p = p[s]
+ if p.has_key(""):
+ ret.append(p[""])
+ except KeyError:
+ pass
+ return ret
+
+
+def queso(*args,**kargs):
+ """Queso OS fingerprinting
+queso(target, dport=80, timeout=3)"""
+ return queso_search(queso_sig(*args, **kargs))
+
+
+
+######################
+## nmap OS fp stuff ##
+######################
+
+
+class NmapKnowledgeBase(KnowledgeBase):
+ def lazy_init(self):
+ try:
+ f=open(self.filename)
+ except IOError:
+ return
+
+ self.base = []
+ name = None
+ try:
+ for l in f:
+ l = l.strip()
+ if not l or l[0] == "#":
+ continue
+ if l[:12] == "Fingerprint ":
+ if name is not None:
+ self.base.append((name,sig))
+ name = l[12:].strip()
+ sig={}
+ p = self.base
+ continue
+ elif l[:6] == "Class ":
+ continue
+ op = l.find("(")
+ cl = l.find(")")
+ if op < 0 or cl < 0:
+ warning("error reading nmap os fp base file")
+ continue
+ test = l[:op]
+ s = map(lambda x: x.split("="), l[op+1:cl].split("%"))
+ si = {}
+ for n,v in s:
+ si[n] = v
+ sig[test]=si
+ if name is not None:
+ self.base.append((name,sig))
+ except:
+ self.base = None
+ warning("Can't read nmap database [%s](new nmap version ?)" % self.filename)
+ f.close()
+
+def TCPflags2str(f):
+ fl="FSRPAUEC"
+ s=""
+ for i in range(len(fl)):
+ if f & 1:
+ s = fl[i]+s
+ f >>= 1
+ return s
+
+def nmap_tcppacket_sig(pkt):
+ r = {}
+ if pkt is not None:
+# r["Resp"] = "Y"
+ r["DF"] = (pkt.flags & 2) and "Y" or "N"
+ r["W"] = "%X" % pkt.window
+ r["ACK"] = pkt.ack==2 and "S++" or pkt.ack==1 and "S" or "O"
+ r["Flags"] = TCPflags2str(pkt.payload.flags)
+ r["Ops"] = "".join(map(lambda x: x[0][0],pkt.payload.options))
+ else:
+ r["Resp"] = "N"
+ return r
+
+
+def nmap_udppacket_sig(S,T):
+ r={}
+ if T is None:
+ r["Resp"] = "N"
+ else:
+ r["DF"] = (T.flags & 2) and "Y" or "N"
+ r["TOS"] = "%X" % T.tos
+ r["IPLEN"] = "%X" % T.len
+ r["RIPTL"] = "%X" % T.payload.payload.len
+ r["RID"] = S.id == T.payload.payload.id and "E" or "F"
+ r["RIPCK"] = S.chksum == T.getlayer(IPerror).chksum and "E" or T.getlayer(IPerror).chksum == 0 and "0" or "F"
+ r["UCK"] = S.payload.chksum == T.getlayer(UDPerror).chksum and "E" or T.getlayer(UDPerror).chksum ==0 and "0" or "F"
+ r["ULEN"] = "%X" % T.getlayer(UDPerror).len
+ r["DAT"] = T.getlayer(Raw) is None and "E" or S.getlayer(Raw).load == T.getlayer(Raw).load and "E" or "F"
+ return r
+
+
+
+def nmap_match_one_sig(seen, ref):
+ c = 0
+ for k in seen.keys():
+ if ref.has_key(k):
+ if seen[k] in ref[k].split("|"):
+ c += 1
+ if c == 0 and seen.get("Resp") == "N":
+ return 0.7
+ else:
+ return 1.0*c/len(seen.keys())
+
+
+
+def nmap_sig(target, oport=80, cport=81, ucport=1):
+ res = {}
+
+ tcpopt = [ ("WScale", 10),
+ ("NOP",None),
+ ("MSS", 256),
+ ("Timestamp",(123,0)) ]
+ tests = [ IP(dst=target, id=1)/TCP(seq=1, sport=5001, dport=oport, options=tcpopt, flags="CS"),
+ IP(dst=target, id=1)/TCP(seq=1, sport=5002, dport=oport, options=tcpopt, flags=0),
+ IP(dst=target, id=1)/TCP(seq=1, sport=5003, dport=oport, options=tcpopt, flags="SFUP"),
+ IP(dst=target, id=1)/TCP(seq=1, sport=5004, dport=oport, options=tcpopt, flags="A"),
+ IP(dst=target, id=1)/TCP(seq=1, sport=5005, dport=cport, options=tcpopt, flags="S"),
+ IP(dst=target, id=1)/TCP(seq=1, sport=5006, dport=cport, options=tcpopt, flags="A"),
+ IP(dst=target, id=1)/TCP(seq=1, sport=5007, dport=cport, options=tcpopt, flags="FPU"),
+ IP(str(IP(dst=target)/UDP(sport=5008,dport=ucport)/(300*"i"))) ]
+
+ ans, unans = sr(tests, timeout=2)
+ ans += map(lambda x: (x,None), unans)
+
+ for S,T in ans:
+ if S.sport == 5008:
+ res["PU"] = nmap_udppacket_sig(S,T)
+ else:
+ t = "T%i" % (S.sport-5000)
+ if T is not None and T.haslayer(ICMP):
+ warning("Test %s answered by an ICMP" % t)
+ T=None
+ res[t] = nmap_tcppacket_sig(T)
+
+ return res
+
+def nmap_probes2sig(tests):
+ tests=tests.copy()
+ res = {}
+ if "PU" in tests:
+ res["PU"] = nmap_udppacket_sig(*tests["PU"])
+ del(tests["PU"])
+ for k in tests:
+ res[k] = nmap_tcppacket_sig(tests[k])
+ return res
+
+
+def nmap_search(sigs):
+ guess = 0,[]
+ for os,fp in nmap_kdb.get_base():
+ c = 0.0
+ for t in sigs.keys():
+ if t in fp:
+ c += nmap_match_one_sig(sigs[t], fp[t])
+ c /= len(sigs.keys())
+ if c > guess[0]:
+ guess = c,[ os ]
+ elif c == guess[0]:
+ guess[1].append(os)
+ return guess
+
+
+def nmap_fp(target, oport=80, cport=81):
+ """nmap fingerprinting
+nmap_fp(target, [oport=80,] [cport=81,]) -> list of best guesses with accuracy
+"""
+ sigs = nmap_sig(target, oport, cport)
+ return nmap_search(sigs)
+
+
+def nmap_sig2txt(sig):
+ torder = ["TSeq","T1","T2","T3","T4","T5","T6","T7","PU"]
+ korder = ["Class", "gcd", "SI", "IPID", "TS",
+ "Resp", "DF", "W", "ACK", "Flags", "Ops",
+ "TOS", "IPLEN", "RIPTL", "RID", "RIPCK", "UCK", "ULEN", "DAT" ]
+ txt=[]
+ for i in sig.keys():
+ if i not in torder:
+ torder.append(i)
+ for t in torder:
+ sl = sig.get(t)
+ if sl is None:
+ continue
+ s = []
+ for k in korder:
+ v = sl.get(k)
+ if v is None:
+ continue
+ s.append("%s=%s"%(k,v))
+ txt.append("%s(%s)" % (t, "%".join(s)))
+ return "\n".join(txt)
+
+
+
+
+
+###################
+## User commands ##
+###################
+
+
+def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
+ """Sniff packets
+sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
+
+ count: number of packets to capture. 0 means infinity
+ store: wether to store sniffed packets or discard them
+ prn: function to apply to each packet. If something is returned,
+ it is displayed. Ex:
+ ex: prn = lambda x: x.summary()
+lfilter: python function applied to each packet to determine
+ if further action may be done
+ ex: lfilter = lambda x: x.haslayer(Padding)
+offline: pcap file to read packets from, instead of sniffing them
+timeout: stop sniffing after a given time (default: None)
+L2socket: use the provided L2socket
+ """
+ c = 0
+
+ if offline is None:
+ if L2socket is None:
+ L2socket = conf.L2listen
+ s = L2socket(type=ETH_P_ALL, *arg, **karg)
+ else:
+ s = PcapReader(offline)
+
+ lst = []
+ if timeout is not None:
+ stoptime = time.time()+timeout
+ remain = None
+ while 1:
+ try:
+ if timeout is not None:
+ remain = stoptime-time.time()
+ if remain <= 0:
+ break
+ sel = select([s],[],[],remain)
+ if s in sel[0]:
+ p = s.recv(MTU)
+ if p is None:
+ break
+ if lfilter and not lfilter(p):
+ continue
+ if store:
+ lst.append(p)
+ c += 1
+ if prn:
+ r = prn(p)
+ if r is not None:
+ print r
+ if count > 0 and c >= count:
+ break
+ except KeyboardInterrupt:
+ break
+ return PacketList(lst,"Sniffed")
+
+
+
+def arpcachepoison(target, victim, interval=60):
+ """Poison target's cache with (your MAC,victim's IP) couple
+arpcachepoison(target, victim, [interval=60]) -> None
+"""
+ tmac = getmacbyip(target)
+ p = Ether(dst=tmac)/ARP(op="who-has", psrc=victim, pdst=target)
+ try:
+ while 1:
+ sendp(p, iface_hint=target)
+ if conf.verb > 1:
+ os.write(1,".")
+ time.sleep(interval)
+ except KeyboardInterrupt:
+ pass
+
+def traceroute(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), l4 = None, filter=None, timeout=2, verbose=None, **kargs):
+ """Instant TCP traceroute
+traceroute(target, [maxttl=30,] [dport=80,] [sport=80,] [verbose=conf.verb]) -> None
+"""
+ if verbose is None:
+ verbose = conf.verb
+ if filter is None:
+ filter="(icmp and icmp[0]=11) or (tcp and (tcp[13] & 0x16 > 0x10))"
+ if l4 is None:
+ a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport),
+ timeout=timeout, filter=filter, verbose=verbose, **kargs)
+ else:
+ a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/l4,
+ verbose=verbose, timeout=timeout, **kargs)
+
+ a = TracerouteResult(a.res)
+ if verbose:
+ a.show()
+ return a,b
+
+
+
+
+def arping(net, timeout=2, cache=0, verbose=None, **kargs):
+ """Send ARP who-has requests to determine which hosts are up
+arping(net, [cache=0,] [iface=conf.iface,] [verbose=conf.verb]) -> None
+Set cache=True if you want arping to modify internal ARP-Cache"""
+ if verbose is None:
+ verbose = conf.verb
+ ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=net), verbose=verbose,
+ filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
+ ans = ARPingResult(ans.res)
+
+ if cache and ans is not None:
+ for pair in ans:
+ arp_cache[pair[1].psrc] = (pair[1].hwsrc, time.time())
+ if verbose:
+ ans.show()
+ return ans,unans
+
+def dyndns_add(nameserver, name, rdata, type="A", ttl=10):
+ """Send a DNS add message to a nameserver for "name" to have a new "rdata"
+dyndns_add(nameserver, name, rdata, type="A", ttl=10) -> result code (0=ok)
+
+example: dyndns_add("ns1.toto.com", "dyn.toto.com", "127.0.0.1")
+RFC2136
+"""
+ zone = name[name.find(".")+1:]
+ r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
+ qd=[DNSQR(qname=zone, qtype="SOA")],
+ ns=[DNSRR(rrname=name, type="A",
+ ttl=ttl, rdata=rdata)]),
+ verbose=0, timeout=5)
+ if r and r.haslayer(DNS):
+ return r.getlayer(DNS).rcode
+ else:
+ return -1
+
+
+
+
+def dyndns_del(nameserver, name, type="ALL", ttl=10):
+ """Send a DNS delete message to a nameserver for "name"
+dyndns_del(nameserver, name, type="ANY", ttl=10) -> result code (0=ok)
+
+example: dyndns_del("ns1.toto.com", "dyn.toto.com")
+RFC2136
+"""
+ zone = name[name.find(".")+1:]
+ r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
+ qd=[DNSQR(qname=zone, qtype="SOA")],
+ ns=[DNSRR(rrname=name, type=type,
+ rclass="ANY", ttl=0, rdata="")]),
+ verbose=0, timeout=5)
+ if r and r.haslayer(DNS):
+ return r.getlayer(DNS).rcode
+ else:
+ return -1
+
+
+def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00",**kargs):
+ """Try to guess if target is in Promisc mode. The target is provided by its ip."""
+
+ responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip),type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0,**kargs)
+
+ return responses is not None
+
+def promiscping(net, timeout=2, fake_bcast="ff:ff:ff:ff:ff:fe", **kargs):
+ """Send ARP who-has requests to determine which hosts are in promiscuous mode
+ promiscping(net, iface=conf.iface)"""
+ ans,unans = srp(Ether(dst=fake_bcast)/ARP(pdst=net),
+ filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
+ ans = ARPingResult(ans.res, name="PROMISCPing")
+
+ ans.display()
+ return ans,unans
+
+def ikescan(ip):
+ return sr(IP(dst=ip)/UDP()/ISAKMP(init_cookie=RandString(8),
+ exch_type=2)/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()))
+
+
+def dhcp_request(iface=None,**kargs):
+ if conf.checkIPaddr != 0:
+ warning("conf.checkIPaddr is not 0, I may not be able to match the answer")
+ if iface is None:
+ iface = conf.iface
+ fam,hw = get_if_raw_hwaddr(iface)
+ return srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)
+ /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)
+
+def snmpwalk(dst, oid="1", community="public"):
+ try:
+ while 1:
+ r = sr1(IP(dst=dst)/UDP(sport=RandShort())/SNMP(community=community, PDU=SNMPnext(varbindlist=[SNMPvarbind(oid=oid)])),timeout=2, chainCC=1, verbose=0, retry=2)
+ if ICMP in r:
+ print repr(r)
+ break
+ if r is None:
+ print "No answers"
+ break
+ print "%-40s: %r" % (r[SNMPvarbind].oid.val,r[SNMPvarbind].value)
+ oid = r[SNMPvarbind].oid
+
+ except KeyboardInterrupt:
+ pass
+
+
+#####################
+## Reporting stuff ##
+#####################
+
+def report_ports(target, ports):
+ """portscan a target and output a LaTeX table
+report_ports(target, ports) -> string"""
+ ans,unans = sr(IP(dst=target)/TCP(dport=ports),timeout=5)
+ rep = "\\begin{tabular}{|r|l|l|}\n\\hline\n"
+ for s,r in ans:
+ if not r.haslayer(ICMP):
+ if r.payload.flags == 0x12:
+ rep += r.sprintf("%TCP.sport% & open & SA \\\\\n")
+ rep += "\\hline\n"
+ for s,r in ans:
+ if r.haslayer(ICMP):
+ rep += r.sprintf("%TCPerror.dport% & closed & ICMP type %ICMP.type%/%ICMP.code% from %IP.src% \\\\\n")
+ elif r.payload.flags != 0x12:
+ rep += r.sprintf("%TCP.sport% & closed & TCP %TCP.flags% \\\\\n")
+ rep += "\\hline\n"
+ for i in unans:
+ rep += i.sprintf("%TCP.dport% & ? & unanswered \\\\\n")
+ rep += "\\hline\n\\end{tabular}\n"
+ return rep
+
+
+def __make_table(yfmtfunc, fmtfunc, endline, list, fxyz, sortx=None, sorty=None, seplinefunc=None):
+ vx = {}
+ vy = {}
+ vz = {}
+ vxf = {}
+ vyf = {}
+ l = 0
+ for e in list:
+ xx,yy,zz = map(str, fxyz(e))
+ l = max(len(yy),l)
+ vx[xx] = max(vx.get(xx,0), len(xx), len(zz))
+ vy[yy] = None
+ vz[(xx,yy)] = zz
+
+ vxk = vx.keys()
+ vyk = vy.keys()
+ if sortx:
+ vxk.sort(sortx)
+ else:
+ try:
+ vxk.sort(lambda x,y:int(x)-int(y))
+ except:
+ try:
+ vxk.sort(lambda x,y: cmp(atol(x),atol(y)))
+ except:
+ vxk.sort()
+ if sorty:
+ vyk.sort(sorty)
+ else:
+ try:
+ vyk.sort(lambda x,y:int(x)-int(y))
+ except:
+ try:
+ vyk.sort(lambda x,y: cmp(atol(x),atol(y)))
+ except:
+ vyk.sort()
+
+
+ if seplinefunc:
+ sepline = seplinefunc(l, map(lambda x:vx[x],vxk))
+ print sepline
+
+ fmt = yfmtfunc(l)
+ print fmt % "",
+ for x in vxk:
+ vxf[x] = fmtfunc(vx[x])
+ print vxf[x] % x,
+ print endline
+ if seplinefunc:
+ print sepline
+ for y in vyk:
+ print fmt % y,
+ for x in vxk:
+ print vxf[x] % vz.get((x,y), "-"),
+ print endline
+ if seplinefunc:
+ print sepline
+
+def make_table(*args, **kargs):
+ __make_table(lambda l:"%%-%is" % l, lambda l:"%%-%is" % l, "", *args, **kargs)
+
+def make_lined_table(*args, **kargs):
+ __make_table(lambda l:"%%-%is |" % l, lambda l:"%%-%is |" % l, "",
+ seplinefunc=lambda a,x:"+".join(map(lambda y:"-"*(y+2), [a-1]+x+[-2])),
+ *args, **kargs)
+
+def make_tex_table(*args, **kargs):
+ __make_table(lambda l: "%s", lambda l: "& %s", "\\\\", seplinefunc=lambda a,x:"\\hline", *args, **kargs)
+
+
+######################
+## Online doc stuff ##
+######################
+
+
+def lsc(cmd=None):
+ """List user commands"""
+ if cmd is None:
+ for c in user_commands:
+ doc = "No doc. available"
+ if c.__doc__:
+ doc = c.__doc__.split("\n")[0]
+
+ print "%-16s : %s" % (c.__name__, doc)
+ else:
+ print cmd.__doc__
+
+def ls(obj=None):
+ """List available layers, or infos on a given layer"""
+ if obj is None:
+ import __builtin__
+ all = __builtin__.__dict__.copy()
+ all.update(globals())
+ objlst = filter(lambda (n,o): isinstance(o,type) and issubclass(o,Packet), all.items())
+ objlst.sort(lambda x,y:cmp(x[0],y[0]))
+ for n,o in objlst:
+ print "%-10s : %s" %(n,o.name)
+ else:
+ if isinstance(obj, type) and issubclass(obj, Packet):
+ for f in obj.fields_desc:
+ print "%-10s : %-20s = (%s)" % (f.name, f.__class__.__name__, repr(f.default))
+ elif isinstance(obj, Packet):
+ for f in obj.fields_desc:
+ print "%-10s : %-20s = %-15s (%s)" % (f.name, f.__class__.__name__, repr(getattr(obj,f.name)), repr(f.default))
+ if not isinstance(obj.payload, NoPayload):
+ print "--"
+ ls(obj.payload)
+
+
+ else:
+ print "Not a packet class. Type 'ls()' to list packet classes."
+
+
+
+
+
+user_commands = [ sr, sr1, srp, srp1, srloop, srploop, sniff, p0f, arpcachepoison, send, sendp, traceroute, arping, ls, lsc, queso, nmap_fp, report_ports, dyndns_add, dyndns_del, is_promisc, promiscping ]
+
+
+##############
+## Automata ##
+##############
+
+class ATMT:
+ STATE = "State"
+ ACTION = "Action"
+ CONDITION = "Condition"
+ RECV = "Receive condition"
+ TIMEOUT = "Timeout condition"
+
+ class NewStateRequested(Exception):
+ def __init__(self, state_func, automaton, *args, **kargs):
+ self.func = state_func
+ self.state = state_func.atmt_state
+ self.initial = state_func.atmt_initial
+ self.error = state_func.atmt_error
+ self.final = state_func.atmt_final
+ Exception.__init__(self, "Request state [%s]" % self.state)
+ self.automaton = automaton
+ self.args = args
+ self.kargs = kargs
+ self.action_parameters() # init action parameters
+ def action_parameters(self, *args, **kargs):
+ self.action_args = args
+ self.action_kargs = kargs
+ return self
+ def run(self):
+ return self.func(self.automaton, *self.args, **self.kargs)
+
+ @staticmethod
+ def state(initial=0,final=0,error=0):
+ def deco(f,initial=initial, final=final):
+ f.atmt_type = ATMT.STATE
+ f.atmt_state = f.func_name
+ f.atmt_initial = initial
+ f.atmt_final = final
+ f.atmt_error = error
+ def state_wrapper(self, *args, **kargs):
+ return ATMT.NewStateRequested(f, self, *args, **kargs)
+
+ state_wrapper.func_name = "%s_wrapper" % f.func_name
+ state_wrapper.atmt_type = ATMT.STATE
+ state_wrapper.atmt_state = f.func_name
+ state_wrapper.atmt_initial = initial
+ state_wrapper.atmt_final = final
+ state_wrapper.atmt_error = error
+ state_wrapper.atmt_origfunc = f
+ return state_wrapper
+ return deco
+ @staticmethod
+ def action(cond, prio=0):
+ def deco(f,cond=cond):
+ if not hasattr(f,"atmt_type"):
+ f.atmt_cond = {}
+ f.atmt_type = ATMT.ACTION
+ f.atmt_cond[cond.atmt_condname] = prio
+ return f
+ return deco
+ @staticmethod
+ def condition(state, prio=0):
+ def deco(f, state=state):
+ f.atmt_type = ATMT.CONDITION
+ f.atmt_state = state.atmt_state
+ f.atmt_condname = f.func_name
+ f.atmt_prio = prio
+ return f
+ return deco
+ @staticmethod
+ def receive_condition(state, prio=0):
+ def deco(f, state=state):
+ f.atmt_type = ATMT.RECV
+ f.atmt_state = state.atmt_state
+ f.atmt_condname = f.func_name
+ f.atmt_prio = prio
+ return f
+ return deco
+ @staticmethod
+ def timeout(state, timeout, name=None):
+ def deco(f, state=state, timeout=timeout,name=name):
+ f.atmt_type = ATMT.TIMEOUT
+ f.atmt_state = state.atmt_state
+ f.atmt_timeout = timeout
+ f.atmt_condname = f.func_name
+ return f
+ return deco
+
+
+class Automaton_metaclass(type):
+ def __new__(cls, name, bases, dct):
+ cls = super(Automaton_metaclass, cls).__new__(cls, name, bases, dct)
+ cls.states={}
+ cls.state = None
+ cls.recv_conditions={}
+ cls.conditions={}
+ cls.timeout={}
+ cls.actions={}
+ cls.initial_states=[]
+
+ members = {}
+ classes = [cls]
+ while classes:
+ c = classes.pop(0) # order is important to avoid breaking method overloading
+ classes += list(c.__bases__)
+ for k,v in c.__dict__.iteritems():
+ if k not in members:
+ members[k] = v
+
+ decorated = [v for v in members.itervalues()
+ if type(v) is types.FunctionType and hasattr(v, "atmt_type")]
+
+ for m in decorated:
+ if m.atmt_type == ATMT.STATE:
+ s = m.atmt_state
+ cls.states[s] = m
+ cls.recv_conditions[s]=[]
+ cls.conditions[s]=[]
+ cls.timeout[s]=[]
+ if m.atmt_initial:
+ cls.initial_states.append(m)
+ elif m.atmt_type in [ATMT.CONDITION, ATMT.RECV, ATMT.TIMEOUT]:
+ cls.actions[m.atmt_condname] = []
+
+ for m in decorated:
+ if m.atmt_type == ATMT.CONDITION:
+ cls.conditions[m.atmt_state].append(m)
+ elif m.atmt_type == ATMT.RECV:
+ cls.recv_conditions[m.atmt_state].append(m)
+ elif m.atmt_type == ATMT.TIMEOUT:
+ cls.timeout[m.atmt_state].append((m.atmt_timeout, m))
+ elif m.atmt_type == ATMT.ACTION:
+ for c in m.atmt_cond:
+ cls.actions[c].append(m)
+
+
+ for v in cls.timeout.itervalues():
+ v.sort(lambda (t1,f1),(t2,f2): cmp(t1,t2))
+ v.append((None, None))
+ for v in itertools.chain(cls.conditions.itervalues(),
+ cls.recv_conditions.itervalues()):
+ v.sort(lambda c1,c2: cmp(c1.atmt_prio,c2.atmt_prio))
+ for condname,actlst in cls.actions.iteritems():
+ actlst.sort(lambda c1,c2: cmp(c1.atmt_cond[condname], c2.atmt_cond[condname]))
+
+ return cls
+
+
+ def graph(self, **kargs):
+ s = 'digraph "%s" {\n' % self.__class__.__name__
+
+ se = "" # Keep initial nodes at the begining for better rendering
+ for st in self.states.itervalues():
+ if st.atmt_initial:
+ se = ('\t"%s" [ style=filled, fillcolor=blue, shape=box, root=true];\n' % st.atmt_state)+se
+ elif st.atmt_final:
+ se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state
+ elif st.atmt_error:
+ se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state
+ s += se
+
+ for st in self.states.values():
+ for n in st.atmt_origfunc.func_code.co_names+st.atmt_origfunc.func_code.co_consts:
+ if n in self.states:
+ s += '\t"%s" -> "%s" [ color=green ];\n' % (st.atmt_state,n)
+
+
+ for c,k,v in [("purple",k,v) for k,v in self.conditions.items()]+[("red",k,v) for k,v in self.recv_conditions.items()]:
+ for f in v:
+ for n in f.func_code.co_names+f.func_code.co_consts:
+ if n in self.states:
+ l = f.atmt_condname
+ for x in self.actions[f.atmt_condname]:
+ l += "\\l>[%s]" % x.func_name
+ s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % (k,n,l,c)
+ for k,v in self.timeout.iteritems():
+ for t,f in v:
+ if f is None:
+ continue
+ for n in f.func_code.co_names+f.func_code.co_consts:
+ if n in self.states:
+ l = "%s/%.1fs" % (f.atmt_condname,t)
+ for x in self.actions[f.atmt_condname]:
+ l += "\\l>[%s]" % x.func_name
+ s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % (k,n,l)
+ s += "}\n"
+ return do_graph(s, **kargs)
+
+
+
+class Automaton:
+ __metaclass__ = Automaton_metaclass
+
+ def __init__(self, *args, **kargs):
+ self.debug_level=0
+ self.init_args=args
+ self.init_kargs=kargs
+ self.parse_args(*args, **kargs)
+
+ def debug(self, lvl, msg):
+ if self.debug_level >= lvl:
+ log_interactive.debug(msg)
+
+
+
+
+ class ErrorState(Exception):
+ def __init__(self, msg, result=None):
+ Exception.__init__(self, msg)
+ self.result = result
+ class Stuck(ErrorState):
+ pass
+
+ def parse_args(self, debug=0, store=1, **kargs):
+ self.debug_level=debug
+ self.socket_kargs = kargs
+ self.store_packets = store
+
+
+ def master_filter(self, pkt):
+ return True
+
+ def run_condition(self, cond, *args, **kargs):
+ try:
+ cond(self,*args, **kargs)
+ except ATMT.NewStateRequested, state_req:
+ self.debug(2, "%s [%s] taken to state [%s]" % (cond.atmt_type, cond.atmt_condname, state_req.state))
+ if cond.atmt_type == ATMT.RECV:
+ self.packets.append(args[0])
+ for action in self.actions[cond.atmt_condname]:
+ self.debug(2, " + Running action [%s]" % action.func_name)
+ action(self, *state_req.action_args, **state_req.action_kargs)
+ raise
+ else:
+ self.debug(2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname))
+
+
+ def run(self, *args, **kargs):
+ # Update default parameters
+ a = args+self.init_args[len(args):]
+ k = self.init_kargs
+ k.update(kargs)
+ self.parse_args(*a,**k)
+
+ # Start the automaton
+ self.state=self.initial_states[0](self)
+ self.send_sock = conf.L3socket()
+ l = conf.L2listen(**self.socket_kargs)
+ self.packets = PacketList(name="session[%s]"%self.__class__.__name__)
+ while 1:
+ try:
+ self.debug(1, "## state=[%s]" % self.state.state)
+
+ # Entering a new state. First, call new state function
+ state_output = self.state.run()
+ if self.state.error:
+ raise self.ErrorState("Reached %s: [%r]" % (self.state.state, state_output), result=state_output)
+ if self.state.final:
+ return state_output
+
+ if state_output is None:
+ state_output = ()
+ elif type(state_output) is not list:
+ state_output = state_output,
+
+ # Then check immediate conditions
+ for cond in self.conditions[self.state.state]:
+ self.run_condition(cond, *state_output)
+
+ # If still there and no conditions left, we are stuck!
+ if ( len(self.recv_conditions[self.state.state]) == 0
+ and len(self.timeout[self.state.state]) == 1 ):
+ raise self.Stuck("stuck in [%s]" % self.state.state,result=state_output)
+
+ # Finally listen and pay attention to timeouts
+ expirations = iter(self.timeout[self.state.state])
+ next_timeout,timeout_func = expirations.next()
+ t0 = time.time()
+
+ while 1:
+ t = time.time()-t0
+ if next_timeout is None:
+ remain = None
+ else:
+ if next_timeout <= t:
+ self.run_condition(timeout_func, *state_output)
+ next_timeout,timeout_func = expirations.next()
+ remain = next_timeout-t
+
+ r,_,_ = select([l],[],[],remain)
+ if l in r:
+ pkt = l.recv(MTU)
+ if pkt is not None:
+ if self.master_filter(pkt):
+ self.debug(3, "RECVD: %s" % pkt.summary())
+ for rcvcond in self.recv_conditions[self.state.state]:
+ self.run_condition(rcvcond, pkt, *state_output)
+ else:
+ self.debug(4, "FILTR: %s" % pkt.summary())
+
+ except ATMT.NewStateRequested,state_req:
+ self.debug(2, "switching from [%s] to [%s]" % (self.state.state,state_req.state))
+ self.state = state_req
+ except KeyboardInterrupt:
+ self.debug(1,"Interrupted by user")
+ break
+
+ def my_send(self, pkt):
+ self.send_sock.send(pkt)
+
+ def send(self, pkt):
+ self.my_send(pkt)
+ self.debug(3,"SENT : %s" % pkt.summary())
+ self.packets.append(pkt.copy())
+
+
+
+
+
+
+class TFTP_read(Automaton):
+ def parse_args(self, filename, server, sport = None, port=69, **kargs):
+ Automaton.parse_args(self, **kargs)
+ self.filename = filename
+ self.server = server
+ self.port = port
+ self.sport = sport
+
+
+ def master_filter(self, pkt):
+ return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
+ and pkt[UDP].dport == self.my_tid
+ and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
+
+ # BEGIN
+ @ATMT.state(initial=1)
+ def BEGIN(self):
+ self.blocksize=512
+ self.my_tid = self.sport or RandShort()._fix()
+ bind_bottom_up(UDP, TFTP, dport=self.my_tid)
+ self.server_tid = None
+ self.res = ""
+
+ self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
+ self.last_packet = self.l3/TFTP_RRQ(filename=self.filename, mode="octet")
+ self.send(self.last_packet)
+ self.awaiting=1
+
+ raise self.WAITING()
+
+ # WAITING
+ @ATMT.state()
+ def WAITING(self):
+ pass
+
+
+ @ATMT.receive_condition(WAITING)
+ def receive_data(self, pkt):
+ if TFTP_DATA in pkt and pkt[TFTP_DATA].block == self.awaiting:
+ if self.server_tid is None:
+ self.server_tid = pkt[UDP].sport
+ self.l3[UDP].dport = self.server_tid
+ raise self.RECEIVING(pkt)
+
+ @ATMT.receive_condition(WAITING, prio=1)
+ def receive_error(self, pkt):
+ if TFTP_ERROR in pkt:
+ raise self.ERROR(pkt)
+
+
+ @ATMT.timeout(WAITING, 3)
+ def timeout_waiting(self):
+ raise self.WAITING()
+ @ATMT.action(timeout_waiting)
+ def retransmit_last_packet(self):
+ self.send(self.last_packet)
+
+ @ATMT.action(receive_data)
+# @ATMT.action(receive_error)
+ def send_ack(self):
+ self.last_packet = self.l3 / TFTP_ACK(block = self.awaiting)
+ self.send(self.last_packet)
+
+
+ # RECEIVED
+ @ATMT.state()
+ def RECEIVING(self, pkt):
+ recvd = pkt[Raw].load
+ self.res += recvd
+ self.awaiting += 1
+ if len(recvd) == self.blocksize:
+ raise self.WAITING()
+ raise self.END()
+
+ # ERROR
+ @ATMT.state(error=1)
+ def ERROR(self,pkt):
+ split_bottom_up(UDP, TFTP, dport=self.my_tid)
+ return pkt[TFTP_ERROR].summary()
+
+ #END
+ @ATMT.state(final=1)
+ def END(self):
+ split_bottom_up(UDP, TFTP, dport=self.my_tid)
+ return self.res
+
+
+
+
+class TFTP_write(Automaton):
+ def parse_args(self, filename, data, server, sport=None, port=69,**kargs):
+ Automaton.parse_args(self, **kargs)
+ self.filename = filename
+ self.server = server
+ self.port = port
+ self.sport = sport
+ self.blocksize = 512
+ self.origdata = data
+
+ def master_filter(self, pkt):
+ return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
+ and pkt[UDP].dport == self.my_tid
+ and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
+
+
+ # BEGIN
+ @ATMT.state(initial=1)
+ def BEGIN(self):
+ self.data = [ self.origdata[i*self.blocksize:(i+1)*self.blocksize]
+ for i in range( len(self.origdata)/self.blocksize+1) ]
+ self.my_tid = self.sport or RandShort()._fix()
+ bind_bottom_up(UDP, TFTP, dport=self.my_tid)
+ self.server_tid = None
+
+ self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
+ self.last_packet = self.l3/TFTP_WRQ(filename=self.filename, mode="octet")
+ self.send(self.last_packet)
+ self.res = ""
+ self.awaiting=0
+
+ raise self.WAITING_ACK()
+
+ # WAITING_ACK
+ @ATMT.state()
+ def WAITING_ACK(self):
+ pass
+
+ @ATMT.receive_condition(WAITING_ACK)
+ def received_ack(self,pkt):
+ if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.awaiting:
+ if self.server_tid is None:
+ self.server_tid = pkt[UDP].sport
+ self.l3[UDP].dport = self.server_tid
+ raise self.SEND_DATA()
+
+ @ATMT.receive_condition(WAITING_ACK)
+ def received_error(self, pkt):
+ if TFTP_ERROR in pkt:
+ raise self.ERROR(pkt)
+
+ @ATMT.timeout(WAITING_ACK, 3)
+ def timeout_waiting(self):
+ raise self.WAITING_ACK()
+ @ATMT.action(timeout_waiting)
+ def retransmit_last_packet(self):
+ self.send(self.last_packet)
+
+ # SEND_DATA
+ @ATMT.state()
+ def SEND_DATA(self):
+ self.awaiting += 1
+ self.last_packet = self.l3/TFTP_DATA(block=self.awaiting)/self.data.pop(0)
+ self.send(self.last_packet)
+ if self.data:
+ raise self.WAITING_ACK()
+ raise self.END()
+
+
+ # ERROR
+ @ATMT.state(error=1)
+ def ERROR(self,pkt):
+ split_bottom_up(UDP, TFTP, dport=self.my_tid)
+ return pkt[TFTP_ERROR].summary()
+
+ # END
+ @ATMT.state(final=1)
+ def END(self):
+ split_bottom_up(UDP, TFTP, dport=self.my_tid)
+
+
+class TFTP_WRQ_server(Automaton):
+
+ def parse_args(self, ip=None, sport=None, *args, **kargs):
+ Automaton.parse_args(self, *args, **kargs)
+ self.ip = ip
+ self.sport = sport
+
+ def master_filter(self, pkt):
+ return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)
+
+ @ATMT.state(initial=1)
+ def BEGIN(self):
+ self.blksize=512
+ self.blk=0
+ self.filedata=""
+ self.my_tid = self.sport or random.randint(10000,65500)
+ bind_bottom_up(UDP, TFTP, dport=self.my_tid)
+
+ @ATMT.receive_condition(BEGIN)
+ def receive_WRQ(self,pkt):
+ if TFTP_WRQ in pkt:
+ raise self.WAIT_DATA().action_parameters(pkt)
+
+ @ATMT.action(receive_WRQ)
+ def ack_WRQ(self, pkt):
+ ip = pkt[IP]
+ self.ip = ip.dst
+ self.dst = ip.src
+ self.filename = pkt[TFTP_WRQ].filename
+ options = pkt[TFTP_Options]
+ self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=pkt.sport)/TFTP()
+ if options is None:
+ self.last_packet = self.l3/TFTP_ACK(block=0)
+ self.send(self.last_packet)
+ else:
+ opt = [x for x in options.options if x.oname == "BLKSIZE"]
+ if opt:
+ self.blksize = int(opt[0].value)
+ self.debug(2,"Negotiated new blksize at %i" % self.blksize)
+ self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
+ self.send(self.last_packet)
+
+ @ATMT.state()
+ def WAIT_DATA(self):
+ self.blk += 1
+
+ @ATMT.receive_condition(WAIT_DATA)
+ def receive_data(self, pkt):
+ if TFTP_DATA in pkt:
+ data = pkt[TFTP_DATA]
+ if data.block == self.blk:
+ raise self.DATA(data)
+
+ @ATMT.action(receive_data)
+ def ack_data(self):
+ self.last_packet = self.l3/TFTP_ACK(block = self.blk)
+ self.send(self.last_packet)
+
+ @ATMT.state()
+ def DATA(self, data):
+ self.filedata += data.load
+ if len(data.load) < self.blksize:
+ raise self.END()
+ raise self.WAIT_DATA()
+
+ @ATMT.state(final=1)
+ def END(self):
+ return self.filename,self.filedata
+ split_bottom_up(UDP, TFTP, dport=self.my_tid)
+
+
+
+########################
+## Answering machines ##
+########################
+
+class ReferenceAM(type):
+ def __new__(cls, name, bases, dct):
+ o = super(ReferenceAM, cls).__new__(cls, name, bases, dct)
+ if o.function_name:
+ globals()[o.function_name] = lambda o=o,*args,**kargs: o(*args,**kargs)()
+ return o
+
+
+class AnsweringMachine(object):
+ __metaclass__ = ReferenceAM
+ function_name = ""
+ filter = None
+ sniff_options = { "store":0 }
+ sniff_options_list = [ "store", "iface", "count", "promisc", "filter", "type", "prn" ]
+ send_options = { "verbose":0 }
+ send_options_list = ["iface", "inter", "loop", "verbose"]
+ send_function = staticmethod(send)
+
+
+ def __init__(self, **kargs):
+ self.mode = 0
+ if self.filter:
+ kargs.setdefault("filter",self.filter)
+ kargs.setdefault("prn", self.reply)
+ self.optam1 = {}
+ self.optam2 = {}
+ self.optam0 = {}
+ doptsend,doptsniff = self.parse_all_options(1, kargs)
+ self.defoptsend = self.send_options.copy()
+ self.defoptsend.update(doptsend)
+ self.defoptsniff = self.sniff_options.copy()
+ self.defoptsniff.update(doptsniff)
+ self.optsend,self.optsniff = [{},{}]
+
+ def __getattr__(self, attr):
+ for d in [self.optam2, self.optam1]:
+ if attr in d:
+ return d[attr]
+ raise AttributeError,attr
+
+ def __setattr__(self, attr, val):
+ mode = self.__dict__.get("mode",0)
+ if mode == 0:
+ self.__dict__[attr] = val
+ else:
+ [self.optam1, self.optam2][mode-1][attr] = val
+
+ def parse_options(self):
+ pass
+
+ def parse_all_options(self, mode, kargs):
+ sniffopt = {}
+ sendopt = {}
+ for k in kargs.keys():
+ if k in self.sniff_options_list:
+ sniffopt[k] = kargs[k]
+ if k in self.send_options_list:
+ sendopt[k] = kargs[k]
+ if k in self.sniff_options_list+self.send_options_list:
+ del(kargs[k])
+ if mode != 2 or kargs:
+ if mode == 1:
+ self.optam0 = kargs
+ elif mode == 2 and kargs:
+ k = self.optam0.copy()
+ k.update(kargs)
+ self.parse_options(**k)
+ kargs = k
+ omode = self.__dict__.get("mode",0)
+ self.__dict__["mode"] = mode
+ self.parse_options(**kargs)
+ self.__dict__["mode"] = omode
+ return sendopt,sniffopt
+
+ def is_request(self, req):
+ return 1
+
+ def make_reply(self, req):
+ return req
+
+ def send_reply(self, reply):
+ self.send_function(reply, **self.optsend)
+
+ def print_reply(self, req, reply):
+ print "%s ==> %s" % (req.summary(),reply.summary())
+
+ def reply(self, pkt):
+ if not self.is_request(pkt):
+ return
+ reply = self.make_reply(pkt)
+ self.send_reply(reply)
+ if conf.verb >= 0:
+ self.print_reply(pkt, reply)
+
+ def run(self, *args, **kargs):
+ log_interactive.warning("run() method deprecated. The intance is now callable")
+ self(*args,**kargs)
+
+ def __call__(self, *args, **kargs):
+ optsend,optsniff = self.parse_all_options(2,kargs)
+ self.optsend=self.defoptsend.copy()
+ self.optsend.update(optsend)
+ self.optsniff=self.defoptsniff.copy()
+ self.optsniff.update(optsniff)
+
+ try:
+ self.sniff()
+ except KeyboardInterrupt:
+ print "Interrupted by user"
+
+ def sniff(self):
+ sniff(**self.optsniff)
+
+
+class BOOTP_am(AnsweringMachine):
+ function_name = "bootpd"
+ filter = "udp and port 68 and port 67"
+ send_function = staticmethod(sendp)
+ def parse_options(self, pool=Net("192.168.1.128/25"), network="192.168.1.0/24",gw="192.168.1.1",
+ renewal_time=60, lease_time=1800):
+ if type(pool) is str:
+ poom = Net(pool)
+ netw,msk = (network.split("/")+["32"])[:2]
+ msk = itom(int(msk))
+ self.netmask = ltoa(msk)
+ self.network = ltoa(atol(netw)&msk)
+ self.broadcast = ltoa( atol(self.network) | (0xffffffff&~msk) )
+ self.gw = gw
+ if isinstance(pool,Gen):
+ pool = [k for k in pool if k not in [gw, self.network, self.broadcast]]
+ pool.reverse()
+ if len(pool) == 1:
+ pool, = pool
+ self.pool = pool
+ self.lease_time = lease_time
+ self.renewal_time = renewal_time
+ self.leases = {}
+
+ def is_request(self, req):
+ if not req.haslayer(BOOTP):
+ return 0
+ reqb = req.getlayer(BOOTP)
+ if reqb.op != 1:
+ return 0
+ return 1
+
+ def print_reply(self, req, reply):
+ print "Reply %s to %s" % (reply.getlayer(IP).dst,reply.dst)
+
+ def make_reply(self, req):
+ mac = req.src
+ if type(self.pool) is list:
+ if not self.leases.has_key(mac):
+ self.leases[mac] = self.pool.pop()
+ ip = self.leases[mac]
+ else:
+ ip = self.pool
+
+ repb = req.getlayer(BOOTP).copy()
+ repb.op="BOOTREPLY"
+ repb.yiaddr = ip
+ repb.siaddr = self.gw
+ repb.ciaddr = self.gw
+ repb.giaddr = self.gw
+ del(repb.payload)
+ rep=Ether(dst=mac)/IP(dst=ip)/UDP(sport=req.dport,dport=req.sport)/repb
+ return rep
+
+
+class DHCP_am(BOOTP_am):
+ function_name="dhcpd"
+ def make_reply(self, req):
+ resp = BOOTP_am.make_reply(self, req)
+ if DHCP in req:
+ dhcp_options = [(op[0],{1:2,3:5}.get(op[1],op[1]))
+ for op in req[DHCP].options
+ if type(op) is tuple and op[0] == "message-type"]
+ dhcp_options += [("router", self.gw),
+ ("name_server", self.gw),
+ ("broadcast_address", self.broadcast),
+ ("subnet_mask", self.netmask),
+ ("renewal_time", self.renewal_time),
+ ("lease_time", self.lease_time),
+ ]
+ resp /= DHCP(options=dhcp_options)
+ return resp
+
+
+
+class DNS_am(AnsweringMachine):
+ function_name="dns_spoof"
+ filter = "udp port 53"
+
+ def parse_options(self, joker="192.168.1.1", match=None):
+ if match is None:
+ self.match = {}
+ else:
+ self.match = match
+ self.joker=joker
+
+ def is_request(self, req):
+ return req.haslayer(DNS) and req.getlayer(DNS).qr == 0
+
+ def make_reply(self, req):
+ ip = req.getlayer(IP)
+ dns = req.getlayer(DNS)
+ resp = IP(dst=ip.src, src=ip.dst)/UDP(dport=ip.sport,sport=ip.dport)
+ rdata = self.match.get(dns.qd.qname, self.joker)
+ resp /= DNS(id=dns.id, qr=1, qd=dns.qd,
+ an=DNSRR(rrname=dns.qd.qname, ttl=10, rdata=rdata))
+ return resp
+
+
+class WiFi_am(AnsweringMachine):
+ """Before using this, initialize "iffrom" and "ifto" interfaces:
+iwconfig iffrom mode monitor
+iwpriv orig_ifto hostapd 1
+ifconfig ifto up
+note: if ifto=wlan0ap then orig_ifto=wlan0
+note: ifto and iffrom must be set on the same channel
+ex:
+ifconfig eth1 up
+iwconfig eth1 mode monitor
+iwconfig eth1 channel 11
+iwpriv wlan0 hostapd 1
+ifconfig wlan0ap up
+iwconfig wlan0 channel 11
+iwconfig wlan0 essid dontexist
+iwconfig wlan0 mode managed
+"""
+ function_name = "airpwn"
+ filter = None
+
+ def parse_options(iffrom, ifto, replace, pattern="", ignorepattern=""):
+ self.iffrom = iffrom
+ self.ifto = ifto
+ ptrn = re.compile(pattern)
+ iptrn = re.compile(ignorepattern)
+
+ def is_request(self, pkt):
+ if not isinstance(pkt,Dot11):
+ return 0
+ if not pkt.FCfield & 1:
+ return 0
+ if not pkt.haslayer(TCP):
+ return 0
+ ip = pkt.getlayer(IP)
+ tcp = pkt.getlayer(TCP)
+ pay = str(tcp.payload)
+ if not self.ptrn.match(pay):
+ return 0
+ if self.iptrn.match(pay):
+ return 0
+
+ def make_reply(self, p):
+ ip = p.getlayer(IP)
+ tcp = p.getlayer(TCP)
+ pay = str(tcp.payload)
+ del(p.payload.payload.payload)
+ p.FCfield="from-DS"
+ p.addr1,p.addr2 = p.addr2,p.addr1
+ p /= IP(src=ip.dst,dst=ip.src)
+ p /= TCP(sport=tcp.dport, dport=tcp.sport,
+ seq=tcp.ack, ack=tcp.seq+len(pay),
+ flags="PA")
+ q = p.copy()
+ p /= self.replace
+ q.ID += 1
+ q.getlayer(TCP).flags="RA"
+ q.getlayer(TCP).seq+=len(replace)
+ return [p,q]
+
+ def print_reply(self):
+ print p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")
+
+ def send_reply(self, reply):
+ sendp(reply, iface=self.ifto, **self.optsend)
+
+ def sniff(self):
+ sniff(iface=self.iffrom, **self.optsniff)
+
+
+
+class ARP_am(AnsweringMachine):
+ function_name="farpd"
+ filter = "arp"
+ send_function = staticmethod(sendp)
+
+ def parse_options(self, IP_addr=None, iface=None, ARP_addr=None):
+ self.IP_addr=IP_addr
+ self.iface=iface
+ self.ARP_addr=ARP_addr
+
+ def is_request(self, req):
+ return (req.haslayer(ARP) and
+ req.getlayer(ARP).op == 1 and
+ (self.IP_addr == None or self.IP_addr == req.getlayer(ARP).pdst))
+
+ def make_reply(self, req):
+ ether = req.getlayer(Ether)
+ arp = req.getlayer(ARP)
+ iff,a,gw = conf.route.route(arp.psrc)
+ if self.iface != None:
+ iff = iface
+ ARP_addr = self.ARP_addr
+ IP_addr = arp.pdst
+ resp = Ether(dst=ether.src,
+ src=ARP_addr)/ARP(op="is-at",
+ hwsrc=ARP_addr,
+ psrc=IP_addr,
+ hwdst=arp.hwsrc,
+ pdst=arp.pdst)
+ return resp
+
+ def sniff(self):
+ sniff(iface=self.iface, **self.optsniff)
+
+
+#############
+## Fuzzing ##
+#############
+
+
+def fuzz(p, _inplace=0):
+ if not _inplace:
+ p = p.copy()
+ q = p
+ while not isinstance(q, NoPayload):
+ for f in q.fields_desc:
+ if isinstance(f, PacketListField):
+ for r in getattr(q, f.name):
+ print "fuzzing", repr(r)
+ fuzz(r, _inplace=1)
+ elif f.default is not None:
+ rnd = f.randval()
+ if rnd is not None:
+ q.default_fields[f.name] = rnd
+ q = q.payload
+ return p
+
+
+
+
+###################
+## Testing stuff ##
+###################
+
+
+
+def merge(x,y):
+ if len(x) > len(y):
+ y += "\x00"*(len(x)-len(y))
+ elif len(x) < len(y):
+ x += "\x00"*(len(y)-len(x))
+ m = ""
+ for i in range(len(x)/ss):
+ m += x[ss*i:ss*(i+1)]+y[ss*i:ss*(i+1)]
+ return m
+# return "".join(map(str.__add__, x, y))
+
+
+def voip_play(s1,list=None,**kargs):
+ FIFO="/tmp/conv1.%i.%%i" % os.getpid()
+ FIFO1=FIFO % 1
+ FIFO2=FIFO % 2
+
+ os.mkfifo(FIFO1)
+ os.mkfifo(FIFO2)
+ try:
+ os.system("soxmix -t .ul %s -t .ul %s -t ossdsp /dev/dsp &" % (FIFO1,FIFO2))
+
+ c1=open(FIFO1,"w", 4096)
+ c2=open(FIFO2,"w", 4096)
+ fcntl.fcntl(c1.fileno(),fcntl.F_SETFL, os.O_NONBLOCK)
+ fcntl.fcntl(c2.fileno(),fcntl.F_SETFL, os.O_NONBLOCK)
+
+ # dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp")
+ def play(pkt,last=[]):
+ if not pkt:
+ return
+ if not pkt.haslayer(UDP):
+ return
+ ip=pkt.getlayer(IP)
+ if s1 in [ip.src, ip.dst]:
+ if not last:
+ last.append(pkt)
+ return
+ load=last.pop()
+ # x1 = load.load[12:]
+ c1.write(load.load[12:])
+ if load.getlayer(IP).src == ip.src:
+ # x2 = ""
+ c2.write("\x00"*len(load.load[12:]))
+ last.append(pkt)
+ else:
+ # x2 = pkt.load[:12]
+ c2.write(pkt.load[12:])
+ # dsp.write(merge(x1,x2))
+
+ if list is None:
+ sniff(store=0, prn=play, **kargs)
+ else:
+ for p in list:
+ play(p)
+ finally:
+ os.unlink(FIFO1)
+ os.unlink(FIFO2)
+
+
+
+def voip_play1(s1,list=None,**kargs):
+
+
+ dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp")
+ def play(pkt):
+ if not pkt:
+ return
+ if not pkt.haslayer(UDP):
+ return
+ ip=pkt.getlayer(IP)
+ if s1 in [ip.src, ip.dst]:
+ dsp.write(pkt.getlayer(Raw).load[12:])
+ try:
+ if list is None:
+ sniff(store=0, prn=play, **kargs)
+ else:
+ for p in list:
+ play(p)
+ finally:
+ dsp.close()
+ rd.close()
+
+def voip_play2(s1,**kargs):
+ dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp")
+ def play(pkt,last=[]):
+ if not pkt:
+ return
+ if not pkt.haslayer(UDP):
+ return
+ ip=pkt.getlayer(IP)
+ if s1 in [ip.src, ip.dst]:
+ if not last:
+ last.append(pkt)
+ return
+ load=last.pop()
+ x1 = load.load[12:]
+# c1.write(load.load[12:])
+ if load.getlayer(IP).src == ip.src:
+ x2 = ""
+# c2.write("\x00"*len(load.load[12:]))
+ last.append(pkt)
+ else:
+ x2 = pkt.load[:12]
+# c2.write(pkt.load[12:])
+ dsp.write(merge(x1,x2))
+
+ sniff(store=0, prn=play, **kargs)
+
+def voip_play3(lst=None,**kargs):
+ dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp")
+ try:
+ def play(pkt, dsp=dsp):
+ if pkt and pkt.haslayer(UDP) and pkt.haslayer(Raw):
+ dsp.write(pkt.getlayer(RTP).load)
+ if lst is None:
+ sniff(store=0, prn=play, **kargs)
+ else:
+ for p in lst:
+ play(p)
+ finally:
+ try:
+ dsp.close()
+ rd.close()
+ except:
+ pass
+
+
+def IPID_count(lst, funcID=lambda x:x[1].id, funcpres=lambda x:x[1].summary()):
+ idlst = map(funcID, lst)
+ idlst.sort()
+ classes = [idlst[0]]+map(lambda x:x[1],filter(lambda (x,y): abs(x-y)>50, map(lambda x,y: (x,y),idlst[:-1], idlst[1:])))
+ lst = map(lambda x:(funcID(x), funcpres(x)), lst)
+ lst.sort()
+ print "Probably %i classes:" % len(classes), classes
+ for id,pr in lst:
+ print "%5i" % id, pr
+
+
+
+
+
+last=None
+
+
+def tethereal(*args,**kargs):
+ sniff(prn=lambda x: x.display(),*args,**kargs)
+
+def etherleak(target, **kargs):
+ return srpflood(Ether()/ARP(pdst=target), prn=lambda (s,r): Padding in r and hexstr(r[Padding].load),
+ filter="arp", **kargs)
+
+
+def fragleak(target,sport=123, dport=123, timeout=0.2, onlyasc=0):
+ load = "XXXXYYYYYYYYYY"
+# getmacbyip(target)
+# pkt = IP(dst=target, id=RandShort(), options="\x22"*40)/UDP()/load
+ pkt = IP(dst=target, id=RandShort(), options="\x00"*40, flags=1)/UDP(sport=sport, dport=sport)/load
+ s=conf.L3socket()
+ intr=0
+ found={}
+ try:
+ while 1:
+ try:
+ if not intr:
+ s.send(pkt)
+ sin,sout,serr = select([s],[],[],timeout)
+ if not sin:
+ continue
+ ans=s.recv(1600)
+ if not isinstance(ans, IP): #TODO: IPv6
+ continue
+ if not isinstance(ans.payload, ICMP):
+ continue
+ if not isinstance(ans.payload.payload, IPerror):
+ continue
+ if ans.payload.payload.dst != target:
+ continue
+ if ans.src != target:
+ print "leak from", ans.src,
+
+
+# print repr(ans)
+ if not ans.haslayer(Padding):
+ continue
+
+
+# print repr(ans.payload.payload.payload.payload)
+
+# if not isinstance(ans.payload.payload.payload.payload, Raw):
+# continue
+# leak = ans.payload.payload.payload.payload.load[len(load):]
+ leak = ans.getlayer(Padding).load
+ if leak not in found:
+ found[leak]=None
+ linehexdump(leak, onlyasc=onlyasc)
+ except KeyboardInterrupt:
+ if intr:
+ raise
+ intr=1
+ except KeyboardInterrupt:
+ pass
+
+def fragleak2(target, timeout=0.4, onlyasc=0):
+ found={}
+ try:
+ while 1:
+ p = sr1(IP(dst=target, options="\x00"*40, proto=200)/"XXXXYYYYYYYYYYYY",timeout=timeout,verbose=0)
+ if not p:
+ continue
+ if Padding in p:
+ leak = p[Padding].load
+ if leak not in found:
+ found[leak]=None
+ linehexdump(leak,onlyasc=onlyasc)
+ except:
+ pass
+
+
+
+plst=[]
+def get_toDS():
+ global plst
+ while 1:
+ p,=sniff(iface="eth1",count=1)
+ if not isinstance(p,Dot11):
+ continue
+ if p.FCfield & 1:
+ plst.append(p)
+ print "."
+
+
+# if not ifto.endswith("ap"):
+# print "iwpriv %s hostapd 1" % ifto
+# os.system("iwpriv %s hostapd 1" % ifto)
+# ifto += "ap"
+#
+# os.system("iwconfig %s mode monitor" % iffrom)
+#
+
+def airpwn(iffrom, ifto, replace, pattern="", ignorepattern=""):
+ """Before using this, initialize "iffrom" and "ifto" interfaces:
+iwconfig iffrom mode monitor
+iwpriv orig_ifto hostapd 1
+ifconfig ifto up
+note: if ifto=wlan0ap then orig_ifto=wlan0
+note: ifto and iffrom must be set on the same channel
+ex:
+ifconfig eth1 up
+iwconfig eth1 mode monitor
+iwconfig eth1 channel 11
+iwpriv wlan0 hostapd 1
+ifconfig wlan0ap up
+iwconfig wlan0 channel 11
+iwconfig wlan0 essid dontexist
+iwconfig wlan0 mode managed
+"""
+
+ ptrn = re.compile(pattern)
+ iptrn = re.compile(ignorepattern)
+ def do_airpwn(p, ifto=ifto, replace=replace, ptrn=ptrn, iptrn=iptrn):
+ if not isinstance(p,Dot11):
+ return
+ if not p.FCfield & 1:
+ return
+ if not p.haslayer(TCP):
+ return
+ ip = p.getlayer(IP)
+ tcp = p.getlayer(TCP)
+ pay = str(tcp.payload)
+# print "got tcp"
+ if not ptrn.match(pay):
+ return
+# print "match 1"
+ if iptrn.match(pay):
+ return
+# print "match 2"
+ del(p.payload.payload.payload)
+ p.FCfield="from-DS"
+ p.addr1,p.addr2 = p.addr2,p.addr1
+ q = p.copy()
+ p /= IP(src=ip.dst,dst=ip.src)
+ p /= TCP(sport=tcp.dport, dport=tcp.sport,
+ seq=tcp.ack, ack=tcp.seq+len(pay),
+ flags="PA")
+ q = p.copy()
+ p /= replace
+ q.ID += 1
+ q.getlayer(TCP).flags="RA"
+ q.getlayer(TCP).seq+=len(replace)
+
+ sendp([p,q], iface=ifto, verbose=0)
+# print "send",repr(p)
+# print "send",repr(q)
+ print p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")
+
+ sniff(iface=iffrom,prn=do_airpwn)
+
+
+
+
+##################
+## Color themes ##
+##################
+
+class Color:
+ normal = "\033[0m"
+ black = "\033[30m"
+ red = "\033[31m"
+ green = "\033[32m"
+ yellow = "\033[33m"
+ blue = "\033[34m"
+ purple = "\033[35m"
+ cyan = "\033[36m"
+ grey = "\033[37m"
+
+ bold = "\033[1m"
+ uline = "\033[4m"
+ blink = "\033[5m"
+ invert = "\033[7m"
+
+
+class ColorTheme:
+ def __repr__(self):
+ return "<%s>" % self.__class__.__name__
+ def __getattr__(self, attr):
+ return lambda x:x
+
+
+class NoTheme(ColorTheme):
+ pass
+
+
+class AnsiColorTheme(ColorTheme):
+ def __getattr__(self, attr):
+ if attr.startswith("__"):
+ raise AttributeError(attr)
+ s = "style_%s" % attr
+ if s in self.__class__.__dict__:
+ before = getattr(self, s)
+ after = self.style_normal
+ else:
+ before = after = ""
+
+ def do_style(val, fmt=None, before=before, after=after):
+ if fmt is None:
+ if type(val) is not str:
+ val = str(val)
+ else:
+ val = fmt % val
+ return before+val+after
+ return do_style
+
+
+ style_normal = ""
+ style_prompt = ""
+ style_punct = ""
+ style_id = ""
+ style_not_printable = ""
+ style_layer_name = ""
+ style_field_name = ""
+ style_field_value = ""
+ style_emph_field_name = ""
+ style_emph_field_value = ""
+ style_packetlist_name = ""
+ style_packetlist_proto = ""
+ style_packetlist_value = ""
+ style_fail = ""
+ style_success = ""
+ style_odd = ""
+ style_even = ""
+ style_opening = ""
+ style_active = ""
+ style_closed = ""
+ style_left = ""
+ style_right = ""
+
+class BlackAndWhite(AnsiColorTheme):
+ pass
+
+class DefaultTheme(AnsiColorTheme):
+ style_normal = Color.normal
+ style_prompt = Color.blue+Color.bold
+ style_punct = Color.normal
+ style_id = Color.blue+Color.bold
+ style_not_printable = Color.grey
+ style_layer_name = Color.red+Color.bold
+ style_field_name = Color.blue
+ style_field_value = Color.purple
+ style_emph_field_name = Color.blue+Color.uline+Color.bold
+ style_emph_field_value = Color.purple+Color.uline+Color.bold
+ style_packetlist_name = Color.red+Color.bold
+ style_packetlist_proto = Color.blue
+ style_packetlist_value = Color.purple
+ style_fail = Color.red+Color.bold
+ style_success = Color.blue+Color.bold
+ style_even = Color.black+Color.bold
+ style_odd = Color.black
+ style_opening = Color.yellow
+ style_active = Color.black
+ style_closed = Color.grey
+ style_left = Color.blue+Color.invert
+ style_right = Color.red+Color.invert
+
+class BrightTheme(AnsiColorTheme):
+ style_normal = Color.normal
+ style_punct = Color.normal
+ style_id = Color.yellow+Color.bold
+ style_layer_name = Color.red+Color.bold
+ style_field_name = Color.yellow+Color.bold
+ style_field_value = Color.purple+Color.bold
+ style_emph_field_name = Color.yellow+Color.bold
+ style_emph_field_value = Color.green+Color.bold
+ style_packetlist_name = Color.red+Color.bold
+ style_packetlist_proto = Color.yellow+Color.bold
+ style_packetlist_value = Color.purple+Color.bold
+ style_fail = Color.red+Color.bold
+ style_success = Color.blue+Color.bold
+ style_even = Color.black+Color.bold
+ style_odd = Color.black
+ style_left = Color.cyan+Color.invert
+ style_right = Color.purple+Color.invert
+
+
+class RastaTheme(AnsiColorTheme):
+ style_normal = Color.normal+Color.green+Color.bold
+ style_prompt = Color.yellow+Color.bold
+ style_punct = Color.red
+ style_id = Color.green+Color.bold
+ style_not_printable = Color.green
+ style_layer_name = Color.red+Color.bold
+ style_field_name = Color.yellow+Color.bold
+ style_field_value = Color.green+Color.bold
+ style_emph_field_name = Color.green
+ style_emph_field_value = Color.green
+ style_packetlist_name = Color.red+Color.bold
+ style_packetlist_proto = Color.yellow+Color.bold
+ style_packetlist_value = Color.green+Color.bold
+ style_fail = Color.red
+ style_success = Color.red+Color.bold
+ style_even = Color.yellow
+ style_odd = Color.green
+ style_left = Color.yellow+Color.invert
+ style_right = Color.red+Color.invert
+
+
+class FormatTheme(ColorTheme):
+ def __getattr__(self, attr):
+ if attr.startswith("__"):
+ raise AttributeError(attr)
+ col = self.__class__.__dict__.get("style_%s" % attr, "%s")
+ def do_style(val, fmt=None, col=col):
+ if fmt is None:
+ if type(val) is not str:
+ val = str(val)
+ else:
+ val = fmt % val
+ return col % val
+ return do_style
+
+
+class LatexTheme(FormatTheme):
+ style_prompt = r"\textcolor{blue}{%s}"
+ style_not_printable = r"\textcolor{gray}{%s}"
+ style_layer_name = r"\textcolor{red}{\bf %s}"
+ style_field_name = r"\textcolor{blue}{%s}"
+ style_field_value = r"\textcolor{purple}{%s}"
+ style_emph_field_name = r"\textcolor{blue}{\underline{%s}}" #ul
+ style_emph_field_value = r"\textcolor{purple}{\underline{%s}}" #ul
+ style_packetlist_name = r"\textcolor{red}{\bf %s}"
+ style_packetlist_proto = r"\textcolor{blue}{%s}"
+ style_packetlist_value = r"\textcolor{purple}{%s}"
+ style_fail = r"\textcolor{red}{\bf %s}"
+ style_success = r"\textcolor{blue}{\bf %s}"
+ style_left = r"\textcolor{blue}{%s}"
+ style_right = r"\textcolor{red}{%s}"
+# style_even = r"}{\bf "
+# style_odd = ""
+
+class LatexTheme2(FormatTheme):
+ style_prompt = r"@`@textcolor@[@blue@]@@[@%s@]@"
+ style_not_printable = r"@`@textcolor@[@gray@]@@[@%s@]@"
+ style_layer_name = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@"
+ style_field_name = r"@`@textcolor@[@blue@]@@[@%s@]@"
+ style_field_value = r"@`@textcolor@[@purple@]@@[@%s@]@"
+ style_emph_field_name = r"@`@textcolor@[@blue@]@@[@@`@underline@[@%s@]@@]@"
+ style_emph_field_value = r"@`@textcolor@[@purple@]@@[@@`@underline@[@%s@]@@]@"
+ style_packetlist_name = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@"
+ style_packetlist_proto = r"@`@textcolor@[@blue@]@@[@%s@]@"
+ style_packetlist_value = r"@`@textcolor@[@purple@]@@[@%s@]@"
+ style_fail = r"@`@textcolor@[@red@]@@[@@`@bfseries@[@@]@%s@]@"
+ style_success = r"@`@textcolor@[@blue@]@@[@@`@bfserices@[@@]@%s@]@"
+ style_even = r"@`@textcolor@[@gray@]@@[@@`@bfseries@[@@]@%s@]@"
+# style_odd = r"@`@textcolor@[@black@]@@[@@`@bfseries@[@@]@%s@]@"
+ style_left = r"@`@textcolor@[@blue@]@@[@%s@]@"
+ style_right = r"@`@textcolor@[@red@]@@[@%s@]@"
+
+class HTMLTheme(FormatTheme):
+ style_prompt = "<span class=prompt>%s</span>"
+ style_not_printable = "<span class=not_printable>%s</span>"
+ style_layer_name = "<span class=layer_name>%s</span>"
+ style_field_name = "<span class=field_name>%s</span>"
+ style_field_value = "<span class=field_value>%s</span>"
+ style_emph_field_name = "<span class=emph_field_name>%s</span>"
+ style_emph_field_value = "<span class=emph_field_value>%s</span>"
+ style_packetlist_name = "<span class=packetlist_name>%s</span>"
+ style_packetlist_proto = "<span class=packetlist_proto>%s</span>"
+ style_packetlist_value = "<span class=packetlist_value>%s</span>"
+ style_fail = "<span class=fail>%s</span>"
+ style_success = "<span class=success>%s</span>"
+ style_even = "<span class=even>%s</span>"
+ style_odd = "<span class=odd>%s</span>"
+ style_left = "<span class=left>%s</span>"
+ style_right = "<span class=right>%s</span>"
+
+class HTMLTheme2(HTMLTheme):
+ style_prompt = "#[#span class=prompt#]#%s#[#/span#]#"
+ style_not_printable = "#[#span class=not_printable#]#%s#[#/span#]#"
+ style_layer_name = "#[#span class=layer_name#]#%s#[#/span#]#"
+ style_field_name = "#[#span class=field_name#]#%s#[#/span#]#"
+ style_field_value = "#[#span class=field_value#]#%s#[#/span#]#"
+ style_emph_field_name = "#[#span class=emph_field_name#]#%s#[#/span#]#"
+ style_emph_field_value = "#[#span class=emph_field_value#]#%s#[#/span#]#"
+ style_packetlist_name = "#[#span class=packetlist_name#]#%s#[#/span#]#"
+ style_packetlist_proto = "#[#span class=packetlist_proto#]#%s#[#/span#]#"
+ style_packetlist_value = "#[#span class=packetlist_value#]#%s#[#/span#]#"
+ style_fail = "#[#span class=fail#]#%s#[#/span#]#"
+ style_success = "#[#span class=success#]#%s#[#/span#]#"
+ style_even = "#[#span class=even#]#%s#[#/span#]#"
+ style_odd = "#[#span class=odd#]#%s#[#/span#]#"
+ style_left = "#[#span class=left#]#%s#[#/span#]#"
+ style_right = "#[#span class=right#]#%s#[#/span#]#"
+
+
+class ColorPrompt:
+ __prompt = ">>> "
+ def __str__(self):
+ try:
+ ct = conf.color_theme
+ if isinstance(ct, AnsiColorTheme):
+ ## ^A and ^B delimit invisible caracters for readline to count right
+ return "\001%s\002" % ct.prompt("\002"+conf.prompt+"\001")
+ else:
+ return ct.prompt(conf.prompt)
+ except:
+ return self.__prompt
+
+############
+## Config ##
+############
+
+class ConfClass:
+ def configure(self, cnf):
+ self.__dict__ = cnf.__dict__.copy()
+ def __repr__(self):
+ return str(self)
+ def __str__(self):
+ s="Version = %s\n" % VERSION
+ keys = self.__class__.__dict__.copy()
+ keys.update(self.__dict__)
+ keys = keys.keys()
+ keys.sort()
+ for i in keys:
+ if i[0] != "_":
+ s += "%-10s = %s\n" % (i, repr(getattr(self, i)))
+ return s[:-1]
+
+class ProgPath(ConfClass):
+ pdfreader = "acroread"
+ psreader = "gv"
+ dot = "dot"
+ display = "display"
+ tcpdump = "tcpdump"
+ tcpreplay = "tcpreplay"
+ hexedit = "hexer"
+ wireshark = "wireshark"
+
+class Resolve:
+ def __init__(self):
+ self.fields = {}
+ def add(self, *flds):
+ for fld in flds:
+ self.fields[fld]=None
+ def remove(self, *flds):
+ for fld in flds:
+ if fld in self.fields:
+ del(self.fields[fld])
+ def __contains__(self, elt):
+ return elt in self.fields
+ def __repr__(self):
+ return "<Resolve [%s]>" % " ".join(str(x) for x in self.fields)
+
+
+
+
+class Conf(ConfClass):
+ """This object contains the configuration of scapy.
+session : filename where the session will be saved
+stealth : if 1, prevents any unwanted packet to go out (ARP, DNS, ...)
+checkIPID: if 0, doesn't check that IPID matches between IP sent and ICMP IP citation received
+ if 1, checks that they either are equal or byte swapped equals (bug in some IP stacks)
+ if 2, strictly checks that they are equals
+checkIPsrc: if 1, checks IP src in IP and ICMP IP citation match (bug in some NAT stacks)
+check_TCPerror_seqack: if 1, also check that TCP seq and ack match the ones in ICMP citation
+iff : selects the default output interface for srp() and sendp(). default:"eth0")
+verb : level of verbosity, from 0 (almost mute) to 3 (verbose)
+promisc : default mode for listening socket (to get answers if you spoof on a lan)
+sniff_promisc : default mode for sniff()
+filter : bpf filter added to every sniffing socket to exclude traffic from analysis
+histfile : history file
+padding : includes padding in desassembled packets
+except_filter : BPF filter for packets to ignore
+debug_match : when 1, store received packet that are not matched into debug.recv
+route : holds the Scapy routing table and provides methods to manipulate it
+warning_threshold : how much time between warnings from the same place
+ASN1_default_codec: Codec used by default for ASN1 objects
+mib : holds MIB direct access dictionnary
+resolve : holds list of fields for which resolution should be done
+noenum : holds list of enum fields for which conversion to string should NOT be done
+AS_resolver: choose the AS resolver class to use
+"""
+ session = ""
+ stealth = "not implemented"
+ iface = get_working_if()
+ checkIPID = 0
+ checkIPsrc = 1
+ checkIPaddr = 1
+ check_TCPerror_seqack = 0
+ verb = 2
+ prompt = ">>> "
+ promisc = 1
+ sniff_promisc = 1
+ L3socket = L3PacketSocket
+ L2socket = L2Socket
+ L2listen = L2ListenSocket
+ BTsocket = BluetoothL2CAPSocket
+ histfile = os.path.join(os.environ["HOME"], ".scapy_history")
+ padding = 1
+ p0f_base ="/etc/p0f/p0f.fp"
+ queso_base ="/etc/queso.conf"
+ nmap_base ="/usr/share/nmap/nmap-os-fingerprints"
+ IPCountry_base = "GeoIPCountry4Scapy.gz"
+ countryLoc_base = "countryLoc.csv"
+ gnuplot_world = "world.dat"
+ except_filter = ""
+ debug_match = 0
+ route = Route()
+ wepkey = ""
+ auto_fragment = 1
+ debug_dissector = 0
+ color_theme = DefaultTheme()
+ warning_threshold = 5
+ ASN1_default_codec = ASN1_Codecs.BER
+ mib = MIBDict(_name="MIB")
+ prog = ProgPath()
+ resolve = Resolve()
+ noenum = Resolve()
+ ethertypes = ETHER_TYPES
+ protocols = IP_PROTOS
+ services_tcp = TCP_SERVICES
+ services_udp = UDP_SERVICES
+ manufdb = MANUFDB
+ AS_resolver = AS_resolver_multi()
+
+
+conf=Conf()
+
+betteriface = conf.route.route("0.0.0.0", verbose=0)[0]
+if betteriface != "lo": #XXX linux specific...
+ conf.iface = betteriface
+del(betteriface)
+
+if PCAP:
+ conf.L2listen=L2pcapListenSocket
+ if DNET:
+ conf.L3socket=L3dnetSocket
+ conf.L2socket=L2dnetSocket
+
+
+p0f_kdb = p0fKnowledgeBase(conf.p0f_base)
+queso_kdb = QuesoKnowledgeBase(conf.queso_base)
+nmap_kdb = NmapKnowledgeBase(conf.nmap_base)
+IP_country_kdb = IPCountryKnowledgeBase(conf.IPCountry_base)
+country_loc_kdb = CountryLocKnowledgeBase(conf.countryLoc_base)
+
+
+#########################
+##### Autorun stuff #####
+#########################
+
+
+class ScapyAutorunInterpreter(code.InteractiveInterpreter):
+ def __init__(self, *args, **kargs):
+ code.InteractiveInterpreter.__init__(self, *args, **kargs)
+ self.error = 0
+ def showsyntaxerror(self, *args, **kargs):
+ self.error = 1
+ return code.InteractiveInterpreter.showsyntaxerror(self, *args, **kargs)
+ def showtraceback(self, *args, **kargs):
+ self.error = 1
+ return code.InteractiveInterpreter.showtraceback(self, *args, **kargs)
+
+
+def autorun_commands(cmds,my_globals=None,verb=0):
+ sv = conf.verb
+ import __builtin__
+ try:
+ if my_globals is None:
+ my_globals = globals()
+ conf.verb = verb
+ interp = ScapyAutorunInterpreter(my_globals)
+ cmd = ""
+ cmds = cmds.splitlines()
+ cmds.append("") # ensure we finish multiline commands
+ cmds.reverse()
+ __builtin__.__dict__["_"] = None
+ while 1:
+ if cmd:
+ sys.stderr.write(sys.__dict__.get("ps2","... "))
+ else:
+ sys.stderr.write(str(sys.__dict__.get("ps1",ColorPrompt())))
+
+ l = cmds.pop()
+ print l
+ cmd += "\n"+l
+ if interp.runsource(cmd):
+ continue
+ if interp.error:
+ return 0
+ cmd = ""
+ if len(cmds) <= 1:
+ break
+ finally:
+ conf.verb = sv
+ return _
+
+def autorun_get_interactive_session(cmds, **kargs):
+ class StringWriter:
+ def __init__(self):
+ self.s = ""
+ def write(self, x):
+ self.s += x
+
+ sw = StringWriter()
+ sstdout,sstderr = sys.stdout,sys.stderr
+ try:
+ sys.stdout = sys.stderr = sw
+ res = autorun_commands(cmds, **kargs)
+ finally:
+ sys.stdout,sys.stderr = sstdout,sstderr
+ return sw.s,res
+
+def autorun_get_text_interactive_session(cmds, **kargs):
+ ct = conf.color_theme
+ try:
+ conf.color_theme = NoTheme()
+ s,res = autorun_get_interactive_session(cmds, **kargs)
+ finally:
+ conf.color_theme = ct
+ return s,res
+
+def autorun_get_ansi_interactive_session(cmds, **kargs):
+ ct = conf.color_theme
+ try:
+ conf.color_theme = DefaultTheme()
+ s,res = autorun_get_interactive_session(cmds, **kargs)
+ finally:
+ conf.color_theme = ct
+ return s,res
+
+def autorun_get_html_interactive_session(cmds, **kargs):
+ ct = conf.color_theme
+ try:
+ conf.color_theme = HTMLTheme2()
+ s,res = autorun_get_interactive_session(cmds, **kargs)
+ finally:
+ conf.color_theme = ct
+
+ s = s.replace("<","&lt;").replace(">","&gt;").replace("#[#","<").replace("#]#",">")
+ return s,res
+
+def autorun_get_latex_interactive_session(cmds, **kargs):
+ ct = conf.color_theme
+ try:
+ conf.color_theme = LatexTheme2()
+ s,res = autorun_get_interactive_session(cmds, **kargs)
+ finally:
+ conf.color_theme = ct
+ s = tex_escape(s)
+ s = s.replace("@[@","{").replace("@]@","}").replace("@`@","\\")
+ return s,res
+
+
+################
+##### Main #####
+################
+
+def scapy_write_history_file(readline):
+ if conf.histfile:
+ try:
+ readline.write_history_file(conf.histfile)
+ except IOError,e:
+ try:
+ warning("Could not write history to [%s]\n\t (%s)" % (conf.histfile,e))
+ tmp = os.tempnam("","scapy")
+ readline.write_history_file(tmp)
+ warning("Wrote history to [%s]" % tmp)
+ except:
+ warning("Cound not write history to [%s]. Discarded" % tmp)
+
+
+def interact(mydict=None,argv=None,mybanner=None,loglevel=1):
+ import code,sys,cPickle,types,os,imp,getopt,logging
+
+ logging.getLogger("scapy").setLevel(loglevel)
+
+ the_banner = "Welcome to Scapy (%s)"
+ if mybanner is not None:
+ the_banner += "\n"
+ the_banner += mybanner
+
+ if argv is None:
+ argv = sys.argv
+
+# scapy_module = argv[0][argv[0].rfind("/")+1:]
+# if not scapy_module:
+# scapy_module = "scapy"
+# else:
+# if scapy_module.endswith(".py"):
+# scapy_module = scapy_module[:-3]
+#
+# scapy=imp.load_module("scapy",*imp.find_module(scapy_module))
+
+
+ import __builtin__
+# __builtin__.__dict__.update(scapy.__dict__)
+ __builtin__.__dict__.update(globals())
+ if mydict is not None:
+ __builtin__.__dict__.update(mydict)
+
+
+ import re, atexit
+ try:
+ import rlcompleter,readline
+ except ImportError:
+ log_loading.info("Can't load Python libreadline or completer")
+ READLINE=0
+ else:
+ READLINE=1
+ class ScapyCompleter(rlcompleter.Completer):
+ def global_matches(self, text):
+ matches = []
+ n = len(text)
+ for lst in [dir(__builtin__), session.keys()]:
+ for word in lst:
+ if word[:n] == text and word != "__builtins__":
+ matches.append(word)
+ return matches
+
+
+ def attr_matches(self, text):
+ m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
+ if not m:
+ return
+ expr, attr = m.group(1, 3)
+ try:
+ object = eval(expr)
+ except:
+ object = eval(expr, session)
+ if isinstance(object, Packet) or isinstance(object, Packet_metaclass):
+ words = filter(lambda x: x[0]!="_",dir(object))
+ words += [x.name for x in object.fields_desc]
+ else:
+ words = dir(object)
+ if hasattr( object,"__class__" ):
+ words = words + rlcompleter.get_class_members(object.__class__)
+ matches = []
+ n = len(attr)
+ for word in words:
+ if word[:n] == attr and word != "__builtins__":
+ matches.append("%s.%s" % (expr, word))
+ return matches
+
+ readline.set_completer(ScapyCompleter().complete)
+ readline.parse_and_bind("C-o: operate-and-get-next")
+ readline.parse_and_bind("tab: complete")
+
+
+ session=None
+ session_name=""
+ CONFIG_FILE = DEFAULT_CONFIG_FILE
+
+ iface = None
+ try:
+ opts=getopt.getopt(argv[1:], "hs:Cc:")
+ for opt, parm in opts[0]:
+ if opt == "-h":
+ usage()
+ elif opt == "-s":
+ session_name = parm
+ elif opt == "-c":
+ CONFIG_FILE = parm
+ elif opt == "-C":
+ CONFIG_FILE = None
+
+ if len(opts[1]) > 0:
+ raise getopt.GetoptError("Too many parameters : [%s]" % string.join(opts[1]),None)
+
+
+ except getopt.GetoptError, msg:
+ log_loading.error(msg)
+ sys.exit(1)
+
+
+ if CONFIG_FILE:
+ read_config_file(CONFIG_FILE)
+
+ if session_name:
+ try:
+ os.stat(session_name)
+ except OSError:
+ log_loading.info("New session [%s]" % session_name)
+ else:
+ try:
+ try:
+ session = cPickle.load(gzip.open(session_name,"rb"))
+ except IOError:
+ session = cPickle.load(open(session_name,"rb"))
+ log_loading.info("Using session [%s]" % session_name)
+ except EOFError:
+ log_loading.error("Error opening session [%s]" % session_name)
+ except AttributeError:
+ log_loading.error("Error opening session [%s]. Attribute missing" % session_name)
+
+ if session:
+ if "conf" in session:
+ conf.configure(session["conf"])
+ session["conf"] = conf
+ else:
+ conf.session = session_name
+ session={"conf":conf}
+
+ else:
+ session={"conf": conf}
+
+ __builtin__.__dict__["scapy_session"] = session
+
+
+ if READLINE:
+ if conf.histfile:
+ try:
+ readline.read_history_file(conf.histfile)
+ except IOError:
+ pass
+ atexit.register(scapy_write_history_file,readline)
+
+ sys.ps1 = ColorPrompt()
+ code.interact(banner = the_banner % (VERSION), local=session)
+
+ if conf.session:
+ save_session(conf.session, session)
+
+ sys.exit()
+
+
+def read_config_file(configfile):
+ try:
+ execfile(configfile)
+ except IOError,e:
+ log_loading.warning("Cannot read config file [%s] [%s]" % (configfile,e))
+ except Exception,e:
+ log_loading.exception("Error during evaluation of config file [%s]" % configfile)
+
+
+if __name__ == "__main__":
+ interact()
+else:
+ if DEFAULT_CONFIG_FILE:
+ read_config_file(DEFAULT_CONFIG_FILE)
diff --git a/cesar/maximus/python/maximus/ethernet/sniffer.py b/cesar/maximus/python/maximus/ethernet/sniffer.py
new file mode 100644
index 0000000000..65abfa2d35
--- /dev/null
+++ b/cesar/maximus/python/maximus/ethernet/sniffer.py
@@ -0,0 +1,128 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.macframe.msdu import MSDU_TYPES, MSDU
+from maximus.utils.exception import Error, OutOfRangeError
+from maximus.utils.format import *
+
+# Sniffer types
+SNIFFER_TYPES = ['Beacon', 'MME']
+
+class Sniffer(MSDU):
+ """The Sniffer object is composed of the 4 following fields:
+ way - a Python boolean:
+ 'False' for Tx
+ 'True' for Rx
+ encryption - a Python boolean
+ sniffer type - a Python dictionnary
+ packet - a Python string
+ """
+
+ def __init__(self, way, encryption, sniffer_type):
+ self.set_way(way)
+ self.set_encryption(encryption)
+ self.set_sniffer_type(sniffer_type)
+ self.__packet = None
+
+ def set_way(self, way):
+ """This function sets the way.
+ The way must be a Python boolean.
+ """
+ self.__way = None
+ if type(way) is not bool:
+ raise TypeError("Way")
+ else:
+ self.__way = way
+
+ def set_encryption(self, encryption):
+ """This function sets the encryption.
+ The encryption must be a Python boolean.
+ """
+ self.__encryption = None
+ if type(encryption) is not bool:
+ raise TypeError("Encryption")
+ else:
+ self.__encryption = encryption
+
+ def set_sniffer_type(self, sniffer_type):
+ """This function sets the sniffer type.
+ The sniffer type must be a Python integer lower than the SNIFFER_TYPES Python list length.
+ """
+ self.__sniffer_type = None
+ if type(sniffer_type) is not int:
+ raise TypeError("Sniffer type")
+ elif sniffer_type >= len(SNIFFER_TYPES):
+ raise OutOfRangeError("Sniffer type")
+ else:
+ self.__sniffer_type = sniffer_type
+
+ def set_msdu_attr(self, payload):
+ """This function sets the MSDU attributes from the received Ethernet Frame.
+ """
+ if type(payload) is not str:
+ raise TypeError("Packet")
+ else:
+ self.__packet = payload
+
+ def sendnrecv(self, maximus, station, file=None, timeout=None, filter=None, count=1):
+ raise Error("Cannot call this function for a sniffed Ethernet Frame")
+
+ def send(self, maximus, station, file=None):
+ raise Error("Cannot call this function for a sniffed Ethernet Frame")
+
+ def get(self):
+ """This function returns the sniffed packet into a string.
+ """
+ return self.__packet
+
+ def get_ether_type(self):
+ """This function returns the Sniffer object type into a Python integer (u8).
+ """
+ ether_type = None
+ for i in range (0,len(MSDU_TYPES)):
+ if MSDU_TYPES[i] == self.get_type():
+ ether_type = i
+ return ether_type # 7
+
+ def get_type(self):
+ """This function returns the Sniffer object type into a Python string.
+ """
+ return 'ETHERNET_TYPE_SNIFFER'
+
+ def get_way(self):
+ """This function gets the way.
+ The way is a Python boolean.
+ """
+ return self.__way
+
+ def get_encryption(self):
+ """This function gets the encryption.
+ The encryption is a Python boolean.
+ """
+ return self.__encryption
+
+ def get_sniffer_type(self):
+ """This function gets the sniffer type.
+ The sniffer type is a Python integer lower than the SNIFFER_TYPES Python list length.
+ """
+ return self.__sniffer_type
+
+ def display(self):
+ """This function displays the sniffed Ethernet Frame.
+ """
+ print "display the sniffed Ethernet Frame"
+ print "way =",
+ if self.get_way():
+ print 'Rx'
+ else:
+ print 'Tx'
+ print "encryption =", self.get_encryption()
+ print "sniffer type =", SNIFFER_TYPES[self.get_sniffer_type()]
+ print "packet =",
+ if self.get() is not None:
+ for c in self.get():
+ print hex(ntoh8(c)),
+ print
+ else:
+ print self.get()
diff --git a/cesar/maximus/python/maximus/fsm/FSM.py b/cesar/maximus/python/maximus/fsm/FSM.py
new file mode 100644
index 0000000000..e4b09f9f11
--- /dev/null
+++ b/cesar/maximus/python/maximus/fsm/FSM.py
@@ -0,0 +1,263 @@
+#!/usr/bin/env python
+'''This module implements a Finite State Machine (FSM).
+In addition to state this FSM also maintains a user defined "something".
+This "something" is effectively memory, so this FSM could be considered
+a Push-down Automata (PDA) since a PDA is a FSM + memory.
+
+The following describes how the FSM works, but you will probably also need
+to see the example function to understand how the FSM is used in practice.
+
+You define an FSM by building tables of transitions.
+For a given input symbol the process() method uses these tables
+to decide what action to call and what the next state will be.
+The FSM has a table of transitions that associate:
+ (input_symbol, current_state) --> (action, next_state)
+where "action" is a function you define. The symbols and states
+can be any objects. You use the add_transition() and add_transition_list()
+methods to add to the transition table. The FSM also has a table
+of transitions that associate:
+ (current_state) --> (action, next_state)
+You use the add_transition_any() method to add to this transition table.
+The FSM also has one default transition that is not associated
+with any specific input_symbol or state. You use the
+set_default_transition() method to set the default transition.
+
+When an action function is called it is passed a reference to the FSM.
+The action function may then access attributes of the FSM such as
+input_symbol, current_state, or "something". The "something" attribute
+can be any object that you want to pass along to the action functions.
+It is not used by the FSM. For parsing you would typically pass a list
+to be used as a stack.
+
+The processing sequence is as follows.
+The process() method is given an input_symbol to process.
+The FSM will search the table of transitions that associate:
+ (input_symbol, current_state) --> (action, next_state)
+If the pair (input_symbol, current_state) is found then
+process() will call the associated action function and then set the
+current state to the next_state.
+
+If the FSM cannot find a match for (input_symbol, current_state)
+it will then search the table of transitions that associate:
+ (current_state) --> (action, next_state)
+If the current_state is found then the process() method will call
+the associated action function and then set the current state to
+the next_state. Notice that this table lacks an input_symbol.
+It lets you define transitions for a current_state and ANY input_symbol.
+Hence, it is called the "any" table. Remember, it is always checked
+after first searching the table for a specific (input_symbol, current_state).
+
+For the case where the FSM did not match either of the previous two cases
+the FSM will try to use the default transition. If the default transition
+is defined then the process() method will call the associated action function
+and then set the current state to the next_state. This lets you define
+a default transition as a catch-all case. You can think of it as an
+exception handler. There can be only one default transition.
+
+Finally, if none of the previous cases are defined for an input_symbol
+and current_state then the FSM will raise an exception.
+This may be desirable, but you can always prevent this just by
+defining a default transition.
+
+Noah Spurrier 20020822
+'''
+
+class ExceptionFSM(Exception):
+ '''This is the FSM Exception class.'''
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return `self.value`
+
+class FSM:
+ '''This is a Finite State Machine (FSM).
+ '''
+
+ def __init__(self, initial_state, something):
+ '''This creates the FSM.
+ You set the initial state here. The "something" attribute is any
+ object that you want to pass along to the action functions.
+ It is not used by the FSM. For parsing you would typically pass
+ a list to be used as a stack.
+ '''
+ # Map (input_symbol, current_state) --> (action, next_state).
+ self.state_transitions = {}
+ # Map (current_state) --> (action, next_state).
+ self.state_transitions_any = {}
+ self.default_transition = None
+
+ self.input_symbol = None
+ self.initial_state = initial_state
+ self.current_state = self.initial_state
+ self.something = something
+
+ def reset (self):
+ '''This sets the current_state to the initial_state and
+ sets input_symbol to None.
+ The initial state was set by the constructor __init__().
+ '''
+ self.current_state = self.initial_state
+ self.input_symbol = None
+
+ def add_transition (self, input_symbol, state, action, next_state):
+ '''This adds a transition that associates
+ (input_symbol, current_state) --> (action, next_state)
+ The action may be set to None in which case the process() method
+ will ignore the action and only set the next_state.
+
+ You can also set transitions for a list of symbols by using
+ add_transition_list().
+ '''
+ self.state_transitions[(input_symbol, state)] = (action, next_state)
+
+ def add_transition_list (self, list_input_symbols, state, action, next_state):
+ '''This adds the same transition for lots of different input symbols.
+ You can pass a list or a string. Note that it is handy to use
+ string.digits, string.whitespace, string.letters, etc. to add
+ transitions that match character classes.
+ '''
+ for input_symbol in list_input_symbols:
+ self.add_transition (input_symbol, state, action, next_state)
+
+ def add_transition_any (self, state, action, next_state):
+ '''This adds a transition that associates
+ (current_state) --> (action, next_state)
+ The process() method checks these associations if it cannot
+ first find a match of an (input_symbol, current_state).
+ '''
+ self.state_transitions_any [state] = (action, next_state)
+
+ def set_default_transition (self, action, next_state):
+ '''This sets the default transition.
+ This defines an action and next_state if the FSM cannot find the
+ input symbol and the current state in the transition list and
+ if the FSM cannot find the current_state in the transition_any list.
+ This is useful for catching errors and undefined states.
+
+ The default transition can be removed by setting the attribute
+ default_transition to None.
+ '''
+ self.default_transition = (action, next_state)
+
+ def get_transition (self, input_symbol, state):
+ '''This returns (action, next state) given an input_symbol and state.
+ This leaves the FSM unchanged. This does not update the current state
+ nor does it trigger the output action. Normally you do not call
+ this method. It is called by process().
+
+ The sequence of steps to check for a defined transition goes from
+ the most specific to the least specific.
+ 1. Check state_transitions[] that match (input_symbol, state)
+ 2. Check state_transitions_any[] that match (state)
+ In other words, match a specific state and ANY input_symbol.
+ 3. Check if the default_transition is defined.
+ This catches any input_symbol and any state.
+ This is a handler for errors, undefined states, or defaults.
+ 4. No transition was defined. If we get here then raise an exception.
+ '''
+ if self.state_transitions.has_key((input_symbol, self.current_state)):
+ return self.state_transitions[(input_symbol, self.current_state)]
+ elif self.state_transitions_any.has_key (self.current_state):
+ return self.state_transitions_any[self.current_state]
+ elif self.default_transition != None:
+ return self.default_transition
+ else:
+ raise ExceptionFSM ('Transition is undefined: (%s, %s).' %
+ (str(input_symbol), str(self.current_state)) )
+
+ def process (self, input_symbol):
+ '''This is the main method that you call to process input.
+ This may cause the FSM to change state and call an action.
+ This method calls get_transition() to find the action and next_state
+ associated with the input_symbol and current_state.
+ If the action is None then the action is not called and
+ only the current state is changed.
+ This method processes one input symbol. You can process a list of
+ symbols (or a string) by calling process_list().
+ '''
+ self.input_symbol = input_symbol
+ (action, next_state) = self.get_transition (self.input_symbol, self.current_state)
+ if action != None:
+ action (self)
+ self.current_state = next_state
+
+ def process_list (self, s):
+ '''This takes a list and sends each element to process().
+ The list may be a string.
+ '''
+ for c in s:
+ self.process (c)
+
+##########################################################################
+# The following example demonstrates the use of the FSM class in
+# processing RPN expressions. Run this module from the command line.
+# You will get a prompt > for input.
+# Enter an RPN Expression.
+# Numbers may be integers. Operators are * / + -
+# Use the = sign to evaluate and print the expression.
+# For example:
+# 167 3 2 2 * * * 1 - =
+# will print:
+# 2003
+##########################################################################
+
+import string
+
+#
+# These define the actions.
+# Note that "something" is a list being used as a stack.
+#
+def BeginBuildNumber (fsm):
+ fsm.something.append (fsm.input_symbol)
+def BuildNumber (fsm):
+ s = fsm.something.pop ()
+ s = s + fsm.input_symbol
+ fsm.something.append (s)
+def EndBuildNumber (fsm):
+ s = fsm.something.pop ()
+ fsm.something.append (int(s))
+def DoOperator (fsm):
+ ar = fsm.something.pop()
+ al = fsm.something.pop()
+ if fsm.input_symbol == '+':
+ fsm.something.append (al + ar)
+ elif fsm.input_symbol == '-':
+ fsm.something.append (al - ar)
+ elif fsm.input_symbol == '*':
+ fsm.something.append (al * ar)
+ elif fsm.input_symbol == '/':
+ fsm.something.append (al / ar)
+def DoEqual (fsm):
+ print str(fsm.something.pop())
+def Error (fsm):
+ print 'That does not compute.'
+ print str(fsm.input_symbol)
+
+#
+# This is where the example starts and the FSM state transitions are defined.
+# Note that states (such as 'INIT') are strings. This is not necessary, but
+# it makes the example easier to read.
+#
+def example ():
+ f = FSM ('INIT', []) # "something" will be used as a stack.
+ f.set_default_transition (Error, 'INIT')
+ f.add_transition_any ('INIT', None, 'INIT')
+ f.add_transition ('=', 'INIT', DoEqual, 'INIT')
+ f.add_transition_list (string.digits, 'INIT', BeginBuildNumber, 'BUILDING_NUMBER')
+ f.add_transition_list (string.digits, 'BUILDING_NUMBER', BuildNumber, 'BUILDING_NUMBER')
+ f.add_transition_list (string.whitespace, 'BUILDING_NUMBER', EndBuildNumber, 'INIT')
+ f.add_transition_list ('+-*/', 'INIT', DoOperator, 'INIT')
+
+ print
+ print 'Enter an RPN Expression.'
+ print 'Numbers may be integers. Operators are * / + -'
+ print 'Use the = sign to evaluate and print the expression.'
+ print 'For example: '
+ print ' 167 3 2 2 * * * 1 - ='
+ inputs = raw_input ('>')
+ for s in inputs:
+ f.process (s)
+
+if __name__ == '__main__':
+ example ()
+
diff --git a/cesar/maximus/python/maximus/fsm/__init__.py b/cesar/maximus/python/maximus/fsm/__init__.py
new file mode 100644
index 0000000000..8606c61734
--- /dev/null
+++ b/cesar/maximus/python/maximus/fsm/__init__.py
@@ -0,0 +1,7 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = ["FSM"]
+
+import FSM
diff --git a/cesar/maximus/python/maximus/macframe/__init__.py b/cesar/maximus/python/maximus/macframe/__init__.py
new file mode 100644
index 0000000000..a9482d470f
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/__init__.py
@@ -0,0 +1,13 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = ["create", "fc_10", "fc_av", "macframe", "macframeheader", "macframequeue", "mpdu", "msdu", "pb"]
+
+from fc_10 import FC_10
+from fc_av import FC_AV
+from macframe import MACFrame
+from macframeheader import MACFrameHeader
+from macframequeue import MACFrameQueue
+from mpdu import MPDU_TYPES
+from pbheader import PBHeader
diff --git a/cesar/maximus/python/maximus/macframe/create.py b/cesar/maximus/python/maximus/macframe/create.py
new file mode 100644
index 0000000000..99055e4e86
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/create.py
@@ -0,0 +1,10 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.macframe.pb import PB
+
+def create_pb():
+ """This function creates and returns a new PB object.
+ """
+ return PB()
diff --git a/cesar/maximus/python/maximus/macframe/fc_10.py b/cesar/maximus/python/maximus/macframe/fc_10.py
new file mode 100644
index 0000000000..f6ad3ffc3f
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/fc_10.py
@@ -0,0 +1,135 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.utils.crc import crc8
+from maximus.utils.exception import OutOfRangeError
+from maximus.utils.format import *
+
+# Constants to check arguments validity
+MAX_VALUE_OF_CC = 0x01
+DT_DICTIONARY = {'SOF':0x00, 'SOF_RSP':0x01, 'EOF':0x02, 'EOF_RSP':0x03, 'ACK':0x04, 'NACK':0x05}
+MAX_VALUE_OF_DT = 0x07
+MAX_VALUE_OF_VF = 0x1FFF
+MAX_VALUE_OF_FCCS = MAX_VALUE_OF_U8
+SIZE_OF_FCCS = SIZE_OF_U8 # in octets
+
+# Constants for 'self.get()' function
+size_of_dt = 3 # in bits
+size_of_vf = 13 # in bits
+size_of_fccs = 8 * SIZE_OF_FCCS # in bits
+
+class FC_10:
+ """The FC 1.0 is composed of the 4 following fields:
+ CC (1-bit)
+ DT (3-bit)
+ VF (13-bit)
+ FCCS (8-bit)
+ """
+ def __init__(self, CC=0, DT='SOF', VF=0, FCCS=None):
+ self.set_cc(CC)
+ self.set_dt(DT)
+ self.set_vf(VF)
+ self.set_fccs(FCCS)
+
+ def set_cc(self, cc):
+ """Set the CC.
+ The CC must be a Python integer (decimal or hexadecimal value).
+ """
+ if cc <= MAX_VALUE_OF_CC and cc >= 0:
+ self.__cc = cc
+ else:
+ raise OutOfRangeError("CC")
+
+ def set_dt(self, dt):
+ """Set the DT.
+ The DT can be a Python integer (decimal or hexadecimal value),
+ or a Python string of the DT dictionary.
+ """
+ if dt in DT_DICTIONARY:
+ self.__dt = DT_DICTIONARY[dt]
+ elif dt <= MAX_VALUE_OF_DT and dt >= 0:
+ self.__dt = dt
+ else:
+ raise OutOfRangeError("DT")
+
+ def set_vf(self, vf):
+ """Set the VF.
+ The VF must be a Python integer (decimal or hexadecimal value).
+ """
+ if vf <= MAX_VALUE_OF_VF and vf >= 0:
+ self.__vf = vf
+ else:
+ raise OutOfRangeError("VF")
+
+ def set_fccs(self, fccs):
+ """Set the FCCS.
+ The FCCS can be a Python integer (decimal or hexadecimal value),
+ or a Python string of length equals to sizeof(u8).
+ """
+ if fccs != None:
+ try:
+ if len(fccs) == SIZE_OF_FCCS:
+ # FCCS is a Python string of length equals to sizeof(u8)
+ self.__fccs = hptoh8(fccs)
+ else:
+ raise OutOfRangeError("FCCS")
+ except TypeError:
+ # FCCS is a Python integer
+ if fccs <= MAX_VALUE_OF_FCCS and fccs >= 0:
+ self.__fccs = fccs
+ else:
+ raise OutOfRangeError("FCCS")
+ else:
+ self.__fccs = None
+
+ def get_cc(self):
+ """Get the CC.
+ The CC is a Python integer.
+ """
+ return self.__cc
+
+ def get_dt(self):
+ """Get the DT.
+ The DT is a Python integer.
+ """
+ return self.__dt
+
+ def get_vf(self):
+ """Get the VF.
+ The VF is a Python integer.
+ """
+ return self.__vf
+
+ def get_fccs(self):
+ """Get the FCCS.
+ The FCCS is a Python integer.
+ """
+ return self.__fccs
+
+ def get(self):
+ """This function returns the FC 1.0 into a Python long (u32).
+ """
+ fc10 = self.get_cc() << (size_of_dt + size_of_vf + size_of_fccs)
+ fc10 += self.get_dt() << (size_of_vf + size_of_fccs)
+ fc10 += self.get_vf() << size_of_fccs
+
+ if self.get_fccs() is None:
+ # The 8-bit CRC must be calculated
+ self.__fccs = crc8(htohp24(fc10 >> size_of_fccs))
+
+ fc10 += self.get_fccs()
+ return fc10
+
+ def display(self):
+ """This function displays the FC 1.0 in hexadecimal values.
+ """
+ print "display the FC 1.0"
+ print "CC =", hex(self.get_cc())
+ print "DT =", hex(self.get_dt())
+ print "VF =", hex(self.get_vf())
+ if self.get_fccs() != None:
+ print "FCCS =", hex(self.get_fccs())
+ else:
+ print "FCCS = None"
+
diff --git a/cesar/maximus/python/maximus/macframe/fc_av.py b/cesar/maximus/python/maximus/macframe/fc_av.py
new file mode 100644
index 0000000000..38cccc8e2b
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/fc_av.py
@@ -0,0 +1,173 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.utils.crc import crc24
+from maximus.utils.exception import OutOfRangeError
+from maximus.utils.format import *
+
+# Constants to check arguments validity
+size_of_u8 = 8 * SIZE_OF_U8 # in bits
+size_of_u32 = 8 * SIZE_OF_U32 # in bits
+DT_AV_DICTIONARY = {'Beacon':0x00, 'SOF':0x01, 'SACK':0x02, 'RTS_CTS':0x03, 'Sound':0x04, 'RSOF':0x05}
+MAX_VALUE_OF_DT_AV = 0x07
+MAX_VALUE_OF_ACCESS = 0x01
+MAX_VALUE_OF_SNID = 0x0F
+MAX_VALUE_OF_VF_AV = 0xFFFFFFFFFFFFFFFFFFFFFFFF
+SIZE_OF_VF_AV = 3 * SIZE_OF_U32 # in octets
+MAX_VALUE_OF_FCCS_AV = 0xFFFFFF
+SIZE_OF_FCCS_AV = 3 * SIZE_OF_U8 # in octets
+
+# Constants for 'self.get()' function
+size_of_dt_av = 3 # in bits
+size_of_access = 1 # in bits
+size_of_vf_av = 8 * SIZE_OF_VF_AV # in bits
+size_of_fccs_av = 8 * SIZE_OF_FCCS_AV # in bits
+
+class FC_AV:
+ """The FC AV is composed of the 5 following fields:
+ DT_AV (3-bit)
+ ACCESS (1-bit)
+ SNID (4-bit)
+ VF_AV (96-bit)
+ FCCS_AV (24-bit)
+ """
+ def __init__(self, DT_AV='Beacon', ACCESS=0, SNID=0, VF_AV=0, FCCS_AV=None):
+ self.set_dt_av(DT_AV)
+ self.set_access(ACCESS)
+ self.set_snid(SNID)
+ self.set_vf_av(VF_AV)
+ self.set_fccs_av(FCCS_AV)
+
+ def set_dt_av(self, dt_av):
+ """Set the DT AV.
+ The DT AV can be a Python integer (decimal or hexadecimal value),
+ or a Python string of the DT AV dictionary.
+ """
+ if dt_av in DT_AV_DICTIONARY:
+ self.__dt_av = DT_AV_DICTIONARY[dt_av]
+ elif dt_av <= MAX_VALUE_OF_DT_AV and dt_av >= 0:
+ self.__dt_av = dt_av
+ else:
+ raise OutOfRangeError("DT AV")
+
+ def set_access(self, access):
+ """Set the ACCESS.
+ The ACCESS must be a Python integer (decimal or hexadecimal value).
+ """
+ if access <= MAX_VALUE_OF_ACCESS and access >= 0:
+ self.__access = access
+ else:
+ raise OutOfRangeError("ACCESS")
+
+ def set_snid(self, snid):
+ """Set the SNID.
+ The SNID must be a Python integer (decimal or hexadecimal value).
+ """
+ if snid <= MAX_VALUE_OF_SNID and snid >= 0:
+ self.__snid = snid
+ else:
+ raise OutOfRangeError("SNID")
+
+ def set_vf_av(self, vf_av):
+ """Set the VF AF.
+ The VF AF can be a Python long (decimal or hexadecimal value),
+ or a Python string of length equals to 12 octets.
+ """
+ try:
+ if len(vf_av) == SIZE_OF_VF_AV:
+ # VF AV is a Python string of length equals to 12 octets
+ vf_av = unpack(hp + 3 * u32, vf_av)
+ self.__vf_av = (vf_av[2] << 2*size_of_u32) + (vf_av[1] << size_of_u32) + vf_av[0]
+ else:
+ raise OutOfRangeError("VF AV")
+ except TypeError:
+ # VF AV is a Python long
+ if vf_av <= MAX_VALUE_OF_VF_AV and vf_av >= 0:
+ self.__vf_av = vf_av
+ else:
+ raise OutOfRangeError("VF AV")
+
+ def set_fccs_av(self, fccs_av):
+ """Set the FCCS AV.
+ The FCCS can be a Python long (decimal or hexadecimal value),
+ or a Python string of length equals to 3 octets.
+ """
+ if fccs_av != None:
+ try:
+ if len(fccs_av) == SIZE_OF_FCCS_AV:
+ # FCCS AV is a Python string of length equals to 3 octets
+ self.__fccs_av = hptoh24(fccs_av)
+ else:
+ raise OutOfRangeError("FCCS AV")
+ except TypeError:
+ # FCCS AV is a Python long
+ if fccs_av <= MAX_VALUE_OF_FCCS_AV and fccs_av >= 0:
+ self.__fccs_av = fccs_av
+ else:
+ raise OutOfRangeError("FCCS AV")
+ else:
+ self.__fccs_av = None
+
+ def get_dt_av(self):
+ """Get the DT AV.
+ The DT AV is a Python integer.
+ """
+ return self.__dt_av
+
+ def get_access(self):
+ """Get the ACCESS.
+ The ACCESS is a Python integer.
+ """
+ return self.__access
+
+ def get_snid(self):
+ """Get the SNID.
+ The SNID is a Python integer.
+ """
+ return self.__snid
+
+ def get_vf_av(self):
+ """Get the VF AV.
+ The VF is a Python long.
+ """
+ return self.__vf_av
+
+ def get_fccs_av(self):
+ """Get the FCCS AV.
+ The FCCS AV is a Python long.
+ """
+ return self.__fccs_av
+
+ def get(self):
+ """This function returns the FC AV into a tuple of 4 Python longs (u32).
+ """
+ tuple0 = self.get_snid() << (size_of_access + size_of_dt_av + 3*size_of_u8)
+ tuple0 += self.get_access() << (size_of_dt_av + 3*size_of_u8)
+ tuple0 += self.get_dt_av() << (3*size_of_u8)
+ tuple0 += self.get_vf_av() >> (2*size_of_u32 + size_of_u8)
+ tuple1 = ((self.get_vf_av() >> (size_of_u32 + size_of_u8))) & MAX_VALUE_OF_U32
+ tuple2 = (self.get_vf_av() >> size_of_u8) & MAX_VALUE_OF_U32
+ tuple3 = (self.get_vf_av() & MAX_VALUE_OF_U8) << size_of_fccs_av
+
+ if self.get_fccs_av() is None:
+ # The 24-bit CRC must be calculated
+ self.__fccs_av = crc24(htohp32(tuple0) + htohp32(tuple1) + htohp32(tuple2) + htohp8(tuple3 >> size_of_fccs_av))
+
+ tuple3 += self.get_fccs_av()
+ tuple = tuple0, tuple1, tuple2, tuple3
+ return tuple
+
+ def display(self):
+ """This function displays the FC AV in hexadecimal values.
+ """
+ print "display the FC AV"
+ print "DT AV =", hex(self.get_dt_av())
+ print "ACCESS =", hex(self.get_access())
+ print "SNID =", hex(self.get_snid())
+ print "VF AV =", hex(self.get_vf_av())
+ if self.get_fccs_av() != None:
+ print "FCCS AV =", hex(self.get_fccs_av())
+ else:
+ print "FCCS AV = None"
+
diff --git a/cesar/maximus/python/maximus/macframe/macframe.py b/cesar/maximus/python/maximus/macframe/macframe.py
new file mode 100644
index 0000000000..e5c8b56e37
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/macframe.py
@@ -0,0 +1,252 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.macframe.fc_av import FC_AV
+from maximus.macframe.macframeheader import MACFrameHeader
+from maximus.macframe.mpdu import SIZE_OF_IV, SIZE_OF_NEK, SIZE_OF_PB136, SIZE_OF_PB520, MAX_PB_NB_PER_MPDU, MPDU_TYPES, MPDU
+from maximus.macframe.msdu import MAX_SIZE_OF_MSDU
+from maximus.utils.crc import crc32
+from maximus.utils.exception import Error, OutOfRangeError
+from maximus.utils.format import *
+
+# Constants to check arguments validity
+SIZE_OF_FC_10 = SIZE_OF_U32 # in octets
+SIZE_OF_FC_AV = 4 * SIZE_OF_U32 # in octets
+SIZE_OF_MACFRAMEHEADER = SIZE_OF_U16 # in octets
+SIZE_OF_ATS_CONFOUNDER = SIZE_OF_U32 # in octets
+SIZE_OF_ICV = SIZE_OF_U32 # in octets
+SIZE_OF_IV = 3 * SIZE_OF_U32 # in octets
+SIZE_OF_NEK = 4 * SIZE_OF_U32 # in octets
+MAX_VALUE_OF_FC_10 = MAX_VALUE_OF_U32
+MAX_VALUE_OF_MACFRAMEHEADER = MAX_VALUE_OF_U16
+MAX_VALUE_OF_ATS_CONFOUNDER = MAX_VALUE_OF_U32
+MAX_VALUE_OF_ICV = MAX_VALUE_OF_U32
+MAX_SIZE_OF_MACFRAME = MAX_SIZE_OF_MSDU + SIZE_OF_MACFRAMEHEADER + SIZE_OF_ATS_CONFOUNDER + SIZE_OF_ICV # 1528 octets
+
+class MACFrame(MPDU):
+ """The MAC Frame is composed of the 4 following fields:
+ MACFrameHeader (2-octet)
+ ATS or Confounder (4-octet)
+ ICV (4-octet)
+ msdu (1518-octet max)
+ """
+ def __init__(self, FC_10=None, FC_AV=FC_AV(), MACFrameHeader=MACFrameHeader(), ATS=None, Confounder=None, ICV=None, msdu=None, iv=SIZE_OF_IV*'0', nek=SIZE_OF_NEK*'0', PBHeader=0):
+
+ # Set FC 1.0 and FC AV
+ self.set_fc_10(FC_10)
+ self.set_fc_av(FC_AV)
+
+ # Set MAC Frame Header
+ self.set_macframeheader(MACFrameHeader)
+
+ # Set ATS or Confounder
+ if ATS != None and Confounder != None:
+ raise Error("Usage: cannot give the ATS AND the Confounder as arguments")
+ else:
+ self.set_ats(ATS)
+ self.set_confounder(Confounder)
+
+ # Set ICV, MSDU, IV, and NEK
+ self.set_icv(ICV)
+ self.set_msdu(msdu)
+ self.set_iv(iv)
+ self.set_nek(nek)
+
+ # Set first PB Header
+ mmqf = False
+ try:
+ if msdu.get_type() is 'ETHERNET_TYPE_MME':
+ mmqf = True
+ except AttributeError:
+ pass
+ self.set_first_pb_header(first_pb_header=PBHeader, mmqf=mmqf)
+
+ def set_macframeheader(self, macframeheader):
+ """Set the MAC Frame Header.
+ The MAC Frame Header can be a MAC Frame Header object,
+ a Python integer (decimal or hexadecimal value),
+ or a Python string of length equals to sizeof(u16).
+ """
+ if macframeheader is not None:
+ try:
+ # MAC Frame Header is a MAC Frame Header object
+ self.__macframeheader = macframeheader.get() # set MAC Frame Header into a Python string of length equals to sizeof(u16)
+ except AttributeError:
+ try:
+ if len(macframeheader) == SIZE_OF_MACFRAMEHEADER:
+ # MAC Frame Header is a Python string of length equals to sizeof(u16)
+ self.__macframeheader = macframeheader
+ else:
+ raise OutOfRangeError("MAC Frame Header")
+ except TypeError:
+ # MAC Frame Header is a Python integer
+ if macframeheader <= MAX_VALUE_OF_MACFRAMEHEADER and macframeheader >= 0:
+ self.__macframeheader = htohp16(macframeheader) # set MAC Frame Header into a Python string of length equals to sizeof(u16)
+ else:
+ raise OutOfRangeError("MAC Frame Header")
+ else:
+ self.__macframeheader = None
+
+ def set_ats(self, ats):
+ """Set the ATS.
+ The ATS can be a Python long (decimal or hexadecimal value),
+ or a Python string of length equals to sizeof(u32).
+ """
+ if ats != None:
+ try:
+ if len(ats) == SIZE_OF_ATS_CONFOUNDER:
+ # ATS is a Python string of length equals to sizeof(u32)
+ self.__ats = ats
+ else:
+ raise OutOfRangeError("ATS")
+ except TypeError:
+ # ATS is a Python long
+ if ats <= MAX_VALUE_OF_ATS_CONFOUNDER and ats >= 0:
+ self.__ats = htohp32(ats) # set ATS into a Python string of length equals to sizeof(u32)
+ else:
+ raise OutOfRangeError("ATS")
+ else:
+ self.__ats = None
+
+ def set_confounder(self, confounder):
+ """Set the Confounder.
+ The Confounder can be a Python long (decimal or hexadecimal value),
+ or a Python string of length equals to sizeof(u32).
+ """
+ if confounder != None:
+ try:
+ if len(confounder) == SIZE_OF_ATS_CONFOUNDER:
+ # Confounder is a Python string of length equals to sizeof(u32)
+ self.__confounder = confounder
+ else:
+ raise OutOfRangeError("Confounder")
+ except TypeError:
+ # Confounder is a Python long
+ if confounder <= MAX_VALUE_OF_ATS_CONFOUNDER and confounder >= 0:
+ self.__confounder = htohp32(confounder) # set Confounder into a Python string of length equals to sizeof(u32)
+ else:
+ raise OutOfRangeError("Confounder")
+ else:
+ self.__confounder = None
+
+ def set_icv(self, icv):
+ """Set the ICV.
+ The ICV can be a Python long (decimal or hexadecimal value),
+ or a Python string of length equals to sizeof(u32).
+ """
+ if icv != None:
+ try:
+ if len(icv) == SIZE_OF_ICV:
+ # ICV is a Python string of length equals to sizeof(u32)
+ self.__icv = icv
+ else:
+ raise OutOfRangeError("ICV")
+ except TypeError:
+ # ICV is a Python long
+ if icv <= MAX_VALUE_OF_ICV and icv >= 0:
+ self.__icv = htohp32(icv) # set ICV into a Python string of length equals to sizeof(u32)
+ else:
+ raise OutOfRangeError("ICV")
+ else:
+ self.__icv = None
+
+ def set_msdu(self, msdu):
+ """Set the MSDU.
+ The MSDU can be an MSDU object,
+ or a Python string.
+ """
+ if msdu == None:
+ self.__msdu = ''
+ else:
+ try:
+ # MSDU is an MSDU object
+ self.__msdu = msdu.get() # set MSDU into a Python string
+ except AttributeError:
+ # MSDU is a Python string of length smaller than 1518 octets
+ if len(msdu) <= MAX_SIZE_OF_MSDU:
+ self.__msdu = msdu
+ else:
+ raise OutOfRangeError("MSDU too long")
+
+ def get_macframeheader(self):
+ """Get the MAC Frame Header.
+ The MAC Frame Header is a Python string of length equals to sizeof(u16).
+ """
+ return self.__macframeheader
+
+ def get_ats(self):
+ """Get the ATS.
+ The ATS is Python string of length equals to sizeof(u32).
+ """
+ return self.__ats
+
+ def get_confounder(self):
+ """Get the Confounder.
+ The Confounder is a Python string of length equals to sizeof(u32).
+ """
+ return self.__confounder
+
+ def get_icv(self):
+ """Get the ICV.
+ The ICV is a Python string of length equals to sizeof(u32).
+ """
+ return self.__icv
+
+ def get_msdu(self):
+ """Get the MSDU.
+ The MSDU is a Python string.
+ """
+ return self.__msdu
+
+ def get_type(self):
+ """This function returns the MAC Frame object type into a Python string.
+ """
+ return MPDU_TYPES[1]
+
+ def fill_mpdu_attr(self, fc_mode, short_ppdu, mod):
+ """Set the MPDU attributes from the MAC Frame to send.
+ """
+ # Set ATS or Confounder, and computes the MFT of the MAC Frame Header
+ if self.__ats != None and self.__confounder != None:
+ raise MACFrameSendError("Cannot send the ATS AND the Confounder")
+ elif self.__ats == None and self.__confounder == None:
+ # Ethernet frame without ATS => MFT = 0b01
+ ats_confounder = ''
+ mft = 0x01
+ elif self.__ats != None:
+ # Ethernet frame with ATS => MFT = 0b10
+ ats_confounder = self.__ats
+ mft = 0x02
+ elif self.__confounder != None:
+ # MME => MFT = 0b11
+ ats_confounder = self.__confounder
+ mft = 0x03
+
+ # Set ICV
+ if self.get_icv() is None:
+ # The 32-bit CRC must be calculated
+ self.__icv = htohp32(crc32(self.__msdu))
+
+ if self.get_macframeheader() is None\
+ or (type(self.get_macframeheader()) is str and hptoh16(self.get_macframeheader()) == 0):
+ # Set the MFT and the MFL of the MAC Frame Header
+ # "MAC Frame Length (MFL) is a 14-bit field that specifies the MAC Frame length in octets,
+ # excluding the 2-octet MAC Frame Header field and the 4-octet ICV, but including the ATS or
+ # counfounder (if either is present). A value of 0x0000 indicates a length of 1 octet, and so on."
+ if len(ats_confounder + self.__msdu) >= 1:
+ mfl = len(ats_confounder + self.__msdu) - 1
+ else:
+ mfl = 0
+ self.set_macframeheader(MACFrameHeader(MFT=mft, MFL=mfl))
+
+ # Set the MPDU payload
+ self.payload = self.__macframeheader + ats_confounder + self.__msdu + self.__icv
+
+ # Set the MAC Frame Boundary Offset
+ self.mfbo = (0, 0)
+
+ # Set PHY attributes
+ self.fc_mode = fc_mode
+ self.short_ppdu = short_ppdu
+ self.mod = mod
diff --git a/cesar/maximus/python/maximus/macframe/macframeheader.py b/cesar/maximus/python/maximus/macframe/macframeheader.py
new file mode 100644
index 0000000000..e0ce5b1014
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/macframeheader.py
@@ -0,0 +1,80 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.utils.exception import OutOfRangeError, MACFrameSendError
+from maximus.utils.format import *
+
+# Constants to check arguments validity
+MAX_VALUE_OF_MFT = 0x03 # MFT is coded on 2 bits (max value is 0b11)
+MAX_VALUE_OF_MFL = 0x3FFF # MFL is coded on 14 bits
+
+# Constant for 'self.get()' function
+size_of_mft = 2 # in bits
+
+class MACFrameHeader:
+ """The MAC Frame Header is composed of the 2 following fields:
+ MFT (2-bit LSB)
+ MFL (14-bit MSB)
+ """
+ def __init__(self, MFT=0, MFL=0):
+ self.set_mft(MFT)
+ self.set_mfl(MFL)
+
+ def set_mft(self, mft):
+ """Set the MFT.
+ The MFT must be a Python integer (decimal or hexadecimal value).
+ """
+ if mft <= MAX_VALUE_OF_MFT and mft >= 0:
+ self.__mft = mft
+ else:
+ raise OutOfRangeError("MFT")
+
+ def set_mfl(self, mfl):
+ """Set the MFL.
+ The MFL must be a Python integer (decimal or hexadecimal value).
+ """
+ if mfl <= MAX_VALUE_OF_MFL and mfl >= 0:
+ self.__mfl = mfl
+ else:
+ raise OutOfRangeError("MFL")
+
+ def get_mft(self):
+ """Get the MFT.
+ The MFT is a Python integer.
+ """
+ return self.__mft
+
+ def get_mfl(self):
+ """Get the MFL.
+ The MFL is a Python integer.
+ """
+ return self.__mfl
+
+ def set(self, mft, mfl):
+ """This function computes the MAC Frame Header fields if they are not set.
+ """
+ # Check MFT
+ if self.get_mft() == 0:
+ self.set_mft(mft)
+ elif self.get_mft() != mft:
+ raise MACFrameSendError("Incoherent MFT")
+ # Check MFL
+ if self.get_mfl() == 0:
+ self.set_mfl(mfl)
+ elif self.get_mfl() != mfl:
+ raise MACFrameSendError("Incoherent MFL")
+
+ def get(self):
+ """This function returns the MAC Frame Header into a string
+ of length equals to sizeof(u16).
+ """
+ header = (self.get_mfl() << size_of_mft) + self.get_mft()
+ return htohp16(header)
+
+ def display(self):
+ """This function displays the MAC Frame Header in hexadecimal values.
+ """
+ print "display the MAC Frame Header"
+ print "MFT =", hex(self.get_mft())
+ print "MFL =", hex(self.get_mfl())
diff --git a/cesar/maximus/python/maximus/macframe/macframequeue.py b/cesar/maximus/python/maximus/macframe/macframequeue.py
new file mode 100644
index 0000000000..9008d58966
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/macframequeue.py
@@ -0,0 +1,90 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.macframe.fc_av import FC_AV
+from maximus.macframe.macframe import MAX_SIZE_OF_MACFRAME
+from maximus.macframe.mpdu import SIZE_OF_IV, SIZE_OF_NEK, SIZE_OF_PB520, MAX_PB_NB_PER_MPDU, MPDU_TYPES, MPDU
+from maximus.utils.exception import OutOfRangeError
+
+MAX_SIZE_OF_LIST = (SIZE_OF_PB520*MAX_PB_NB_PER_MPDU + (MAX_SIZE_OF_MACFRAME - 1)) / MAX_SIZE_OF_MACFRAME # 80 elements
+
+class MACFrameQueue(MPDU):
+ """The MAC Frame Queue is composed of the following field:
+ macframelist - a Python list composed of 80 MAC Frames maximum
+ """
+ def __init__(self, FC_10=None, FC_AV=FC_AV(), iv=SIZE_OF_IV*'0', nek=SIZE_OF_NEK*'0', PBHeader=0, macframelist=None):
+
+ # Set FC 1.0, FC AV, IV, NEK, first PB Header, and list
+ self.set_fc_10(FC_10)
+ self.set_fc_av(FC_AV)
+ self.set_iv(iv)
+ self.set_nek(nek)
+ self.set_first_pb_header(first_pb_header=PBHeader)
+ self.set_macframelist(macframelist)
+
+ def set_macframelist(self, macframelist):
+ """Set the list of MAC Frames.
+ The list of MAC Frames must be a Python list composed of 80 MAC Frames maximum.
+ """
+ if macframelist is None:
+ self.__macframelist = []
+ elif type(macframelist) is list:
+ if len(macframelist) <= MAX_SIZE_OF_LIST:
+ self.__macframelist = macframelist
+ else:
+ raise OutOfRangeError("List of MAC Frames too long")
+ else:
+ raise OutOfRangeError("List of MAC Frames")
+
+ def add(self, frame):
+ """Add a MAC Frame or a list of MAC Frames to the list of MAC Frames.
+ The frame must be a MAC Frame,
+ or a Python list of MAC Frames.
+ """
+ try:
+ # frame is a MAC Frame object
+ if frame.get_type() is MPDU_TYPES[1]:
+ if len(self.get_macframelist()) + 1 <= MAX_SIZE_OF_LIST:
+ self.get_macframelist().append(frame)
+ else:
+ raise OutOfRangeError("List of MAC Frames too long")
+ except AttributeError:
+ if type(frame) is list:
+ if len(self.get_macframelist()) + len(frame) <= MAX_SIZE_OF_LIST:
+ self.get_macframelist().extend(frame)
+ else:
+ raise OutOfRangeError("List of MAC Frames too long")
+ else:
+ raise OutOfRangeError("List of MAC Frames")
+
+ def get_macframelist(self):
+ """Get the list of MAC Frames.
+ The list of MAC Frames is a Python list composed of 80 MAC Frames maximum.
+ """
+ return self.__macframelist
+
+ def get_type(self):
+ """This function returns the MAC Frame Queue object type into a Python string.
+ """
+ return MPDU_TYPES[2]
+
+ def fill_mpdu_attr(self, fc_mode, short_ppdu, mod):
+ """Set the MPDU attributes from the MAC Frame Queue to send.
+ """
+
+ self.payload = ''
+ self.mfbo = 0,
+ for i in range (len(self.get_macframelist())):
+ # Set the MPDU payload
+ frame = self.get_macframelist().pop(0)
+ frame.fill_mpdu_attr(fc_mode, short_ppdu, mod)
+ self.payload += frame.payload
+ # Set the MAC Frame Boundary Offset
+ self.mfbo += len(frame.payload),
+ self.mfbo += 0,
+
+ # Set PHY attributes
+ self.fc_mode = fc_mode
+ self.short_ppdu = short_ppdu
+ self.mod = mod
diff --git a/cesar/maximus/python/maximus/macframe/mpdu.py b/cesar/maximus/python/maximus/macframe/mpdu.py
new file mode 100644
index 0000000000..88806ff8de
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/mpdu.py
@@ -0,0 +1,187 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.macframe.fc_10 import FC_10
+from maximus.macframe.fc_av import FC_AV
+from maximus.macframe.pbheader import PBHeader
+from maximus.utils.exception import OutOfRangeError
+from maximus.utils.format import *
+from interface import *
+
+# Constants to check arguments validity
+
+SIZE_OF_FC_10 = SIZE_OF_U32 # in octets
+MAX_VALUE_OF_FC_10 = MAX_VALUE_OF_U32
+SIZE_OF_FC_AV = 4 * SIZE_OF_U32 # in octets
+SIZE_OF_IV = 3 * SIZE_OF_U32 # in octets
+SIZE_OF_NEK = 4 * SIZE_OF_U32 # in octets
+
+SIZE_OF_PB136 = 128 # in octets
+SIZE_OF_PB520 = 512 # in octets
+MAX_PB_NB_PER_MPDU = 236
+
+# MPDU object type
+MPDU_TYPES = ['PHY_TYPE_NONE',\
+ 'PHY_TYPE_MACFrame',\
+ 'PHY_TYPE_MACFrameQueue',\
+ 'PHY_TYPE_MPDU_PAYLOAD']
+
+class MPDU:
+ """The MPDU is composed of the 5 following fields:
+ FC_10 (4-octet)
+ FC_AV (16-octet)
+ iv (12-octet)
+ nek (16-octet)
+ first PB Header (4-octet)
+ """
+ def set_fc_10(self, fc_10):
+ """Set the FC 1.0 (FC 1.0 is optional).
+ The FC 1.0 can be an FC 1.0 object,
+ a Python long (decimal or hexadecimal value),
+ or a Python string of length equals to sizeof(u32).
+ """
+ if fc_10 != None:
+ try:
+ # FC 1.0 is an FC 1.0 object
+ self.fc_10 = fc_10.get() # set FC 1.0 into a Python long (u32)
+ except AttributeError:
+ try:
+ if len(fc_10) == SIZE_OF_FC_10:
+ # FC 1.0 is a Python string of length equals to sizeof(u32)
+ self.fc_10 = hptoh32(fc_10) # set FC 1.0 into a Python long (u32)
+ else:
+ raise OutOfRangeError("FC 1.0")
+ except TypeError:
+ # FC 1.0 is a Python long
+ if fc_10 <= MAX_VALUE_OF_FC_10 and fc_10 >= 0:
+ self.fc_10 = fc_10
+ else:
+ raise OutOfRangeError("FC 1.0")
+ else:
+ self.fc_10 = 0
+
+ def set_fc_av(self, fc_av):
+ """Set the FC AV.
+ The FC AV can be an FC AV object,
+ a Python string of length equals to 4 * sizeof(u32),
+ or a tuple of 4 Python longs (u32).
+ """
+ try:
+ # FC AV is an FC AV object
+ self.fc_av = fc_av.get() # set FC AV into a tuple of 4 Python longs (u32)
+ except AttributeError:
+ if type(fc_av) is str:
+ if len(fc_av) == SIZE_OF_FC_AV:
+ # FC AV is a Python string of length equals to 4 * sizeof(32)
+ self.fc_av = unpack(hp + 4 * u32, fc_av) # set FC AV into a tuple of 4 Python longs (u32)
+ else:
+ raise OutOfRangeError("FC AV")
+ elif type(fc_av) is tuple:
+ if len(fc_av) == 4:
+ # FC AV is a tuple of 4 Python longs (u32)
+ self.fc_av = fc_av
+ else:
+ raise OutOfRangeError("FC AV")
+ else:
+ raise OutOfRangeError("FC AV")
+
+ def set_iv(self, iv):
+ """Set the IV.
+ IV must be a Python string of length equals to 3 * sizeof(u32).
+ """
+ if len(iv) == SIZE_OF_IV:
+ self.iv = iv
+ else:
+ raise OutOfRangeError("IV")
+
+ def set_nek(self, nek):
+ """Set the NEK.
+ NEK must be a Python string of length equals to 4 * sizeof(u32).
+ """
+ if len(nek) == SIZE_OF_NEK:
+ self.nek = nek
+ else:
+ raise OutOfRangeError("NEK")
+
+ def set_first_pb_header(self, first_pb_header, mmqf=False):
+ """Set the first PB Header.
+ The first PB Header can be a PB Header object,
+ or a Python long (decimal or hexadecimal value).
+ The MMQF must be a Python boolean.
+ """
+ if type(first_pb_header) is int or type(first_pb_header) is long:
+ # First PB Header is a Python long (u32)
+ if first_pb_header >=0 and first_pb_header <= MAX_VALUE_OF_U32:
+ self.first_pb_header = first_pb_header
+ else:
+ raise OutOfRangeError("First PB Header")
+ else:
+ try:
+ # First PB Header is a PB Header object
+ first_pb_header.set_mmqf(mmqf)
+ self.first_pb_header = first_pb_header.get()
+ except AttributeError:
+ raise TypeError("First PB Header")
+
+ def get_fc_10(self):
+ """Get the FC 1.0.
+ The FC 1.0 is a Python long (u32).
+ """
+ return self.fc_10
+
+ def get_fc_av(self):
+ """Get the FC AV.
+ The FC AV is a tuple of 4 Python longs (u32).
+ """
+ return self.fc_av
+
+ def get_iv(self):
+ """Get the IV.
+ IV is a string of length equals to 3 * sizeof(u32).
+ """
+ return self.iv
+
+ def get_nek(self):
+ """Get the NEK.
+ NEK is a string of length equals to 4 * sizeof(u32).
+ """
+ return self.nek
+
+ def get_first_pb_header(self):
+ """Get the first PB Header.
+ The first PB Header is a Python long (u32).
+ """
+ return self.first_pb_header
+
+ def set_mpdu_attr(self, fc_10, fc_av, payload):
+ """Set the MPDU attributes from the received MPDU.
+ """
+
+ def sendnrecv(self, maximus, fc_mode=4, short_ppdu=0, mod=4, file=None, timeout=None, filter=None, count=1):
+ """This function sends the MPDU synchronously.
+ """
+ from maximus.simu.rx import recv
+ # Set MPDU attributes for Maximus
+ self.fill_mpdu_attr(fc_mode, short_ppdu, mod)
+ # Request to Maximus to send the MPDU synchronously
+ maximus.send_mpdu(self)
+ # Return the received MAC Frame(s)
+ return recv(maximus, timeout=timeout, filter=filter, count=count)
+
+ def send(self, maximus, fc_mode=4, short_ppdu=0, mod=4, file=None):
+ """This function sends the MPDU asynchronously.
+ """
+ # Set MPDU attributes for Maximus
+ self.fill_mpdu_attr(fc_mode, short_ppdu, mod)
+ # Request to Maximus to send the MPDU asynchronously
+ maximus.send_mpdu(self)
+
+ def get_type(self):
+ """This function returns the MPDU object type into a Python string.
+ """
+ return MPDU_TYPES[0] # 'PHY_TYPE_NONE'
+
+ def fill_mpdu_attr(self, fc_mode, short_ppdu, mod):
+ """Set the MPDU attributes from the MPDU to send.
+ """
diff --git a/cesar/maximus/python/maximus/macframe/msdu.py b/cesar/maximus/python/maximus/macframe/msdu.py
new file mode 100644
index 0000000000..26d8997c5d
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/msdu.py
@@ -0,0 +1,66 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.utils.format import *
+
+# Constants to check arguments validity
+MIN_SIZE_OF_MSDU = 60 # in octets
+MAX_SIZE_OF_MSDU = 1518 # in octets
+
+# MSDU object type
+MSDU_TYPES = ['ETHERNET_TYPE_NONE',\
+ 'ETHERNET_TYPE_DATA',\
+ 'ETHERNET_TYPE_MME',\
+ 'ETHERNET_TYPE_DATA_BUFFER_ADD',\
+ 'ETHERNET_TYPE_MME_BUFFER_ADD',\
+ 'ETHERNET_TYPE_INTERFACE_BUFFER_ADD',\
+ 'ETHERNET_TYPE_BUFFER_RELEASED',\
+ 'ETHERNET_TYPE_SNIFFER']
+
+class MSDU:
+
+ def set_msdu_attr(self, payload):
+ """This function sets the MSDU attributes from the received Ethernet Frame.
+ """
+
+ def sendnrecv(self, maximus, station, file=None, timeout=None, filter=None, count=1):
+ """This function sends the MSDU synchronously.
+ """
+ from maximus.simu.rx import recv
+ # Request to Maximus to send the MSDU synchronously
+ while not station.is_idle():
+ maximus.process()
+ maximus.send_msdu(self, station.get_station_id())
+ # Return the received Ethernet Frame(s)
+ return recv(maximus, timeout=timeout, filter=filter, count=count)
+
+ def send(self, maximus, station, file=None):
+ """This function sends the MSDU asynchronously.
+ """
+ # Request to Maximus to send the MSDU asynchronously
+ while not station.is_idle():
+ maximus.process()
+ maximus.send_msdu(self, station.get_station_id())
+
+ def get(self):
+ """This function returns the MSDU object into a string.
+ """
+
+ def get_ether_type(self):
+ """This function returns the MSDU object type into a Python integer (u8).
+ """
+ return 0
+
+ def get_type(self):
+ """This function returns the MSDU object type into a Python string.
+ """
+ return MSDU_TYPES[self.get_ether_type()] # 'ETHERNET_TYPE_NONE'
+
+ def pad(self, length):
+ """This function adds padding to the MSDU.
+ """
+ pad = ''
+ for i in range (0, length):
+ pad += htohp8(0)
+ return pad
diff --git a/cesar/maximus/python/maximus/macframe/pb.py b/cesar/maximus/python/maximus/macframe/pb.py
new file mode 100644
index 0000000000..3ff0df41f9
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/pb.py
@@ -0,0 +1,59 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.macframe.mpdu import SIZE_OF_PB136, SIZE_OF_PB520, MPDU_TYPES, MPDU
+from maximus.utils.exception import OutOfRangeError
+
+class PB(MPDU):
+ """The PB is composed of the following field:
+ pblist - a Python list composed of 236 PBs maximum
+ """
+ def __init__(self):
+ self.__pblist = []
+
+ def __set_pblist(self, payload):
+ """Set the list of received PBs.
+ The payload must be a Python string.
+ """
+ if payload is None:
+ self.__pblist = []
+ elif len(payload) == SIZE_OF_PB136:
+ self.__pblist.append(payload)
+ elif len(payload) % SIZE_OF_PB520 == 0:
+ for i in range(0,len(payload)/SIZE_OF_PB520):
+ self.__pblist.append(payload[i*SIZE_OF_PB520:min((i+1)*SIZE_OF_PB520, len(payload))])
+ else:
+ raise OutOfRangeError("List of PBs")
+
+ def get_pblist(self):
+ """Get the list of received PBs.
+ The list of PBs is a Python list of Python strings.
+ """
+ return self.__pblist
+
+ def get_type(self):
+ """This function returns the PB object type into a Python string.
+ """
+ return MPDU_TYPES[3]
+
+ def set_mpdu_attr(self, fc_10, fc_av, payload):
+ """Set the MPDU attributes from the received MPDU.
+ """
+ # Set FC 1.0
+ if type(fc_10) is not int:
+ raise OutOfRangeError("FC 1.0")
+ else:
+ self.set_fc_10(fc_10)
+
+ # Set FC AV
+ if type(fc_av) is not tuple:
+ raise OutOfRangeError("FC AV")
+ else:
+ self.set_fc_av(fc_av)
+
+ # Set list of PBs
+ if type(payload) is not str:
+ raise OutOfRangeError("Payload")
+ else:
+ self.__set_pblist(payload)
diff --git a/cesar/maximus/python/maximus/macframe/pbheader.py b/cesar/maximus/python/maximus/macframe/pbheader.py
new file mode 100644
index 0000000000..9b9c65ef40
--- /dev/null
+++ b/cesar/maximus/python/maximus/macframe/pbheader.py
@@ -0,0 +1,95 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.utils.exception import OutOfRangeError
+from maximus.utils.format import MAX_VALUE_OF_U16, SIZE_OF_U16
+
+# Constants to check arguments validity
+MAX_VALUE_OF_SSN = MAX_VALUE_OF_U16
+MAX_VALUE_OF_MFBO = 0x1FF
+MAX_VALUE_OF_RSVD = 0x7
+
+# Constants for 'self.get()' function
+size_of_ssn = 8 * SIZE_OF_U16 # in bits
+size_of_mfbo = 9 # in bits
+
+class PBHeader:
+ """The PB is composed of the 8 following fields:
+ SSN (16 bits) - a Python integer
+ MFBO (9 bits) - a Python integer
+ VPBF (1 bit) - a Python boolean
+ MMQF (1 bit) - a Python boolean
+ MFBF (1 bit) - a Python boolean
+ OPSF (1 bit) - a Python boolean
+ RSVD (3 bits) - a Python integer
+ """
+ def __init__(self, SSN=0, MFBO=0, VPBF=True, MMQF=False, MFBF=True, OPSF=False, RSVD=0):
+
+ # Set first Segment Sequence Number
+ if type(SSN) is int:
+ if SSN >=0 and SSN <= MAX_VALUE_OF_SSN:
+ self.__ssn = SSN
+ else:
+ raise OutOfRangeError("SSN")
+ else:
+ raise TypeError("SSN")
+
+ # Set MAC Frame Boundary Offset
+ if type(MFBO) is int:
+ if MFBO >=0 and MFBO <= MAX_VALUE_OF_MFBO:
+ self.__mfbo = MFBO
+ else:
+ raise OutOfRangeError("MFBO")
+ else:
+ raise TypeError("MFBO")
+
+ # Set Valid PHY Block Flag
+ if type(VPBF) is bool:
+ self.__vpbf = VPBF
+ else:
+ raise TypeError("VPBF")
+
+ # Set Management Message Queue Flag
+ if type(MMQF) is bool:
+ self.__mmqf = MMQF
+ else:
+ raise TypeError("MMQF")
+
+ # Set MAC Frame Boundary Flag
+ if type(MFBF) is bool:
+ self.__mfbf = MFBF
+ else:
+ raise TypeError("MFBF")
+
+ # Set Oldest Pending Segment Flag
+ if type(OPSF) is bool:
+ self.__opsf = OPSF
+ else:
+ raise TypeError("OPSF")
+
+ # Set Reserved
+ if type(RSVD) is int:
+ if RSVD >=0 and RSVD <= MAX_VALUE_OF_RSVD:
+ self.__rsvd = RSVD
+ else:
+ raise OutOfRangeError("RSVD")
+ else:
+ raise TypeError("RSVD")
+
+ def set_mmqf(self, mmqf):
+ """Sets the Management Message Queue Flag.
+ The MMQF must be a Python boolean.
+ """
+ self.__mmqf = mmqf
+
+ def get(self):
+ """This function returns the PB Header into an u32.
+ """
+ return (self.__rsvd << (size_of_ssn + size_of_mfbo + 4)) +\
+ (int(self.__opsf) << (size_of_ssn + size_of_mfbo + 3)) +\
+ (int(self.__mfbf) << (size_of_ssn + size_of_mfbo + 2)) +\
+ (int(self.__mmqf) << (size_of_ssn + size_of_mfbo + 1)) +\
+ (int(self.__vpbf) << (size_of_ssn + size_of_mfbo)) +\
+ (self.__mfbo << size_of_ssn) +\
+ self.__ssn
diff --git a/cesar/maximus/python/maximus/mme/__init__.py b/cesar/maximus/python/maximus/mme/__init__.py
new file mode 100644
index 0000000000..a1178d6a80
--- /dev/null
+++ b/cesar/maximus/python/maximus/mme/__init__.py
@@ -0,0 +1,10 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = ["create", "mme", "mmentry", "mmheader", "mmtype"]
+
+from mme import MME
+from mmentry import MMEntry
+from mmheader import MMHeader
+from mmtype import *
diff --git a/cesar/maximus/python/maximus/mme/create.py b/cesar/maximus/python/maximus/mme/create.py
new file mode 100644
index 0000000000..5ddb4e7725
--- /dev/null
+++ b/cesar/maximus/python/maximus/mme/create.py
@@ -0,0 +1,10 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.mme.mme import MME
+
+def create_mme():
+ """This function creates and returns a new MME object.
+ """
+ return MME()
diff --git a/cesar/maximus/python/maximus/mme/mme.py b/cesar/maximus/python/maximus/mme/mme.py
new file mode 100644
index 0000000000..b4dcdb5326
--- /dev/null
+++ b/cesar/maximus/python/maximus/mme/mme.py
@@ -0,0 +1,130 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.mme.mmentry import MAX_SIZE_OF_MMENTRY, MMEntry
+from maximus.mme.mmheader import MMHeader, MIN_SIZE_OF_MMHEADER, MAX_SIZE_OF_MMHEADER,\
+ SIZE_OF_ODA, SIZE_OF_OSA,\
+ SIZE_OF_VLANTAG, MIN_VALUE_OF_VLANTAG, MAX_VALUE_OF_VLANTAG
+from maximus.macframe.msdu import MIN_SIZE_OF_MSDU, MSDU_TYPES, MSDU
+from maximus.utils.exception import OutOfRangeError
+from maximus.utils.format import ntoh32
+
+# Define an empty MME structure for Maximus
+class MMEStruct:
+ """The MME structure is composed of the 2 following fields:
+ header - a Python string of length equals to 23 octets
+ entry - a Python string of length smaller than 1518 octets
+ """
+ pass
+
+class MME(MSDU):
+ """The MME is composed of the 2 following fields:
+ MMHeader (23-octet)
+ MMEntry
+ """
+ def __init__(self, MMHeader=MMHeader(), MMEntry=MMEntry()):
+
+ # Create an MME structure for Maximus
+ self.__mme = MMEStruct()
+
+ self.set_mmheader(MMHeader)
+ self.set_mmentry(MMEntry)
+
+ def set_mmheader(self, mmheader):
+ """Set the MM Header.
+ The MM Header can be an MM Header object,
+ or a Python string of length equals to 19 or 23 octets.
+ """
+ self.__mmheader = mmheader
+ try:
+ # MM Header is an MM Header object
+ self.__mme.header = mmheader.get() # set MM Header into a Python string of length equals to 23 octets
+ except AttributeError:
+ if len(mmheader) == MIN_SIZE_OF_MMHEADER or len(mmheader) == MAX_SIZE_OF_MMHEADER:
+ # MM Header is a Python string of length equals to 19 or 23 octets
+ self.__mme.header = mmheader
+ else:
+ raise OutOfRangeError("MM Header")
+
+ def set_mmentry(self, mmentry):
+ """Set the MM Entry.
+ The MM Entry can be an MM Entry object,
+ or a Python string of length smaller than (1518 - 23) octets.
+ """
+ self.__mmentry = mmentry
+ try:
+ # MM Entry is an MM Entry object
+ self.__mme.entry = mmentry.get() # set MM Entry into a Python string of length smaller than (1518 - 23) octets
+ except AttributeError:
+ if len(mmentry) <= MAX_SIZE_OF_MMENTRY:
+ # MM Entry is a Python string of length smaller than (1518 - 23) octets
+ self.__mme.entry = mmentry
+ else:
+ raise OutOfRangeError("MM Entry too long")
+
+ def set_msdu_attr(self, payload):
+ """Set the MME attributes from the received Ethernet Frame.
+ """
+ # Check VLAN Tag
+ begin = SIZE_OF_ODA + SIZE_OF_OSA
+ end = begin + SIZE_OF_VLANTAG
+ if ntoh32(payload[begin:end]) <= MAX_VALUE_OF_VLANTAG\
+ and ntoh32(payload[begin:end]) >= MIN_VALUE_OF_VLANTAG:
+ # There is a VLAN Tag
+ end = MAX_SIZE_OF_MMHEADER
+ else:
+ # There is no VLAN Tag
+ end = MIN_SIZE_OF_MMHEADER
+
+ # Set MM Header
+ begin = 0
+ self.set_mmheader(payload[begin:end])
+
+ # Set MM Entry
+ begin = end
+ end = len(payload)
+ self.set_mmentry(payload[begin:end])
+
+ def get_mmheader(self):
+ """Get the MM Header.
+ The MM Header can be an MM Header object,
+ or a Python string of length equals to 23 octets.
+ """
+ return self.__mmheader
+
+ def get_mmentry(self):
+ """Get the MM Entry.
+ The MM Entry can be an MM Entry object,
+ or a Python string of length smaller than 1518 octets.
+ """
+ return self.__mmentry
+
+ def get(self):
+ """This function returns the MME into a string.
+ """
+ length = len(self.__mme.header) + len(self.__mme.entry)
+ mmepad = self.pad(MIN_SIZE_OF_MSDU - length)
+ mme = self.__mme.header + self.__mme.entry + mmepad
+ return mme
+
+ def get_ether_type(self):
+ """This function returns the MME type into a Python integer (uint8_t).
+ """
+ type = 0
+ for i, j in enumerate(MSDU_TYPES):
+ if j == self.get_type():
+ type = i
+ return type # 2
+
+ def get_type(self):
+ """This function returns the MME type into a Python string.
+ """
+ return MSDU_TYPES[2] # 'ETHERNET_TYPE_MME'
+
+ def display(self):
+ """This function displays the MME in strings.
+ """
+ print "display the MME"
+ print "MM Header =", self.__mme.header
+ print "MM Entry =", self.__mme.entry
diff --git a/cesar/maximus/python/maximus/mme/mmentry.py b/cesar/maximus/python/maximus/mme/mmentry.py
new file mode 100644
index 0000000000..7d69dd0817
--- /dev/null
+++ b/cesar/maximus/python/maximus/mme/mmentry.py
@@ -0,0 +1,33 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.mme.mmheader import MIN_SIZE_OF_MMHEADER
+from maximus.macframe.msdu import MAX_SIZE_OF_MSDU
+from maximus.utils.exception import OutOfRangeError
+
+# Constants to check arguments validity
+MAX_SIZE_OF_MMENTRY = MAX_SIZE_OF_MSDU - MIN_SIZE_OF_MMHEADER
+MAX_SIZE_OF_DATA = MAX_SIZE_OF_MMENTRY
+
+class MMEntry:
+
+ def __init__(self, data=''):
+ self.set_data(data)
+
+ def set_data(self, data):
+ """Set Data.
+ Data must be a Python string of length smaller than 1518 octets.
+ """
+ self.__data = data
+ if len(data) > MAX_SIZE_OF_DATA:
+ raise OutOfRangeError("Data")
+
+ def get_data(self):
+ """Get Data.
+ Data must be a Python string of length smaller than 1518 octets.
+ """
+ return self.__data
+
+ def get(self):
+ return self.get_data()
diff --git a/cesar/maximus/python/maximus/mme/mmheader.py b/cesar/maximus/python/maximus/mme/mmheader.py
new file mode 100644
index 0000000000..01588973c0
--- /dev/null
+++ b/cesar/maximus/python/maximus/mme/mmheader.py
@@ -0,0 +1,298 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.utils.exception import OutOfRangeError
+from maximus.utils.format import *
+
+# Constants to check arguments validity
+MIN_SIZE_OF_MMHEADER = 19 # in octets
+MAX_SIZE_OF_MMHEADER = 23 # in octets
+SIZE_OF_ODA = SIZE_OF_U48
+MAX_VALUE_OF_ODA = MAX_VALUE_OF_U48
+SIZE_OF_OSA = SIZE_OF_ODA
+MAX_VALUE_OF_OSA = MAX_VALUE_OF_ODA
+MIN_VALUE_OF_VLANTAG = 0x81000000
+MAX_VALUE_OF_VLANTAG = 0x8100FFFF
+SIZE_OF_MTYPE = SIZE_OF_U16
+MAX_VALUE_OF_MTYPE = MAX_VALUE_OF_U16
+SIZE_OF_VLANTAG = SIZE_OF_U32
+SIZE_OF_MMV = SIZE_OF_U8
+MAX_VALUE_OF_MMV = MAX_VALUE_OF_U8
+SIZE_OF_MMTYPE = SIZE_OF_U16
+MAX_VALUE_OF_MMTYPE = MAX_VALUE_OF_U16
+SIZE_OF_FMI = SIZE_OF_U16
+MAX_VALUE_OF_FMI = MAX_VALUE_OF_U16
+
+# Define an empty MM Header structure for Maximus
+class MMHeaderStruct:
+ """The MME structure is composed of the 7 following fields:
+ oda - a Python string of length equals to 6 octets
+ osa - a Python string of length equals to 6 octets
+ vlantag (optional) - a Python string of length equals to 4 octets
+ mtype - a Python string of length equals to 2 octets
+ mmv - a Python string of length equals to 1 octet
+ mmtype - a Python string of length equals to 2 octets
+ fmi - a Python string of length equals to 2 octets
+ """
+ pass
+
+class MMHeader:
+
+ def __init__(self, ODA=MAX_VALUE_OF_ODA, OSA=0, VLANTag=None, MTYPE=0x88e1, MMV=0, MMTYPE=0, FMI=0):
+
+ # Create an MME structure for Maximus
+ self.__mmheader = MMHeaderStruct()
+
+ self.set_oda(ODA)
+ self.set_osa(OSA)
+ self.set_vlantag(VLANTag)
+ self.set_mtype(MTYPE)
+ self.set_mmv(MMV)
+ self.set_mmtype(MMTYPE)
+ self.set_fmi(FMI)
+
+ def set_oda(self, oda):
+ """Set the ODA.
+ The ODA can be a Python tuple of 6 Python integers,
+ a Python long (decimal or hexadecimal value),
+ a Python string of length equals to 6 octets,
+ or a Python string of length equals to 17 octets.
+ """
+ self.__oda = oda
+ if type(oda) is str:
+ if len(oda) == 3 * SIZE_OF_ODA - 1:
+ # ODA is a Python string of length equals to 17 octets ('XX:XX:XX:XX:XX:XX')
+ if oda.count(':') == SIZE_OF_ODA - 1:
+ self.__mmheader.oda = pack(n + u64, int(oda.replace(':',''), 16))[SIZE_OF_U16:]
+ else:
+ raise OutOfRangeError("ODA")
+ elif len(oda) == SIZE_OF_ODA:
+ # ODA is a Python string of length equals to 6 octets
+ self.__mmheader.oda = oda
+ else:
+ raise OutOfRangeError("ODA")
+ elif type(oda) is long or type(oda) is int:
+ # ODA is a Python long
+ if oda <= MAX_VALUE_OF_ODA and oda >= 0:
+ self.__mmheader.oda = hton48(oda)
+ else:
+ raise OutOfRangeError("ODA")
+ elif type(oda) is tuple:
+ # ODA is a Python tuple
+ if len(oda) == SIZE_OF_ODA:
+ self.__mmheader.oda = hton48_tuple(oda)
+ else:
+ raise OutOfRangeError("ODA")
+ else:
+ raise TypeError("ODA")
+
+ def set_osa(self, osa):
+ """Set the OSA.
+ The OSA can be a Python tuple of 6 Python integers,
+ a Python long (decimal or hexadecimal value),
+ a Python string of length equals to 6 octets,
+ or a Python string of length equals to 17 octets.
+ """
+ self.__osa = osa
+ if type(osa) is str:
+ if len(osa) == 3 * SIZE_OF_OSA - 1:
+ # OSA is a Python string of length equals to 17 octets ('XX:XX:XX:XX:XX:XX')
+ if osa.count(':') == SIZE_OF_OSA - 1:
+ self.__mmheader.osa = pack(n + u64, int(osa.replace(':',''), 16))[SIZE_OF_U16:]
+ else:
+ raise OutOfRangeError("OSA")
+ elif len(osa) == SIZE_OF_OSA:
+ # OSA is a Python string of length equals to 6 octets
+ self.__mmheader.osa = osa
+ else:
+ raise OutOfRangeError("OSA")
+ elif type(osa) is long or type(osa) is int:
+ # OSA is a Python long
+ if osa <= MAX_VALUE_OF_OSA and osa >= 0:
+ self.__mmheader.osa = hton48(osa)
+ else:
+ raise OutOfRangeError("OSA")
+ elif type(osa) is tuple:
+ # OSA is a Python tuple
+ if len(osa) == SIZE_OF_OSA:
+ self.__mmheader.osa = hton48_tuple(osa)
+ else:
+ raise OutOfRangeError("OSA")
+ else:
+ raise TypeError("OSA")
+
+ def set_vlantag(self, vlantag):
+ """Set the VLAN Tag (VLAN Tag is optional).
+ The VLAN Tag can be a Python long (decimal or hexadecimal value),
+ or a Python string of length equals to 4 octets.
+ """
+ self.__vlantag = vlantag
+ if type(vlantag) is str:
+ if len(vlantag) == SIZE_OF_VLANTAG:
+ # VLAN Tag is a Python string of length equals to 4 octets
+ if ntoh32(vlantag) <= MAX_VALUE_OF_VLANTAG and ntoh32(vlantag) >= MIN_VALUE_OF_VLANTAG:
+ self.__mmheader.vlantag = vlantag
+ else:
+ raise OutOfRangeError("VLAN Tag")
+ else:
+ raise OutOfRangeError("VLAN Tag")
+ elif type(vlantag) is int or type(vlantag) is long:
+ # VLAN Tag is a Python long
+ if vlantag <= MAX_VALUE_OF_VLANTAG and vlantag >= MIN_VALUE_OF_VLANTAG:
+ self.__mmheader.vlantag = hton32(vlantag)
+ else:
+ raise OutOfRangeError("VLAN Tag")
+ elif vlantag is None:
+ self.__mmheader.vlantag = ''
+ else:
+ raise TypeError("VLAN Tag")
+
+ def set_mtype(self, mtype):
+ """Set the MTYPE.
+ The MTYPE can be a Python integer (decimal or hexadecimal value),
+ or a Python string of length equals to 2 octets.
+ """
+ self.__mtype = mtype
+ try:
+ if len(mtype) == SIZE_OF_MTYPE:
+ # MTYPE is a Python string of length equals to 2 octets
+ self.__mmheader.mtype = mtype
+ else:
+ raise OutOfRangeError("MTYPE")
+ except TypeError:
+ # MTYPE is a Python integer
+ if mtype <= MAX_VALUE_OF_MTYPE and mtype >= 0:
+ self.__mmheader.mtype = hton16(mtype)
+ else:
+ raise OutOfRangeError("MTYPE")
+
+ def set_mmv(self, mmv):
+ """Set the MMV.
+ The MMV can be a Python integer (decimal or hexadecimal value),
+ or a Python string of length equals to 1 octet.
+ """
+ self.__mmv = mmv
+ try:
+ if len(mmv) == SIZE_OF_MMV:
+ # MMV is a Python string of length equals to 1 octet
+ self.__mmheader.mmv = mmv
+ else:
+ raise OutOfRangeError("MMV")
+ except TypeError:
+ # MMV is a Python integer
+ if mmv <= MAX_VALUE_OF_MMV and mmv >= 0:
+ self.__mmheader.mmv = htohp8(mmv)
+ else:
+ raise OutOfRangeError("MMV")
+
+ def set_mmtype(self, mmtype):
+ """Set the MMTYPE.
+ The MMTYPE can be a Python integer (decimal or hexadecimal value),
+ or a Python string of length equals to 2 octets.
+ """
+ self.__mmtype = mmtype
+ if mmtype != None:
+ try:
+ if len(mmtype) == SIZE_OF_MMTYPE:
+ # MMTYPE is a Python string of length equals to 2 octets
+ self.__mmheader.mmtype = mmtype
+ else:
+ raise OutOfRangeError("MMTYPE")
+ except TypeError:
+ # MMTYPE is a Python integer
+ if mmtype <= MAX_VALUE_OF_MMTYPE and mmtype >= 0:
+ self.__mmheader.mmtype = htohp16(mmtype)
+ else:
+ raise OutOfRangeError("MMTYPE")
+
+ def set_fmi(self, fmi):
+ """Set the FMI.
+ The FMI can be a Python integer (decimal or hexadecimal value),
+ or a Python string of length equals to 2 octets.
+ """
+ self.__fmi = fmi
+ try:
+ if len(fmi) == SIZE_OF_FMI:
+ # FMI is a Python string of length equals to 2 octets
+ self.__mmheader.fmi = fmi
+ else:
+ raise OutOfRangeError("FMI")
+ except TypeError:
+ # FMI is a Python integer
+ if fmi <= MAX_VALUE_OF_FMI and fmi >= 0:
+ self.__mmheader.fmi = htohp16(fmi)
+ else:
+ raise OutOfRangeError("FMI")
+
+ def get_oda(self):
+ """Get the ODA.
+ The ODA can be a Python tuple of 6 Python integers,
+ a Python long (decimal or hexadecimal value),
+ a Python string of length equals to 6 octets,
+ or a Python string of length equals to 17 octets.
+ """
+ return self.__oda
+
+ def get_osa(self):
+ """Get the OSA.
+ The OSA can be a Python tuple of 6 Python integers,
+ a Python long (decimal or hexadecimal value),
+ a Python string of length equals to 6 octets,
+ or a Python string of length equals to 17 octets.
+ """
+ return self.__osa
+
+ def get_vlantag(self):
+ """Get the VLAN Tag (VLAN Tag is optional).
+ The VLAN Tag can be a Python long,
+ or a Python string of length equals to 4 octets.
+ """
+ return self.__vlantag
+
+ def get_mtype(self):
+ """Get the MTYPE.
+ The MTYPE can be a Python integer,
+ or a Python string of length equals to 2 octets.
+ """
+ return self.__mtype
+
+ def get_mmv(self):
+ """Get the MMV.
+ The MMV can be a Python integer,
+ or a Python string of length equals to 1 octet.
+ """
+ return self.__mmv
+
+ def get_mmtype(self):
+ """Get the MMTYPE.
+ The MMTYPE can be a Python integer,
+ or a Python string of length equals to 2 octets.
+ """
+ return self.__mmtype
+
+ def get_fmi(self):
+ """Get the FMI.
+ The FMI can be a Python integer,
+ or a Python string of length equals to 2 octets.
+ """
+ return self.__fmi
+
+ def get(self):
+ """This function returns the MM Header into a string.
+ """
+ mmheader = self.__mmheader.oda + self.__mmheader.osa + self.__mmheader.vlantag + self.__mmheader.mtype + self.__mmheader.mmv + self.__mmheader.mmtype + self.__mmheader.fmi
+ return mmheader
+
+ def display(self):
+ """This function displays the MM Header in hexadecimal values.
+ """
+ print "display the MM Header"
+ print "ODA =", hex(ntoh48(self.__mmheader.oda))
+ print "OSA =", hex(ntoh48(self.__mmheader.oda))
+ if self.get_vlantag() is not None:
+ print "VLAN Tag =", hex(ntoh16(self.__mmheader.vlantag))
+ print "MTYPE =", hex(ntoh16(self.__mmheader.mtype))
+ print "MMV =", hex(hptoh8(self.__mmheader.mmv))
+ print "MMTYPE =", hex(hptoh16(self.__mmheader.mmtype))
+ print "FMI =", hex(hptoh16(self.__mmheader.fmi))
diff --git a/cesar/maximus/python/maximus/mme/mmtype.py b/cesar/maximus/python/maximus/mme/mmtype.py
new file mode 100644
index 0000000000..bc4f978f48
--- /dev/null
+++ b/cesar/maximus/python/maximus/mme/mmtype.py
@@ -0,0 +1,20 @@
+#! usr/bin/env python
+
+#print __name__
+
+# MME name constants to compute MMTYPE
+DRV_STA_SET_MAC_ADDR = 0xA000
+DRV_STA_SET_CCO_PREF = 0xA004
+DRV_STA_SET_WAS_CCO = 0xA008
+DRV_STA_SET_NPW = 0xA00C
+DRV_STA_SET_DPW = 0xA010
+DRV_STA_SET_SL = 0xA014
+DRV_STA_SET_M_STA_HFID = 0xA018
+DRV_STA_SET_U_STA_HFID = 0xA01C
+DRV_STA_SET_AVLN_HFID = 0xA020
+DRV_STA_SET_TONEMASK = 0xA024
+DRV_STA_START = 0xA028
+DRV_STA_STOP = 0xA02C
+
+# MME types dictionnary to compute MMTYPE
+MME_TYPES = {'REQ':0x00, 'CNF':0x01, 'IND':0x02, 'RSP':0x03}
diff --git a/cesar/maximus/python/maximus/result/__init__.py b/cesar/maximus/python/maximus/result/__init__.py
new file mode 100644
index 0000000000..730e8c685d
--- /dev/null
+++ b/cesar/maximus/python/maximus/result/__init__.py
@@ -0,0 +1,5 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = []
diff --git a/cesar/maximus/python/maximus/simu/__init__.py b/cesar/maximus/python/maximus/simu/__init__.py
new file mode 100644
index 0000000000..abcdd28c01
--- /dev/null
+++ b/cesar/maximus/python/maximus/simu/__init__.py
@@ -0,0 +1,8 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = ["rx", "tx"]
+
+from rx import recv
+from tx import sendnrecv, send
diff --git a/cesar/maximus/python/maximus/simu/rx.py b/cesar/maximus/python/maximus/simu/rx.py
new file mode 100644
index 0000000000..d4257bf12a
--- /dev/null
+++ b/cesar/maximus/python/maximus/simu/rx.py
@@ -0,0 +1,136 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.ethernet.create import create_eth, create_buffer, create_sniffer
+from maximus.macframe.create import create_pb
+from maximus.mme.create import create_mme
+
+class GenericCallback:
+ """Following class permits to pre-register parameters for a function,
+ then call the function with registered parameters
+ followed by optional additional parameters precised during the real call.
+ """
+ def __init__(self, callback, *firstArgs):
+ self.__callback = callback
+ self.__firstArgs = firstArgs
+ def __call__(self, *args):
+ apply(self.__callback, self.__firstArgs + args)
+
+def cb(rx, frame):
+ """When a frame is received, check if it corresponds to user expectations.
+ If this is the case, add it to the RX received frame(s) list
+ and decrement the RX messages counter.
+ Return 'True' is the RX messages counter equals 0.
+ """
+ ended = False
+ if rx.call_filter_fc(frame):
+ rx.add_frame(frame)
+ rx.decr_counter()
+ if rx.get_counter() == 0:
+ ended = True
+ return ended
+
+class Rx:
+ """RX is an internal object for Maximus, to define the expected response.
+ """
+ def __init__(self, maximus, filter_fc=None, counter=0):
+ # Set RX attributes
+ self.set_filter_fc(filter_fc)
+ self.set_counter(counter)
+
+ # Set the received MAC Frame(s) list to its default value
+ self.__frame_list = None
+
+ # Set Maximus reception attributes
+ self.__maximus = maximus
+ self.__cb = GenericCallback(cb, self)
+ self.__maximus.set_mpdu_rx(self.__cb, create_pb)
+ self.__maximus.set_msdu_rx(self.__cb, create_eth, create_mme, create_buffer, create_sniffer)
+
+ def recv(self, timeout=None):
+ """This function only returns when the response defined by user is received,
+ i.e. when the messages counter equals 0,
+ or when the timeout expires.
+ The returned value is the received frame(s) list,
+ or None if timeout has expired before receiving any frame.
+ """
+ if timeout is None:
+ while self.get_counter() != 0:
+ self.__maximus.process()
+ elif type(timeout) is int or long and timeout >= 0:
+ # Calculate timeout tick value
+ timeout_tick_value = self.__maximus.get_date() + timeout
+ while self.get_counter() != 0 and self.__maximus.get_date() < timeout_tick_value:
+ self.__maximus.process()
+ else:
+ raise OutOfRangeError("Timeout")
+ return self.get_frame_list()
+
+ def set_filter_fc(self, filter_fc):
+ """Set the messages filter.
+ The messages filter must be a Python function taking a MAC Frame / MSDU object as argument,
+ returning 'True' if the received frame corresponds to the user expectations,
+ 'False' otherwise.
+ """
+ self.__filter_fc = filter_fc
+
+ def set_counter(self, counter):
+ """Set the messages counter.
+ The messages counter must be a Python integer.
+ """
+ if type(counter) is int and counter >= 0:
+ self.__counter = counter
+ else:
+ raise OutOfRangeError("Counter")
+
+ def decr_counter(self):
+ """When a message corresponding to the filter is received,
+ decrement the messages counter.
+ """
+ if self.get_counter() > 0:
+ self.__counter -= 1
+ else:
+ self.__counter = 0
+
+ def add_frame(self, frame):
+ """Add the received frame to the received frame(s) list.
+ The frame must be a MAC Frame / MSDU object.
+ """
+ if frame is None:
+ raise OutOfRangeError("Received frame")
+ if self.get_frame_list() is None:
+ self.__frame_list = [frame]
+ else:
+ self.__frame_list.append(frame)
+
+ def call_filter_fc(self, frame):
+ """This function calls the filter function with the received frame as argument,
+ and returns its result.
+ """
+ filter = True
+ if frame is None:
+ raise OutOfRangeError("Received frame")
+ elif self.__filter_fc is not None:
+ filter = self.__filter_fc(frame)
+ return filter
+
+ def get_counter(self):
+ """Get the messages counter.
+ The messages counter is a Python integer.
+ """
+ return self.__counter
+
+ def get_frame_list(self):
+ """Get the received frame(s) list.
+ The received frame(s) list is a list of (messages counter) received MAC Frame / MSDU object(s).
+ """
+ return self.__frame_list
+
+def recv(maximus, timeout=None, filter=None, count=1):
+ """This function waits for (count) specific frame(s) defined by user by the filter function.
+ """
+ # Create an RX object for frame(s) reception
+ rx = Rx(maximus, filter_fc=filter, counter=count)
+ # Return the received frame(s)
+ return rx.recv(timeout)
diff --git a/cesar/maximus/python/maximus/simu/tx.py b/cesar/maximus/python/maximus/simu/tx.py
new file mode 100644
index 0000000000..0e3f679531
--- /dev/null
+++ b/cesar/maximus/python/maximus/simu/tx.py
@@ -0,0 +1,9 @@
+#! usr/bin/env python
+
+#print __name__
+
+def sendnrecv(file, timeout=None, filter=None, count=1):
+ pass
+
+def send(file, count=1):
+ pass
diff --git a/cesar/maximus/python/maximus/station/__init__.py b/cesar/maximus/python/maximus/station/__init__.py
new file mode 100644
index 0000000000..87afe293ab
--- /dev/null
+++ b/cesar/maximus/python/maximus/station/__init__.py
@@ -0,0 +1,8 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = ["config", "sta"]
+
+from config import Config
+from sta import STA
diff --git a/cesar/maximus/python/maximus/station/config.py b/cesar/maximus/python/maximus/station/config.py
new file mode 100644
index 0000000000..2c5b8fce25
--- /dev/null
+++ b/cesar/maximus/python/maximus/station/config.py
@@ -0,0 +1,98 @@
+#! usr/bin/env python
+
+#print __name__
+
+# Default values of station parameters
+DEFAULT_MAC_ADDRESS = 0x123456789ABC
+DEFAULT_CCO_PREFERENCE = False
+DEFAULT_WAS_CCO = False
+DEFAULT_NPW = "HomePlugAV0123"
+DEFAULT_DPW = "DPW_"
+DEFAULT_M_STA_HFID = "M_STA_HFID_"
+DEFAULT_U_STA_HFID = "U_STA_HFID_"
+DEFAULT_AVLN_HFID = "AVLN_HomePlugAV0123"
+DEFAULT_SL = 0
+DEFAULT_TONEMASK = 85,139,167,214,225,282,302,409,419,569,591,736,748,856,882,1015,1027,1143,1535
+DEFAULT_SNID = 0
+
+class Config:
+ """The Config structure is composed of the 11 following fields:
+ mac_address - a Python tuple of 6 Python integers
+ cco_preference - a Python boolean
+ was_cco - a Python boolean
+ npw - a Python string of length from 8 to 64 octets
+ dpw - a Python string of length from 0 to 64 octets
+ m_sta_hfid - a Python string of length from 0 to 64 octets
+ u_sta_hfid - a Python string of length from 0 to 64 octets
+ avln_hfid - a Python string of length from 0 to 64 octets
+ sl - a Python integer from 0 to 2
+ tonemask - a Python tuple of Python integers
+ snid - a Python integer from 0 to 15
+ """
+ def __init__(self, default_config=True, mac_address=None, cco_preference=None, was_cco=None, npw=None, dpw=None, m_sta_hfid=None, u_sta_hfid=None, avln_hfid=None, sl=None, tonemask=None, snid=None):
+
+ # MAC address
+ if mac_address is None and default_config is True:
+ self.mac_address = DEFAULT_MAC_ADDRESS
+ else:
+ self.mac_address = mac_address
+
+ # CCo preference
+ if cco_preference is None and default_config is True:
+ self.cco_preference = DEFAULT_CCO_PREFERENCE
+ else:
+ self.cco_preference = cco_preference
+
+ # Was CCo
+ if was_cco is None and default_config is True:
+ self.was_cco = DEFAULT_WAS_CCO
+ else:
+ self.was_cco = was_cco
+
+ # Network password
+ if npw is None and default_config is True:
+ self.npw = DEFAULT_NPW
+ else:
+ self.npw = npw
+
+ # Device password
+ if dpw is None and default_config is True:
+ self.dpw = DEFAULT_DPW
+ else:
+ self.dpw = dpw
+
+ # Manufacturer STA HFID
+ if m_sta_hfid is None and default_config is True:
+ self.m_sta_hfid = DEFAULT_M_STA_HFID
+ else:
+ self.m_sta_hfid = m_sta_hfid
+
+ # User STA HFID
+ if u_sta_hfid is None and default_config is True:
+ self.u_sta_hfid = DEFAULT_U_STA_HFID
+ else:
+ self.u_sta_hfid = u_sta_hfid
+
+ # AVLN HFID
+ if avln_hfid is None and default_config is True:
+ self.avln_hfid = DEFAULT_AVLN_HFID
+ else:
+ self.avln_hfid = avln_hfid
+
+ # Security level
+ if sl is None and default_config is True:
+ self.sl = DEFAULT_SL
+ else:
+ self.sl = sl
+
+ # Tonemask
+ if tonemask is None and default_config is True:
+ self.tonemask = DEFAULT_TONEMASK
+ else:
+ self.tonemask = tonemask
+
+ # SNID
+ if snid is None and default_config is True:
+ self.snid = DEFAULT_SNID
+ else:
+ self.snid = snid
diff --git a/cesar/maximus/python/maximus/station/sta.py b/cesar/maximus/python/maximus/station/sta.py
new file mode 100644
index 0000000000..ecd49ba425
--- /dev/null
+++ b/cesar/maximus/python/maximus/station/sta.py
@@ -0,0 +1,1052 @@
+#! usr/bin/env python
+
+#print __name__
+
+from maximus.station.config import *
+from maximus.ethernet.buffer import alloc_data_buffer, alloc_mme_buffer, alloc_interface_buffer
+from maximus.macframe.msdu import MSDU_TYPES
+from maximus.mme import *
+from maximus.mme.mmheader import MIN_SIZE_OF_MMHEADER, SIZE_OF_MMTYPE, SIZE_OF_FMI
+from maximus.utils.exception import Error, OutOfRangeError
+from maximus.utils.format import *
+
+# Constants to check arguments validity
+SIZE_OF_MAC_ADDRESS = SIZE_OF_U48 # in octets
+MAX_VALUE_OF_MAC_ADDRESS = MAX_VALUE_OF_U48
+MIN_SIZE_OF_NPW = 8 # in octets
+MAX_SIZE_OF_NPW = 64 # in octets
+MAX_SIZE_OF_DPW = MAX_SIZE_OF_NPW
+MAX_SIZE_OF_HFID = MAX_SIZE_OF_DPW
+MAX_VALUE_OF_SL = 2
+MAX_VALUE_OF_SNID = 15
+
+# Constants from 'hal/phy/defs.h'
+PHY_CARRIER_NB = 1155 # number of OFDM carrier, defined by the hardware
+PHY_CARRIER_OFFSET = 74 # number of first OFDM carrier, defined by the hardware
+PHY_TONEMASK_SIZE = ((PHY_CARRIER_NB + 8 - 1) / 8) # number of bytes needed to define a tonemask
+
+# Possible configuration modes to set station parameters
+CONFIG_MODES = ['MME', 'fcall_process_drv', 'fcall_cp_station']
+
+# Constants for MME responses
+# Driver ID result
+FAILURE = 0x00
+SUCCESS = 0x01
+RESERVED = 0x02 # to 0xFF
+# Driver ID error code on failure
+ERROR_CODES = {0x00:'Bad parameter', 0x01:'Unknown ID', 0x02:'Invalid value'}
+
+# Filter function to receive only MME responses
+def mme_filter(rsp):
+ if rsp.get_type() is MSDU_TYPES[2]: # ETHERNET_TYPE_MME
+ return True
+ elif rsp.get_type() is MSDU_TYPES[6]: # ETHERNET_TYPE_BUFFER_RELEASED
+ return False
+ else:
+ raise Error("Received unexpected message of type " + rsp.get_type())
+ return False
+
+class STA:
+ """The STA class is composed of the 16 following private attributes:
+ maximus - a Maximus object
+ station - a Sta object
+ name - a Python string
+ data_buffer_nb - a Python integer
+ mme_buffer_nb - a Python integer
+ interface_buffer_nb - a Python integer
+ mme_config - a Python boolean
+ mac_address - a Python tuple of 6 Python integers
+ cco_preference - a Python boolean
+ was_cco - a Python boolean
+ npw - a Python string of length from 8 to 64 octets
+ dpw - a Python string of length from 0 to 64 octets
+ m_sta_hfid - a Python string of length from 0 to 64 octets
+ u_sta_hfid - a Python string of length from 0 to 64 octets
+ avln_hfid - a Python string of length from 0 to 64 octets
+ sl - a Python integer from 0 to 2
+ tonemask - a Python tuple of Python integers
+ snid - a Python integer from 0 to 15
+ """
+ def __init__(self,\
+ maximus,\
+ executable=None,\
+ debug=False,\
+ name=None,\
+ data_buffer_nb=0,\
+ mme_buffer_nb=1,\
+ interface_buffer_nb=0,\
+ config_mode=CONFIG_MODES[0],\
+ config=Config()):
+ """Initialize the STA with following attributes:
+ maximus - a Maximus object (already initialized)
+ executable - a Python string
+ debug - a Python boolean
+ name - a Python string
+ data_buffer_nb - a Python integer
+ mme_buffer_nb - a Python integer
+ interface_buffer_nb - a Python integer
+ config_mode - a Python string
+ config - a Python Config object
+ """
+
+ # Set Maximus
+ self.__set_maximus(maximus)
+
+ # Create station and launch debugger if requested
+ self.__create_station(executable, debug)
+
+ # Set station configuration
+ self.set_name(name)
+ self.set_data_buffer_nb(data_buffer_nb)
+ self.set_mme_buffer_nb(mme_buffer_nb)
+ self.set_interface_buffer_nb(interface_buffer_nb)
+ self.set_config_mode(config_mode)
+ self.set_config(config)
+
+ # Start station
+ self.__start()
+
+ def __set_maximus(self, maximus):
+ """Set Maximus.
+ Maximus must be a Maximus object (already initialized).
+ """
+ self.__maximus = maximus
+
+ def __create_station(self, executable, debug):
+ """Create the station and launch the debugger if requested.
+ The station is a Sta object.
+ """
+ if executable is None:
+ self.__station = self.__get_maximus().create_sta()
+ else:
+ self.__station = self.__get_maximus().create_sta(executable)
+ if debug is True:
+ self.__station.debug()
+
+ def __start(self):
+ """Send the MAC_START message to the station.
+ """
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_mac_start") \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_START + MME_TYPES['REQ'])
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_mac_start") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_START)
+
+ def stop(self):
+ """Send the MAC_STOP message to the station.
+ """
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_mac_stop") \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_STOP + MME_TYPES['REQ'])
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_mac_stop") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_STOP)
+
+ def set_name(self, name):
+ """Set the name.
+ The name must be a Python string.
+ """
+ self.__name = name
+
+ # Configure the station name
+ if self.get_name() is not None:
+ self.get().set_name(name)
+
+ def set_data_buffer_nb(self, data_buffer_nb):
+ """Set the number of data buffers to allocate into the station.
+ The number of data buffers must be a Python integer.
+ """
+ if type(data_buffer_nb) is int:
+ if data_buffer_nb >= 0:
+ self.__data_buffer_nb = data_buffer_nb
+ else:
+ raise OutOfRangeError("Number of data buffers")
+ else:
+ raise TypeError
+
+ # Allocate data buffers
+ if data_buffer_nb > 0:
+ alloc_data_buffer(maximus=self.__get_maximus(), station=self.get(), buffer_nb=data_buffer_nb)
+
+ def set_mme_buffer_nb(self, mme_buffer_nb):
+ """Set the number of MME buffers to allocate into the station.
+ The number of MME buffers must be a Python integer.
+ """
+ if type(mme_buffer_nb) is int:
+ if mme_buffer_nb >= 0:
+ self.__mme_buffer_nb = mme_buffer_nb
+ else:
+ raise OutOfRangeError("Number of MME buffers")
+ else:
+ raise TypeError
+
+ # Allocate MME buffers
+ if mme_buffer_nb > 0:
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get(), buffer_nb=mme_buffer_nb)
+
+ def set_interface_buffer_nb(self, interface_buffer_nb):
+ """Set the number of interface buffers to allocate into the station.
+ The number of interface buffers must be a Python integer.
+ """
+ if type(interface_buffer_nb) is int:
+ if interface_buffer_nb >= 0:
+ self.__interface_buffer_nb = interface_buffer_nb
+ else:
+ raise OutOfRangeError("Number of interface buffers")
+ else:
+ raise TypeError
+
+ # Allocate interface buffers
+ if interface_buffer_nb > 0:
+ alloc_interface_buffer(maximus=self.__get_maximus(), station=self.get(), buffer_nb=interface_buffer_nb)
+
+ def set_config_mode(self, config_mode):
+ """Set the configuration mode.
+ The configuration mode must be a Python string of the CONFIG_MODES Python list.
+ """
+ if type(config_mode) is str:
+ if config_mode in CONFIG_MODES:
+ self.__config_mode = config_mode
+ else:
+ raise OutOfRangeError("Configuration mode")
+ else:
+ raise TypeError
+
+ def set_config(self, config):
+ """Set the station parameters.
+ The station configuration must be a Python Config structure.
+ """
+ self.set_mac_address(config.mac_address)
+ self.set_cco_preference(config.cco_preference)
+ self.set_was_cco(config.was_cco)
+ self.set_npw(config.npw)
+ self.set_dpw(config.dpw)
+ self.set_m_sta_hfid(config.m_sta_hfid)
+ self.set_u_sta_hfid(config.u_sta_hfid)
+ self.set_avln_hfid(config.avln_hfid)
+ self.set_sl(config.sl)
+ self.set_tonemask(config.tonemask)
+ self.set_snid(config.snid)
+
+ def set_mac_address(self, mac_address):
+ """Set the MAC address.
+ The MAC address can be a Python tuple of 6 Python integers,
+ a Python long (decimal or hexadecimal value),
+ a Python string of length equals to 6 octets,
+ or a Python string of length equals to 17 octets.
+ """
+ if type(mac_address) is str:
+ if len(mac_address) == 3 * SIZE_OF_MAC_ADDRESS - 1:
+ # MAC address is a Python string of length equals to 17 octets ('XX:XX:XX:XX:XX:XX')
+ if mac_address.count(':') == SIZE_OF_MAC_ADDRESS - 1:
+ self.__mac_address = unpack(6 * u8, pack(n + u64, int(mac_address.replace(':',''), 16))[SIZE_OF_U16:])
+ else:
+ raise OutOfRangeError("MAC address")
+ elif len(mac_address) == SIZE_OF_MAC_ADDRESS:
+ # MAC address is a Python string of length equals to 6 octets
+ self.__mac_address = ntoh48_tuple(mac_address)
+ else:
+ raise OutOfRangeError("MAC address")
+ elif type(mac_address) is long or type(mac_address) is int:
+ # MAC address is a Python long
+ if mac_address <= MAX_VALUE_OF_MAC_ADDRESS and mac_address >= 0:
+ self.__mac_address = ntoh48_tuple(hton48(mac_address))
+ else:
+ raise OutOfRangeError("MAC address")
+ elif type(mac_address) is tuple:
+ # MAC address is a Python tuple
+ if len(mac_address) == SIZE_OF_MAC_ADDRESS:
+ self.__mac_address = mac_address
+ else:
+ raise OutOfRangeError("MAC address")
+ elif mac_address is None:
+ self.__mac_address = None
+ else:
+ raise TypeError("MAC address")
+
+ # Send a message to the station to configure the MAC address
+ self.__send_mac_address()
+
+ def set_cco_preference(self, cco_preference):
+ """Set the CCo preference.
+ The CCo preference must be a Python boolean.
+ """
+ if type(cco_preference) is bool or cco_preference is None:
+ self.__cco_preference = cco_preference
+ else:
+ raise TypeError("CCo preference")
+
+ # Send a message to the station to configure the CCo preference
+ self.__send_cco_preference()
+
+ def set_was_cco(self, was_cco):
+ """Set the previous CCo status.
+ The previous CCo status must be a Python boolean.
+ """
+ if type(was_cco) is bool or was_cco is None:
+ self.__was_cco = was_cco
+ else:
+ raise TypeError("Was CCo")
+
+ # Send a message to the station to configure the previous CCo status
+ self.__send_was_cco()
+
+ def set_npw(self, npw):
+ """Set the Network PassWord.
+ The NPW must be a Python string of length from 8 to 64 octets.
+ """
+ if type(npw) is str:
+ if len(npw) >= MIN_SIZE_OF_NPW and len(npw) <= MAX_SIZE_OF_NPW:
+ self.__npw = npw
+ else:
+ raise OutOfRangeError("NPW")
+ elif npw is None:
+ self.__npw = npw
+ else:
+ raise TypeError("NPW")
+
+ # Send a message to the station to configure the NPW
+ self.__send_npw()
+
+ def set_dpw(self, dpw):
+ """Set the Device PassWord.
+ The DPW must be a Python string of length from 0 to 64 octets.
+ """
+ if type(dpw) is str:
+ if dpw is DEFAULT_DPW:
+ self.__dpw = DEFAULT_DPW + str(self.get_station_id())
+ elif len(dpw) <= MAX_SIZE_OF_DPW:
+ self.__dpw = dpw
+ else:
+ raise OutOfRangeError("DPW")
+ elif dpw is None:
+ self.__dpw = dpw
+ else:
+ raise TypeError("DPW")
+
+ # Send a message to the station to configure the DPW
+ self.__send_dpw()
+
+ def set_m_sta_hfid(self, m_sta_hfid):
+ """Set the Manufacturer STA HFID.
+ The Manufacturer STA HFID must be a Python string of length from 0 to 64 octets.
+ """
+ if type(m_sta_hfid) is str:
+ if m_sta_hfid is DEFAULT_M_STA_HFID:
+ self.__m_sta_hfid = DEFAULT_M_STA_HFID + str(self.get_station_id())
+ elif len(m_sta_hfid) <= MAX_SIZE_OF_HFID:
+ self.__m_sta_hfid = m_sta_hfid
+ else:
+ raise OutOfRangeError("Manufacturer STA HFID")
+ elif m_sta_hfid is None:
+ self.__m_sta_hfid = m_sta_hfid
+ else:
+ raise TypeError("Manufacturer STA HFID")
+
+ # Send a message to the station to configure the Manufacturer STA HFID
+ self.__send_m_sta_hfid()
+
+ def set_u_sta_hfid(self, u_sta_hfid):
+ """Set the User STA HFID.
+ The User STA HFID must be a Python string of length from 0 to 64 octets.
+ """
+ if type(u_sta_hfid) is str:
+ if u_sta_hfid is DEFAULT_U_STA_HFID:
+ self.__u_sta_hfid = DEFAULT_U_STA_HFID + str(self.get_station_id())
+ elif len(u_sta_hfid) <= MAX_SIZE_OF_HFID:
+ self.__u_sta_hfid = u_sta_hfid
+ else:
+ raise OutOfRangeError("User STA HFID")
+ elif u_sta_hfid is None:
+ self.__u_sta_hfid = u_sta_hfid
+ else:
+ raise TypeError("User STA HFID")
+
+ # Send a message to the station to configure the User STA HFID
+ self.__send_u_sta_hfid()
+
+ def set_avln_hfid(self, avln_hfid):
+ """Set the AVLN HFID.
+ The AVLN HFID must be a Python string of length from 0 to 64 octets.
+ """
+ if type(avln_hfid) is str:
+ if len(avln_hfid) <= MAX_SIZE_OF_HFID:
+ self.__avln_hfid = avln_hfid
+ else:
+ raise OutOfRangeError("AVLN HFID")
+ elif avln_hfid is None:
+ self.__avln_hfid = avln_hfid
+ else:
+ raise TypeError("AVLN HFID")
+
+ # Send a message to the station to configure the AVLN HFID
+ self.__send_avln_hfid()
+
+ def set_sl(self, sl):
+ """Set the Security Level.
+ The SL must be a Python integer from 0 to 2.
+ """
+ if type(sl) is int:
+ if sl >= 0 and sl <= MAX_VALUE_OF_SL:
+ self.__sl = sl
+ else:
+ raise OutOfRangeError("Security Level")
+ elif sl is None:
+ self.__sl = sl
+ else:
+ raise TypeError("SL")
+
+ # Send a message to the station to configure the SL
+ self.__send_sl()
+
+ def set_tonemask(self, carriers):
+ """Set the tonemask.
+ The carriers must be a Python tuple of Python integers.
+ """
+ if type(carriers) is tuple:
+ # Use the algorithm from 'mac/common/src/tonemask.c'
+ dtc_idx = 0
+ dtc_stop = carriers[dtc_idx] - PHY_CARRIER_OFFSET
+ dtc_on = False
+ tonemask = [] # Python list
+ for l in range(0, PHY_TONEMASK_SIZE):
+ tonemask.append(0)
+ for i in range(0, PHY_TONEMASK_SIZE):
+ for j in range(0, 8):
+ if i * 8 + j > dtc_stop:
+ dtc_on = not dtc_on
+ dtc_idx += 1
+ dtc_stop = carriers[dtc_idx] - PHY_CARRIER_OFFSET
+ if dtc_on is True:
+ tonemask[i] |= 1 << j
+
+ self.__tonemask = ''
+ for t in tonemask:
+ self.__tonemask += htohp8(t)
+ elif carriers is None:
+ self.__tonemask = carriers
+ else:
+ raise TypeError("Tonemask")
+
+ # Send a message to the station to configure the tonemask
+ self.__send_tonemask()
+
+ def set_snid(self, snid):
+ """Set the SNID.
+ The SNID must be a Python integer from 0 to 15.
+ """
+ if type(snid) is int:
+ if snid >= 0 and snid <= MAX_VALUE_OF_SNID:
+ self.__snid = snid
+ else:
+ raise OutOfRangeError("SNID")
+ elif snid is None:
+ self.__snid = snid
+ else:
+ raise TypeError("SNID")
+
+ # Send a message to the station to configure the SNID
+ self.__send_snid()
+
+ def __get_maximus(self):
+ """Get Maximus.
+ Maximus is a Maximus object.
+ """
+ return self.__maximus
+
+ def get(self):
+ """Get the station.
+ The station is a Sta object.
+ """
+ return self.__station
+
+ def get_name(self):
+ """Get the name.
+ The name is a Python string.
+ """
+ return self.__name
+
+ def get_data_buffer_nb(self):
+ """Get the number of data buffers allocated into the station.
+ The number of data buffers is a Python integer.
+ """
+ return self.__data_buffer_nb
+
+ def get_mme_buffer_nb(self):
+ """Get the number of MME buffers allocated into the station.
+ The number of MME buffers is a Python integer.
+ """
+ return self.__mme_buffer_nb
+
+ def get_interface_buffer_nb(self):
+ """Get the number of interface buffers allocated into the station.
+ The number of interface buffers is a Python integer.
+ """
+ return self.__interface_buffer_nb
+
+ def get_config_mode(self):
+ """Get the configuration mode.
+ The configuration mode is a Python string of the CONFIG_MODES Python list.
+ """
+ return self.__config_mode
+
+ def get_config(self):
+ """Get the station parameters.
+ The station configuration is a Python Config structure.
+ """
+ return Config(mac_address=self.get_mac_address(), \
+ cco_preference=self.get_cco_preference(), \
+ was_cco=self.get_was_cco(), \
+ npw=self.get_npw(), \
+ dpw=self.get_dpw(), \
+ m_sta_hfid=self.get_m_sta_hfid(), \
+ u_sta_hfid=self.get_u_sta_hfid(), \
+ avln_hfid=self.get_avln_hfid(), \
+ sl=self.get_sl(), \
+ tonemask=self.get_tonemask())
+
+ def get_mac_address(self):
+ """Get the MAC address.
+ The MAC address is a Python tuple of 6 Python integers.
+ """
+ return self.__mac_address
+
+ def get_cco_preference(self):
+ """Get the CCo preference.
+ The CCo preference is a Python boolean.
+ """
+ return self.__cco_preference
+
+ def get_was_cco(self):
+ """Get the previous CCo status.
+ The previous CCo status is a Python boolean.
+ """
+ return self.__was_cco
+
+ def get_npw(self):
+ """Get the Network PassWord.
+ The NPW is a Python string of length from 8 to 64 octets.
+ """
+ return self.__npw
+
+ def get_dpw(self):
+ """Get the Device PassWord.
+ The DPW is a Python string of length from 0 to 64 octets.
+ """
+ return self.__dpw
+
+ def get_m_sta_hfid(self):
+ """Get the Manufacturer STA HFID.
+ The Manufacturer STA HFID is a Python string of length from 0 to 64 octets.
+ """
+ return self.__m_sta_hfid
+
+ def get_u_sta_hfid(self):
+ """Get the User STA HFID.
+ The User STA HFID is a Python string of length from 0 to 64 octets.
+ """
+ return self.__u_sta_hfid
+
+ def get_avln_hfid(self):
+ """Get the AVLN HFID.
+ The AVLN HFID is a Python string of length from 0 to 64 octets.
+ """
+ return self.__avln_hfid
+
+ def get_sl(self):
+ """Get the Security Level.
+ The SL is a Python integer.
+ """
+ return self.__sl
+
+ def get_tonemask(self):
+ """Get the tonemask.
+ The tonemask is a bits field.
+ """
+ return self.__tonemask
+
+ def get_snid(self):
+ """Get the SNID.
+ The SNID is a Python integer.
+ """
+ return self.__snid
+
+ def __send_mac_address(self):
+ """Send a message to the station to configure the MAC address.
+ """
+ if self.get_mac_address() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_mac_address") \
+ .add_param_n_u8("mac_address", self.get_mac_address()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=self.get_mac_address(), MMV=0x01, MMTYPE = DRV_STA_SET_MAC_ADDR + MME_TYPES['REQ'])
+
+ # Computes MM Entry: Mac address of the station
+ # Octet Number = 0 - 5
+ # Field Size (Octets) = 6
+ StaMAC = ''
+ for t in self.get_mac_address():
+ StaMAC += htohp8(t)
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=StaMAC)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_mac_address") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_MAC_ADDR)
+
+ def __send_cco_preference(self):
+ """Send a message to the station to configure the CCo preference.
+ """
+ if self.get_cco_preference() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_cco_preference") \
+ .add_param_bool("cco_preference", self.get_cco_preference()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_SET_CCO_PREF + MME_TYPES['REQ'])
+
+ # Computes MM Entry:
+ # - 0x00 = Station is not CCo
+ # - 0x01 = Station is CCo
+ # - 0x02 - 0xFF = Reserved
+ # Octet Number = 0
+ # Field Size (Octets) = 1
+ if self.get_cco_preference() is True:
+ CCoPref = htohp8(0x01)
+ else:
+ CCoPref = htohp8(0x00)
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=CCoPref)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_cco_preference") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_CCO_PREF)
+
+ def __send_was_cco(self):
+ """Send a message to the station to configure the previous CCo status.
+ """
+ if self.get_was_cco() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_was_cco") \
+ .add_param_bool("was_cco", self.get_was_cco()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_SET_WAS_CCO + MME_TYPES['REQ'])
+
+ # Computes MM Entry:
+ # - 0x00 = Station was not CCo
+ # - 0x01 = Station was previously CCo
+ # - 0x02 - 0xFF = Reserved
+ # Octet Number = 0
+ # Field Size (Octets) = 1
+ if self.get_was_cco() is True:
+ WasCCo = htohp8(0x01)
+ else:
+ WasCCo = htohp8(0x00)
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=WasCCo)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_was_cco") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_WAS_CCO)
+
+ def __send_npw(self):
+ """Send a message to the station to configure the NPW.
+ """
+ if self.get_npw() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_npw") \
+ .add_param("npw", self.get_npw()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_SET_NPW + MME_TYPES['REQ'])
+
+ # Computes MM Entry: Human-Readable (ASCII) Station Network Password
+ # Octet Number = 0 - 63
+ # Field Size (Octets) = 64
+ StaNPW = self.get_npw()
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=StaNPW)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_npw") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_NPW)
+
+ def __send_dpw(self):
+ """Send a message to the station to configure the DPW.
+ """
+ if self.get_dpw() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_dpw") \
+ .add_param("dpw", self.get_dpw()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_SET_DPW + MME_TYPES['REQ'])
+
+ # Computes MM Entry: Human-Readable (ASCII) Station Device Password
+ # Octet Number = 0 - 63
+ # Field Size (Octets) = 64
+ StaDPW = self.get_dpw()
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=StaDPW)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_dpw") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_DPW)
+
+ def __send_m_sta_hfid(self):
+ """Send a message to the station to configure the Manufacturer STA HFID.
+ """
+ if self.get_m_sta_hfid() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_m_sta_hfid") \
+ .add_param("m_sta_hfid", self.get_m_sta_hfid()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_SET_M_STA_HFID + MME_TYPES['REQ'])
+
+ # Computes MM Entry: Manufacturer Station Human-Friendly ID in ASCII format
+ # Octet Number = 0 - 63
+ # Field Size (Octets) = 64
+ Sta_m_HFID = self.get_m_sta_hfid()
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=Sta_m_HFID)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_m_sta_hfid") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_M_STA_HFID)
+
+ def __send_u_sta_hfid(self):
+ """Send a message to the station to configure the User STA HFID.
+ """
+ if self.get_u_sta_hfid() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_u_sta_hfid") \
+ .add_param("u_sta_hfid", self.get_u_sta_hfid()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_SET_U_STA_HFID + MME_TYPES['REQ'])
+
+ # Computes MM Entry: User Station Human-Friendly ID in ASCII format
+ # Octet Number = 0 - 63
+ # Field Size (Octets) = 64
+ Sta_u_HFID = self.get_u_sta_hfid()
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=Sta_u_HFID)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_u_sta_hfid") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_U_STA_HFID)
+
+ def __send_avln_hfid(self):
+ """Send a message to the station to configure the AVLN HFID.
+ """
+ if self.get_avln_hfid() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_avln_hfid") \
+ .add_param("avln_hfid", self.get_avln_hfid()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_SET_AVLN_HFID + MME_TYPES['REQ'])
+
+ # Computes MM Entry: AVLN Station Human-Readable ID in ASCII format
+ # Octet Number = 0 - 63
+ # Field Size (Octets) = 64
+ Sta_AVLN_HFID = self.get_avln_hfid()
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=Sta_AVLN_HFID)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_avln_hfid") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_AVLN_HFID)
+
+ def __send_sl(self):
+ """Send a message to the station to configure the SL.
+ """
+ if self.get_sl() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_sl") \
+ .add_param_uchar("sl", self.get_sl()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_SET_SL + MME_TYPES['REQ'])
+
+ # Computes MM Entry: Security Level for New NMK
+ # Octet Number = 0
+ # Field Size (Octets) = 1
+ SL = htohp8(self.get_sl())
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=SL)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_sl") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_SL)
+
+ def __send_tonemask(self):
+ """Send a message to the station to configure the tonemask.
+ """
+ if self.get_tonemask() is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_tonemask") \
+ .add_param("tonemask", self.get_tonemask()) \
+ .send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ if self.get_mac_address() is not None:
+ osa = self.get_mac_address()
+ else:
+ osa = DEFAULT_MAC_ADDRESS
+ mmheader = MMHeader(ODA=DEFAULT_MAC_ADDRESS, OSA=osa, MMV=0x01, MMTYPE = DRV_STA_SET_TONEMASK + MME_TYPES['REQ'])
+
+ # Computes MM Entry:
+
+ # First carrier offset
+ # Octet Number = 0 - 1
+ # Field Size (Octets) = 2
+ Tonemask_offset = htohp16(PHY_CARRIER_OFFSET)
+
+ # Size of tonemask in bits
+ # Octet Number = 2 - 3
+ # Field Size (Octets) = 2
+ Tonemask_length = htohp16(PHY_CARRIER_NB)
+
+ # Station Tonemask bitfield
+ # Octet Number = 0 - 191
+ # Field Size (Octets) = 192
+ Sta_Tonemask = self.get_tonemask()
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=Tonemask_offset+Tonemask_length+Sta_Tonemask)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ self.__get_maximus().create_fcall("maximus_set_tonemask") \
+ .add_param("mme", mme.get()) \
+ .send(self.get())
+ else: # 'MME'
+ # Allocate an MME buffer
+ alloc_mme_buffer(maximus=self.__get_maximus(), station=self.get())
+
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp, DRV_STA_SET_TONEMASK)
+
+ def __send_snid(self):
+ """Send a message to the station to configure the SNID.
+ """
+ if self.get_snid() is not None:
+ # allways 'fcall_cp_station'
+ self.__get_maximus().create_fcall("maximus_set_snid") \
+ .add_param_uchar("snid", self.get_snid()) \
+ .send(self.get())
+
+ def __check_cnf(self, rsp, name):
+ """Check the MME response validity.
+ """
+ mmtype = hptoh16(rsp[0].get_mmheader()[MIN_SIZE_OF_MMHEADER - SIZE_OF_FMI - SIZE_OF_MMTYPE:MIN_SIZE_OF_MMHEADER - SIZE_OF_FMI])
+ if mmtype != name + MME_TYPES['CNF']:
+ raise Error("Received unexpected message of type " + hex(mmtype))
+ result = hptoh8(rsp[0].get_mmentry()[0])
+ if result == FAILURE:
+ err_code = hptoh8(rsp[0].get_mmentry()[1])
+ try:
+ err_msg = ERROR_CODES[err_code]
+ except KeyError:
+ err_msg = "Unknow error code"
+ raise Error(hex(name) + ".CNF => Failure: " + err_msg)
+ elif result >= RESERVED:
+ raise Error(hex(name) + ".CNF => Reserved: " + hex(result))
+
+ # Following functions just are encapsulation of interface module Boost Python functions.
+ #
+
+ def remove(self):
+ return self.get().remove()
+
+ def deactivate(self):
+ return self.get().deactivate()
+
+ def activate(self):
+ return self.get().activate()
+
+ def debug(self):
+ return self.get().debug()
+
+ def is_idle(self):
+ return self.get().is_idle()
+
+ def get_station_id(self):
+ return self.get().get_station_id()
diff --git a/cesar/maximus/python/maximus/utils/__init__.py b/cesar/maximus/python/maximus/utils/__init__.py
new file mode 100644
index 0000000000..817bb5db8a
--- /dev/null
+++ b/cesar/maximus/python/maximus/utils/__init__.py
@@ -0,0 +1,10 @@
+#! usr/bin/env python
+
+#print __name__
+
+#__all__ = ["converter", "crc", "exception", "format"]
+
+from converter import *
+from crc import *
+from exception import *
+from format import *
diff --git a/cesar/maximus/python/maximus/utils/converter.py b/cesar/maximus/python/maximus/utils/converter.py
new file mode 100644
index 0000000000..4f19d5d1ce
--- /dev/null
+++ b/cesar/maximus/python/maximus/utils/converter.py
@@ -0,0 +1,106 @@
+#! usr/bin/env python
+
+#print __name__
+
+from re import *
+from struct import pack, unpack
+
+class Data:
+
+ """Allow to get values in different formats.
+ """
+
+ def __init__(self, n=0, b=0, s=''):
+ self.base2=None
+ self.base10=None
+ self.base16=None
+ self.data=None
+ if b==0:
+ if s=='':
+ raise Exception, "unspecified base"
+ else:
+ self.data=s
+ t=unpack(len(self.data)*'B',self.data)
+ self.base2=''
+ i=0
+ for c in t:
+ self.base10=t[i]
+ self.base2+=self.get_bin(8)
+ i+=1
+ self.base10=int(self.base2,2)
+ self.base16=hex(self.base10).strip('L')
+ elif b==2:
+ self.base2=n
+ self.base10=int(self.base2,2)
+ self.base16=hex(self.base10).strip('L')
+ self.data=self.string()
+ elif b==10:
+ self.base10=n
+ self.base16=hex(self.base10).strip('L')
+ self.base2=self.bin(self.base10)
+ self.data=self.string()
+ elif b==16:
+ self.base16=n
+ self.base10=int(self.base16,16)
+ self.base2=self.bin(self.base10)
+ self.data=self.string()
+ else:
+ raise Exception, "unsupported base"
+
+ def bin(self, n):
+ base2 = ''
+ if n < 0:
+ raise ValueError, "must be a positive integer"
+ elif n == 0:
+ return '0'
+ else:
+ while n > 0:
+ base2 = str(n % 2) + base2
+ n = n >> 1
+ return base2
+
+ def string(self):
+ data=''
+ i=0
+ s=''
+ for c in self.get_hex():
+ if i<2:
+ s+=c
+ i+=1
+ if i==2:
+ data += pack('B',int(s,16))
+ i=0
+ s=''
+ return data
+
+ def get_bin(self, count=0):
+ if count < 0:
+ raise ValueError, "must be a positive integer"
+ elif count == 0:
+ return self.base2
+ else:
+ return ''.join([str((self.base10 >> y) & 1) for y in range(count-1, -1, -1)])
+
+ def get_int(self):
+ return self.base10
+
+ def get_hex(self, count=0):
+
+ """Get hexadecimal value.
+
+ >>> from maximus.utils.converter import *
+ >>> d=Data(123,10)
+ >>> d.get_hex()
+ '7b'
+ """
+
+ string=sub("0x", '', self.base16, 1)
+ if count < 0:
+ raise ValueError, "must be a positive integer"
+ elif count > 0:
+ for i in range(len(self.base16)-1,count+1):
+ string = '0' + string
+ return string
+
+ def get_str(self):
+ return self.data
diff --git a/cesar/maximus/python/maximus/utils/crc.py b/cesar/maximus/python/maximus/utils/crc.py
new file mode 100644
index 0000000000..05f7bd281f
--- /dev/null
+++ b/cesar/maximus/python/maximus/utils/crc.py
@@ -0,0 +1,102 @@
+#! usr/bin/env python
+
+#print __name__
+
+import sys
+base = '../../../../'
+path = 'maximus/python/lib/fcVf/crc24'
+sys.path.append (__file__[:__file__.find("crc.py")] + base + path) # or ".pyc"
+
+from maximus.utils.format import *
+from pycrc24 import check_string
+import binascii # for 'binascii.crc32()'
+
+CRC8_TABLE = [ 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
+ 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
+ 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
+ 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
+ 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
+ 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
+ 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
+ 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
+ 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
+ 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
+ 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
+ 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
+ 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
+ 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
+ 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
+ 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
+ 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
+ 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
+ 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
+ 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
+ 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
+ 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
+ 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
+ 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
+ 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
+ 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
+ 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
+ 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
+ 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
+ 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
+ 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
+ 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3 ]
+
+CRC16_TABLE = [ 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
+ 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
+ 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
+ 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
+ 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
+ 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
+ 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
+ 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
+ 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+ 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
+ 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
+ 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
+ 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
+ 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
+ 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
+ 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
+ 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
+ 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+ 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
+ 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
+ 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
+ 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
+ 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
+ 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
+ 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
+ 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
+ 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+ 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
+ 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
+ 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
+ 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
+ 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 ]
+
+def crc8(data):
+ """Calculates CRC-8.
+ Data must be a Python string.
+ """
+ # CRC-8 polynomial: x^8 + x^2 + x^1 + x^0
+ crc = 0
+ for i in range(0, len(data)):
+ crc = CRC8_TABLE[crc^hptoh8(data[i])]
+ return crc
+
+def crc24(data):
+ """Calculates CRC-24.
+ Data must be a Python string.
+ """
+ # CRC-24 polynomial: x^24 + x^23 + x^6 + x^5 + x^1 + x^0
+ return check_string(data)
+
+def crc32(data):
+ """Calculates CRC-32.
+ Data must be a Python string.
+ """
+ # CRC-8 polynomial: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + x^0
+ return unpack(u32, pack('q', binascii.crc32(data))[0:SIZE_OF_U32])[0]
diff --git a/cesar/maximus/python/maximus/utils/exception.py b/cesar/maximus/python/maximus/utils/exception.py
new file mode 100644
index 0000000000..d94fed771d
--- /dev/null
+++ b/cesar/maximus/python/maximus/utils/exception.py
@@ -0,0 +1,21 @@
+#! usr/bin/env python
+
+#print __name__
+
+class Error(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+class OutOfRangeError(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+class MACFrameSendError(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
diff --git a/cesar/maximus/python/maximus/utils/format.py b/cesar/maximus/python/maximus/utils/format.py
new file mode 100644
index 0000000000..5285a23acd
--- /dev/null
+++ b/cesar/maximus/python/maximus/utils/format.py
@@ -0,0 +1,263 @@
+#! usr/bin/env python
+
+#print __name__
+
+from struct import calcsize, pack, unpack
+
+
+# Define needed constants for 'struct.pack()' and 'struct.unpack()' functions
+#
+
+# pack(fmt, v1, v2, ...)
+# Return a string containing the values v1, v2, ..., packed according to the given format.
+# The arguments must match the values required by the format exactly.
+
+# unpack(fmt, string)
+# Unpack the string (presumably packed by pack(fmt, ... )) according to the given format.
+# The result is a tuple even if it contains exactly one item.
+# The string must contain exactly the amount of data required by the format (len(string) must equal calcsize(fmt)).
+
+# calcsize(fmt)
+# Return the size of the struct (and hence of the string) corresponding to the given format.
+
+
+# Format C Type Python
+# "x" pad byte no value
+# "c" char string of length 1
+# "b" signed char integer
+# "B" unsigned char integer
+# "h" short integer
+# "H" unsigned short integer
+# "i" int integer
+# "I" unsigned int long
+# "l" long integer
+# "L" unsigned long long
+# "q" long long long
+# "Q" unsigned long long long
+# "f" float float
+# "d" double float
+# "s" char[] string
+# "p" char[] string
+# "P" void * integer
+
+u8 = 'B'
+u16 = 'H'
+u32 = 'L' # or 'I'
+u64 = 'Q'
+
+# In octets
+SIZE_OF_U8 = calcsize(u8)
+SIZE_OF_U16 = calcsize(u16)
+SIZE_OF_U24 = 3 * SIZE_OF_U8
+SIZE_OF_U32 = calcsize(u32)
+SIZE_OF_U48 = SIZE_OF_U32 + SIZE_OF_U16
+SIZE_OF_U64 = calcsize(u64)
+
+# In bits
+size_of_u8 = 8
+size_of_u16 = 16
+size_of_u24 = 24
+size_of_u32 = 32
+size_of_u48 = 48
+size_of_u64 = 64
+
+MAX_VALUE_OF_U8 = 0xFF
+MAX_VALUE_OF_U16 = 0xFFFF
+MAX_VALUE_OF_U24 = 0xFFFFFF
+MAX_VALUE_OF_U32 = 0xFFFFFFFF
+MAX_VALUE_OF_U48 = 0xFFFFFFFFFFFF
+MAX_VALUE_OF_U64 = 0xFFFFFFFFFFFFFFFF
+
+
+# Character Byte order Size and alignment
+# "@" native native
+# "=" native standard
+# "<" little-endian standard
+# ">" big-endian standard
+# "!" network (= big-endian) standard
+
+h = '=' # hardware (= native = little-endian)
+le = '<' # little-endian
+be = '>' # big-endian
+n = '!' # network (= big-endian)
+hp = le # HomePlug (= little-endian)
+
+
+# Following functions respectively pack a u8, u16, u24, u32, u48 or u64 value into a string
+#
+
+def htohp8(value):
+ """Hardware to HomePlug,
+ i.e. little-endian to little-endian.
+ """
+ return pack(hp + u8, value)
+
+def htohp16(value):
+ """Hardware to HomePlug,
+ i.e. little-endian to little-endian.
+ """
+ return pack(hp + u16, value)
+
+def htohp24(value):
+ """Hardware to HomePlug,
+ i.e. little-endian to little-endian.
+ """
+ string = pack(hp + u32, value)
+ return string[:SIZE_OF_U24]
+
+def htohp32(value):
+ """Hardware to HomePlug,
+ i.e. little-endian to little-endian.
+ """
+ return pack(hp + u32, value)
+
+def htohp48(value):
+ """Hardware to HomePlug,
+ i.e. little-endian to little-endian.
+ """
+ string = pack(hp + u64, value)
+ return string[SIZE_OF_U16:SIZE_OF_U48] + string[:SIZE_OF_U16]
+
+def htohp48_tuple(tuple):
+ """Hardware to HomePlug,
+ i.e. little-endian to little-endian.
+ """
+ string = ''
+ for t in tuple:
+ string += htohp8(t)
+ result = ''
+ for i in range(0, len(string)):
+ result += string[len(string)-1-i]
+ return result[SIZE_OF_U16:SIZE_OF_U48] + result[:SIZE_OF_U16]
+
+def htohp64(value):
+ """Hardware to HomePlug,
+ i.e. little-endian to little-endian.
+ """
+ return pack(hp + u64, value)
+
+def hton8(value):
+ """Hardware to network,
+ i.e. little-endian to big-endian.
+ """
+ return pack(n + u8, value)
+
+def hton16(value):
+ """Hardware to network,
+ i.e. little-endian to big-endian.
+ """
+ return pack(n + u16, value)
+
+def hton32(value):
+ """Hardware to network,
+ i.e. little-endian to big-endian.
+ """
+ return pack(n + u32, value)
+
+def hton48(value):
+ """Hardware to network,
+ i.e. little-endian to big-endian.
+ """
+ return pack(n + u64, value)[SIZE_OF_U16:]
+
+def hton48_tuple(tuple):
+ """Hardware to HomePlug,
+ i.e. little-endian to big-endian.
+ """
+ string = ''
+ for t in tuple:
+ string += htohp8(t)
+ return string
+
+def hton64(value):
+ """Hardware to network,
+ i.e. little-endian to big-endian.
+ """
+ return pack(n + u64, value)
+
+
+# Following functions respectively unpack a string into a u8, u16, u24, u32, u48 or u64 value
+#
+
+def ntoh8(string):
+ """Network to hardware,
+ i.e. big-endian to little-endian.
+ """
+ return unpack(n + u8, string)[0]
+
+def ntoh16(string):
+ """Network to hardware,
+ i.e. big-endian to little-endian.
+ """
+ return unpack(n + u16, string)[0]
+
+def ntoh32(string):
+ """Network to hardware,
+ i.e. big-endian to little-endian.
+ """
+ return unpack(n + u32, string)[0]
+
+def ntoh48(string):
+ """Network to hardware,
+ i.e. big-endian to little-endian.
+ """
+ return unpack(n + u64, '\0\0' + string)[0]
+
+def ntoh48_tuple(string):
+ """HomePlug to hardware,
+ i.e. big-endian to little-endian.
+ """
+ return unpack(hp + len(string) * u8, string)[:len(string)]
+
+def ntoh64(string):
+ """Network to hardware,
+ i.e. big-endian to little-endian.
+ """
+ return unpack(n + u64, string)[0]
+
+def hptoh8(string):
+ """HomePlug to hardware,
+ i.e. little-endian to little-endian.
+ """
+ return unpack(hp + u8, string)[0]
+
+def hptoh16(string):
+ """HomePlug to hardware,
+ i.e. little-endian to little-endian.
+ """
+ return unpack(hp + u16, string)[0]
+
+def hptoh24(string):
+ """HomePlug to hardware,
+ i.e. little-endian to little-endian.
+ """
+ return unpack(hp + u32, string + '\0')[0]
+
+def hptoh32(string):
+ """HomePlug to hardware,
+ i.e. little-endian to little-endian.
+ """
+ return unpack(hp + u32, string)[0]
+
+def hptoh48(string):
+ """HomePlug to hardware,
+ i.e. little-endian to little-endian.
+ """
+ return unpack(hp + u64, string[SIZE_OF_U32:SIZE_OF_U48] + string[:SIZE_OF_U32] + '\0\0')[0]
+
+def hptoh48_tuple(string):
+ """HomePlug to hardware,
+ i.e. little-endian to little-endian.
+ """
+ string = string[SIZE_OF_U32:SIZE_OF_U48] + string[:SIZE_OF_U32]
+ tuple = unpack(hp + len(string) * u8, string)[:len(string)]
+ result = ()
+ for i in range(0, len(tuple)):
+ result += (tuple[len(tuple)-1-i]),
+ return result
+
+def hptoh64(string):
+ """HomePlug to hardware,
+ i.e. little-endian to little-endian.
+ """
+ return unpack(hp + u64, string)[0]
diff --git a/cesar/maximus/python/py/script_example.py b/cesar/maximus/python/py/script_example.py
new file mode 100644
index 0000000000..aa0c643fd5
--- /dev/null
+++ b/cesar/maximus/python/py/script_example.py
@@ -0,0 +1,140 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+
+# SCRIPT EXAMPLE
+# To be run with "stationtest.elf" station executable
+# (to be compiled under "/trunk/maximus/stationtest").
+
+from interface import *
+from struct import pack, unpack
+
+def my_cb (msg):
+ print "=>",my_cb.func_name
+ if msg.is_param("result_2"):
+ result2 = unpack('q',msg.bind_param("result_2"))
+ print "result 2 =",result2[0]
+ receive_fc1_rsp = True
+
+# Instantiate a Maximus object and initialize it.
+maximus = Maximus()
+maximus.init(sys.argv)
+
+# Create three stations.
+stationA = maximus.create_sta()
+stationB = maximus.create_sta()
+stationC = maximus.create_sta()
+
+# Launch a debugger attached to station B.
+stationB.debug()
+
+# Send an asynchronous function message to station A.
+#
+
+# Create a function message and set the name of the function to call of station A.
+fc1 = maximus.create_fcall("function_1")
+
+# Add a first parameter to the created message.
+param1 = pack('iiB',1,2,True)
+fc1.add_param("param_1", param1)
+
+# Add a second parameter to the created message.
+param2 = pack('iiiiiiiiii',0,1,2,3,4,5,6,7,8,9)
+fc1.add_param("param_2", param2)
+
+# Add a third parameter to the created message.
+param3 = "hello"
+fc1.add_param("param_3", param3)
+
+# Add a fourth parameter to the created message.
+param4 = pack('q',123)
+fc1.add_param("param_4", param4)
+
+# Register a callback function which will be called at message response reception.
+fc1.set_cb(my_cb)
+
+# Set destination station of message 1.
+fc1.set_sta(stationA)
+
+# Send the configured message in an asynchronous mode.
+receive_fc1_rsp = False
+fc1.send_async()
+
+# Send a synchronous function message to station B.
+
+# Create a function message and set the name of the function to call into station B.
+fc2 = maximus.create_fcall("function_2")
+
+# Add a first parameter to the created message.
+fc2.add_param_bool("param_5", True)
+
+# Send the configured message to station B in a synchronous mode.
+fc2.send(stationB)
+
+# Get the function result.
+result1 = fc2.bind_param_string("result_1")
+print "result1 =",result1
+
+# Set a parameter value of station B.
+probe1 = maximus.create_probe()
+param6 = 789
+probe1.add_param_ulong("param_6", param6)
+probe1.send(stationB)
+
+# Get a parameter value from station B.
+probe2 = maximus.create_probe().add_param("param_7")
+probe2.send(stationB)
+param7 = probe2.bind_param_ulong("param_7")
+print "param 7 =",param7
+
+# Get the same parameter value from station C, re-using existing message.
+probe2.send(stationC)
+
+# Send asynchronous function message(s) to station B.
+if 456 == param7:
+ fc3 = maximus.create_fcall("function_3")
+ fc3.send_async(stationC)
+fc4 = maximus.create_fcall("function_4")
+fc4.send_async(stationC)
+
+# Send an asynchronous function message to station C.
+fc5 = maximus.create_fcall("function_5")
+fc5.send_async(stationC)
+
+# Wait for responses to all sent messages in asynchronous mode.
+maximus.wait()
+
+# Get list of all registered parameters of stations C.
+probe3 = maximus.create_probe()
+probe3.send(stationC)
+if probe3.is_param("param_8"):
+ # Get parameter 8 value and set parameter 9 value of station C.
+ probe4 = maximus.create_probe()
+ probe4.add_param("param_8")
+ probe4.add_param_bool("param_9", False)
+ probe4.send(stationC)
+ param8 = probe4.bind_param_bool("param_8")
+ print "param 8 =",param8
+
+# Wait during 1000000 ticks before creating another station.
+maximus.wait(1000000)
+
+# Create a fourth station.
+stationD = maximus.create_sta()
+
+# Wait during 1000000 ticks before terminating the program.
+maximus.wait(1000000)
+
+# Remove stations.
+stationA.remove()
+stationB.remove()
+stationC.remove()
+stationD.remove()
+
+print "\n*** END ***\n"
diff --git a/cesar/maximus/python/py/test_cb.py b/cesar/maximus/python/py/test_cb.py
new file mode 100644
index 0000000000..5bb8f46b97
--- /dev/null
+++ b/cesar/maximus/python/py/test_cb.py
@@ -0,0 +1,84 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+
+# TICKET #47
+# To be run with "test_cb.elf" station executable
+# (to be compiled under "/trunk/maximus/stationtest").
+
+from interface import *
+
+# Instantiate a Maximus object and initialize it.
+maximus = Maximus()
+maximus.init(sys.argv)
+
+# Create three stations.
+sta = maximus.create_sta()
+
+def get_seg_cb1 (msg):
+ print "=> get_seg_cb1"
+m1 = maximus.create_fcall ('get_seg')
+m1.set_cb (get_seg_cb1)
+m1.send_async (sta)
+maximus.wait()
+
+def get_seg_cb2 (msg):
+ print "=> get_seg_cb2"
+def a():
+ m2 = maximus.create_fcall ('get_seg')
+ m2.set_cb (get_seg_cb2)
+ m2.send_async (sta)
+a()
+maximus.wait()
+
+def b():
+ s = "=> get_seg_cb3"
+ def get_seg_cb3 (msg):
+ print s
+ m3 = maximus.create_fcall ('get_seg')
+ m3.set_cb (get_seg_cb3)
+ m3.send_async (sta)
+b()
+maximus.wait()
+
+
+# TICKET #48
+
+def a2 (m, msg):
+ s = 'I am "a2", '
+ def cb_a2(msg):
+ print s + m
+ msg.set_cb (cb_a2)
+
+def cb_b2_inner (msg):
+ print 'I am "b2", ' + m
+
+def b2 (m, msg):
+ msg.set_cb (lambda x: cb_b2_inner (x))
+
+def c (m, msg):
+ class CCb:
+ def __call__ (self, msg):
+ print self.s + m
+ c_cb = CCb ()
+ c_cb.s = 'I am "c", '
+ msg.set_cb (c_cb)
+
+m = 'I am being called'
+msg = maximus.create_fcall ('get_seg')
+a2 (m, msg)
+msg.send (sta)
+b2 (m, msg)
+msg.send (sta)
+c (m, msg)
+msg.send (sta)
+
+sta.remove()
+
+print "\n*** END ***\n"
diff --git a/cesar/maximus/python/py/test_ether.py b/cesar/maximus/python/py/test_ether.py
new file mode 100644
index 0000000000..db2184c29c
--- /dev/null
+++ b/cesar/maximus/python/py/test_ether.py
@@ -0,0 +1,227 @@
+#!/usr/bin/python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+from interface import *
+from maximus import *
+from maximus.ethernet.eth import MAX_SIZE_OF_HEADER
+from maximus.mme.mmheader import MAX_SIZE_OF_MMHEADER
+from maximus.macframe.msdu import MIN_SIZE_OF_MSDU
+from maximus.simu.rx import * # for 'recv()' function
+from struct import pack
+
+m = Maximus()
+m.init(sys.argv)
+
+
+# TEST ETHER
+# To be run with "test_ether.elf" station executable
+# (to be compiled under "/trunk/maximus/stationtest").
+
+# Create station(s)
+sta1 = m.create_sta ()
+sta1.debug()
+
+# Init ether
+fcall = m.create_fcall('init_ether')
+fcall.send(sta1)
+
+# Test following functions:
+# - send(self, maximus, file=None)
+# - sendnrecv(self, maximus, file=None, timeout=None, filter=None, count=1)
+# - recv(maximus, timeout=None, filter=None, count=1)
+
+# Disable the automatic buffer allocation
+realloc_buffer(False)
+
+# Ethernet Frame config
+dst = '41:42:43:44:45:46'
+src = '47:48:49:4a:4b:4c'
+vlantag = 0x81004D4E
+type = 0x4F50
+
+# MME config
+mmheader = 'MMHeader 19 octets!'
+mmentry = '--- This is the Management Message Entry ---'
+
+# Send an Ethernet Frame asynchronously
+frame1 = Eth()
+frame1.dst = dst
+frame1.src = src
+frame1.vlantag = vlantag
+frame1.type = type
+msdu1 = 'This is the Ethernet payload'
+frame1.payload = msdu1
+alloc_data_buffer(m, sta1, buffer_nb=2)
+frame1.send(m, sta1)
+rsp1 = recv(m, count=4)
+
+# Test the 1st received MSDU (Eth) object
+i = 0
+if rsp1[i].dst != dst:
+ print "dst1 =", rsp1[i].dst
+ raise Error("dst1")
+if rsp1[i].src != src:
+ print "src1 =", rsp1[i].src
+ raise Error("src1")
+if rsp1[i].vlantag != vlantag:
+ print "vlantag1 =", hex(rsp1[i].vlantag)
+ raise Error("vlantag1")
+if rsp1[i].type != type:
+ print "type1 =", hex(rsp1[i].type)
+ raise Error("type1")
+if str(rsp1[i].payload) != msdu1 + (MIN_SIZE_OF_MSDU - MAX_SIZE_OF_HEADER - len(msdu1)) * pack('B', 0):
+ print len(str(rsp1[i].payload))
+ print "msdu1 =", str(rsp1[i].payload)
+ raise Error("msdu1")
+
+# Test the 2nd received MSDU (MME) object
+i = 2 # i = 2 because the second received frame is the BUFFER RELEASED message
+if rsp1[i].get_mmheader() != 'ABCDEFGHIJKL' + pack('!I', vlantag) + 'OPThis ':
+ print "mmheader1 =", rsp1[i].get_mmheader()
+ raise Error("mmheader1")
+if rsp1[i].get_mmentry() != 'is the Ethernet payload' + (MIN_SIZE_OF_MSDU - MAX_SIZE_OF_MMHEADER - 23) * pack('B', 0):
+ print "mmentry1 =", rsp1[i].get_mmentry()
+ raise Error("mmentry1")
+
+m.wait(100000)
+
+# Send an Ethernet Frame synchronously
+frame2 = Eth()
+frame2.dst = dst
+frame2.src = src
+frame2.vlantag = vlantag
+frame2.type = type
+msdu2 = 'This is the Ethernet payload'
+frame2.payload = msdu2
+alloc_data_buffer(m, sta1, buffer_nb=2)
+rsp2 = frame2.sendnrecv(m, sta1, count=4)
+
+# Test the 1st received MSDU (Eth) object
+i = 0
+if rsp2[i].dst != dst:
+ print "dst2 =", rsp2[i].dst
+ raise Error("dst2")
+if rsp2[i].src != src:
+ print "src2 =", rsp2[i].src
+ raise Error("src2")
+if rsp2[i].vlantag != vlantag:
+ print "vlantag2 =", hex(rsp2[i].vlantag)
+ raise Error("vlantag2")
+if rsp2[i].type != type:
+ print "type2 =", hex(rsp2[i].type)
+ raise Error("type2")
+if str(rsp2[i].payload) != msdu2 + (MIN_SIZE_OF_MSDU - MAX_SIZE_OF_HEADER - len(msdu2)) * pack('B', 0):
+ print "msdu2 =", str(rsp2[i].payload)
+ raise Error("msdu2")
+
+# Test the 2nd received MSDU (MME) object
+i = 2 # i = 2 because the second received frame is the BUFFER RELEASED message
+if rsp2[i].get_mmheader() != 'ABCDEFGHIJKL' + pack('!I', vlantag) + 'OPThis ':
+ print "mmheader2 =", rsp2[i].get_mmheader()
+ raise Error("mmheader2")
+if rsp2[i].get_mmentry() != 'is the Ethernet payload' + (MIN_SIZE_OF_MSDU - MAX_SIZE_OF_MMHEADER - 23) * pack('B', 0):
+ print "mmentry2 =", rsp2[i].get_mmentry()
+ raise Error("mmentry2")
+
+m.wait(100000)
+
+# Send an MME asynchronously
+mme3 = MME(MMHeader=mmheader, MMEntry=mmentry)
+alloc_data_buffer(m, sta1, buffer_nb=2)
+mme3.send(m, sta1)
+rsp3 = recv(m, count=4)
+
+# Test the 1st received MSDU (Eth) object
+i = 0
+if rsp3[i].dst != '4d:4d:48:65:61:64': # 'MMHead'
+ print "dst3 =", rsp3[i].dst
+ raise Error("dst3")
+if rsp3[i].src != '65:72:20:31:39:20': # 'er 19 '
+ print "src3 =", rsp3[i].src
+ raise Error("src3")
+if rsp3[i].type != 0x6F63: # 'oc'
+ print "type3 =", hex(rsp3[i].type)
+ raise Error("type3")
+if str(rsp3[i].payload) != 'tets!--- This is the Management Message Entry ---':
+ print "msdu3 =", str(rsp3[i].payload)
+ raise Error("msdu3")
+
+# Test the 2nd received MSDU (MME) object
+i = 2 # i = 2 because the second received frame is the BUFFER RELEASED message
+if rsp3[i].get_mmheader() != mmheader:
+ print "mmheader3 =", rsp3[i].get_mmheader()
+ raise Error("mmheader3")
+if rsp3[i].get_mmentry() != mmentry:
+ print "mmentry3 =", rsp3[i].get_mmentry()
+ raise Error("mmentry3")
+
+m.wait(100000)
+
+# Send an MME synchronously
+mme4 = MME(MMHeader=mmheader, MMEntry=mmentry)
+alloc_data_buffer(m, sta1, buffer_nb=2)
+rsp4 = mme4.sendnrecv(m, sta1, count=4)
+
+# Test the 1st received MSDU (Eth) object
+i = 0
+if rsp4[i].dst != '4d:4d:48:65:61:64': # 'MMHead'
+ print "dst4 =", rsp4[i].dst
+ raise Error("dst4")
+if rsp4[i].src != '65:72:20:31:39:20': # 'er 19 '
+ print "src4 =", rsp4[i].src
+ raise Error("src4")
+if rsp4[i].type != 0x6F63: # 'oc'
+ print "type4 =", hex(rsp4[i].type)
+ raise Error("type4")
+if str(rsp4[i].payload) != 'tets!--- This is the Management Message Entry ---':
+ print "msdu4 =", str(rsp4[i].payload)
+ raise Error("msdu4")
+
+# Test the 2nd received MSDU (MME) object
+i = 2 # i = 2 because the second received frame is the BUFFER RELEASED message
+if rsp4[i].get_mmheader() != mmheader:
+ print "mmheader4 =", rsp4[i].get_mmheader()
+ raise Error("mmheader4")
+if rsp4[i].get_mmentry() != mmentry:
+ print "mmentry4 =", rsp4[i].get_mmentry()
+ raise Error("mmentry4")
+
+m.wait(100000)
+
+# Test the sniffed received MSDU (Sniffer) object
+alloc_interface_buffer(m, sta1)
+snif = recv(m, count=2)[0] # the second received frame is the BUFFER RELEASED message
+snif.display()
+if snif.get()[0:48] != "This is a sniffed packet coming from the station":
+ print "packet =", snif.get()
+ raise Error("packet")
+if snif.get_ether_type() != 7:
+ print "ether type =", snif.get_ether_type()
+ raise Error("ether type")
+if snif.get_type() != 'ETHERNET_TYPE_SNIFFER':
+ print "type =", snif.get_type()
+ raise Error("type")
+if snif.get_way() != True:
+ print "way =", snif.get_way()
+ raise Error("way")
+if snif.get_encryption() != True:
+ print "encryption =", snif.get_encryption()
+ raise Error("encryption")
+if snif.get_sniffer_type() != 1:
+ print "sniffer type =", snif.get_sniffer_type()
+ raise Error("sniffer type")
+
+# Uninit ether
+fcall2 = m.create_fcall('uninit_ether')
+fcall2.send(sta1)
+
+# Remove station(s)
+sta1.remove()
+
+print "\n*** END ***\n"
diff --git a/cesar/maximus/python/py/test_false_alarm.py b/cesar/maximus/python/py/test_false_alarm.py
new file mode 100644
index 0000000000..9de6c4f5aa
--- /dev/null
+++ b/cesar/maximus/python/py/test_false_alarm.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+from interface import *
+from maximus import *
+
+m = Maximus()
+m.init(sys.argv)
+
+
+# TEST FALSE ALARM (= WRONG PREAMBLES TRANSMISSIONS)
+# To be run with "test_false_alarm.elf" station executable
+# (to be compiled under "/trunk/maximus/stationtest").
+
+# Create station(s)
+sta1 = m.create_sta()
+sta1.set_name("sta1")
+sta1.debug()
+sta2 = m.create_sta()
+sta2.set_name("sta2")
+sta2.debug()
+
+# Init HAL PHY
+m.create_fcall('init_phy').send(sta1)
+m.create_fcall('init_phy').send(sta2)
+
+# Activate false alarm feature
+duration = 100
+deviation = 10
+m.activate_false_alarm(duration, deviation)
+
+# Activate RX in Hybrid Mode for sta1
+fc_mode_10 = 0 # PHY_FC_MODE_HYBRID_1
+m.create_fcall('activate_rx').add_param_ushort("fc_mode", fc_mode_10).add_param_bool("pre_detection", True).send(sta1)
+
+# Activate RX in AV Only Mode for sta2
+fc_mode_av = 2 # PHY_FC_MODE_AV_1
+m.create_fcall('activate_rx').add_param_ushort("fc_mode", fc_mode_av).add_param_bool("pre_detection", True).send(sta2)
+
+# Wait 1200 ticks for preamble detection => first wrong preamble
+m.wait(1200)
+
+# Activate RX for both stations
+m.create_fcall('activate_rx').add_param_ushort("fc_mode", fc_mode_10).add_param_bool("pre_detection", True).send(sta1)
+m.create_fcall('activate_rx').add_param_ushort("fc_mode", fc_mode_av).add_param_bool("pre_detection", True).send(sta2)
+
+# Wait 1200 ticks for preamble detection => second wrong preamble
+m.wait(1200)
+
+# Deactivate false alarm feature
+m.deactivate_false_alarm()
+
+# Deactivate preamble detection for both stations
+m.create_fcall('activate_rx').add_param_ushort("fc_mode", fc_mode_10).add_param_bool("pre_detection", False).send(sta1)
+m.create_fcall('activate_rx').add_param_ushort("fc_mode", fc_mode_av).add_param_bool("pre_detection", False).send(sta2)
+
+# Wait to check that there are no more wrong preambles sent
+m.wait(150)
+
+# Uninit HAL PHY
+m.create_fcall('uninit_phy').send(sta1)
+m.create_fcall('uninit_phy').send(sta2)
+
+# Remove station(s)
+sta1.remove()
+sta2.remove()
+
+print "\n*** END ***\n"
diff --git a/cesar/maximus/python/py/test_send_mpdu.py b/cesar/maximus/python/py/test_send_mpdu.py
new file mode 100644
index 0000000000..7397fb7b0b
--- /dev/null
+++ b/cesar/maximus/python/py/test_send_mpdu.py
@@ -0,0 +1,158 @@
+#!/usr/bin/python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+from interface import *
+from maximus import *
+from maximus.macframe.macframequeue import MAX_PB_NB_PER_MPDU
+from struct import pack
+
+# To be run with "test_send.elf" station executable
+# (to be compiled under "/trunk/maximus/stationtest").
+
+maximus = Maximus()
+maximus.init(sys.argv)
+
+def send_fcall2(station):
+ # Send an fcall for one PB of 128 octets
+ fcall2 = maximus.create_fcall('prepare_rx')
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ fcall2.add_param_ushort("fc_mode", fc_mode)
+ fcall2.add_param_bool("short_ppdu", False)
+ mod = 2 # PHY_MOD_MINI_ROBO
+ fcall2.add_param_ushort("mod", mod)
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ fcall2.add_param_ushort("fecrate", fecrate)
+ pb_size = 0 # PHY_PB_SIZE_136
+ fcall2.add_param_ushort("pb_size", pb_size)
+ gil = 1 # PHY_GIL_567
+ fcall2.add_param_ushort("gil", gil)
+ pb_nb = 1
+ fcall2.add_param_ushort("pb_nb", pb_nb)
+ fcall2.send(station)
+
+def send_fcall3(station):
+ # Send an fcall for 3 PBs of 512 octets
+ fcall3 = maximus.create_fcall('prepare_rx')
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ fcall3.add_param_ushort("fc_mode", fc_mode)
+ fcall3.add_param_bool("short_ppdu", False)
+ mod = 0 # PHY_MOD_ROBO
+ fcall3.add_param_ushort("mod", mod)
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ fcall3.add_param_ushort("fecrate", fecrate)
+ pb_size = 1 # PHY_PB_SIZE_520
+ fcall3.add_param_ushort("pb_size", pb_size)
+ gil = 0 # PHY_GIL_417
+ fcall3.add_param_ushort("gil", gil)
+ pb_nb = 3
+ fcall3.add_param_ushort("pb_nb", pb_nb)
+ fcall3.send(station)
+
+def send_fcall4(station):
+ # Send an fcall for a short PPDU with a FC 1.0
+ fcall4 = maximus.create_fcall('prepare_rx')
+ fc_mode = 0 # PHY_FC_MODE_HYBRID_1
+ fcall4.add_param_ushort("fc_mode", fc_mode)
+ fcall4.add_param_bool("short_ppdu", True)
+ fcall4.send(station)
+
+def send_fcall5(station):
+ # Send an fcall for one PB of 512 octets with a FC 1.0
+ fcall5 = maximus.create_fcall('prepare_rx')
+ fc_mode = 0 # PHY_FC_MODE_HYBRID_1
+ fcall5.add_param_ushort("fc_mode", fc_mode)
+ fcall5.add_param_bool("short_ppdu", False)
+ mod = 0 # PHY_MOD_ROBO
+ fcall5.add_param_ushort("mod", mod)
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ fcall5.add_param_ushort("fecrate", fecrate)
+ pb_size = 1 # PHY_PB_SIZE_520
+ fcall5.add_param_ushort("pb_size", pb_size)
+ gil = 0 # PHY_GIL_417
+ fcall5.add_param_ushort("gil", gil)
+ pb_nb = 1
+ fcall5.add_param_ushort("pb_nb", pb_nb)
+ fcall5.send(station)
+
+def send_fcall_236(station):
+ # Send an fcall for 236 PBs of 512 octets
+ fcall_236 = maximus.create_fcall('prepare_rx')
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ fcall_236.add_param_ushort("fc_mode", fc_mode)
+ fcall_236.add_param_bool("short_ppdu", False)
+ mod = 0 # PHY_MOD_ROBO
+ fcall_236.add_param_ushort("mod", mod)
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ fcall_236.add_param_ushort("fecrate", fecrate)
+ pb_size = 1 # PHY_PB_SIZE_520
+ fcall_236.add_param_ushort("pb_size", pb_size)
+ gil = 0 # PHY_GIL_417
+ fcall_236.add_param_ushort("gil", gil)
+ pb_nb = MAX_PB_NB_PER_MPDU
+ fcall_236.add_param_ushort("pb_nb", pb_nb)
+ fcall_236.send(station)
+
+sta = maximus.create_sta ()
+sta.debug ()
+
+fcall1 = maximus.create_fcall('set_tonemask')
+fcall1.send(sta)
+
+# Send an MPDU containing one PB of 128 octets
+send_fcall2(sta)
+macFrame2 = MACFrame()
+macFrame2.set_fc_av(pack('IIII', 123, 456, 789, 10))
+macFrame2.set_msdu('This is the MPDU payload')
+macFrame2.send(maximus)
+
+# Send an MPDU containing 3 PBs of 512 octets
+send_fcall3(sta)
+macFrame3 = MACFrame()
+macFrame3.set_fc_av(pack('IIII', 0, 456, 789, 10))
+macFrame3.set_msdu(1500*'a')
+macFrame3.send(maximus)
+
+# Send a short PPDU with a FC 1.0
+send_fcall4(sta)
+macFrame4 = MACFrame()
+macFrame4.set_fc_10(1)
+macFrame4.set_fc_av(pack('IIII', 123, 456, 789, 10))
+macFrame4.send(maximus, short_ppdu=True)
+
+# Send an MPDU containing one PB of 512 octets with a FC 1.0
+send_fcall5(sta)
+macFrame5 = MACFrame()
+macFrame5.set_fc_10(10)
+macFrame5.set_fc_av(pack('IIII', 123, 456, 789, 10))
+macFrame5.set_msdu(200*'b')
+macFrame5.send(maximus)
+
+# Send an MPDU containing one PB of 128 octets, created from an MME
+send_fcall2(sta)
+macFrame6 = MACFrame(MACFrameHeader='H!', ICV='ICV!')
+macFrame6.set_fc_av(pack('IIII', 123, 456, 789, 10))
+macFrame6.set_msdu(mme.MME(MMHeader='MMHeader 19 octets!', MMEntry='--- This is the Management Message Entry ---'))
+macFrame6.send(maximus)
+
+# Send an MPDU containing 236 PBs
+send_fcall_236(sta)
+macFrame6.set_msdu(512*'a')
+macFrameQueue = MACFrameQueue()
+for i in range (0,79):
+ macFrameQueue.add(macFrame6)
+macFrameQueue.send(maximus)
+
+maximus.wait(10000)
+
+fcall6 = maximus.create_fcall('uninit_phy')
+fcall6.send(sta)
+
+sta.remove()
+
+print "\n*** END ***\n"
diff --git a/cesar/maximus/python/py/test_send_noise.py b/cesar/maximus/python/py/test_send_noise.py
new file mode 100644
index 0000000000..1e5f7ca535
--- /dev/null
+++ b/cesar/maximus/python/py/test_send_noise.py
@@ -0,0 +1,86 @@
+#!/usr/bin/python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+from interface import *
+from maximus import *
+from struct import pack
+
+# To be run with "test_send.elf" station executable
+# (to be compiled under "/trunk/maximus/stationtest").
+
+# Create and initializes Maximus
+maximus = Maximus()
+maximus.init(sys.argv)
+
+# Create stations
+sta1 = maximus.create_sta ()
+sta1.debug ()
+sta2 = maximus.create_sta ()
+sta2.debug ()
+
+# Set TONEMASK
+fcall1 = maximus.create_fcall('set_tonemask')
+fcall1.send(sta1)
+fcall2 = maximus.create_fcall('set_tonemask')
+fcall2.send(sta2)
+
+# This function sends a prepare_rx message to the RX station
+def my_prepare_rx(station):
+ fcall = maximus.create_fcall('prepare_rx')
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ fcall.add_param_ushort("fc_mode", fc_mode)
+ fcall.add_param_bool("short_ppdu", False)
+ mod = 0 # PHY_MOD_ROBO
+ fcall.add_param_ushort("mod", mod)
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ fcall.add_param_ushort("fecrate", fecrate)
+ pb_size = 1 # PHY_PB_SIZE_520
+ fcall.add_param_ushort("pb_size", pb_size)
+ gil = 0 # PHY_GIL_417
+ fcall.add_param_ushort("gil", gil)
+ pb_nb = 3
+ fcall.add_param_ushort("pb_nb", pb_nb)
+ fcall.send(station)
+
+# This function sends an MPDU containing 3 PBs of 512 octets
+def my_send_mpdu(station):
+ my_prepare_rx(station)
+ macFrame1 = MACFrame()
+ macFrame1.set_fc_av(pack('IIII', 0, 456, 789, 10))
+ macFrame1.set_msdu(1500*'a')
+ macFrame1.send(maximus)
+
+# Channel perturbation is disabled => send empty NOISE
+my_prepare_rx(sta2)
+my_send_mpdu(sta1)
+maximus.wait(10000)
+
+# Enable channel perturbation => send default NOISE
+maximus.disturb_channel()
+my_prepare_rx(sta2)
+my_send_mpdu(sta1)
+maximus.wait(10000)
+
+# Set SNR => send default NOISE (because transmitting "station" is Maximus)
+set_snr(maximus, value=15)
+my_prepare_rx(sta2)
+my_send_mpdu(sta1)
+maximus.wait(10000)
+
+# Uninitialize PHY
+fcall3 = maximus.create_fcall('uninit_phy')
+fcall3.send(sta1)
+fcall4 = maximus.create_fcall('uninit_phy')
+fcall4.send(sta2)
+
+# Remove stations
+sta1.remove()
+sta2.remove()
+
+print "\n*** END ***\n"
diff --git a/cesar/maximus/python/py/test_tx_rx.py b/cesar/maximus/python/py/test_tx_rx.py
new file mode 100644
index 0000000000..ac1867ec2b
--- /dev/null
+++ b/cesar/maximus/python/py/test_tx_rx.py
@@ -0,0 +1,217 @@
+#!/usr/bin/python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+from interface import *
+from maximus import *
+from struct import pack
+
+m = Maximus()
+m.init(sys.argv)
+
+
+# TEST TX AND RX
+# To be run with "test_tx_rx.elf" station executable
+# (to be compiled under "/trunk/maximus/stationtest").
+
+# Create station(s)
+sta1 = m.create_sta ()
+
+# Enable channel perturbation
+m.disturb_channel()
+
+# Set tonemask
+fcall1 = m.create_fcall('set_tonemask')
+fcall1.send(sta1)
+
+def create_fcall_128():
+ # Create a fcall for an MPDU containing one PB of 128 octets
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ short_ppdu = False
+ mod = 2 # PHY_MOD_MINI_ROBO
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ pb_size = 0 # PHY_PB_SIZE_136
+ gil = 1 # PHY_GIL_567
+ pb_nb = 1
+ fcall_128 = m.create_fcall('prepare_rx')
+ fcall_128.add_param_ushort("fc_mode", fc_mode)
+ fcall_128.add_param_bool("short_ppdu", short_ppdu)
+ fcall_128.add_param_ushort("mod", mod)
+ fcall_128.add_param_ushort("fecrate", fecrate)
+ fcall_128.add_param_ushort("pb_size", pb_size)
+ fcall_128.add_param_ushort("gil", gil)
+ fcall_128.add_param_ushort("pb_nb", pb_nb)
+ return fcall_128
+
+def create_fcall_512_1():
+ # Create a fcall for an MPDU containing one PB of 512 octets with a FC 1.0
+ fc_mode = 0 # PHY_FC_MODE_HYBRID_1
+ short_ppdu = False
+ mod = 3 # PHY_MOD_TM
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ pb_size = 1 # PHY_PB_SIZE_520
+ gil = 1 # PHY_GIL_567
+ pb_nb = 1
+ fcall_512_1 = m.create_fcall('prepare_rx')
+ fcall_512_1.add_param_ushort("fc_mode", fc_mode)
+ fcall_512_1.add_param_bool("short_ppdu", short_ppdu)
+ fcall_512_1.add_param_ushort("mod", mod)
+ fcall_512_1.add_param_ushort("fecrate", fecrate)
+ fcall_512_1.add_param_ushort("pb_size", pb_size)
+ fcall_512_1.add_param_ushort("gil", gil)
+ fcall_512_1.add_param_ushort("pb_nb", pb_nb)
+ return fcall_512_1
+
+def create_fcall_512_3():
+ # Create a fcall for an MPDU containing 3 PBs of 512 octets
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ short_ppdu = False
+ mod = 0 # PHY_MOD_ROBO
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ pb_size = 1 # PHY_PB_SIZE_520
+ gil = 0 # PHY_GIL_417
+ pb_nb = 3
+ fcall_512_3 = m.create_fcall('prepare_rx')
+ fcall_512_3.add_param_ushort("fc_mode", fc_mode)
+ fcall_512_3.add_param_bool("short_ppdu", short_ppdu)
+ fcall_512_3.add_param_ushort("mod", mod)
+ fcall_512_3.add_param_ushort("fecrate", fecrate)
+ fcall_512_3.add_param_ushort("pb_size", pb_size)
+ fcall_512_3.add_param_ushort("gil", gil)
+ fcall_512_3.add_param_ushort("pb_nb", pb_nb)
+ return fcall_512_3
+
+def create_fcall_short_fc10():
+ # Create a fcall for a short PPDU with a FC 1.0
+ fc_mode = 0 # PHY_FC_MODE_HYBRID_1
+ short_ppdu = True
+ fcall_short_fc10 = m.create_fcall('prepare_rx')
+ fcall_short_fc10.add_param_ushort("fc_mode", fc_mode)
+ fcall_short_fc10.add_param_bool("short_ppdu", short_ppdu)
+ fcall_short_fc10.add_param_ushort("mod", 0)
+ fcall_short_fc10.add_param_ushort("fecrate", 0)
+ fcall_short_fc10.add_param_ushort("pb_size", 0)
+ fcall_short_fc10.add_param_ushort("gil", 0)
+ fcall_short_fc10.add_param_ushort("pb_nb", 0)
+ return fcall_short_fc10
+
+def get_pad(n):
+ pad = ''
+ for i in range (0,n):
+ pad += pack('B', 0)
+ return pad
+
+# Test following functions:
+# - send(self, maximus, fc_mode=4, short_ppdu=0, mod=4, file=None)
+# - sendnrecv(self, maximus, fc_mode=4, short_ppdu=0, mod=4, file=None, timeout=None, filter=None, count=1)
+# - recv(maximus, timeout=None, filter=None, count=1)
+
+# Send an MPDU containing one PB of 128 octets
+fcall_128 = create_fcall_128()
+fcall_128.send(sta1)
+macFrame1 = MACFrame()
+fc_av_1 = (0, 456, 789, 10)
+macFrame1.set_fc_av(fc_av_1)
+msdu1 = 'This is the MPDU payload'
+macFrame1.set_msdu(msdu1)
+macFrame1.set_macframeheader(MACFrameHeader(MFL=len(msdu1)-1))
+macFrame1.send(m)
+rsp1 = recv(m)
+if rsp1[0].get_fc_av() != fc_av_1:
+ print "fc_av_1 =", rsp1[0].get_fc_av()
+ raise Error("fc_av_1")
+if rsp1[0].get_pblist()[0] != MACFrameHeader(MFL=len(msdu1)-1).get() + msdu1 + macFrame1.get_icv() + get_pad(98):
+ print "msdu1 =", rsp1[0].get_pblist()[0]
+ raise Error("msdu1")
+m.wait(100000)
+
+# Send an MPDU containing 3 PBs of 512 octets
+fcall_512_3 = create_fcall_512_3()
+fcall_512_3.send(sta1)
+macFrame2 = MACFrame()
+fc_av_2 = fc_av_1
+macFrame2.set_fc_av(fc_av_2)
+msdu2 = 1500*'a'
+macFrame2.set_msdu(msdu2)
+macFrame2.set_macframeheader(MACFrameHeader(MFL=len(msdu2)-1))
+rsp2 = macFrame2.sendnrecv(m)
+if rsp2[0].get_fc_av() != fc_av_2:
+ print "fc_av_2 =", rsp2[0].get_fc_av()
+ raise Error("fc_av_2")
+if rsp2[0].get_pblist()[0] != MACFrameHeader(MFL=len(msdu2)-1).get() + 510*'a' \
+or rsp2[0].get_pblist()[1] != 512*'a' \
+or rsp2[0].get_pblist()[2] != 478*'a' + macFrame2.get_icv() + get_pad(30):
+ print "msdu2 =", rsp2[0].get_pblist()[0], rsp2[0].get_pblist()[1], rsp2[0].get_pblist()[2]
+ raise Error("msdu2")
+m.wait(100000)
+
+# Send a short PPDU with a FC 1.0
+fcall_short_fc10 = create_fcall_short_fc10()
+fcall_short_fc10.send(sta1)
+macFrame3 = MACFrame()
+fc_10_3 = 1
+macFrame3.set_fc_10(fc_10_3)
+fc_av_3 = (123, 456, 789, 10)
+macFrame3.set_fc_av(fc_av_3)
+macFrame3.send(maximus=m, short_ppdu=True)
+# no rsp3
+m.wait(100000)
+
+# Send an MPDU containing one PB of 512 octets with a FC 1.0
+fcall_512_1 = create_fcall_512_1()
+fcall_512_1.send(sta1)
+macFrame4 = MACFrame()
+fc_10_4 = 10
+macFrame4.set_fc_10(fc_10_4)
+fc_av_4 = fc_av_1
+macFrame4.set_fc_av(fc_av_4)
+msdu4 = 200*'b'
+macFrame4.set_msdu(msdu4)
+macFrame4.set_macframeheader(MACFrameHeader(MFL=len(msdu4)-1))
+macFrame4.send(m)
+rsp4 = recv(m)
+if rsp4[0].get_fc_10() != fc_10_4:
+ print "fc_10_4 =", rsp4[0].get_fc_10()
+ raise Error("fc_10_4")
+if rsp4[0].get_fc_av() != fc_av_4:
+ print "fc_av_4 =", rsp4[0].get_fc_av()
+ raise Error("fc_av_4")
+if rsp4[0].get_pblist()[0] != MACFrameHeader(MFL=len(msdu4)-1).get() + msdu4 + macFrame4.get_icv() + get_pad(306):
+ print "msdu4 =", rsp4[0].get_pblist()[0]
+ raise Error("msdu4")
+m.wait(100000)
+
+# Send an MPDU containing one PB of 128 octets, created from an MME
+fcall_128 = create_fcall_128()
+fcall_128.send(sta1)
+icv5 = 'ICV!'
+macFrame5 = MACFrame(ICV=icv5)
+fc_av_5 = fc_av_1
+macFrame5.set_fc_av(fc_av_5)
+mmheader5 = 'MMHeader 19 octets!'
+mmentry5 = '--- This is the Management Message Entry ---'
+msdu5 = MME(MMHeader=mmheader5, MMEntry=mmentry5)
+macFrame5.set_msdu(msdu5)
+macFrame5.set_macframeheader(MACFrameHeader(MFL=len(mmheader5)+len(mmentry5)-1))
+rsp5 = macFrame5.sendnrecv(m)
+if rsp5[0].get_fc_av() != fc_av_5:
+ print "fc_av_5 =", rsp5[0].get_fc_av()
+ raise Error("fc_av_5")
+if rsp5[0].get_pblist()[0] != MACFrameHeader(MFL=len(mmheader5)+len(mmentry5)-1).get() + mmheader5 + mmentry5 + macFrame5.get_icv() + get_pad(59):
+ print "msdu5 =", rsp5[0].get_pblist()[0]
+ raise Error("msdu5")
+m.wait(100000)
+
+# Uninitialize PHY
+fcall2 = m.create_fcall('uninit_phy')
+fcall2.send(sta1)
+
+# Remove station(s)
+sta1.remove()
+
+print "\n*** END ***\n"
diff --git a/cesar/maximus/python/src/interface_module.cpp b/cesar/maximus/python/src/interface_module.cpp
new file mode 100644
index 0000000000..7890989579
--- /dev/null
+++ b/cesar/maximus/python/src/interface_module.cpp
@@ -0,0 +1,745 @@
+
+#include <boost/python.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/call.hpp>
+#include <boost/python/call_method.hpp>
+
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/copy_non_const_reference.hpp>
+#include <boost/python/return_internal_reference.hpp>
+
+#include <boost/python/detail/api_placeholder.hpp>
+
+#include "maximus/common/interfaces/Maximus.h"
+#include "maximus/common/interfaces/Sta.h"
+#include "maximus/common/interfaces/Msg.h"
+
+#include "ISystem.h"
+#include "IFunctionCall.h"
+#include "PhySciMsgMpdu.h"
+#include "PhySciMsgFc.h"
+#include "EtherSciMsg.h"
+
+#include "Logger.h"
+
+using namespace std;
+using namespace boost::python;
+
+// For unitary tests
+extern bool UNITTEST;
+extern string stationTest;
+
+// For Maximus log
+extern Logger logger;
+
+// To catch signals
+extern Maximus * pMaximus;
+
+// To log Ether SCI messages
+File_Descriptor etherLogFileDescriptor = -1;
+
+typedef std::multimap<Function_Call_Msg_Id, object, compareMsgId> CbsList;
+CbsList listOfCbs;
+
+typedef struct rx_param_phy
+{
+ object create_pb;
+ object cb;
+ bool activated;
+} rx_param_phy_t;
+rx_param_phy_t phy_rx_param;
+
+typedef struct rx_param_ether
+{
+ object create_eth;
+ object create_mme;
+ object create_buffer;
+ object create_sniffer;
+ object cb;
+ bool activated;
+} rx_param__ether_t;
+rx_param__ether_t ether_rx_param;
+
+
+void log_ether ( EtherSciMsg & ether )
+{
+ logFunction();
+
+ if (-1 != etherLogFileDescriptor)
+ {
+ /* Write the Ether SCI message into the Ether log file. */
+ int length = 0;
+ int totalLength = 0;
+ while(totalLength < (int)ether.getSpecializedSciMsgDataLength())
+ {
+ length = write(etherLogFileDescriptor, ether.getSpecializedSciMsgData() + totalLength, ether.getSpecializedSciMsgDataLength() - totalLength);
+ if(length < 0)
+ {
+ if (EAGAIN != errno)
+ {
+ Error e(__PRETTY_FUNCTION__, "write Ether SCI message failed", errno);
+ e.display();
+ throw e;
+ }
+ else
+ {
+ length = 0;
+ }
+ }
+ totalLength += length;
+ }
+ }
+}
+
+
+void set_fcall_cb ( const Msg & msg, object user_cb )
+{
+ listOfCbs.insert(CbsList::value_type(msg.get_tx_msg_id(), user_cb));
+}
+
+
+void remove_fcall_cb ( const Msg & msg )
+{
+ for (CbsList::const_iterator it = listOfCbs.begin(); it != listOfCbs.end(); ++it)
+ {
+ if (msg.get_tx_msg_id() == it->first)
+ {
+ listOfCbs.erase(it->first);
+ break;
+ }
+ }
+}
+
+
+void recv_fcall_cb ( Msg & msg )
+{
+ for (CbsList::const_iterator it = listOfCbs.begin(); it != listOfCbs.end(); ++it)
+ {
+ if (msg.get_rx_msg_id() == it->first)
+ {
+ (it->second)(msg);
+ listOfCbs.erase(it->first);
+ break;
+ }
+ }
+}
+
+
+void recv_phy_mpdu_cb ( PhySciMsgMpdu & mpdu )
+{
+ logFunction();
+
+ if (phy_rx_param.activated)
+ {
+ // Create a new MPDU Python object (PB)
+ object rx_mpdu = phy_rx_param.create_pb();
+
+ // Get PHY SCI message MPDU attributes
+ // and set the MPDU object attributes
+ // (FC 1.0, FC AV and MPDU payload)
+ string payload((char *)mpdu.getSpecializedSciMsgData(), mpdu.getSpecializedSciMsgDataLength());
+ rx_mpdu.attr("set_mpdu_attr")(mpdu.getFc10(),
+ make_tuple(mpdu.getFcAv()[0], mpdu.getFcAv()[1], mpdu.getFcAv()[2], mpdu.getFcAv()[3]),
+ payload);
+
+ // Call the Python reception callback
+ phy_rx_param.activated = !phy_rx_param.cb(rx_mpdu);
+ }
+}
+
+
+void recv_ether_cb ( EtherSciMsg & ether )
+{
+ logFunction();
+
+ // Log the received Ether SCI message
+ log_ether(ether);
+
+ if ( ether_rx_param.activated
+ || (ETHERNET_TYPE_BUFFER_RELEASED == ether.getSpecializedSciMsgType()) )
+ {
+ // Get Ethernet SCI message attributes
+ string payload((char *)ether.getSpecializedSciMsgData(), ether.getSpecializedSciMsgDataLength());
+
+ // Create a new MSDU Python object (Eth, MME, Buffer or Sniffer)
+ object rx_msdu;
+ if (ETHERNET_TYPE_DATA == ether.getSpecializedSciMsgType())
+ {
+ rx_msdu = ether_rx_param.create_eth();
+ }
+ else if (ETHERNET_TYPE_MME == ether.getSpecializedSciMsgType())
+ {
+ rx_msdu = ether_rx_param.create_mme();
+ }
+ else if (ETHERNET_TYPE_BUFFER_RELEASED == ether.getSpecializedSciMsgType())
+ {
+ rx_msdu = ether_rx_param.create_buffer();
+ }
+ else if (ETHERNET_TYPE_SNIFFER == ether.getSpecializedSciMsgType())
+ {
+ /* Read flags. */
+ // way
+ bool way = (ETHERNET_FLAG_WAY == (ether.getFlags() & ETHERNET_FLAG_WAY));
+ // encryption
+ bool encryption = (ETHERNET_FLAG_ENCRYPTED == (ether.getFlags() & ETHERNET_FLAG_ENCRYPTED));
+
+ rx_msdu = ether_rx_param.create_sniffer(way, encryption, ether.getSnifferType());
+ }
+ else
+ {
+ errno = ENOMSG;
+ Error e(__PRETTY_FUNCTION__, "receive an Ether SCI message with a bad type (should be DATA, MME, BUFFER_RELEASED or SNIFFER)", errno);
+ e.display();
+ throw e;
+ }
+
+ if (ETHERNET_TYPE_BUFFER_RELEASED == ether.getSpecializedSciMsgType())
+ {
+ // Reallocate a buffer if requested by user
+ rx_msdu.attr("realloc")(ether.getSciMsgStationId(), payload);
+ }
+
+ // Set the MSDU object attributes (payload)
+ rx_msdu.attr("set_msdu_attr")(payload);
+
+ if (ether_rx_param.activated)
+ {
+ // Call the Python reception callback
+ ether_rx_param.activated = !ether_rx_param.cb(rx_msdu);
+ }
+ }
+}
+
+/*
+void init_wrap ( Maximus & m, const int argc, const string args )
+{
+ size_t previous = 0;
+ size_t found = 0;
+ char * argv[argc];
+ int i = 0;
+
+ do
+ {
+ found = args.find(' ', previous);
+ string temp = args.substr(previous, found-previous);
+ argv[i] = new char[temp.size()+1];
+ strcpy(argv[i], temp.c_str());
+ previous = found+1;
+ i++;
+ }
+ while ((found != string::npos) && (i<argc));
+
+ m.init(argc,argv);
+
+ for (i=0; i<argc; i++)
+ {
+ delete [] argv[i];
+ }
+}
+*/
+
+void init_wrap ( Maximus & m, object args )
+{
+ int argc = len (args);
+ /* std::string.c_str() returns a const, need a temporary storage because
+ * of getopt. */
+ std::vector<char> args_copy[argc];
+ char *argv[argc];
+ /* Make the argv array. */
+ for (int i = 0; i < argc; i++)
+ {
+ const std::string s = extract<std::string> (args[i]);
+ args_copy[i].insert (args_copy[i].end (), s.c_str (),
+ s.c_str () + s.size () + 1);
+ argv[i] = &args_copy[i][0];
+ }
+ /* Call the real function. */
+ m.init (argc, argv);
+
+ phy_rx_param.activated = false;
+ ether_rx_param.activated = false;
+ m.init_phy (&recv_phy_mpdu_cb);
+ etherLogFileDescriptor = m.init_ether (&recv_ether_cb);
+}
+
+
+PyObject * create_sta_wrapx1 ( Maximus & m )
+{
+ return_internal_reference<1, Maximus>::result_converter::apply<Sta &>::type converter;
+ return converter(m.create_sta());
+}
+
+
+PyObject * create_sta_wrapx2 ( Maximus & m, const string & station_executable )
+{
+ return_internal_reference<1, Maximus>::result_converter::apply<Sta &>::type converter;
+ return converter(m.create_sta(station_executable));
+}
+
+
+PyObject * create_fcall_wrap ( Maximus & m, const string name )
+{
+ return_internal_reference<1, Maximus>::result_converter::apply<Msg &>::type converter;
+ return converter(m.create_fc(name));
+}
+
+
+PyObject * create_probe_wrap ( Maximus & m )
+{
+ return_internal_reference<1, Maximus>::result_converter::apply<Msg &>::type converter;
+ return converter(m.create_probe());
+}
+
+
+void send_phy ( Maximus & m, object mpdu )
+{
+ /* Create a PHY SCI message MPDU. */
+ PhySciMsgMpdu * pMpdu = m.create_mpdu();
+
+ /* Extract MPDU object attributes
+ * and set the PHY SCI message MPDU attributes. */
+
+ // Extract and set FC 1.0
+ uint32_t fc_10 = extract<uint32_t>(mpdu.attr("fc_10"));
+ if (0 != fc_10)
+ {
+ pMpdu->setFc10(fc_10);
+ }
+
+ // Extract and set FC AV
+ uint32_t fc_av[4];
+ for (int i=0; i<4; i++)
+ {
+ fc_av[i] = extract<uint32_t>(mpdu.attr("fc_av")[i]);
+ }
+ pMpdu->setFcAv(fc_av);
+
+ // Extract MPDU payload and set MPDU payload length and MPDU payload
+ string payload = extract<string>(mpdu.attr("payload"));
+ pMpdu->setMpdu((unsigned long)payload.length(), (unsigned char *)payload.c_str());
+
+ // Set MPDU format
+ // HomePlug AV specs => delimiter type (DT_AV) is described by bits 0-2 of first fc_av octet:
+ // 000 Beacon
+ // 001 SOF
+ // 010 SACK
+ // 011 RTS/CTS
+ // 100 SOUND
+ // 101 RSOF
+ pMpdu->setMpduFormat((Phy_Mpdu_Format)((fc_av[0] & 0x07) + 1)); // +1 to have the correspondance with our own MPDU format definition (of 'phy_types.h')
+
+ // Extract and set FC mode
+ int fc_mode = extract<int>(mpdu.attr("fc_mode"));
+ if ( PHY_FC_MODE_NONE == (Phy_Fc_Mode)fc_mode )
+ {
+ if (0 == fc_10)
+ {
+ fc_mode = PHY_FC_MODE_AV_1;
+ }
+ else
+ {
+ fc_mode = PHY_FC_MODE_HYBRID_1;
+ }
+ }
+ pMpdu->setFcMode((Phy_Fc_Mode)fc_mode);
+
+ // Extract and set short PPDU
+ pMpdu->setShortPpdu((Phy_Short_Ppdu)extract<int>(mpdu.attr("short_ppdu")));
+
+ // Set default flags
+ pMpdu->setFlags(PHY_FLAG_CRC_OK);
+
+ if (!pMpdu->getShortPpdu())
+ {
+ // Extract and set modulation
+ int mod = extract<int>(mpdu.attr("mod"));
+ if (PHY_MOD_TM == (Phy_Mod)mod)
+ {
+ errno = EINVAL;
+ Error e(__PRETTY_FUNCTION__, "modulation cannot be set to PHY_MOD_TM", errno);
+ e.display();
+ throw e;
+ }
+ else if ((PHY_MOD_NONE == (Phy_Mod)mod) && (MAC_PB136_BYTES >= payload.length()))
+ {
+ mod = PHY_MOD_MINI_ROBO;
+ }
+ else if ((PHY_MOD_NONE == (Phy_Mod)mod) && (MAC_PB136_BYTES < payload.length()))
+ {
+ mod = PHY_MOD_ROBO;
+ }
+ pMpdu->setMod((Phy_Mod)mod);
+
+ // Set default FEC rate
+ pMpdu->setFecrate(PHY_FEC_RATE_1_2);
+
+ if (PHY_MOD_MINI_ROBO == pMpdu->getMod())
+ {
+ // Set default Guard Interval
+ pMpdu->setGil(PHY_GIL_567);
+ // Set default PB size
+ pMpdu->setPbSize(MAC_PB136_BYTES);
+ }
+ else
+ {
+ // Set default Guard Interval
+ pMpdu->setGil(PHY_GIL_417);
+ // Set default PB size
+ pMpdu->setPbSize(MAC_PB520_BYTES);
+ // Set default flags
+ pMpdu->setFlags(PHY_FLAG_CRC_OK+PHY_FLAG_PB512);
+ }
+ }
+
+ // Extract and set PB Header
+ uint32_t pbHeader = extract<uint32_t>(mpdu.attr("first_pb_header"));
+ if (0 != pbHeader)
+ {
+ unsigned short int mfboCounter = 1;
+ unsigned long mfbo = extract<unsigned long>(mpdu.attr("mfbo")[mfboCounter]);
+ for (unsigned short int n=0; n<MAC_MAX_PB_PER_MPDU; n++)
+ {
+ if (0 != n)
+ {
+ while ( (0 != mfbo) && (mfbo < (unsigned long)(n * pMpdu->getPbSize())) )
+ {
+ // increment MFBO counter
+ mfboCounter++;
+ // extract MFBO
+ mfbo = extract<unsigned long>(mpdu.attr("mfbo")[mfboCounter]);
+ }
+
+ // extract MFBO
+ if ( (0 != mfbo) && (mfbo < (unsigned long)((n + 1) * pMpdu->getPbSize())) )
+ {
+ // set MFBF
+ pbHeader |= (1 << 27);
+ // set MFB0
+ pbHeader += ((mfbo % pMpdu->getPbSize()) << 16);
+ }
+ }
+
+ // set PBs Headers
+ pMpdu->setPbsHeaders(n, pbHeader);
+
+ // reset MFBF and MFBO, and increment SSN
+ if (0xFFFF > (pbHeader & 0xFFFF))
+ {
+ pbHeader = (pbHeader & 0xF600FFFF) + 1;
+ }
+ else
+ {
+ pbHeader &= 0xF6000000;
+ }
+ }
+ }
+
+ /* Send the PHY SCI message MPDU. */
+ m.send_mpdu(pMpdu);
+ while (!pMpdu->isSent())
+ {
+ m.process();
+ }
+
+ /* Delete the PHY SCI message MPDU. */
+ if (NULL != pMpdu)
+ {
+ delete (pMpdu);
+ pMpdu = NULL;
+ }
+}
+
+
+void set_phy_rx ( Maximus & m, object user_cb, object create_pb_function )
+{
+ phy_rx_param.cb = user_cb;
+ phy_rx_param.create_pb = create_pb_function;
+ phy_rx_param.activated = true;
+}
+
+
+void send_ether ( Maximus & m, object msdu, int station_id )
+{
+ /* Create an Ether SCI message. */
+ EtherSciMsg * pEther = m.create_ether();
+
+ /* Set the Ether SCI message attributes. */
+
+ // Extract MSDU payload and set Ether SCI message payload length and Ether SCI message payload
+ string payload = extract<string>(msdu.attr("get")());
+ pEther->setSpecializedSciMsgDataLength((unsigned long)payload.length());
+ pEther->setSpecializedSciMsgData((unsigned char *)payload.c_str());
+
+ // Set Ether SCI message type
+ int type = extract<int>(msdu.attr("get_ether_type")());
+ pEther->setSpecializedSciMsgType(static_cast<Ethernet_Type>(type));
+
+ // Set station ID
+ pEther->setSciMsgStationId(static_cast<Sci_Msg_Station_Id>(station_id));
+
+ /* Log the Ether SCI message to send. */
+ log_ether(*pEther);
+
+ /* Send the Ether SCI message. */
+ m.send_ether(*pEther);
+
+ /* Delete the Ether SCI message. */
+ if (NULL != pEther)
+ {
+ delete (pEther);
+ pEther = NULL;
+ }
+}
+
+
+void set_ether_rx ( Maximus & m,
+ object user_cb,
+ object create_eth_function,
+ object create_mme_function,
+ object create_buffer_function,
+ object create_sniffer_function )
+{
+ ether_rx_param.cb = user_cb;
+ ether_rx_param.create_eth = create_eth_function;
+ ether_rx_param.create_mme = create_mme_function;
+ ether_rx_param.create_buffer = create_buffer_function;
+ ether_rx_param.create_sniffer = create_sniffer_function;
+ ether_rx_param.activated = true;
+}
+
+
+PyObject * add_param_bool ( Msg & msg, const string name, const bool value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ msg.add_param<bool>(name, value);
+ return converter(msg);
+}
+
+
+PyObject * add_param_uchar ( Msg & msg, const string name, const unsigned char value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ msg.add_param(name, sizeof(unsigned char), &value);
+ return converter(msg);
+}
+
+
+PyObject * add_param_ushort ( Msg & msg, const string name, const unsigned short int value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ msg.add_param<unsigned short int>(name, value);
+ return converter(msg);
+}
+
+
+PyObject * add_param_ulong ( Msg & msg, const string name, const unsigned long int value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ msg.add_param<unsigned long int>(name, value);
+ return converter(msg);
+}
+
+
+PyObject * add_param_n_u8 ( Msg & msg, const string name, tuple value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ unsigned long length = (unsigned long)len(value);
+ unsigned char param[length];
+ for (unsigned long i=0; i<length; i++)
+ {
+ param[i] = extract<unsigned char>(value[i]);
+ }
+ msg.add_param(name, length*sizeof(unsigned char), param);
+ return converter(msg);
+}
+
+
+PyObject * add_param_n_u16 ( Msg & msg, const string name, tuple value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ unsigned long length = (unsigned long)len(value);
+ unsigned short int param[length];
+ for (unsigned long i=0; i<length; i++)
+ {
+ param[i] = htons(extract<unsigned short int>(value[i]));
+ }
+ msg.add_param(name, length*sizeof(unsigned short int), (unsigned char *)&param);
+ return converter(msg);
+}
+
+
+PyObject * add_param_n_u32 ( Msg & msg, const string name, tuple value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ unsigned long length = (unsigned long)len(value);
+ unsigned long int param[length];
+ for (unsigned long i=0; i<length; i++)
+ {
+ param[i] = htonl(extract<unsigned long int>(value[i]));
+ }
+ msg.add_param(name, length*sizeof(unsigned long int), (unsigned char *)&param);
+ return converter(msg);
+}
+
+
+PyObject * set_cb_wrap ( Msg & msg, object user_cb )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ remove_fcall_cb(msg);
+ set_fcall_cb(msg, user_cb);
+ msg.set_cb(&recv_fcall_cb);
+ return converter(msg);
+}
+
+
+PyObject * remove_cb_wrap ( Msg & msg )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ remove_fcall_cb(msg);
+ msg.remove_cb();
+ return converter(msg);
+}
+
+
+string bind_param ( Msg & msg, const string name )
+{
+ string str;
+ unsigned long ulLength = FUNCTION_CALL_PARAM_MAX_SIZE;
+ unsigned char ucValue[ulLength];
+ if (NULL != msg.bind_param(name, ulLength, ucValue))
+ {
+ str.assign((char *)ucValue, ulLength);
+ }
+ return str;
+}
+
+
+string bind_param_string ( Msg & msg, const string name )
+{
+ string str(bind_param(msg, name));
+ if ( (0 < str.length()) && ('\0' == str[str.length()-1]) )
+ {
+ str.erase(str.length()-1);
+ }
+ return str;
+}
+
+
+bool bind_param_bool ( Msg & msg, const string name )
+{
+ return msg.bind_param<bool>(name);
+}
+
+
+unsigned short int bind_param_ushort ( Msg & msg, const string name )
+{
+ return msg.bind_param<unsigned short int>(name);
+}
+
+
+unsigned long int bind_param_ulong ( Msg & msg, const string name )
+{
+ return msg.bind_param<unsigned long int>(name);
+}
+
+
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(disturb_channel_overloads, Maximus::disturb_channel, 0, 1)
+
+BOOST_PYTHON_MODULE(interface)
+{
+ /* class Maximus */
+
+ void (Maximus::*waitx1)(const tick_t) = &Maximus::wait;
+ void (Maximus::*waitx2)(void) = &Maximus::wait;
+
+ void (Maximus::*set_snrx1)(const float) = &Maximus::set_snr;
+ void (Maximus::*set_snrx2)(const string &) = &Maximus::set_snr;
+ void (Maximus::*set_snr_from_srcx1)(const float, const Sta &, const bool) = &Maximus::set_snr_from_src;
+ void (Maximus::*set_snr_from_srcx2)(const string &, const Sta &, const bool) = &Maximus::set_snr_from_src;
+ void (Maximus::*set_snr_to_dstx1)(const float, const Sta &, const bool) = &Maximus::set_snr_to_dst;
+ void (Maximus::*set_snr_to_dstx2)(const string &, const Sta &, const bool) = &Maximus::set_snr_to_dst;
+ void (Maximus::*set_snr_from_src_to_dstx1)(const float, const Sta &, const Sta &, const bool) = &Maximus::set_snr_from_src_to_dst;
+ void (Maximus::*set_snr_from_src_to_dstx2)(const string &, const Sta &, const Sta &, const bool) = &Maximus::set_snr_from_src_to_dst;
+
+ class_<Maximus, boost::noncopyable>("Maximus")
+ .def("init", init_wrap)
+ .def("process", &Maximus::process)
+ .def("create_sta", create_sta_wrapx1) // create a station with the default station executable (from command line arguments)
+ .def("create_sta", create_sta_wrapx2) // create a station with an explicit station executable
+ .def("create_fcall", create_fcall_wrap)
+ .def("create_probe", create_probe_wrap)
+ .def("send_mpdu", send_phy)
+ .def("set_mpdu_rx", set_phy_rx)
+ .def("send_msdu", send_ether)
+ .def("set_msdu_rx", set_ether_rx)
+ .def("wait", waitx1)
+ .def("wait", waitx2)
+ .def("disturb_channel", &Maximus::disturb_channel, disturb_channel_overloads())
+ .def("get_date", &Maximus::get_date)
+ .def("set_freq", &Maximus::set_freq)
+ .def("get_freq", &Maximus::get_freq)
+ .def("set_snr", set_snrx1)
+ .def("set_snr", set_snrx2)
+ .def("set_snr_from_src", set_snr_from_srcx1)
+ .def("set_snr_from_src", set_snr_from_srcx2)
+ .def("set_snr_to_dst", set_snr_to_dstx1)
+ .def("set_snr_to_dst", set_snr_to_dstx2)
+ .def("set_snr_from_src_to_dst", set_snr_from_src_to_dstx1)
+ .def("set_snr_from_src_to_dst", set_snr_from_src_to_dstx2)
+ .def("activate_false_alarm", &Maximus::activate_false_alarm)
+ .def("deactivate_false_alarm", &Maximus::deactivate_false_alarm)
+ .def("is_station_idle", &Maximus::is_station_idle)
+ ;
+
+ /* class Sta */
+
+ class_<Sta>("Sta", init< Maximus *, ISystem *, const string & >())
+ .def("remove", &Sta::remove)
+ .def("deactivate", &Sta::deactivate)
+ .def("activate", &Sta::activate)
+ .def("debug", &Sta::debug)
+ .def("is_idle", &Sta::is_idle)
+ .def("get_station_id", &Sta::getStationId)
+ .def("set_name", &Sta::set_name)
+ ;
+
+ /* class Msg */
+
+ Msg & (Msg::*add_paramx1)(const string &) = &Msg::add_param;
+ Msg & (Msg::*add_paramx2)(const string &, const string &) = &Msg::add_param;
+
+ void (Msg::*send_asyncx1)(void) = &Msg::send_async;
+ void (Msg::*send_asyncx2)(Sta &) = &Msg::send_async;
+
+ Msg & (Msg::*sendx1)(void) = &Msg::send;
+ Msg & (Msg::*sendx2)(Sta &) = &Msg::send;
+
+ class_<Msg>("Msg", init< Maximus *, IFunctionCall *, ISystem *, optional<const string &> >())
+ .def("add_param", add_paramx1, return_value_policy<copy_non_const_reference>())
+ .def("add_param", add_paramx2, return_value_policy<copy_non_const_reference>())
+ .def("add_param_bool", add_param_bool)
+ .def("add_param_uchar", add_param_uchar)
+ .def("add_param_ushort", add_param_ushort)
+ .def("add_param_ulong", add_param_ulong)
+ .def("add_param_n_u8", add_param_n_u8)
+ .def("add_param_n_u16", add_param_n_u16)
+ .def("add_param_n_u32", add_param_n_u32)
+ .def("remove_param", &Msg::remove_param, return_value_policy<copy_non_const_reference>())
+ .def("set_cb", set_cb_wrap)
+ .def("remove_cb", remove_cb_wrap)
+ .def("set_sta", &Msg::set_sta, return_value_policy<copy_non_const_reference>())
+ .def("send_async", send_asyncx1)
+ .def("send_async", send_asyncx2)
+ .def("send", sendx1, return_value_policy<copy_non_const_reference>())
+ .def("send", sendx2, return_value_policy<copy_non_const_reference>())
+ .def("is_param", &Msg::is_param)
+ .def("bind_param", bind_param)
+ .def("bind_param_string", bind_param_string)
+ .def("bind_param_bool", bind_param_bool)
+ .def("bind_param_ushort", bind_param_ushort)
+ .def("bind_param_ulong", bind_param_ulong)
+ ;
+
+}
+
diff --git a/cesar/maximus/python/test/startup.py b/cesar/maximus/python/test/startup.py
new file mode 100755
index 0000000000..205c4abd0d
--- /dev/null
+++ b/cesar/maximus/python/test/startup.py
@@ -0,0 +1,29 @@
+#! usr/bin/env python
+
+print __name__
+
+import sys
+
+# for maximus package
+sys.path.append('../python')
+sys.path.append('../../python')
+
+# for interface module
+sys.path.append('./obj')
+sys.path.append('../obj')
+
+# for libraries
+sys.path.append('./lib')
+sys.path.append('../lib')
+
+# for Cesar library
+sys.path.append('./lib/cesar')
+sys.path.append('../lib/cesar')
+
+# for CRC 24 library
+sys.path.append('./lib/fcVf/crc24')
+sys.path.append('../lib/fcVf/crc24')
+
+# for proto library
+sys.path.append('./lib/proto')
+sys.path.append('../lib/proto')
diff --git a/cesar/maximus/python/test/test.txt b/cesar/maximus/python/test/test.txt
new file mode 100644
index 0000000000..fdf4907302
--- /dev/null
+++ b/cesar/maximus/python/test/test.txt
@@ -0,0 +1,94 @@
+
+DATA TEST
+---------
+
+Allow to get values in different formats.
+
+>>> from maximus.utils.converter import *
+>>> d=Data(123,10)
+>>> d.get_hex()
+'7b'
+
+
+FORMAT TEST
+-----------
+
+>>> from maximus.utils.format import *
+>>> hton8(0x41)
+'A'
+>>> hex(ntoh8('A'))
+'0x41'
+>>> hex(ntoh8(hton8(0x41)))
+'0x41'
+>>> hton16(0x4142)
+'AB'
+>>> hex(ntoh16('AB'))
+'0x4142'
+>>> hex(ntoh16(hton16(0x4142)))
+'0x4142'
+>>> hton32(0x41424344)
+'ABCD'
+>>> hex(ntoh32('ABCD'))
+'0x41424344'
+>>> hex(ntoh32(hton32(0x41424344)))
+'0x41424344'
+>>> hton48(0x414243444546)
+'ABCDEF'
+>>> hex(ntoh48('ABCDEF'))
+'0x414243444546L'
+>>> hex(ntoh48(hton48(0x414243444546)))
+'0x414243444546L'
+>>> hton48_tuple((0x41, 0x42, 0x43, 0x44, 0x45, 0x46))
+'ABCDEF'
+>>> ntoh48_tuple('ABCDEF')
+(65, 66, 67, 68, 69, 70)
+>>> ntoh48_tuple(hton48_tuple((65, 66, 67, 68, 69, 70)))
+(65, 66, 67, 68, 69, 70)
+>>> hton64(0x4142434445464748)
+'ABCDEFGH'
+>>> hex(ntoh64('ABCDEFGH'))
+'0x4142434445464748L'
+>>> hex(ntoh64(hton64(0x4142434445464748)))
+'0x4142434445464748L'
+>>> htohp8(0x41)
+'A'
+>>> hex(hptoh8('A'))
+'0x41'
+>>> hex(hptoh8(htohp8(0x41)))
+'0x41'
+>>> htohp16(0x4142)
+'BA'
+>>> hex(hptoh16('BA'))
+'0x4142'
+>>> hex(hptoh16(htohp16(0x4142)))
+'0x4142'
+>>> htohp24(0x414243)
+'CBA'
+>>> hex(hptoh24('CBA'))
+'0x414243'
+>>> hex(hptoh24(htohp24(0x414243)))
+'0x414243'
+>>> htohp32(0x41424344)
+'DCBA'
+>>> hex(hptoh32('DCBA'))
+'0x41424344'
+>>> hex(hptoh32(htohp32(0x41424344)))
+'0x41424344'
+>>> htohp48(0x414243444546)
+'DCBAFE'
+>>> hex(hptoh48('DCBAFE'))
+'0x414243444546L'
+>>> hex(hptoh48(htohp48(0x414243444546)))
+'0x414243444546L'
+>>> htohp48_tuple((0x41, 0x42, 0x43, 0x44, 0x45, 0x46))
+'DCBAFE'
+>>> hptoh48_tuple('DCBAFE')
+(65, 66, 67, 68, 69, 70)
+>>> hptoh48_tuple(htohp48_tuple((65, 66, 67, 68, 69, 70)))
+(65, 66, 67, 68, 69, 70)
+>>> htohp64(0x4142434445464748)
+'HGFEDCBA'
+>>> hex(hptoh64('HGFEDCBA'))
+'0x4142434445464748L'
+>>> hex(hptoh64(htohp64(0x4142434445464748)))
+'0x4142434445464748L'
diff --git a/cesar/maximus/python/test/test_channel.py b/cesar/maximus/python/test/test_channel.py
new file mode 100644
index 0000000000..cc8a23d394
--- /dev/null
+++ b/cesar/maximus/python/test/test_channel.py
@@ -0,0 +1,80 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys, startup
+
+from maximus.channel import *
+from maximus.station import *
+from interface import *
+
+
+# CHANNEL TEST
+
+# Create a Maximus instance
+m = Maximus()
+
+# Initialize Maximus with command line arguments
+m.init(sys.argv)
+
+# Enable channel perturbation
+m.disturb_channel()
+
+# Create an SNR description file
+f = open('test/channel_settings.txt', 'w+')
+for i in range(0, 7):
+ f.write(str((i+1)*5000) + "\t")
+f.write("# End times (in ticks) of each interval of the beacon period\n")
+for i in range (0, 1155):
+ f.write(str(i+1+0.1) + "\t" + str(i+1+0.2) + "\t" + str(i+1+0.3) + "\t" + str(i+1+0.4) + "\t" + str(i+1+0.5) + "\t" + str(i+1+0.6) + "\t" + str(i+1+0.7) + "\t" + str(i+1+0.8) + "\t" + "# SNR values (in dB) for carrier number " + str(i+1) + "\n")
+f.close()
+
+# Set the SNR
+staA = STA(m)
+staB = STA(m)
+set_snr(m, value=15)
+set_snr(m, file='test/channel_settings.txt')
+set_snr(m, value=10, src=staA)
+set_snr(m, file='test/channel_settings.txt', src=staA)
+set_snr(m, value=12, dst=staB)
+set_snr(m, file='test/channel_settings.txt', dst=staB)
+set_snr(m, value=12, src=staA, dst=staB)
+set_snr(m, file='test/channel_settings.txt', src=staA, dst=staB)
+staC = STA(m)
+set_snr(m, value=10, src=staA)
+set_snr(m, file='test/channel_settings.txt', src=staC, both_directions=True)
+set_snr(m, value=12, dst=staC)
+set_snr(m, file='test/channel_settings.txt', dst=staC, both_directions=True)
+set_snr(m, value=12, src=staA, dst=staC, both_directions=True)
+set_snr(m, file='test/channel_settings.txt', src=staA, dst=staC, both_directions=True)
+staD = m.create_sta()
+set_snr(m, value=12, src=staD)
+
+# Remove stations
+m.create_fcall("uninit_ether").send(staA.get())
+staA.remove()
+m.create_fcall("uninit_ether").send(staB.get())
+staB.remove()
+m.create_fcall("uninit_ether").send(staC.get())
+staC.remove()
+m.create_fcall("uninit_ether").send(staD)
+staD.remove()
+
+
+# DOC TEST
+
+import doctest
+doctest.testmod(snr)
+
+
+# UNIT TEST
+
+import unittest
+suite = unittest.TestSuite()
+try:
+ suite.addTest(doctest.DocTestSuite(snr))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_cli.py b/cesar/maximus/python/test/test_cli.py
new file mode 100644
index 0000000000..a0b8984d19
--- /dev/null
+++ b/cesar/maximus/python/test/test_cli.py
@@ -0,0 +1,26 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import startup
+
+from maximus.cli import *
+
+
+# CLI TEST
+
+
+# DOC TEST
+
+import doctest
+#doctest.testmod()
+
+
+# UNIT TEST
+
+import unittest
+suite = unittest.TestSuite()
+#try:
+# suite.addTest(doctest.DocTestSuite())
+#except ValueError:
+# print "has no tests"
diff --git a/cesar/maximus/python/test/test_ethernet.py b/cesar/maximus/python/test/test_ethernet.py
new file mode 100644
index 0000000000..fec75fe623
--- /dev/null
+++ b/cesar/maximus/python/test/test_ethernet.py
@@ -0,0 +1,489 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys, startup
+
+from maximus.ethernet import *
+from maximus.ethernet.buffer import Buffer
+from maximus.ethernet.create import create_eth, create_buffer, create_sniffer
+from maximus.ethernet.eth import MIN_SIZE_OF_HEADER, MAX_SIZE_OF_HEADER
+from maximus.ethernet.sniffer import Sniffer
+from maximus.macframe.msdu import MIN_SIZE_OF_MSDU
+from maximus.simu.rx import * # for 'recv()' function
+from maximus.utils.exception import Error, OutOfRangeError
+from interface import *
+from struct import pack, unpack
+
+
+# ETH TEST
+
+# Create a Maximus instance
+m = Maximus()
+
+# Initialize Maximus with command line arguments
+m.init(sys.argv)
+
+# Create the destination station
+staRx = m.create_sta()
+staRx.debug()
+
+# Init ether
+fcall = m.create_fcall('init_ether')
+fcall.send(staRx)
+
+# Create an Ethernet frame
+f = Eth()
+
+# Create an Ethernet frame
+f.dst = '41:42:43:44:45:46'
+f.src = '47:48:49:4a:4b:4c'
+f.vlantag = 0x81004D4E
+f.type = 0x4F50
+s = 'This is the Ethernet Payload'
+f.payload = s
+if len(f) != MIN_SIZE_OF_HEADER + len(s):
+ print "expected length = ", MIN_SIZE_OF_HEADER + len(s)
+ print "length = ", len(f)
+ raise Error('Ethernet frame payload length')
+if str(f) != 'ABCDEFGHIJKLOP' + str(f.payload):
+ print "expected payload =", 'ABCDEFGHIJKLOP' + str(f.payload)
+ print "payload = ", str(f)
+ raise Error('Ethernet frame payload')
+
+# Create an Ethernet frame containing an IP frame
+g = Eth(dst=f.dst, src=f.src)/IP()
+if len(g) != MIN_SIZE_OF_HEADER + len(str(IP())):
+ raise Error('Ethernet IP frame payload length')
+h = unpack(34*'B', str(g))
+if h != (65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 8, 0, 69, 0, 0, 20, 0, 1, 0, 0, 64, 0, 124, 231, 127, 0, 0, 1, 127, 0, 0, 1):
+ raise Error('Ethernet IP frame payload')
+
+# Send the Ethernet frame asynchronously
+alloc_data_buffer(m, staRx, buffer_nb=2)
+f.send(m, staRx)
+
+# Send the Ethernet frame synchronously
+alloc_data_buffer(m, staRx, buffer_nb=2)
+rsp = f.sendnrecv(m, staRx)
+
+# Uninit ether
+fcall2 = m.create_fcall('uninit_ether')
+fcall2.send(staRx)
+
+# Remove the destination station
+staRx.remove()
+
+
+# SCAPY TEST
+
+#print [p for p in IP()]
+target="www.target.com"
+target="www.target.com/30"
+ip=IP(dst=target)
+#hexdump(ip)
+#print [p for p in ip]
+
+#print [p for p in IP()]
+a=IP(dst="172.16.1.40")
+#print [p for p in a]
+#print a.dst
+#print a.ttl
+
+a.ttl=32
+#print [p for p in a]
+del(a.ttl)
+#print [p for p in a]
+#print a.ttl
+
+t=TCP()
+t.flags="SA"
+#print t.flags
+#print [p for p in t]
+t.flags=23
+#print [p for p in t]
+i=IP(flags="DF+MF")
+#print i.flags
+#print [p for p in i]
+i.flags=6
+#print [p for p in i]
+
+#print a.dst
+#print a.src
+del(a.dst)
+#print a.dst
+#print a.src
+a.dst="192.168.11.10"
+#print a.src
+a.dst=target
+#print a.src
+a.src="1.2.3.4"
+#print [p for p in a]
+
+#print [p for p in IP()]
+#print [p for p in IP()/TCP()]
+#print [p for p in Ether()/IP()/TCP()]
+#print [p for p in IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"]
+#print [p for p in Ether()/IP()/IP()/UDP()]
+#print [p for p in IP(proto=55)/TCP()]
+
+#print str(IP())
+#print [p for p in IP(str(IP()))]
+a=Ether()/IP()/TCP()/"GET /index.html HTTP/1.0 \n\n"
+#hexdump(a)
+b=str(a)
+#print b
+c=Ether(b)
+#print [p for p in c]
+
+c.hide_defaults()
+#print [p for p in c]
+
+a=IP(dst="www.slashdot.org/30")
+#hexdump(a)
+#print [p for p in a]
+b=IP(ttl=[1,2,(5,9)])
+#hexdump(b)
+#print [p for p in b]
+c=TCP(dport=[80,443])
+#print [p for p in a/c]
+
+d = IP(dst="1.2.3.4")/ICMP()
+e = Ether()/IP(dst="1.2.3.4",ttl=(1,4))
+
+
+# DOC TEST
+
+import doctest
+doctest.testmod(buffer)
+doctest.testmod(create)
+doctest.testmod(eth)
+doctest.testmod(scapy)
+doctest.testmod(sniffer)
+
+
+# UNIT TEST
+
+import unittest
+
+class TestEthFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.eth = Eth()
+ self.m = m
+
+ def tearDown(self):
+ pass
+
+ def test_set_msdu_attr(self):
+ # Test without vlantag
+ p = 'ABCDEFGHIJKLMNThis is the Ethernet Payload'
+ self.eth.set_msdu_attr(p)
+ self.assertEqual(self.eth.dst, '41:42:43:44:45:46')
+ self.assertEqual(self.eth.src, '47:48:49:4a:4b:4c')
+ self.assertEqual(self.eth.type, 0x4D4E)
+ self.assertEqual(str(self.eth.payload), 'This is the Ethernet Payload')
+
+ # Test with vlantag
+ p = 'ABCDEFGHIJKL' + pack('!I', 0x81004D4E) + 'OPThis is the Ethernet Payload'
+ self.eth.set_msdu_attr(p)
+ self.assertEqual(self.eth.dst, '41:42:43:44:45:46')
+ self.assertEqual(self.eth.src, '47:48:49:4a:4b:4c')
+ self.assertEqual(self.eth.vlantag, 0x81004D4E)
+ self.assertEqual(self.eth.type, 0x4F50)
+ self.assertEqual(str(self.eth.payload), 'This is the Ethernet Payload')
+
+ def test_sendnrecv(self):
+ sta = self.m.create_sta()
+ self.m.create_fcall('init_ether').send(sta)
+ none_buffer = Buffer('ETHERNET_TYPE_NONE')
+ length = len(none_buffer.get_buffer_dict())
+
+ # Disable the automatic buffer allocation
+ realloc_buffer(False)
+
+ alloc_data_buffer(self.m, sta, buffer_nb=2)
+ rsp = self.eth.sendnrecv(self.m, sta, count=4)
+
+ # 1st received frame is the Ethernet frame
+ self.assertEqual(rsp[0].dst, 'ff:ff:ff:ff:ff:ff')
+ self.assertEqual(rsp[0].src, '')
+ self.assertEqual(rsp[0].type, 0)
+
+ # 2nd and 4th received frames are BUFFER RELEASED messages
+ self.assertEqual(rsp[1].get_ether_type(), 6)
+ self.assertEqual(rsp[1].get_type(), 'ETHERNET_TYPE_BUFFER_RELEASED')
+ self.assertEqual(rsp[3].get_ether_type(), 6)
+ self.assertEqual(rsp[3].get_type(), 'ETHERNET_TYPE_BUFFER_RELEASED')
+ self.assertEqual(len(rsp[1].get_buffer_dict()), length)
+
+ # Enable the automatic buffer allocation
+ realloc_buffer(True)
+
+ alloc_data_buffer(self.m, sta, buffer_nb=2)
+ length = len(none_buffer.get_buffer_dict())
+ rsp = self.eth.sendnrecv(self.m, sta, count=4)
+
+ # 1st received frame is the Ethernet frame
+ self.assertEqual(rsp[0].dst, 'ff:ff:ff:ff:ff:ff')
+ self.assertEqual(rsp[0].src, '')
+ self.assertEqual(rsp[0].type, 0)
+
+ # 3rd and 4th received frames are BUFFER RELEASED messages
+ self.assertEqual(rsp[2].get_ether_type(), 6)
+ self.assertEqual(rsp[2].get_type(), 'ETHERNET_TYPE_BUFFER_RELEASED')
+ self.assertEqual(rsp[3].get_ether_type(), 6)
+ self.assertEqual(rsp[3].get_type(), 'ETHERNET_TYPE_BUFFER_RELEASED')
+ self.assertEqual(len(rsp[3].get_buffer_dict()), length)
+
+ self.m.create_fcall('uninit_ether').send(sta)
+ sta.remove()
+
+ def test_send(self):
+ sta = self.m.create_sta()
+ self.m.create_fcall('init_ether').send(sta)
+ alloc_data_buffer(self.m, sta, buffer_nb=2)
+ self.eth.send(self.m, sta)
+ self.m.create_fcall('uninit_ether').send(sta)
+ sta.remove()
+
+ def test_get(self):
+ # Test without vlantag
+ self.eth.dst = '41:42:43:44:45:46'
+ self.eth.src = '47:48:49:4a:4b:4c'
+ self.eth.type = 0x4D4E
+ s = 'This is the Ethernet Payload'
+ self.eth.payload = s
+ self.assertEqual(self.eth.get(), 'ABCDEFGHIJKLMNThis is the Ethernet Payload' + (MIN_SIZE_OF_MSDU - MIN_SIZE_OF_HEADER - len(s)) * pack('B', 0))
+
+ # Test with vlantag
+ self.eth.dst = '41:42:43:44:45:46'
+ self.eth.src = '47:48:49:4a:4b:4c'
+ self.eth.vlantag = 0x81004D4E
+ self.eth.type = 0x4F50
+ s = 'This is the Ethernet Payload'
+ self.eth.payload = s
+ self.assertEqual(self.eth.get(), 'ABCDEFGHIJKL' + pack('!I', 0x81004D4E) + 'OPThis is the Ethernet Payload' + (MIN_SIZE_OF_MSDU - MAX_SIZE_OF_HEADER - len(s)) * pack('B', 0))
+
+ # Test with a bad vlantag
+ test = False
+ self.eth.vlantag = 0x4D4E4D4E
+ try:
+ self.eth.get()
+ except OutOfRangeError:
+ test = True
+ self.assert_(test)
+
+ def test_get_ether_type(self):
+ self.assertEqual(self.eth.get_ether_type(), 1)
+
+ def test_get_type(self):
+ self.assertEqual(self.eth.get_type(), 'ETHERNET_TYPE_DATA')
+
+ def test_create_eth(self):
+ self.assertNotEqual(create_eth(), None)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestEthFunctions)
+
+class TestBufferFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.data_buffer = Buffer('ETHERNET_TYPE_DATA_BUFFER_ADD')
+ self.assertEqual(self.data_buffer.get_ether_type(), 3)
+ self.assertEqual(self.data_buffer.get_type(), 'ETHERNET_TYPE_DATA_BUFFER_ADD')
+ self.assertEqual(self.data_buffer.get_buffer_nb(), 1)
+ self.mme_buffer = Buffer('ETHERNET_TYPE_MME_BUFFER_ADD', buffer_nb=2)
+ self.assertEqual(self.mme_buffer.get_ether_type(), 4)
+ self.assertEqual(self.mme_buffer.get_type(), 'ETHERNET_TYPE_MME_BUFFER_ADD')
+ self.assertEqual(self.mme_buffer.get_buffer_nb(), 2)
+ self.interface_buffer = Buffer('ETHERNET_TYPE_INTERFACE_BUFFER_ADD', buffer_nb=3)
+ self.assertEqual(self.interface_buffer.get_ether_type(), 5)
+ self.assertEqual(self.interface_buffer.get_type(), 'ETHERNET_TYPE_INTERFACE_BUFFER_ADD')
+ self.assertEqual(self.interface_buffer.get_buffer_nb(), 3)
+ self.m = m
+
+ def tearDown(self):
+ pass
+
+ def test_set_type(self):
+ self.data_buffer.set_type('ETHERNET_TYPE_BUFFER_RELEASED')
+ self.assertEqual(self.data_buffer.get_ether_type(), 6)
+ self.assertEqual(self.data_buffer.get_type(), 'ETHERNET_TYPE_BUFFER_RELEASED')
+ try:
+ self.mme_buffer.set_type('ETHERNET_TYPE_MME')
+ except OutOfRangeError:
+ self.assertEqual(self.mme_buffer.get_ether_type(), 0)
+ self.assertEqual(self.mme_buffer.get_type(), 'ETHERNET_TYPE_NONE')
+
+ def test_set_buffer_nb(self):
+ self.data_buffer.set_buffer_nb(123)
+ self.assertEqual(self.data_buffer.get_buffer_nb(), 123)
+ try:
+ self.mme_buffer.set_buffer_nb(-123)
+ except OutOfRangeError:
+ self.assertEqual(self.mme_buffer.get_buffer_nb(), 0)
+
+ def test_set_buffer_realloc(self):
+ self.assertEqual(self.data_buffer.get_buffer_realloc(), False)
+ self.data_buffer.set_buffer_realloc(True)
+ self.assertEqual(self.data_buffer.get_buffer_realloc(), True)
+ self.data_buffer.set_buffer_realloc(False)
+
+ def test_realloc(self):
+ sta = self.m.create_sta()
+ self.m.create_fcall('init_ether').send(sta)
+ realloc_buffer(True)
+ buffer_id = 123
+ self.interface_buffer.get_buffer_dict()[buffer_id] = 'ETHERNET_TYPE_DATA_BUFFER_ADD'
+ self.interface_buffer.realloc(station_id=sta.get_station_id(), payload=pack('I', buffer_id))
+ buffer_id = 456
+ self.interface_buffer.get_buffer_dict()[buffer_id] = 'ETHERNET_TYPE_MME_BUFFER_ADD'
+ self.interface_buffer.realloc(station_id=sta.get_station_id(), payload=pack('I', buffer_id))
+ buffer_id = 789
+ self.interface_buffer.get_buffer_dict()[buffer_id] = 'ETHERNET_TYPE_INTERFACE_BUFFER_ADD'
+ self.interface_buffer.realloc(station_id=sta.get_station_id(), payload=pack('I', buffer_id))
+ rsp = recv(self.m, count=2)
+ self.assertEqual(rsp[0].get_type(), 'ETHERNET_TYPE_SNIFFER')
+ self.assertEqual(rsp[1].get_type(), 'ETHERNET_TYPE_BUFFER_RELEASED')
+ realloc_buffer(False)
+ self.m.create_fcall('uninit_ether').send(sta)
+ sta.remove()
+
+ def test_set_msdu_attr(self):
+ id = 123
+ self.assert_(self.data_buffer.get_buffer_dict().has_key(id))
+ self.data_buffer.set_msdu_attr(pack('I', id))
+ self.assert_(not self.data_buffer.get_buffer_dict().has_key(id))
+
+ def test_sendnrecv(self):
+ sta = self.m.create_sta()
+ self.m.create_fcall('init_ether').send(sta)
+ interface_buffer = Buffer('ETHERNET_TYPE_INTERFACE_BUFFER_ADD', buffer_nb=2)
+ rsp = interface_buffer.sendnrecv(self.m, sta, count=2)
+ self.assertEqual(rsp[0].get_type(), 'ETHERNET_TYPE_SNIFFER')
+ self.assertEqual(rsp[1].get_type(), 'ETHERNET_TYPE_BUFFER_RELEASED')
+ self.m.create_fcall('uninit_ether').send(sta)
+ sta.remove()
+
+ def test_send(self):
+ sta = self.m.create_sta()
+ self.m.create_fcall('init_ether').send(sta)
+ mme_buffer = Buffer('ETHERNET_TYPE_MME_BUFFER_ADD', buffer_nb=10)
+ mme_buffer.send(self.m, sta)
+ self.m.create_fcall('uninit_ether').send(sta)
+ sta.remove()
+
+ def test_get(self):
+ mme_buffer = Buffer('ETHERNET_TYPE_MME_BUFFER_ADD', buffer_nb=3)
+ buf = mme_buffer.get()
+ res = pack('I', mme_buffer.get_buffer_nb())
+ for i in range (0, 3):
+ res += pack('I', mme_buffer.get_buffer_id() - 2 + i)
+ self.assertEqual(buf, res)
+
+ def test_create_buffer(self):
+ self.assertNotEqual(create_buffer(), None)
+
+ def test_alloc_data_buffer(self):
+ sta = self.m.create_sta()
+ self.m.create_fcall('init_ether').send(sta)
+ alloc_data_buffer(self.m, sta)
+ self.m.create_fcall('uninit_ether').send(sta)
+ sta.remove()
+
+ def test_alloc_mme_buffer(self):
+ sta = self.m.create_sta()
+ self.m.create_fcall('init_ether').send(sta)
+ alloc_mme_buffer(self.m, sta)
+ self.m.create_fcall('uninit_ether').send(sta)
+ sta.remove()
+
+ def test_alloc_interface_buffer(self):
+ sta = self.m.create_sta()
+ self.m.create_fcall('init_ether').send(sta)
+ realloc_buffer(True)
+ alloc_interface_buffer(self.m, sta)
+ rsp = recv(self.m, count=2)
+ self.assertEqual(rsp[0].get_type(), 'ETHERNET_TYPE_SNIFFER')
+ self.assertEqual(rsp[1].get_type(), 'ETHERNET_TYPE_BUFFER_RELEASED')
+ realloc_buffer(False)
+ alloc_interface_buffer(self.m, sta)
+ rsp = recv(self.m, count=2)
+ self.assertEqual(rsp[0].get_type(), 'ETHERNET_TYPE_SNIFFER')
+ self.assertEqual(rsp[1].get_type(), 'ETHERNET_TYPE_BUFFER_RELEASED')
+ self.m.create_fcall('uninit_ether').send(sta)
+ sta.remove()
+
+ def test_realloc_buffer(self):
+ self.assertEqual(self.interface_buffer.get_buffer_realloc(), False)
+ realloc_buffer(True)
+ self.assertEqual(self.interface_buffer.get_buffer_realloc(), True)
+ realloc_buffer(False)
+
+ def test_get_buffer_dict(self):
+ get_buffer_dict()
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestBufferFunctions))
+
+class TestSnifferFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.sniffer = Sniffer(way=False, encryption=False, sniffer_type=0)
+ self.assertEqual(self.sniffer.get(), None)
+ self.assertEqual(self.sniffer.get_ether_type(), 7)
+ self.assertEqual(self.sniffer.get_type(), 'ETHERNET_TYPE_SNIFFER')
+ self.assertEqual(self.sniffer.get_way(), False)
+ self.assertEqual(self.sniffer.get_encryption(), False)
+ self.assertEqual(self.sniffer.get_sniffer_type(), 0)
+ self.m = m
+
+ def tearDown(self):
+ pass
+
+ def test_set_way(self):
+ way = True
+ self.sniffer.set_way(way)
+ self.assertEqual(self.sniffer.get_way(), way)
+
+ def test_set_encryption(self):
+ encryption = True
+ self.sniffer.set_encryption(encryption)
+ self.assertEqual(self.sniffer.get_encryption(), encryption)
+
+ def test_set_sniffer_type(self):
+ sniffer_type = 1
+ self.sniffer.set_sniffer_type(sniffer_type)
+ self.assertEqual(self.sniffer.get_sniffer_type(), sniffer_type)
+
+ def test_set_msdu_attr(self):
+ payload = "This is the sniffed packed"
+ self.sniffer.set_msdu_attr(payload)
+ self.assertEqual(self.sniffer.get(), payload)
+
+ def test_display(self):
+ self.sniffer.display()
+ self.sniffer.set_way(True)
+ self.sniffer.set_encryption(True)
+ self.sniffer.set_sniffer_type(1)
+ self.sniffer.set_msdu_attr("ABCD")
+ self.sniffer.display()
+
+ def test_create_sniffer(self):
+ way = True
+ encryption = True
+ sniffer_type = 1
+ self.assertNotEqual(create_sniffer(way, encryption, sniffer_type), None)
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestSnifferFunctions))
+
+try:
+ suite.addTest(doctest.DocTestSuite(buffer))
+ suite.addTest(doctest.DocTestSuite(create))
+ suite.addTest(doctest.DocTestSuite(eth))
+ suite.addTest(doctest.DocTestSuite(scapy))
+ suite.addTest(doctest.DocTestSuite(sniffer))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_fsm.py b/cesar/maximus/python/test/test_fsm.py
new file mode 100644
index 0000000000..598768eb28
--- /dev/null
+++ b/cesar/maximus/python/test/test_fsm.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import startup
+
+from maximus.fsm import *
+
+
+# FSM TEST
+
+def create (fsm):
+ fsm.something.append ("station")
+ print "Create station"
+def send (fsm):
+ print "Send a message"
+def receive (fsm):
+ print "Receive the response"
+def remove (fsm):
+ fsm.something.pop ()
+ print "Remove station"
+def error (fsm):
+ print "Error"
+ print str(fsm.input_symbol)
+
+def trace(fsm):
+ print '=>',fsm.current_state,fsm.something
+
+f = FSM.FSM('INIT',[])
+f.set_default_transition (error, 'IDLE')
+f.add_transition_any ('INIT', None, 'END')
+f.add_transition_any ('IDLE', None, 'END')
+f.add_transition_any ('BUSY', None, 'END')
+f.add_transition ('create_station', 'INIT', create, 'IDLE')
+f.add_transition ('send_message', 'IDLE', send, 'BUSY')
+f.add_transition ('receive_response', 'BUSY', receive, 'IDLE')
+f.add_transition ('remove_station', 'IDLE', remove, 'INIT')
+
+trace(f)
+f.process("create_station")
+trace(f)
+f.process("send_message")
+trace(f)
+f.process("receive_response")
+trace(f)
+f.process("remove_station")
+trace(f)
+f.process("I want to quit!")
+trace(f)
+
+while f.current_state!='END':
+ inputs = raw_input ('>')
+ previous_state = f.current_state
+ f.process (inputs)
+ print previous_state,'=>',f.current_state
+ print f.something
+
+
+# DOC TEST
+
+import doctest
+doctest.testmod(FSM)
+
+
+# UNIT TEST
+
+import unittest
+suite = unittest.TestSuite()
+try:
+ suite.addTest(doctest.DocTestSuite(FSM))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_interface.py b/cesar/maximus/python/test/test_interface.py
new file mode 100644
index 0000000000..ae57e94a6e
--- /dev/null
+++ b/cesar/maximus/python/test/test_interface.py
@@ -0,0 +1,461 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys
+import startup
+
+import interface
+from interface import *
+from maximus.macframe import *
+from maximus.mme import *
+from struct import pack, unpack
+from string import *
+
+# DOC TEST
+
+import doctest
+doctest.testmod(interface)
+
+
+# UNIT TEST
+
+import unittest
+
+# Create a Maximus instance
+m = Maximus()
+
+# Initialize Maximus with command line arguments
+m.init(sys.argv)
+
+def cb1(msg):
+ print "=>",cb1.func_name
+ if not msg.is_param("result_2"):
+ raise Exception(cb1.func_name)
+ result2 = unpack('q',msg.bind_param("result_2"))
+ if result2[0] != 0x0000007B:
+ raise Exception(cb1.func_name)
+
+def cb2(msg):
+ print "=>",cb2.func_name
+ if not msg.is_param("result_2"):
+ raise Exception(cb2.func_name)
+ result2 = unpack('q',msg.bind_param("result_2"))
+ if result2[0] != 0x0000007B:
+ raise Exception(cb2.func_name)
+
+class TestInterfaceFunctions(unittest.TestCase):
+
+ def setUp(self):
+
+ # Set the Maximus instance
+ self.m = m
+
+ # Create a station
+ self.station = self.m.create_sta()
+
+ def tearDown(self):
+
+ # Remove station
+ self.station.remove()
+
+ def test_process(self):
+ self.m.process()
+
+ def test_create_sta(self):
+
+ # Create station 1
+ station1 = self.m.create_sta()
+
+ # Copy to station 2
+ station2 = station1
+
+ # Remove station 1
+ station1.remove()
+
+ # Remove station 2
+ station2.remove()
+
+ def test_create_fcall(self):
+
+ # Create a fcall message
+ fcall1 = self.m.create_fcall("function_1")
+
+ # Copy the message
+ fcall2 = fcall1
+
+ def test_create_probe(self):
+
+ # Create a probe message
+ probe = self.m.create_probe()
+
+ def test_send_mpdu(self):
+
+ fcall1 = self.m.create_fcall('set_tonemask')
+ fcall1.send(self.station)
+ fcall2 = self.m.create_fcall('prepare_rx')
+ fcall2.send(self.station)
+
+ # Create a MAC Frame, configure it and send it asynchronously
+ frame = MACFrame()
+ frame.fc_10 = 123
+ frame.fc_av = (1, 123, 456, 789)
+ frame.payload = 'This is the MPDU payload'
+ frame.fc_mode = 4
+ frame.short_ppdu = 0
+ frame.mod = 4
+ self.m.send_mpdu(frame)
+
+ fcall3 = self.m.create_fcall('uninit_phy')
+ fcall3.send(self.station)
+
+ def test_set_mpdu_rx(self):
+ def cb(mpdu):
+ pass
+ def create_fc():
+ pass
+ self.m.set_mpdu_rx(cb, create_fc)
+
+ def test_send_msdu(self):
+ while not self.station.is_idle():
+ self.m.process()
+ self.m.send_msdu(MME(MMHeader=23*'H', MMEntry=37*'E'), self.station.get_station_id())
+
+ def test_set_msdu_rx(self):
+ def cb(msdu):
+ pass
+ def create_fc1():
+ pass
+ def create_fc2():
+ pass
+ def create_fc3():
+ pass
+ def create_fc4():
+ pass
+ self.m.set_msdu_rx(cb, create_fc1, create_fc2, create_fc3, create_fc4)
+
+ def test_wait(self):
+ self.m.wait()
+ self.m.wait(500000)
+
+ def test_disturb_channel(self):
+ self.m.disturb_channel()
+ self.m.disturb_channel(False)
+
+ def test_get_date(self):
+ date = self.m.get_date()
+ offset = 10000
+ self.m.wait(offset)
+ self.assertEqual(date+offset, self.m.get_date(), "get_date failed")
+
+ def test_set_freq(self):
+ freq = 54.321
+ self.m.set_freq(freq)
+ self.assertAlmostEqual(freq, self.m.get_freq(), 3, "get_freq failed")
+ freq = 0
+ self.m.set_freq(freq)
+ self.assertEqual(freq, self.m.get_freq(), "get_freq failed")
+ freq = 0
+ self.m.set_freq(freq)
+ self.assertEqual(freq, self.m.get_freq(), "get_freq failed")
+ freq = 49
+ self.m.set_freq(freq)
+ self.assertEqual(freq, self.m.get_freq(), "get_freq failed")
+ freq = 0
+ self.m.set_freq(freq)
+ self.assertEqual(freq, self.m.get_freq(), "get_freq failed")
+
+ def test_activate_false_alarm(self):
+ duration = 200
+ deviation = 0.2
+ self.m.activate_false_alarm(duration, deviation)
+ self.m.wait(2*duration)
+ self.m.deactivate_false_alarm()
+
+ def test_deactivate_false_alarm(self):
+ duration = 200
+ deviation = 0.2
+ self.m.deactivate_false_alarm()
+ self.m.activate_false_alarm(duration, deviation)
+ self.m.deactivate_false_alarm()
+
+ def test_is_station_idle(self):
+ self.m.wait(1) # to process the system IDLE message coming from the station
+ self.assert_(self.m.is_station_idle(self.station.get_station_id()))
+ self.station.deactivate()
+ self.assert_(not self.m.is_station_idle(self.station.get_station_id()))
+
+ def test_remove(self):
+
+ # Remove station
+ self.station.remove()
+
+ def test_deactivate(self):
+
+ # Deactivate station
+ self.station.deactivate()
+
+ def test_activate(self):
+
+ # Re-activate station
+ self.station.activate()
+
+ def test_debug(self):
+ self.station.debug()
+
+ def test_is_idle(self):
+ self.m.wait(1) # to process the system IDLE message coming from the station
+ self.assert_(self.station.is_idle())
+ self.station.deactivate()
+ self.assert_(not self.station.is_idle())
+
+ def test_add_param(self):
+
+ # Add an empty parameter to the probe message,
+ # and retrieve the added parameter
+ #
+ probe = self.m.create_probe()
+ probe.add_param("empty_param")
+ self.assert_(probe.is_param("empty_param"))
+
+ # Add a string parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ fcall = self.m.create_fcall("fcall").add_param("string_param", 'ABCD')
+ self.assertEqual(fcall.bind_param_string("string_param"),'ABCD')
+
+ def test_add_param_bool(self):
+
+ # Add a boolean parameter to the probe message,
+ # and retrieve the added parameter
+ #
+ probe = self.m.create_probe()
+ probe.add_param_bool("boolean_param", True)
+ self.assertEqual(probe.bind_param_bool("boolean_param"),True)
+
+ def test_add_param_ushort(self):
+
+ # Add an unsigned short parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ fcall = self.m.create_fcall("fcall")
+ fcall.add_param_ushort("ushort_param", 0xFEDC)
+ self.assertEqual(fcall.bind_param_ushort("ushort_param"),0xFEDC)
+
+ def test_add_param_ulong(self):
+
+ # Add an unsigned long parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ fcall = self.m.create_fcall("fcall")
+ fcall.add_param_ulong("ulong_param", 0xFEDCBA98)
+ self.assertEqual(fcall.bind_param_ulong("ulong_param"),0xFEDCBA98)
+
+ def test_add_param_n_u8(self):
+
+ # Add a Python tuple parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ tuple_u8 = (0x12, 0x34, 0x56)
+ fcall = self.m.create_fcall("test_u8").add_param_n_u8("tuple_u8", tuple_u8)
+ param = fcall.bind_param("tuple_u8")
+ param = unpack('!BBB', param)
+ self.assertEqual(param, tuple_u8)
+
+ def test_add_param_n_u16(self):
+
+ # Add a Python tuple parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+
+ tuple_u16 = (0x12AB, 0x34AB, 0x56AB, 0x78AB)
+ fcall = self.m.create_fcall("test_u16").add_param_n_u16("tuple_u16", tuple_u16)
+ param = fcall.bind_param("tuple_u16")
+ param = unpack('!HHHH', param)
+ self.assertEqual(param, tuple_u16)
+
+ def test_add_param_n_u32(self):
+
+ # Add a Python tuple parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+
+ tuple_u32 = (0x1234ABCD, 0x3456ABCD, 0x5678ABCD, 0x9ABCABCD, 0xEF01ABCD)
+ fcall = self.m.create_fcall("test_u32").add_param_n_u32("tuple_u32", tuple_u32)
+ param = fcall.bind_param("tuple_u32")
+ param = unpack('!IIIII', param)
+ self.assertEqual(param, tuple_u32)
+
+ def test_remove_param(self):
+
+ # Add a parameter to the probe message,
+ # remove the added parameter,
+ # and try to retrieve the removed parameter
+ #
+ probe = self.m.create_probe()
+ probe.add_param("param")
+ probe.remove_param("param")
+ self.failIf(probe.is_param("param"))
+
+ def test_set_cb(self):
+
+ # Set a callback to the fcall message,
+ # and set another callback
+ #
+ fcall = self.m.create_fcall("fcall")
+ fcall.set_cb(cb1)
+ fcall.set_cb(cb2)
+
+ def test_remove_cb(self):
+
+ # Set a callback to the fcall message,
+ # remove the set callback,
+ # and set another callback
+ #
+ fcall = self.m.create_fcall("fcall")
+ fcall.set_cb(cb1)
+ fcall.remove_cb()
+ fcall.set_cb(cb2)
+
+ def test_set_sta(self):
+
+ # Set the destination station to the probe message,
+ # create station 3,
+ # and set the destination station 3 to the probe message
+ #
+ probe = self.m.create_probe()
+ probe.set_sta(self.station)
+ station3 = self.m.create_sta()
+ probe.set_sta(station3)
+ station3.remove()
+
+ def test_send_async(self):
+
+ # Create a fcall message
+ fcall1 = self.m.create_fcall("function_1")
+
+ # Add a first parameter to the created message
+ param1 = pack('iiB',1,2,True)
+ fcall1.add_param("param_1", param1)
+
+ # Add a second parameter to the created message
+ param2 = pack('iiiiiiiiii',0,1,2,3,4,5,6,7,8,9)
+ fcall1.add_param("param_2", param2)
+
+ # Add a third parameter to the created message
+ param3 = "hello"
+ fcall1.add_param("param_3", param3)
+
+ # Add a fourth parameter to the created message
+ param4 = pack('q',123)
+ fcall1.add_param("param_4", param4)
+
+ # Register a callback function which will be called at message response reception
+ fcall1.set_cb(cb1)
+
+ # Set destination station of message
+ fcall1.set_sta(self.station)
+
+ # Send the configured message in an asynchronous mode
+ fcall1.send_async()
+
+ # Send another message in an asynchronous mode
+ station4 = self.m.create_sta()
+ fcall2 = self.m.create_fcall("function_1")
+ fcall2.add_param("param_1", param1)
+ fcall2.add_param("param_2", param2)
+ fcall2.add_param("param_3", param3)
+ fcall2.add_param("param_4", param4)
+ fcall2.set_cb(cb2)
+ fcall2.set_sta(station4)
+ fcall2.send_async()
+
+ # Wait for responses
+ self.m.wait()
+
+ station4.remove()
+
+ def test_send(self):
+
+ # Create a fcall message,
+ # add a boolean parameter,
+ # send the message to station,
+ # and get the result
+ #
+ fcall2 = self.m.create_fcall("function_2")
+ fcall2.add_param_bool("param_5", True)
+ fcall2 = fcall2.send(self.station)
+ result1 = fcall2.bind_param_string("result_1")
+ self.assertEqual(result1,"this is result 1")
+ self.assertEqual(len(result1),16)
+
+ # Create a probe message,
+ # set the destination station,
+ # add a parameter,
+ # send the message,
+ # and get the result
+ #
+ probe = self.m.create_probe().set_sta(self.station).add_param("param_6").send()
+ self.assertEqual(probe.bind_param_ulong("param_6"),0x7B000000)
+
+ def test_is_param(self):
+
+ # Add a parameter to the probe message,
+ # send the message to the destination station,
+ # and get the result
+ #
+ probe = self.m.create_probe()
+ probe.add_param("param_6").send(self.station)
+ self.assert_(probe.is_param("param_6"))
+
+ def test_bind_param_string(self):
+
+ # Add string parameters to the fcall message,
+ # and retrieve added parameters
+ #
+ fcall = self.m.create_fcall("fcall")
+ fcall.add_param("string_param_1","string param 1")
+ fcall.add_param("string_param_2","string param 2")
+ fcall.add_param("string_param_3","string param 3")
+ self.assertEqual(fcall.bind_param_string("string_param_1"),"string param 1")
+ self.assertEqual(fcall.bind_param_string("string_param_2"),"string param 2")
+ self.assertEqual(fcall.bind_param_string("string_param_3"),"string param 3")
+
+ def test_bind_param_bool(self):
+
+ # Add a boolean parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ fcall = self.m.create_fcall("fcall")
+ fcall.add_param_bool("boolean_param", False)
+ self.assertEqual(fcall.bind_param_bool("boolean_param"),False)
+
+ def test_bind_param_ushort(self):
+
+ # Add a parameter to the probe message,
+ # send the message to the destination station,
+ # and get the result
+ #
+ probe = self.m.create_probe()
+ probe = probe.add_param("param_10").send(self.station)
+ self.assertEqual(probe.bind_param_ushort("param_10"),0xEEFF)
+
+ def test_bind_param_ulong(self):
+
+ # Add a parameter to the probe message,
+ # send the message to the destination station,
+ # and get the result
+ #
+ probe = self.m.create_probe()
+ probe = probe.add_param("param_11").send(self.station)
+ self.assertEqual(probe.bind_param_ulong("param_11"),0xCCDDEEFF)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestInterfaceFunctions)
+
+try:
+ suite.addTest(doctest.DocTestSuite(interface))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_lib_cesar.py b/cesar/maximus/python/test/test_lib_cesar.py
new file mode 100644
index 0000000000..9827f2d6de
--- /dev/null
+++ b/cesar/maximus/python/test/test_lib_cesar.py
@@ -0,0 +1,330 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import startup, sys
+
+from maximus import *
+from interface import *
+from maximus_dur import *
+from sta_cesar import STACesar
+from maximus.station.sta import PHY_CARRIER_NB
+
+
+# LIB CESAR TEST
+
+# Create a Maximus instance
+m = Maximus()
+
+# Initialize Maximus with command line arguments
+m.init(sys.argv)
+
+# Create a Cesar station
+sta = STACesar(m, name="sta")
+
+carrier_nb = maximus_dur_carrier_nb(m, sta.get(), sta.get_tonemask())
+
+mod = 3 # PHY_MOD_TM
+tonemap = ''
+for i in range (0, PHY_CARRIER_NB):
+ tonemap += pack('B', 0x01)
+bits_per_symbol = maximus_dur_bits_per_symbol(m, sta.get(), mod, sta.get_tonemask(), tonemap, carrier_nb)
+
+fecrate = 0 # PHY_FEC_RATE_1_2
+pb_size = 1 # PHY_PB_SIZE_520
+pb_nb = 10
+symbol_nb = maximus_dur_symbol_nb(m, sta.get(), fecrate, pb_size, bits_per_symbol, pb_nb)
+
+gil = 2 # PHY_GIL_3534
+data_tck = maximus_dur_data_tck(m, sta.get(), gil, symbol_nb)
+
+if data_tck != maximus_dur(m, sta.get(), sta.get_tonemask(), mod, tonemap, fecrate, pb_size, pb_nb, gil):
+ print "maximus_dur_data_tck =", data_tck
+ print "maximus_dur =", maximus_dur(m, sta.get(), sta.get_tonemask(), mod, tonemap, fecrate, pb_size, pb_nb, gil)
+ raise Error("maximus_dur")
+
+m.create_fcall("uninit_ether").send(sta.get())
+sta.remove()
+
+
+# DOC TEST
+
+import doctest, maximus_dur, sta_cesar
+doctest.testmod(maximus_dur)
+doctest.testmod(sta_cesar)
+
+
+# UNIT TEST
+
+import unittest
+
+class TestMaximusDurFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.maximus = m
+ # Create station
+ self.station = STACesar(self.maximus)
+
+ def tearDown(self):
+ # Remove station
+ m.create_fcall("uninit_ether").send(self.station.get())
+ self.station.remove()
+
+ def test_maximus_dur_carrier_nb(self):
+ # Default tonemask
+ bits_ref = 917
+ bits = maximus_dur_carrier_nb(self.maximus, self.station.get(), self.station.get_tonemask())
+ self.assertEqual(bits, bits_ref)
+
+ def test_maximus_dur_bits_per_symbol(self):
+ # Number of bytes needed to define a tonemap
+ PHY_TONEMAP_SIZE = ((PHY_CARRIER_NB + 2 - 1) / 2)
+
+ # robo
+ self.assertEqual(maximus_dur_bits_per_symbol(self.maximus, self.station.get(), 0, # PHY_MOD_ROBO
+ self.station.get_tonemask(), None, 400), 200)
+ self.assertEqual(maximus_dur_bits_per_symbol(self.maximus, self.station.get(), 0, # PHY_MOD_ROBO
+ self.station.get_tonemask(), None, 403), 200)
+ self.assertEqual(maximus_dur_bits_per_symbol(self.maximus, self.station.get(), 1, # PHY_MOD_HS_ROBO
+ self.station.get_tonemask(), None, 400), 400)
+ self.assertEqual(maximus_dur_bits_per_symbol(self.maximus, self.station.get(), 1, # PHY_MOD_HS_ROBO
+ self.station.get_tonemask(), None, 401), 400)
+ self.assertEqual(maximus_dur_bits_per_symbol(self.maximus, self.station.get(), 2, # PHY_MOD_MINI_ROBO
+ self.station.get_tonemask(), None, 300), 120)
+
+ # tm
+ # Maximum modulations
+ tonemap = ''
+ for i in range (0, PHY_CARRIER_NB / 2):
+ if PHY_CARRIER_NB % 2 == 0:
+ tonemap += pack('B', 0x07)
+ else:
+ tonemap += pack('B', 0x77)
+ bits_ref = 917 * 10
+ bits = maximus_dur_bits_per_symbol(self.maximus, self.station.get(), 3, # PHY_MOD_TM
+ self.station.get_tonemask(), tonemap, 917)
+ self.assertEqual(bits, bits_ref)
+
+ def test_maximus_dur_symbol_nb(self):
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 0, # PHY_FEC_RATE_1_2
+ 0, # PHY_PB_SIZE_136
+ 136 * 8 * 2, 1), 1)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 1, # PHY_FEC_RATE_16_21
+ 0, # PHY_PB_SIZE_136
+ 136 * 8 / 16 * 21, 1), 1)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 0, # PHY_FEC_RATE_1_2
+ 1, # PHY_PB_SIZE_520
+ 520 * 8 * 2, 1), 1)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 1, # PHY_FEC_RATE_16_21
+ 1, # PHY_PB_SIZE_520
+ 520 * 8 / 16 * 21, 1), 1)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 0, # PHY_FEC_RATE_1_2
+ 0, # PHY_PB_SIZE_136
+ 136 * 2, 1), 8)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 1, # PHY_FEC_RATE_16_21
+ 0, # PHY_PB_SIZE_136
+ 136 / 16 * 21, 1), 9)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 0, # PHY_FEC_RATE_1_2
+ 1, # PHY_PB_SIZE_520
+ 520 * 2, 1), 8)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 1, # PHY_FEC_RATE_16_21
+ 1, # PHY_PB_SIZE_520
+ 520 / 16 * 21, 1), 9)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 0, # PHY_FEC_RATE_1_2
+ 1, # PHY_PB_SIZE_520
+ 520 * 8 * 2, 10), 10)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 1, # PHY_FEC_RATE_16_21
+ 1, # PHY_PB_SIZE_520
+ 520 * 8 / 16 * 21, 10), 10)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 0, # PHY_FEC_RATE_1_2
+ 1, # PHY_PB_SIZE_520
+ 2 * 520 * 8 * 2, 10), 5)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 1, # PHY_FEC_RATE_16_21
+ 1, # PHY_PB_SIZE_520
+ 2 * 520 * 8 / 16 * 21, 10), 5)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 0, # PHY_FEC_RATE_1_2
+ 1, # PHY_PB_SIZE_520
+ 2 * 520 * 8 * 2 - 10, 10), 6)
+ self.assertEqual(maximus_dur_symbol_nb(self.maximus, self.station.get(), 1, # PHY_FEC_RATE_16_21
+ 1, # PHY_PB_SIZE_520
+ 2 * 520 * 8 / 16 * 21 - 10, 10), 6)
+
+ def test_maximus_dur_data_tck(self):
+ # Symbol with a 417 sample guard length (ticks)
+ MAC_DX417_TCK = (3489/3)
+ # Symbol with a 567 sample guard length (ticks)
+ MAC_DX567_TCK = (3639/3)
+ # Symbol with a 3534 sample guard length (ticks)
+ MAC_DX3534_TCK = (6606/3)
+
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 0, # PHY_GIL_417
+ 1), MAC_DX567_TCK)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 1, # PHY_GIL_567
+ 1), MAC_DX567_TCK)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 2, # PHY_GIL_3534
+ 1), MAC_DX567_TCK)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 0, # PHY_GIL_417
+ 2), MAC_DX567_TCK * 2)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 1, # PHY_GIL_567
+ 2), MAC_DX567_TCK * 2)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 2, # PHY_GIL_3534
+ 2), MAC_DX567_TCK * 2)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 0, # PHY_GIL_417
+ 3), MAC_DX567_TCK * 2 + MAC_DX417_TCK)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 1, # PHY_GIL_567
+ 3), MAC_DX567_TCK * 2 + MAC_DX567_TCK)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 2, # PHY_GIL_3534
+ 3), MAC_DX567_TCK * 2 + MAC_DX3534_TCK)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 0, # PHY_GIL_417
+ 4), MAC_DX567_TCK * 2 + MAC_DX417_TCK * 2)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 1, # PHY_GIL_567
+ 4), MAC_DX567_TCK * 2 + MAC_DX567_TCK * 2)
+ self.assertEqual(maximus_dur_data_tck(self.maximus, self.station.get(), 2, # PHY_GIL_3534
+ 4), MAC_DX567_TCK * 2 + MAC_DX3534_TCK * 2)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestMaximusDurFunctions)
+
+class TestSTACesarFunctions(unittest.TestCase):
+
+ def setUp(self):
+ # Create station
+ self.station = STACesar(m)
+
+ def tearDown(self):
+ # Remove station
+ m.create_fcall("uninit_ether").send(self.station.get())
+ self.station.remove()
+
+ def test_stop(self):
+ self.station.stop()
+
+ def test_set_name(self):
+ name = "Name of my station"
+ self.station.set_name(name)
+ self.assertEqual(self.station.get_name(), name)
+
+ def test_set_mme_buffer_nb(self):
+ mme_buffer_nb = 4
+ self.station.set_mme_buffer_nb(mme_buffer_nb)
+ self.assertEqual(self.station.get_mme_buffer_nb(), mme_buffer_nb)
+
+ def test_set_config_mode(self):
+ config_mode = 'fcall_process_drv'
+ self.station.set_config_mode(config_mode)
+ self.assertEqual(self.station.get_config_mode(), config_mode)
+
+ def test_set_config(self):
+ test_conf = Config()
+ test_conf.mac_address = (0x11, 0x22, 0x33, 0x44, 0x55, 0x66)
+ test_conf.cco_preference = True
+ self.station.set_config(test_conf)
+ self.assertEqual(self.station.get_config().mac_address, test_conf.mac_address)
+ self.assertEqual(self.station.get_config().cco_preference, test_conf.cco_preference)
+
+ def test_set_mac_address(self):
+ mac_address = (0x41, 0x42, 0x43, 0x44, 0x45, 0x46)
+ # Test with a Python tuple of 6 Python integers
+ self.station.set_mac_address((0x41, 0x42, 0x43, 0x44, 0x45, 0x46))
+ self.assertEqual(self.station.get_mac_address(), mac_address)
+ # Test with a Python long (decimal or hexadecimal value)
+ self.station.set_mac_address(0x414243444546)
+ self.assertEqual(self.station.get_mac_address(), mac_address)
+ # Test with a Python string of length equals to 6 octets
+ self.station.set_mac_address(pack(n + u64, 0x414243444546)[SIZE_OF_U16:])
+ self.assertEqual(self.station.get_mac_address(), mac_address)
+ # Test with a Python string of length equals to 17 octets ('XX:XX:XX:XX:XX:XX')
+ self.station.set_mac_address('41:42:43:44:45:46')
+ self.assertEqual(self.station.get_mac_address(), mac_address)
+
+ def test_set_cco_preference(self):
+ cco_preference = False
+ self.station.set_cco_preference(cco_preference)
+ self.assertEqual(self.station.get_cco_preference(), cco_preference)
+
+ def test_set_was_cco(self):
+ was_cco = True
+ self.station.set_was_cco(was_cco)
+ self.assertEqual(self.station.get_was_cco(), was_cco)
+
+ def test_set_npw(self):
+ npw = "This is the network password"
+ self.station.set_npw(npw)
+ self.assertEqual(self.station.get_npw(), npw)
+
+ def test_set_dpw(self):
+ dpw = "This is the device password"
+ self.station.set_dpw(dpw)
+ self.assertEqual(self.station.get_dpw(), dpw)
+
+ def test_set_m_sta_hfid(self):
+ m_sta_hfid = "This is the manufacturer sta hfid"
+ self.station.set_m_sta_hfid(m_sta_hfid)
+ self.assertEqual(self.station.get_m_sta_hfid(), m_sta_hfid)
+
+ def test_set_u_sta_hfid(self):
+ u_sta_hfid = "This is the user sta hfid"
+ self.station.set_u_sta_hfid(u_sta_hfid)
+ self.assertEqual(self.station.get_u_sta_hfid(), u_sta_hfid)
+
+ def test_set_avln_hfid(self):
+ avln_hfid = "This is the avln hfid"
+ self.station.set_avln_hfid(avln_hfid)
+ self.assertEqual(self.station.get_avln_hfid(), avln_hfid)
+
+ def test_set_sl(self):
+ sl = 0x02
+ self.station.set_sl(sl)
+ self.assertEqual(self.station.get_sl(), sl)
+
+ def test_set_snid(self):
+ snid = 0x02
+ self.station.set_snid(snid)
+ self.assertEqual(self.station.get_snid(), snid)
+
+ def test_set_tonemask(self):
+ tonemask = 85,139,167,214,225,282,302,409,419,569,591,736,748,856,882,1015,1027,1143,1535
+ self.station.set_tonemask(tonemask)
+ self.assertEqual(self.station.get_tonemask()[0 / 8], pack('B', 0)) # 74
+ self.assertEqual(self.station.get_tonemask()[11 / 8], pack('B', 0xf0)) # 85
+ self.assertEqual(self.station.get_tonemask()[345 / 8], pack('B', 0xfc)) # 419
+ self.assertEqual(self.station.get_tonemask()[495 / 8], pack('B', 0xff)) # 569
+ self.assertEqual(self.station.get_tonemask()[782 / 8], pack('B', 0x7f)) # 856
+ self.assertEqual(self.station.get_tonemask()[1069 / 8], pack('B', 0x3f)) # 1143
+ self.assertEqual(self.station.get_tonemask()[1070 / 8], pack('B', 0x3f)) # 1144
+ self.assertEqual(self.station.get_tonemask()[1155 / 8], pack('B', 0x00)) # 1229
+
+ def test_remove(self):
+ m.create_fcall("uninit_ether").send(self.station.get())
+ self.station.remove()
+ self.station = STACesar(m)
+
+ def test_deactivate(self):
+ self.station.deactivate()
+ self.station.activate()
+
+ def test_activate(self):
+ self.station.activate()
+
+ def test_debug(self):
+ self.station.debug()
+
+ def test_is_idle(self):
+ m.wait(1) # to process the system IDLE message coming from the station
+ self.assert_(self.station.is_idle())
+ self.station.deactivate()
+ self.assert_(not self.station.is_idle())
+ self.station.activate()
+
+ def test_get_station_id(self):
+ self.assertNotEqual(self.station.get_station_id(), 0)
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestSTACesarFunctions))
+
+try:
+ suite.addTest(doctest.DocTestSuite(maximus_dur))
+ suite.addTest(doctest.DocTestSuite(sta_cesar))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_lib_proto.py b/cesar/maximus/python/test/test_lib_proto.py
new file mode 100644
index 0000000000..884ed0cdc2
--- /dev/null
+++ b/cesar/maximus/python/test/test_lib_proto.py
@@ -0,0 +1,376 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys
+sys.path.append('./test')
+sys.path.append('../test')
+import startup
+
+#sys.argv += ['-r', '/dev/ttyS0']
+
+from fcall import *
+from struct import pack, unpack
+
+
+# LIB PROTO TEST
+
+def my_cb (msg):
+ print "=>",my_cb.func_name
+ if msg.is_param("result_2"):
+ result2 = unpack('q',msg.bind_param("result_2"))
+ print "result 2 =",result2[0]
+ receive_fc1_rsp = True
+
+stationA = "A"
+stationB = "B"
+stationC = "C"
+
+fc1 = create_fcall("function_1")
+param1 = pack('iiB',1,2,True)
+fc1.add_param("param_1", param1)
+param2 = pack('iiiiiiiiii',0,1,2,3,4,5,6,7,8,9)
+fc1.add_param("param_2", param2)
+param3 = "hello"
+fc1.add_param("param_3", param3)
+param4 = pack('q',123)
+fc1.add_param("param_4", param4)
+fc1.set_cb(my_cb)
+fc1.set_sta(stationA)
+receive_fc1_rsp = False
+fc1.send_async()
+
+fc2 = create_fcall("function_2")
+fc2.add_param_bool("param_5", True)
+fc2.send(stationB)
+result1 = fc2.bind_param_string("result_1")
+print "result1 =",result1
+
+probe1 = create_probe()
+param6 = 789
+probe1.add_param_ulong("param_6", param6)
+probe1.send(stationB)
+
+probe2 = create_probe().add_param("param_7")
+probe2.send(stationB)
+param7 = None #probe2.bind_param_ulong("param_7")
+print "param 7 =",param7
+probe2.send(stationC)
+
+if 456 == param7:
+ fc3 = create_fcall("function_3")
+ fc3.send_async(stationC)
+
+fc4 = create_fcall("function_4")
+fc4.send_async(stationC)
+
+fc5 = create_fcall("function_5")
+fc5.send_async(stationC)
+
+probe3 = create_probe()
+probe3.send(stationC)
+
+if probe3.is_param("param_8"):
+ probe4 = create_probe()
+ probe4.add_param("param_8")
+ probe4.add_param_bool("param_9", False)
+ probe4.send(stationC)
+ param8 = probe4.bind_param_bool("param_8")
+ print "param 8 =",param8
+
+
+# DOC TEST
+
+import doctest, fcall
+doctest.testmod(fcall)
+
+
+# UNIT TEST
+
+import unittest
+
+def cb1(msg):
+ print "=>",cb1.func_name
+ if not msg.is_param("result_2"):
+ raise Exception(cb1.func_name)
+ result2 = unpack('q',msg.bind_param("result_2"))
+ if result2[0] != 0x0000007B:
+ raise Exception(cb1.func_name)
+
+def cb2(msg):
+ print "=>",cb2.func_name
+ if not msg.is_param("result_2"):
+ raise Exception(cb2.func_name)
+ result2 = unpack('q',msg.bind_param("result_2"))
+ if result2[0] != 0x0000007B:
+ raise Exception(cb2.func_name)
+
+class TestFcallFunctions(unittest.TestCase):
+
+ def setUp(self):
+
+ # Create a station
+ self.station = 0
+
+ def tearDown(self):
+
+ # Remove station
+ pass
+
+ def test_create_fcall(self):
+
+ # Create a fcall message
+ fcall1 = create_fcall("function_1")
+
+ # Copy the message
+ fcall2 = fcall1
+
+ def test_create_probe(self):
+
+ # Create a probe message
+ probe = create_probe()
+
+ def test_add_param(self):
+
+ # Add an empty parameter to the probe message,
+ # and retrieve the added parameter
+ #
+ probe = create_probe()
+ probe.add_param("empty_param")
+ self.assert_(probe.is_param("empty_param"))
+
+ # Add a string parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ fcall = create_fcall("fcall").add_param("string_param", 'ABCD')
+ self.assertEqual(fcall.bind_param_string("string_param"),'ABCD')
+
+ def test_add_param_bool(self):
+
+ # Add a boolean parameter to the probe message,
+ # and retrieve the added parameter
+ #
+ probe = create_probe()
+ probe.add_param_bool("boolean_param", True)
+ self.assertEqual(probe.bind_param_bool("boolean_param"),True)
+
+ def test_add_param_ushort(self):
+
+ # Add an unsigned short parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ fcall = create_fcall("fcall")
+ fcall.add_param_ushort("ushort_param", 0xFEDC)
+ self.assertEqual(fcall.bind_param_ushort("ushort_param"),0xFEDC)
+
+ def test_add_param_ulong(self):
+
+ # Add an unsigned long parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ fcall = create_fcall("fcall")
+ fcall.add_param_ulong("ulong_param", 0xFEDCBA98)
+ self.assertEqual(fcall.bind_param_ulong("ulong_param"),0xFEDCBA98)
+
+ def test_add_param_n_u8(self):
+
+ # Add a Python tuple parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ tuple_u8 = (0x12, 0x34, 0x56)
+ fcall = create_fcall("test_u8").add_param_n_u8("tuple_u8", tuple_u8)
+ param = fcall.bind_param("tuple_u8")
+ param = unpack('!BBB', param)
+ self.assertEqual(param, tuple_u8)
+
+ def test_add_param_n_u16(self):
+
+ # Add a Python tuple parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+
+ tuple_u16 = (0x12AB, 0x34AB, 0x56AB, 0x78AB)
+ fcall = create_fcall("test_u16").add_param_n_u16("tuple_u16", tuple_u16)
+ param = fcall.bind_param("tuple_u16")
+ param = unpack('!HHHH', param)
+ self.assertEqual(param, tuple_u16)
+
+ def test_add_param_n_u32(self):
+
+ # Add a Python tuple parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+
+ tuple_u32 = (0x1234ABCD, 0x3456ABCD, 0x5678ABCD, 0x9ABCABCD, 0xEF01ABCD)
+ fcall = create_fcall("test_u32").add_param_n_u32("tuple_u32", tuple_u32)
+ param = fcall.bind_param("tuple_u32")
+ param = unpack('!IIIII', param)
+ self.assertEqual(param, tuple_u32)
+
+ def test_remove_param(self):
+
+ # Add a parameter to the probe message,
+ # remove the added parameter,
+ # and try to retrieve the removed parameter
+ #
+ probe = create_probe()
+ probe.add_param("param")
+ probe.remove_param("param")
+ self.failIf(probe.is_param("param"))
+
+ def test_set_cb(self):
+
+ # Set a callback to the fcall message,
+ # and set another callback
+ #
+ fcall = create_fcall("fcall")
+ fcall.set_cb(cb1)
+ fcall.set_cb(cb2)
+
+ def test_remove_cb(self):
+
+ # Set a callback to the fcall message,
+ # remove the set callback,
+ # and set another callback
+ #
+ fcall = create_fcall("fcall")
+ fcall.set_cb(cb1)
+ fcall.remove_cb()
+ fcall.set_cb(cb2)
+
+ def test_set_sta(self):
+
+ # Set the destination station to the probe message,
+ # create station 3,
+ # and set the destination station 3 to the probe message
+ #
+ probe = create_probe()
+ probe.set_sta(self.station)
+ station1 = 1
+ probe.set_sta(station1)
+
+ def test_send_async(self):
+
+ # Create a fcall message
+ fcall1 = create_fcall("function_1")
+
+ # Add a first parameter to the created message
+ param1 = pack('iiB',1,2,True)
+ fcall1.add_param("param_1", param1)
+
+ # Add a second parameter to the created message
+ param2 = pack('iiiiiiiiii',0,1,2,3,4,5,6,7,8,9)
+ fcall1.add_param("param_2", param2)
+
+ # Add a third parameter to the created message
+ param3 = "hello"
+ fcall1.add_param("param_3", param3)
+
+ # Add a fourth parameter to the created message
+ param4 = pack('q',123)
+ fcall1.add_param("param_4", param4)
+
+ # Register a callback function which will be called at message response reception
+ fcall1.set_cb(cb1)
+
+ # Set destination station of message
+ fcall1.set_sta(self.station)
+
+ # Send the configured message in an asynchronous mode
+ fcall1.send_async()
+
+ # Send another message in an asynchronous mode
+ station2 = 2
+ fcall2 = create_fcall("function_1")
+ fcall2.add_param("param_1", param1)
+ fcall2.add_param("param_2", param2)
+ fcall2.add_param("param_3", param3)
+ fcall2.add_param("param_4", param4)
+ fcall2.set_cb(cb2)
+ fcall2.set_sta(station2)
+ fcall2.send_async()
+
+ def test_send(self):
+
+ # Create a fcall message,
+ # add a boolean parameter,
+ # send the message to station,
+ # and get the result
+ #
+ fcall2 = create_fcall("function_2")
+ fcall2.add_param_bool("param_5", True)
+ fcall2 = fcall2.send(self.station)
+ result1 = fcall2.bind_param_string("result_1")
+ self.assertEqual(result1,"this is result 1")
+ self.assertEqual(len(result1),16)
+
+ # Create a probe message,
+ # set the destination station,
+ # add a parameter,
+ # send the message,
+ # and get the result
+ #
+ probe = create_probe().set_sta(self.station).add_param("param_6").send()
+ self.assertEqual(probe.bind_param_ulong("param_6"),0x7B000000)
+
+ def test_is_param(self):
+
+ # Add a parameter to the probe message,
+ # send the message to the destination station,
+ # and get the result
+ #
+ probe = create_probe()
+ probe.add_param("param_6").send(self.station)
+ self.assert_(probe.is_param("param_6"))
+
+ def test_bind_param_string(self):
+
+ # Add string parameters to the fcall message,
+ # and retrieve added parameters
+ #
+ fcall = create_fcall("fcall")
+ fcall.add_param("string_param_1","string param 1")
+ fcall.add_param("string_param_2","string param 2")
+ fcall.add_param("string_param_3","string param 3")
+ self.assertEqual(fcall.bind_param_string("string_param_1"),"string param 1")
+ self.assertEqual(fcall.bind_param_string("string_param_2"),"string param 2")
+ self.assertEqual(fcall.bind_param_string("string_param_3"),"string param 3")
+
+ def test_bind_param_bool(self):
+
+ # Add a boolean parameter to the fcall message,
+ # and retrieve the added parameter
+ #
+ fcall = create_fcall("fcall")
+ fcall.add_param_bool("boolean_param", False)
+ self.assertEqual(fcall.bind_param_bool("boolean_param"),False)
+
+ def test_bind_param_ushort(self):
+
+ # Add a parameter to the probe message,
+ # send the message to the destination station,
+ # and get the result
+ #
+ probe = create_probe()
+ probe = probe.add_param("param_10").send(self.station)
+ self.assertEqual(probe.bind_param_ushort("param_10"),0xEEFF)
+
+ def test_bind_param_ulong(self):
+
+ # Add a parameter to the probe message,
+ # send the message to the destination station,
+ # and get the result
+ #
+ probe = create_probe()
+ probe = probe.add_param("param_11").send(self.station)
+ self.assertEqual(probe.bind_param_ulong("param_11"),0xCCDDEEFF)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestFcallFunctions)
+
+try:
+ suite.addTest(doctest.DocTestSuite(fcall))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_macframe.py b/cesar/maximus/python/test/test_macframe.py
new file mode 100644
index 0000000000..ab5026ead8
--- /dev/null
+++ b/cesar/maximus/python/test/test_macframe.py
@@ -0,0 +1,547 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys, startup
+
+from maximus.macframe import *
+from maximus.macframe.create import create_pb
+from maximus.macframe.mpdu import SIZE_OF_PB520, MAX_PB_NB_PER_MPDU, MPDU
+from maximus.macframe.msdu import MSDU
+from maximus.macframe.pb import PB
+from maximus.mme import *
+from maximus.utils.crc import crc8, crc24, crc32
+from maximus.utils.format import *
+from interface import *
+from struct import pack, unpack
+
+
+# MPDU TEST
+
+# Create a Maximus instance
+m = Maximus()
+
+# Initialize Maximus with command line arguments
+m.init(sys.argv)
+
+def prepare_rx(s, pb_nb=1):
+ fcall = m.create_fcall('prepare_rx')
+ if pb_nb == 1:
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ short_ppdu = False
+ mod = 2 # PHY_MOD_MINI_ROBO
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ pb_size = 0 # PHY_PB_SIZE_136
+ gil = 1 # PHY_GIL_567
+ else:
+ fc_mode = 2 # PHY_FC_MODE_AV_1
+ short_ppdu = False
+ mod = 0 # PHY_MOD_ROBO
+ fecrate = 0 # PHY_FEC_RATE_1_2
+ pb_size = 1 # PHY_PB_SIZE_520
+ gil = 0 # PHY_GIL_417
+ fcall.add_param_ushort("fc_mode", fc_mode)
+ fcall.add_param_bool("short_ppdu", short_ppdu)
+ fcall.add_param_ushort("mod", mod)
+ fcall.add_param_ushort("fecrate", fecrate)
+ fcall.add_param_ushort("pb_size", pb_size)
+ fcall.add_param_ushort("gil", gil)
+ fcall.add_param_ushort("pb_nb", pb_nb)
+ fcall.send(s)
+
+# Create a MAC Frame (6 octets)
+macFrame1 = MACFrame(FC_10 = FC_10(), FC_AV = FC_AV())
+
+# Create a MAC Frame (6 octets)
+fcav = FC_AV()
+macFrame2 = MACFrame(FC_AV=fcav)
+
+# Create a MAC Frame (14 octets)
+macFrame3 = MACFrame()
+macFrame3.set_msdu(pack('Q', 0x1122334455667788))
+
+# Create a MAC Frame (10 octets)
+f = file('/tmp/data.txt', 'w')
+f.write(pack('I', 0x31323334))
+f.close()
+macFrame4 = MACFrame(FC_AV=FC_AV(DT_AV='SOF'))
+f = file('/tmp/data.txt', 'r')
+macFrame4.set_msdu(f.readline())
+f.close()
+macFrame4.set_fc_10(FC_10(CC=1, DT='SOF_RSP'))
+
+# Maximus needs to receive the TONEMASK from a station
+station = m.create_sta()
+station.debug()
+fcall1 = m.create_fcall('set_tonemask')
+fcall1.send(station)
+
+# Send the MAC Frame asynchronously
+prepare_rx(station)
+macFrame4.send(m)
+
+# Create a MAC Frame containing an MME (66 octets)
+macFrame5 = MACFrame(msdu=MME(), PBHeader=PBHeader(SSN=0xFFF0))
+prepare_rx(station)
+macFrame5.send(m)
+
+# Create a MAC Frame Queue
+list1 = [macFrame1, macFrame2, macFrame3, macFrame4, macFrame5] # 102 octets => 1 PB
+queue = MACFrameQueue(PBHeader=PBHeader(), macframelist=list1)
+list1.reverse()
+queue.add(list1)
+prepare_rx(station, pb_nb=1)
+queue.send(m)
+list2 = [MACFrame(msdu=507*'a'), MACFrame(msdu=1017*'b')] # 1536 octets => 3 PBs
+queue.set_macframelist(list2)
+prepare_rx(station, pb_nb=3)
+queue.send(m)
+
+station.remove()
+
+
+# DOC TEST
+
+import doctest
+doctest.testmod(create)
+doctest.testmod(fc_10)
+doctest.testmod(fc_av)
+doctest.testmod(macframe)
+doctest.testmod(macframeheader)
+doctest.testmod(macframequeue)
+doctest.testmod(mpdu)
+doctest.testmod(msdu)
+doctest.testmod(pb)
+doctest.testmod(pbheader)
+
+# UNIT TEST
+
+import unittest
+
+class TestFC_10Functions(unittest.TestCase):
+
+ def setUp(self):
+ self.fc10 = FC_10()
+
+ def tearDown(self):
+ pass
+
+ def test_set_cc(self):
+ # Test with a Python integer
+ cc = 1
+ self.fc10.set_cc(cc)
+ self.assertEqual(self.fc10.get_cc(),cc)
+
+ def test_set_dt(self):
+ # Test with a Python integer
+ dt = 0x07
+ self.fc10.set_dt(dt)
+ self.assertEqual(self.fc10.get_dt(),dt)
+ # Test with a Python string
+ dt = 'NACK'
+ self.fc10.set_dt(dt)
+ self.assertEqual(self.fc10.get_dt(),0x05)
+
+ def test_set_vf(self):
+ # Test with a Python integer
+ vf = 0x1FFF
+ self.fc10.set_vf(vf)
+ self.assertEqual(self.fc10.get_vf(),vf)
+
+ def test_set_fccs(self):
+ # Test with a Python integer
+ fccs = 0xFF
+ self.fc10.set_fccs(fccs)
+ self.assertEqual(self.fc10.get_fccs(),fccs)
+ # Test with a Python string
+ s = pack('B',fccs)
+ self.fc10.set_fccs(s)
+ self.assertEqual(self.fc10.get_fccs(),fccs)
+
+ def test_get(self):
+ fc10 = FC_10(CC=1, DT='NACK', VF=0x1FFF)
+ self.assertEqual(fc10.get(),0x01BFFF00 + crc8(htohp24(0x01BFFF)))
+ fc10.set_fccs(15)
+ self.assertEqual(fc10.get(),0x01BFFF0F)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestFC_10Functions)
+
+class TestFC_AVFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.fcav = FC_AV()
+
+ def tearDown(self):
+ pass
+
+ def test_set_dt_av(self):
+ # Test with a Python integer
+ dt_av = 3
+ self.fcav.set_dt_av(dt_av)
+ self.assertEqual(self.fcav.get_dt_av(),dt_av)
+ # Test with a Python string
+ dt_av = 'Sound'
+ self.fcav.set_dt_av(dt_av)
+ self.assertEqual(self.fcav.get_dt_av(),4)
+
+ def test_set_access(self):
+ # Test with a Python integer
+ access = 1
+ self.fcav.set_access(access)
+ self.assertEqual(self.fcav.get_access(),access)
+
+ def test_set_snid(self):
+ # Test with a Python integer
+ snid = 0x0F
+ self.fcav.set_snid(snid)
+ self.assertEqual(self.fcav.get_snid(),snid)
+
+ def test_set_vf_av(self):
+ # Test with a Python integer
+ vf_av = 123456789123456789
+ self.fcav.set_vf_av(vf_av)
+ self.assertEqual(self.fcav.get_vf_av(),vf_av)
+ # Test with a Python string
+ vf_av = 'ABCDEFGHIJKL'
+ self.fcav.set_vf_av(vf_av)
+ self.assertEqual(self.fcav.get_vf_av(),0x4C4B4A494847464544434241)
+
+ def test_set_fccs_av(self):
+ # Test with a Python integer
+ fccs_av = 0x123
+ self.fcav.set_fccs_av(fccs_av)
+ self.assertEqual(self.fcav.get_fccs_av(),fccs_av)
+ # Test with a Python string
+ fccs_av = 'ABC'
+ self.fcav.set_fccs_av(fccs_av)
+ self.assertEqual(self.fcav.get_fccs_av(),0x434241)
+
+ def test_get(self):
+ fcav = FC_AV(DT_AV=7, ACCESS=0, SNID=4, VF_AV=0xFFFF)
+ self.assertEqual(fcav.get(),(0x47000000, 0, 0x000000FF,\
+ 0xFF000000 + crc24(htohp32(0x47000000) + htohp32(0) + htohp32(0x000000FF) + htohp8(0xFF))))
+ fcav.set_fccs_av(15)
+ self.assertEqual(fcav.get(),(0x47000000, 0, 0x000000FF, 0xFF00000F))
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestFC_AVFunctions))
+
+class TestMACFrameFunctions(unittest.TestCase):
+
+ def setUp(self):
+
+ self.macframe = MACFrame()
+ self.assertEqual(self.macframe.get_fc_10(), 0)
+ self.assertNotEqual(self.macframe.get_fc_av(), None)
+ self.assertNotEqual(self.macframe.get_macframeheader(), None)
+ self.assertEqual(self.macframe.get_ats(), None)
+ self.assertEqual(self.macframe.get_confounder(), None)
+ self.assertEqual(self.macframe.get_icv(), None)
+ self.assertEqual(self.macframe.get_msdu(), '')
+ self.assertEqual(self.macframe.get_iv(), 3*4*'0')
+ self.assertEqual(self.macframe.get_nek(), 4*4*'0')
+
+ self.m = m
+ self.sta = self.m.create_sta()
+ fcall = self.m.create_fcall('set_tonemask')
+ fcall.send(self.sta)
+
+ def tearDown(self):
+ self.sta.remove()
+
+ def test_set_macframeheader(self):
+ # Test with a MAC Frame Header object
+ header = MACFrameHeader()
+ self.macframe.set_macframeheader(header)
+ self.assertEqual(self.macframe.get_macframeheader(),header.get())
+ # Test with a Python integer
+ header = 0x1234
+ self.macframe.set_macframeheader(header)
+ self.assertEqual(self.macframe.get_macframeheader(),pack('H',header))
+ # Test with a Python string
+ header = 'AB'
+ self.macframe.set_macframeheader(header)
+ self.assertEqual(self.macframe.get_macframeheader(),header)
+
+ def test_set_ats(self):
+ # Test with a Python long
+ ats = 0x12345678
+ self.macframe.set_ats(ats)
+ self.assertEqual(self.macframe.get_ats(),pack('I',ats))
+ # Test with a Python string
+ ats = 'ABCD'
+ self.macframe.set_ats(ats)
+ self.assertEqual(self.macframe.get_ats(),ats)
+
+ def test_set_confounder(self):
+ # Test with a Python long
+ confounder = 0x12345678
+ self.macframe.set_confounder(confounder)
+ self.assertEqual(self.macframe.get_confounder(),pack('I',confounder))
+ # Test with a Python string
+ confounder = 'ABCD'
+ self.macframe.set_confounder(confounder)
+ self.assertEqual(self.macframe.get_confounder(),confounder)
+
+ def test_set_icv(self):
+ # Test with a Python long
+ icv = 4294967295;
+ self.macframe.set_icv(icv)
+ self.assertEqual(self.macframe.get_icv(),pack('I',icv))
+ # Test with a Python string
+ icv = pack('I', 1)
+ self.macframe.set_icv(icv)
+ self.assertEqual(self.macframe.get_icv(),icv)
+
+ def test_set_msdu(self):
+ # Test with an MSDU object
+ msdu = MME()
+ self.macframe.set_msdu(msdu)
+ self.assertEqual(self.macframe.get_msdu(),msdu.get())
+ # Test with a Python string
+ msdu = '0123456789ABCDEF'
+ self.macframe.set_msdu(msdu)
+ self.assertEqual(self.macframe.get_msdu(),msdu)
+
+ def test_sendnrecv(self):
+ # Tested in 'py/test_tx_rx.py' because another station is needed for this test
+ # Here, just test the timeout
+ prepare_rx(self.sta)
+ self.macframe.set_fc_10(123)
+ self.macframe.set_fc_av(pack('IIII', 123, 456, 789, 10))
+ self.macframe.set_msdu('This is the MPDU payload')
+ t = (self.m.get_date() + 250000 - 1) / 250000
+ d = 250000
+ rsp = self.macframe.sendnrecv(self.m, timeout=d)
+ self.assertEqual(rsp, None)
+ self.assertEqual(self.m.get_date(), (t + 1) * 250000)
+
+ def test_send(self):
+ prepare_rx(self.sta)
+ self.macframe.set_fc_10(123)
+ self.macframe.set_fc_av(pack('IIII', 123, 456, 789, 10))
+ self.macframe.set_msdu('This is the MPDU payload')
+ self.macframe.send(self.m)
+
+ def test_fill_mpdu_attr(self):
+ payload = 'ABCDEFGHIJKL'
+ header = MACFrameHeader(MFL=len(payload)-1)
+ self.macframe.set_macframeheader(header)
+ self.macframe.set_msdu(payload)
+ self.macframe.fill_mpdu_attr(0, 0, 0)
+ expected_payload = header.get() + payload + htohp32(crc32(payload))
+ self.assertEqual(self.macframe.payload, expected_payload)
+ icv = '1234'
+ self.macframe.set_icv(icv)
+ self.macframe.fill_mpdu_attr(0, 0, 0)
+ expected_payload = header.get() + payload + icv
+ self.assertEqual(self.macframe.payload, expected_payload)
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMACFrameFunctions))
+
+class TestMACFrameHeaderFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.header = MACFrameHeader()
+
+ def tearDown(self):
+ pass
+
+ def test_set_mft(self):
+ # Test with a Python integer
+ mft = 0x01
+ self.header.set_mft(mft)
+ self.assertEqual(self.header.get_mft(),mft)
+
+ def test_set_mfl(self):
+ # Test with a Python integer
+ mfl = 0x1234
+ self.header.set_mfl(mfl)
+ self.assertEqual(self.header.get_mfl(),mfl)
+
+ def test_set(self):
+ mft = 0x02
+ header = MACFrameHeader(MFT=mft)
+ mfl = 0x2345
+ self.header.set(mft,mfl)
+ self.assertEqual(self.header.get_mft(),mft)
+ self.assertEqual(self.header.get_mfl(),mfl)
+
+ def test_get(self):
+ mft = 0x03
+ mfl = 0x3123
+ get = pack('H', (mfl << 2) + mft)
+ header = MACFrameHeader(MFT=mft, MFL=mfl)
+ self.assertEqual(header.get(),get)
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMACFrameHeaderFunctions))
+
+class TestMACFrameQueueFunctions(unittest.TestCase):
+
+ def setUp(self):
+
+ self.macframequeue = MACFrameQueue()
+ self.assertEqual(self.macframequeue.get_fc_10(), 0)
+ self.assertNotEqual(self.macframequeue.get_fc_av(), None)
+ self.assertEqual(self.macframequeue.get_iv(), 3*4*'0')
+ self.assertEqual(self.macframequeue.get_nek(), 4*4*'0')
+ self.assertEqual(self.macframequeue.get_macframelist(), [])
+
+ self.m = m
+ self.sta = self.m.create_sta()
+ fcall = self.m.create_fcall('set_tonemask')
+ fcall.send(self.sta)
+
+ def tearDown(self):
+ self.sta.remove()
+
+ def test_set_macframelist(self):
+ # Test with an Python list
+ list = [MACFrame(), MACFrame(), MACFrame()]
+ self.macframequeue.set_macframelist(list)
+ self.assertEqual(self.macframequeue.get_macframelist(), list)
+
+ def test_add(self):
+ self.macframequeue.set_macframelist([MACFrame()])
+ # Test with a a MAC Frame
+ self.macframequeue.add(MACFrame())
+ self.assertEqual(len(self.macframequeue.get_macframelist()), 2)
+ # Test with a Python list of MAC Frames
+ self.macframequeue.add([MACFrame(), MACFrame(), MACFrame()])
+ self.assertEqual(len(self.macframequeue.get_macframelist()), 5)
+
+ def test_sendnrecv(self):
+ # Tested in 'py/test_tx_rx.py' because another station is needed for this test
+ # Here, just test the timeout
+ prepare_rx(self.sta, pb_nb=3)
+ self.macframequeue.set_fc_10(123)
+ self.macframequeue.set_fc_av(pack('IIII', 123, 456, 789, 10))
+ list = [MACFrame(), MACFrame(), MACFrame()]
+ self.macframequeue.set_macframelist(list)
+ t = (self.m.get_date() + 250000 - 1) / 250000
+ d = 250000
+ rsp = self.macframequeue.sendnrecv(self.m, timeout=d)
+ self.assertEqual(rsp, None)
+ self.assertEqual(self.m.get_date(), (t + 1) * 250000)
+
+ def test_send(self):
+ prepare_rx(self.sta, pb_nb=3)
+ self.macframequeue.set_fc_10(123)
+ self.macframequeue.set_fc_av(pack('IIII', 123, 456, 789, 10))
+ list = [MACFrame(), MACFrame(), MACFrame()]
+ self.macframequeue.set_macframelist(list)
+ self.macframequeue.send(self.m)
+ self.assertEqual(self.macframequeue.get_macframelist(), [])
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMACFrameQueueFunctions))
+
+class TestMPDUFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.mpdu = MPDU()
+
+ def tearDown(self):
+ pass
+
+ def test_set_fc_10(self):
+ # Test with an FC 1.0 object
+ fc10 = FC_10()
+ self.mpdu.set_fc_10(fc10)
+ self.assertEqual(self.mpdu.get_fc_10(), fc10.get())
+ # Test with a Python long
+ fc10 = 0x12345678
+ self.mpdu.set_fc_10(fc10)
+ self.assertEqual(self.mpdu.get_fc_10(), fc10)
+ # Test with a Python string
+ fc10 = 'ABCD'
+ self.mpdu.set_fc_10(fc10)
+ self.assertEqual(self.mpdu.get_fc_10(),unpack('I', fc10)[0])
+
+ def test_set_fc_av(self):
+ # Test with an FC AV object
+ fcav = FC_AV()
+ self.mpdu.set_fc_av(fcav)
+ self.assertEqual(self.mpdu.get_fc_av(), fcav.get())
+ # Test with a Python string
+ fcav = 4*'ABCD'
+ self.mpdu.set_fc_av(fcav)
+ self.assertEqual(self.mpdu.get_fc_av(), unpack('IIII',fcav))
+ # Test with a tuple of 4 Python longs
+ fcav = (0, 1, 2, 3)
+ self.mpdu.set_fc_av(fcav)
+ self.assertEqual(self.mpdu.get_fc_av(), fcav)
+
+ def test_set_iv(self):
+ # Test with a Python string
+ iv = 3*'0123'
+ self.mpdu.set_iv(iv)
+ self.assertEqual(self.mpdu.get_iv(), iv)
+
+ def test_set_nek(self):
+ # Test with a Python string
+ nek = 4*'0123'
+ self.mpdu.set_nek(nek)
+ self.assertEqual(self.mpdu.get_nek(), nek)
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMPDUFunctions))
+
+class TestMSDUFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.msdu = MSDU()
+
+ def tearDown(self):
+ pass
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMSDUFunctions))
+
+class TestPBFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.pb = PB()
+
+ def tearDown(self):
+ pass
+
+ def test_set_mpdu_attr(self):
+ fc10 = 10
+ fcav = (0, 1, 2, 3)
+ data = 'ABCDEFGH'
+ payload = MAX_PB_NB_PER_MPDU * data * (SIZE_OF_PB520 / len(data))
+ self.pb.set_mpdu_attr(fc10, fcav, payload)
+ self.assertEqual(self.pb.get_fc_10(), fc10)
+ self.assertEqual(self.pb.get_fc_av(), fcav)
+ self.assertEqual(len(self.pb.get_pblist()), MAX_PB_NB_PER_MPDU)
+
+ def test_create_pb(self):
+ self.assertNotEqual(create_pb(), None)
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestPBFunctions))
+
+class TestPBHeaderFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.header = PBHeader()
+
+ def tearDown(self):
+ pass
+
+ def test_get(self):
+ self.assertEqual(self.header.get(), 0x0A000000)
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestPBHeaderFunctions))
+
+try:
+ suite.addTest(doctest.DocTestSuite(create))
+ suite.addTest(doctest.DocTestSuite(fc_10))
+ suite.addTest(doctest.DocTestSuite(fc_av))
+ suite.addTest(doctest.DocTestSuite(macframe))
+ suite.addTest(doctest.DocTestSuite(macframeheader))
+ suite.addTest(doctest.DocTestSuite(mpdu))
+ suite.addTest(doctest.DocTestSuite(msdu))
+ suite.addTest(doctest.DocTestSuite(pb))
+ suite.addTest(doctest.DocTestSuite(pbheader))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_maximus.py b/cesar/maximus/python/test/test_maximus.py
new file mode 100644
index 0000000000..9164b7676c
--- /dev/null
+++ b/cesar/maximus/python/test/test_maximus.py
@@ -0,0 +1,47 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import startup
+
+
+print
+print "MAXIMUS TEST"
+import test_channel
+import test_cli
+import test_ethernet
+import test_fsm
+import test_interface
+import test_macframe
+import test_mme
+import test_result
+import test_simu
+import test_station
+import test_utils
+
+print
+print "PY DOC"
+import pydoc, maximus
+pydoc.getdoc(maximus)
+
+
+print
+print "DOC TEST"
+import doctest
+doctest.testmod(maximus)
+doctest.testfile("test.txt")
+
+
+print
+print "UNIT TEST"
+import unittest
+allTests = unittest.TestSuite([test_channel.suite, test_cli.suite, test_ethernet.suite, test_fsm.suite, test_interface.suite, test_macframe.suite, test_mme.suite, test_result.suite, test_simu.suite, test_station.suite, test_utils.suite])
+testResult = unittest.TextTestRunner(verbosity=2).run(allTests)
+
+
+print
+print "TEST SUPPORT"
+from test import test_support
+def test_main():
+ test_support.run_suite(allTests)
+
diff --git a/cesar/maximus/python/test/test_mme.py b/cesar/maximus/python/test/test_mme.py
new file mode 100644
index 0000000000..f33c5615b8
--- /dev/null
+++ b/cesar/maximus/python/test/test_mme.py
@@ -0,0 +1,304 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys, startup
+
+from maximus.mme import *
+from maximus.mme.create import create_mme
+from maximus.utils.exception import OutOfRangeError
+from interface import *
+from struct import pack
+
+
+# MME TEST
+
+# Create a Maximus instance
+m = Maximus()
+
+# Initialize Maximus with command line arguments
+m.init(sys.argv)
+
+# Create the destination station
+staRx = m.create_sta()
+staRx.debug()
+
+# Create an MME
+mme1 = MME(MMHeader=MMHeader(MMV=0x01), MMEntry=MMEntry('This is the MM Entry'))
+
+# Send the MME asynchronously
+mme1.send(m, staRx)
+
+# Create an MME
+mme2 = MME()
+
+# Send the MME asynchronously
+rsp = mme2.sendnrecv(m, staRx, timeout=250000)
+
+# Remove the destination station
+staRx.remove()
+
+
+# DOC TEST
+
+import doctest
+doctest.testmod(mme)
+doctest.testmod(mmentry)
+doctest.testmod(mmheader)
+doctest.testmod(mmtype)
+
+
+# UNIT TEST
+
+import unittest
+
+class TestMMHeaderFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.mmheader = MMHeader()
+
+ def tearDown(self):
+ pass
+
+ def test_set_oda(self):
+ # Test with a Python long
+ oda = 0x112233445566
+ self.mmheader.set_oda(oda)
+ self.assertEqual(self.mmheader.get_oda(), oda)
+ # Test with a Python string of length equals to 6 octets
+ oda = '123456'
+ self.mmheader.set_oda(oda)
+ self.assertEqual(self.mmheader.get_oda(), oda)
+
+ def test_set_osa(self):
+ # Test with a Python long
+ osa = 0xFFFFFFFFFFFF
+ self.mmheader.set_osa(osa)
+ self.assertEqual(self.mmheader.get_osa(), osa)
+ # Test with a Python string of length equals to 6 octets
+ osa = pack('Q', 0x112233445566)[0:6]
+ self.mmheader.set_osa(osa)
+ self.assertEqual(self.mmheader.get_osa(), osa)
+
+ def test_set_vlantag(self):
+ # Test with a Python integer
+ #
+ vlantag = 0x8100FFFF
+ self.mmheader.set_vlantag(vlantag)
+ self.assertEqual(self.mmheader.get_vlantag(), vlantag)
+
+ # Test with a bad vlantag
+ test = False
+ vlantag = 0xFFFFFFFF
+ try:
+ self.mmheader.set_vlantag(vlantag)
+ except OutOfRangeError:
+ test = True
+ self.assert_(test)
+
+ # Test with a Python string of length equals to 4 octets
+ #
+ vlantag = pack('!I', 0x81000000)
+ self.mmheader.set_vlantag(vlantag)
+ self.assertEqual(self.mmheader.get_vlantag(), vlantag)
+
+ # Test with a bad vlantag
+ test = False
+ vlantag = pack('!I', 0x00000000)
+ try:
+ self.mmheader.set_vlantag(vlantag)
+ except OutOfRangeError:
+ test = True
+ self.assert_(test)
+
+ def test_set_mtype(self):
+ # Test with a Python integer
+ mtype = 0xFFFF
+ self.mmheader.set_mtype(mtype)
+ self.assertEqual(self.mmheader.get_mtype(), mtype)
+ # Test with a Python string of length equals to 2 octets
+ mtype = '12'
+ self.mmheader.set_mtype(mtype)
+ self.assertEqual(self.mmheader.get_mtype(), mtype)
+ mtype = pack('H', 0x1122)
+ self.mmheader.set_mtype(mtype)
+ self.assertEqual(self.mmheader.get_mtype(), mtype)
+
+ def test_set_mmv(self):
+ # Test with a Python integer
+ mmv = 0xFF
+ self.mmheader.set_mmv(mmv)
+ self.assertEqual(self.mmheader.get_mmv(), mmv)
+ # Test with a Python string of length equals to 1 octet
+ mmv = '1'
+ self.mmheader.set_mmv(mmv)
+ self.assertEqual(self.mmheader.get_mmv(), mmv)
+ mmv = pack('B', 0x01)
+ self.mmheader.set_mmv(mmv)
+ self.assertEqual(self.mmheader.get_mmv(), mmv)
+
+ def test_set_mmtype(self):
+ # Test with a Python integer
+ mmtype = 0x1234
+ self.mmheader.set_mmtype(mmtype)
+ self.assertEqual(self.mmheader.get_mmtype(), mmtype)
+ # Test with a Python string of length equals to 2 octets
+ mmtype = 'ab'
+ self.mmheader.set_mmtype(mmtype)
+ self.assertEqual(self.mmheader.get_mmtype(), mmtype)
+ mmtype = pack('H', 0x1234)
+ self.mmheader.set_mmtype(mmtype)
+ self.assertEqual(self.mmheader.get_mmtype(), mmtype)
+
+ def test_set_fmi(self):
+ # Test with a Python integer
+ fmi = 0xFEDC
+ self.mmheader.set_fmi(fmi)
+ self.assertEqual(self.mmheader.get_fmi(), fmi)
+ # Test with a Python string of length equals to 2 octets
+ fmi = 'AB'
+ self.mmheader.set_fmi(fmi)
+ self.assertEqual(self.mmheader.get_fmi(), fmi)
+ fmi = pack('H', 0xFEDC)
+ self.mmheader.set_fmi(fmi)
+ self.assertEqual(self.mmheader.get_fmi(), fmi)
+
+ def test_get(self):
+ # Test without vlantag
+ mmheader = MMHeader(ODA=0x616263646566, OSA=0x6768696A6B6C, MTYPE=0x6D6E, MMV=0x6F, MMTYPE=0x7170, FMI=0x7372)
+ self.assertEqual(mmheader.get(), 'abcdefghijklmnopqrs')
+
+ # Test with vlantag
+ mmheader = MMHeader(ODA=0x616263646566, OSA=0x6768696A6B6C, VLANTag=0x81006D6E, MTYPE=0x6F70, MMV=0x71, MMTYPE=0x7372, FMI=0x7574)
+ self.assertEqual(mmheader.get(), 'abcdefghijkl' + pack('!I', 0x81006D6E) + 'opqrstu')
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestMMHeaderFunctions)
+
+class TestMMEntryFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.mmentry = MMEntry()
+
+ def tearDown(self):
+ pass
+
+ def test_set_data(self):
+ # Test with a Python string of length smaller than 1518 - 23 = 1495
+ data = 1495*'M'
+ self.mmentry.set_data(data)
+ self.assertEqual(self.mmentry.get_data(), data)
+
+ def test_get(self):
+ data = 'This is the Management Message Entry Data'
+ mmentry = MMEntry(data)
+ self.assertEqual(mmentry.get(), data)
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMMEntryFunctions))
+
+class TestMMEFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.mme = MME()
+ self.m = m
+
+ def tearDown(self):
+ pass
+
+ def test_set_mmheader(self):
+ # Test with an MM Header object with VLAN Tag
+ mmheader = MMHeader(VLANTag=0x81000000)
+ self.mme.set_mmheader(mmheader)
+ self.assertEqual(self.mme.get_mmheader(), mmheader)
+
+ # Test with an MM Header object without VLAN Tag
+ mmheader = MMHeader()
+ self.mme.set_mmheader(mmheader)
+ self.assertEqual(self.mme.get_mmheader(), mmheader)
+
+ # Test with a Python string of length equals to 19 octets
+ mmheader = 'abcdefghijklmnopqrs'
+ self.mme.set_mmheader(mmheader)
+ self.assertEqual(self.mme.get_mmheader(), mmheader)
+
+ # Test with a Python string of length equals to 23 octets
+ mmheader = 'abcdefghijklmnopqrstuvw'
+ self.mme.set_mmheader(mmheader)
+ self.assertEqual(self.mme.get_mmheader(), mmheader)
+
+ def test_set_mmentry(self):
+ # Test with a Python string of length smaller than 1500 octets
+ mmentry = 'test'
+ self.mme.set_mmentry(mmentry)
+ self.assertEqual(self.mme.get_mmentry(), mmentry)
+
+ def test_set_msdu_attr(self):
+ # Test with VLAN Tag
+ payload = 12*'H' + pack('!I', 0x81000000) + 7*'H' + 'Payload'
+ self.mme.set_msdu_attr(payload)
+ self.assertEqual(self.mme.get_mmheader(), 12*'H' + pack('!I', 0x81000000) + 7*'H')
+ self.assertEqual(self.mme.get_mmentry(), 'Payload')
+
+ # Test without VLAN Tag
+ payload = 19*'H' + 'Payload'
+ self.mme.set_msdu_attr(payload)
+ self.assertEqual(self.mme.get_mmheader(), 19*'H')
+ self.assertEqual(self.mme.get_mmentry(), 'Payload')
+
+ def test_sendnrecv(self):
+ # Tested in 'py/test_ether.py' because another station is needed for this test
+ # Here, just test the timeout
+ sta = self.m.create_sta()
+ t = self.m.get_date()
+ d = 250000
+ rsp = self.mme.sendnrecv(self.m, sta, timeout=d)
+ self.assertEqual(rsp, None)
+ self.assertEqual(self.m.get_date(), t + d)
+ sta.remove()
+
+ def test_send(self):
+ sta = self.m.create_sta()
+ self.mme.send(self.m, sta)
+ sta.remove()
+
+ def test_get(self):
+ # Test with VLAN Tag
+ mme1 = MME(MMHeader=23*'A', MMEntry='B')
+ self.assertEqual(mme1.get(), 23*'A'+'B'+36*pack('B',0))
+ mme2 = MME(MMHeader=23*'A', MMEntry=36*'B')
+ self.assertEqual(mme2.get(), 23*'A'+36*'B'+pack('B',0))
+ mme3 = MME(MMHeader=23*'A', MMEntry=37*'B')
+ self.assertEqual(mme3.get(), 23*'A'+37*'B')
+ mme4 = MME(MMHeader=23*'A', MMEntry=1000*'B')
+ self.assertEqual(mme4.get(), 23*'A'+1000*'B')
+
+ # Test without VLAN Tag
+ mme1 = MME(MMHeader=19*'A', MMEntry='B')
+ self.assertEqual(mme1.get(), 19*'A'+'B'+40*pack('B',0))
+ mme2 = MME(MMHeader=19*'A', MMEntry=40*'B')
+ self.assertEqual(mme2.get(), 19*'A'+40*'B'+pack('B',0))
+ mme3 = MME(MMHeader=19*'A', MMEntry=41*'B')
+ self.assertEqual(mme3.get(), 19*'A'+41*'B')
+ mme4 = MME(MMHeader=19*'A', MMEntry=1000*'B')
+ self.assertEqual(mme4.get(), 19*'A'+1000*'B')
+
+ def test_get_ether_type(self):
+ self.assertEqual(self.mme.get_ether_type(), 2)
+
+ def test_get_type(self):
+ self.assertEqual(self.mme.get_type(), 'ETHERNET_TYPE_MME')
+
+ def test_create_mme(self):
+ self.assertNotEqual(create_mme(), None)
+
+suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMMEFunctions))
+
+try:
+ suite.addTest(doctest.DocTestSuite(mme))
+ suite.addTest(doctest.DocTestSuite(mmentry))
+ suite.addTest(doctest.DocTestSuite(mmheader))
+ suite.addTest(doctest.DocTestSuite(mmtype))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_result.py b/cesar/maximus/python/test/test_result.py
new file mode 100644
index 0000000000..5fa7a969bf
--- /dev/null
+++ b/cesar/maximus/python/test/test_result.py
@@ -0,0 +1,26 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import startup
+
+from maximus.result import *
+
+
+# RESULT TEST
+
+
+# DOC TEST
+
+import doctest
+#doctest.testmod()
+
+
+# UNIT TEST
+
+import unittest
+suite = unittest.TestSuite()
+#try:
+# suite.addTest(doctest.DocTestSuite())
+#except ValueError:
+# print "has no tests"
diff --git a/cesar/maximus/python/test/test_simu.py b/cesar/maximus/python/test/test_simu.py
new file mode 100644
index 0000000000..e30c2e8e80
--- /dev/null
+++ b/cesar/maximus/python/test/test_simu.py
@@ -0,0 +1,120 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import sys, startup
+
+from maximus.simu import *
+from maximus.simu.rx import Rx
+from interface import *
+
+
+# SIMU TEST
+
+# Create a Maximus instance
+m = Maximus()
+
+# Initialize Maximus with command line arguments
+m.init(sys.argv)
+
+# Transmission
+rsp = sendnrecv(file='data', timeout=5000)
+send(file='data')
+
+# Define a filter function
+def my_filter(rx_macframe):
+ print "=> my_filter"
+ return True
+
+# Reception
+rsp = recv(maximus=m, timeout=10000, filter=my_filter, count=0)
+
+# Get the current date
+t = m.get_date()
+
+
+# DOC TEST
+
+import doctest
+doctest.testmod(rx)
+doctest.testmod(tx)
+
+
+# UNIT TEST
+
+import unittest
+
+class TestRxFunctions(unittest.TestCase):
+
+ def setUp(self):
+ print "setUp"
+ self.reception = Rx(m)
+
+ def tearDown(self):
+ print "tearDown"
+
+ def test_init(self):
+ reception = Rx(maximus=m, filter_fc=my_filter)
+
+ def test_recv(self):
+ reception = Rx(maximus=m, filter_fc=my_filter, counter=2)
+ class MACFrame:
+ pass
+ macframe1 = MACFrame()
+ macframe2 = MACFrame()
+ reception.cb(macframe1)
+ reception.cb(macframe2)
+ self.assertEqual(reception.recv(), [macframe1, macframe2])
+
+ def test_add_frame(self):
+ class MACFrame:
+ pass
+ macframe1 = MACFrame()
+ macframe2 = MACFrame()
+ self.reception.add_frame(macframe1)
+ self.assertEqual(len(self.reception.get_frame_list()), 1)
+ self.assertEqual(self.reception.get_frame_list()[0], macframe1)
+ self.reception.add_frame(macframe2)
+ self.assertEqual(len(self.reception.get_frame_list()), 2)
+ self.assertEqual(self.reception.get_frame_list()[0], macframe1)
+ self.assertEqual(self.reception.get_frame_list()[1], macframe2)
+
+ def test_set_counter(self):
+ counter = 10
+ self.reception.set_counter(counter)
+ self.assertEqual(self.reception.get_counter(), counter)
+
+ def test_decr_counter(self):
+ self.reception.decr_counter()
+ self.assertEqual(self.reception.get_counter(), 0)
+ counter = 10
+ self.reception.set_counter(counter)
+ self.reception.decr_counter()
+ self.assertEqual(self.reception.get_counter(), counter-1)
+
+ def test_call_filter_fc(self):
+ def filter_fc(macframe):
+ print "=> filter_fc"
+ self.reception.set_filter_fc(filter_fc)
+ class MACFrame:
+ pass
+ macframe = MACFrame()
+ self.reception.call_filter_fc(macframe)
+
+ def test_recv(self):
+ self.assertEqual(recv(maximus=m, timeout=None, filter=None, count=0), None)
+ t = m.get_date()
+ d = 750001
+ recv(maximus=m, timeout=d)
+ self.assertEqual(m.get_date(), t + 1000000)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestRxFunctions)
+
+try:
+ suite.addTest(doctest.DocTestSuite(rx))
+ suite.addTest(doctest.DocTestSuite(tx))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_station.py b/cesar/maximus/python/test/test_station.py
new file mode 100644
index 0000000000..bfc1c71331
--- /dev/null
+++ b/cesar/maximus/python/test/test_station.py
@@ -0,0 +1,268 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import startup, sys
+
+from maximus.station import *
+from maximus.ethernet.buffer import realloc_buffer
+from maximus.utils.exception import Error
+from maximus.utils.format import *
+from interface import *
+
+
+# STATION TEST
+
+# Create a Maximus instance
+m = Maximus()
+
+# Initialize Maximus with command line arguments
+m.init(sys.argv)
+
+station_nb = 0
+file_desc_nb = 3 # number of file descriptors per station (3 for pipe, 2 for socket)
+
+# Disable the automatic buffer allocation
+realloc_buffer(False)
+
+sta1 = STA(m, name="my_sta")
+station_nb += 1
+sta1.debug()
+sta1.set_mac_address(0x123456789ABC)
+m.create_fcall("uninit_ether").send(sta1.get())
+sta1.remove()
+
+sta2 = STA(m, config=Config(mac_address='12:34:56:78:9A:BC'))
+station_nb += 1
+sta2.debug()
+sta2.set_cco_preference(False)
+m.create_fcall("uninit_ether").send(sta2.get())
+sta2.remove()
+
+sta3 = STA(m, name="my_sta", executable='../stationtest/obj/test_station.elf')
+station_nb += 1
+sta3.debug()
+m.create_fcall("uninit_ether").send(sta3.get())
+sta3.remove()
+
+conf4 = Config(cco_preference=True)
+sta4 = STA(m, name="my_sta", config=conf4)
+station_nb += 1
+sta4.debug()
+m.create_fcall("uninit_ether").send(sta4.get())
+sta4.remove()
+
+conf5 = Config(was_cco=True, npw="network_password", sl=2)
+sta5 = STA(m, name="This is the name of my station", config=conf5)
+station_nb += 1
+sta5.debug()
+m.create_fcall("uninit_ether").send(sta5.get())
+sta5.remove()
+
+conf = Config()
+conf.mac_address = '12:34:56:78:9A:BC'
+conf.cco_preference = True
+conf.was_cco = False
+conf.npw = "a Python string of length from 8 to 64 octets"
+conf.dpw = "a Python string of length from 0 to 64 octets"
+conf.m_sta_hfid = "a Python string of length from 0 to 64 octets"
+conf.u_sta_hfid = "a Python string of length from 0 to 64 octets"
+conf.avln_hfid = "a Python string of length from 0 to 64 octets"
+conf.sl = 2
+conf.tonemask = (85,139,167,214,225,282,302,409,419,569,591,736,748,856,882,1015,1027,1143,1535)
+conf.snid = 15
+
+sta6 = STA(m, debug=True, name="sta6", config_mode='fcall_cp_station', config=conf)
+station_nb += 1
+m.create_fcall("uninit_ether").send(sta6.get())
+sta6.remove()
+
+sta7 = STA(m)
+station_nb += 1
+try:
+ bad_conf = Config(was_cco="this is a mistake")
+ sta7.set_config(bad_conf)
+except TypeError:
+ m.create_fcall("uninit_ether").send(sta7.get())
+ sta7.remove()
+
+sta8 = STA(m, name="sta8", config_mode='fcall_process_drv', config=conf)
+station_nb += 1
+m.create_fcall("uninit_ether").send(sta8.get())
+sta8.remove()
+
+sta9 = STA(m, name="sta9", config_mode='MME', config=conf)
+station_nb += 1
+m.create_fcall("uninit_ether").send(sta9.get())
+sta9.remove()
+
+# Test with the maximum number of stations,
+# which is limited by the maximum number of open file descriptors (1024)
+station_max_nb = (1024 + (file_desc_nb - 1)) / file_desc_nb - station_nb * file_desc_nb
+station_list = []
+for i in range (0, station_max_nb):
+ station_list.append(STA(m))
+for i in range (0, len(station_list)):
+ m.create_fcall("uninit_ether").send(station_list[i].get())
+ station_list[i].remove()
+if len(station_list) != station_max_nb:
+ print "length of list of stations =", len(station_list)
+ print "number of created stations =", station_max_nb
+ raise Error("incorrect length of list of stations")
+
+
+# DOC TEST
+
+import doctest
+doctest.testmod(config)
+doctest.testmod(sta)
+
+
+# UNIT TEST
+
+import unittest
+
+class TestSTAFunctions(unittest.TestCase):
+
+ def setUp(self):
+ # Create station
+ self.station = STA(m)
+
+ def tearDown(self):
+ # Remove station
+ m.create_fcall("uninit_ether").send(self.station.get())
+ self.station.remove()
+
+ def test_stop(self):
+ self.station.stop()
+
+ def test_set_name(self):
+ name = "Name of my station"
+ self.station.set_name(name)
+ self.assertEqual(self.station.get_name(), name)
+
+ def test_set_mme_buffer_nb(self):
+ mme_buffer_nb = 4
+ self.station.set_mme_buffer_nb(mme_buffer_nb)
+ self.assertEqual(self.station.get_mme_buffer_nb(), mme_buffer_nb)
+
+ def test_set_config_mode(self):
+ config_mode = 'fcall_process_drv'
+ self.station.set_config_mode(config_mode)
+ self.assertEqual(self.station.get_config_mode(), config_mode)
+
+ def test_set_config(self):
+ test_conf = Config()
+ test_conf.mac_address = (0x11, 0x22, 0x33, 0x44, 0x55, 0x66)
+ test_conf.cco_preference = True
+ self.station.set_config(test_conf)
+ self.assertEqual(self.station.get_config().mac_address, test_conf.mac_address)
+ self.assertEqual(self.station.get_config().cco_preference, test_conf.cco_preference)
+
+ def test_set_mac_address(self):
+ mac_address = (0x41, 0x42, 0x43, 0x44, 0x45, 0x46)
+ # Test with a Python tuple of 6 Python integers
+ self.station.set_mac_address((0x41, 0x42, 0x43, 0x44, 0x45, 0x46))
+ self.assertEqual(self.station.get_mac_address(), mac_address)
+ # Test with a Python long (decimal or hexadecimal value)
+ self.station.set_mac_address(0x414243444546)
+ self.assertEqual(self.station.get_mac_address(), mac_address)
+ # Test with a Python string of length equals to 6 octets
+ self.station.set_mac_address(pack(n + u64, 0x414243444546)[SIZE_OF_U16:])
+ self.assertEqual(self.station.get_mac_address(), mac_address)
+ # Test with a Python string of length equals to 17 octets ('XX:XX:XX:XX:XX:XX')
+ self.station.set_mac_address('41:42:43:44:45:46')
+ self.assertEqual(self.station.get_mac_address(), mac_address)
+
+ def test_set_cco_preference(self):
+ cco_preference = False
+ self.station.set_cco_preference(cco_preference)
+ self.assertEqual(self.station.get_cco_preference(), cco_preference)
+
+ def test_set_was_cco(self):
+ was_cco = True
+ self.station.set_was_cco(was_cco)
+ self.assertEqual(self.station.get_was_cco(), was_cco)
+
+ def test_set_npw(self):
+ npw = "This is the network password"
+ self.station.set_npw(npw)
+ self.assertEqual(self.station.get_npw(), npw)
+
+ def test_set_dpw(self):
+ dpw = "This is the device password"
+ self.station.set_dpw(dpw)
+ self.assertEqual(self.station.get_dpw(), dpw)
+
+ def test_set_m_sta_hfid(self):
+ m_sta_hfid = "This is the manufacturer sta hfid"
+ self.station.set_m_sta_hfid(m_sta_hfid)
+ self.assertEqual(self.station.get_m_sta_hfid(), m_sta_hfid)
+
+ def test_set_u_sta_hfid(self):
+ u_sta_hfid = "This is the user sta hfid"
+ self.station.set_u_sta_hfid(u_sta_hfid)
+ self.assertEqual(self.station.get_u_sta_hfid(), u_sta_hfid)
+
+ def test_set_avln_hfid(self):
+ avln_hfid = "This is the avln hfid"
+ self.station.set_avln_hfid(avln_hfid)
+ self.assertEqual(self.station.get_avln_hfid(), avln_hfid)
+
+ def test_set_sl(self):
+ sl = 0x02
+ self.station.set_sl(sl)
+ self.assertEqual(self.station.get_sl(), sl)
+
+ def test_set_snid(self):
+ snid = 0x02
+ self.station.set_snid(snid)
+ self.assertEqual(self.station.get_snid(), snid)
+
+ def test_set_tonemask(self):
+ tonemask = 85,139,167,214,225,282,302,409,419,569,591,736,748,856,882,1015,1027,1143,1535
+ self.station.set_tonemask(tonemask)
+ self.assertEqual(self.station.get_tonemask()[0 / 8], pack('B', 0)) # 74
+ self.assertEqual(self.station.get_tonemask()[11 / 8], pack('B', 0xf0)) # 85
+ self.assertEqual(self.station.get_tonemask()[345 / 8], pack('B', 0xfc)) # 419
+ self.assertEqual(self.station.get_tonemask()[495 / 8], pack('B', 0xff)) # 569
+ self.assertEqual(self.station.get_tonemask()[782 / 8], pack('B', 0x7f)) # 856
+ self.assertEqual(self.station.get_tonemask()[1069 / 8], pack('B', 0x3f)) # 1143
+ self.assertEqual(self.station.get_tonemask()[1070 / 8], pack('B', 0x3f)) # 1144
+ self.assertEqual(self.station.get_tonemask()[1155 / 8], pack('B', 0x00)) # 1229
+
+ def test_remove(self):
+ m.create_fcall("uninit_ether").send(self.station.get())
+ self.station.remove()
+ self.station = STA(m)
+
+ def test_deactivate(self):
+ self.station.deactivate()
+ self.station.activate()
+
+ def test_activate(self):
+ self.station.activate()
+
+ def test_debug(self):
+ self.station.debug()
+
+ def test_is_idle(self):
+ m.wait(1) # to process the system IDLE message coming from the station
+ self.assert_(self.station.is_idle())
+ self.station.deactivate()
+ self.assert_(not self.station.is_idle())
+ self.station.activate()
+
+ def test_get_station_id(self):
+ self.assertNotEqual(self.station.get_station_id(), 0)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestSTAFunctions)
+
+try:
+ suite.addTest(doctest.DocTestSuite(config))
+ suite.addTest(doctest.DocTestSuite(sta))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/cesar/maximus/python/test/test_utils.py b/cesar/maximus/python/test/test_utils.py
new file mode 100644
index 0000000000..20a35f5a15
--- /dev/null
+++ b/cesar/maximus/python/test/test_utils.py
@@ -0,0 +1,107 @@
+#! usr/bin/env python
+
+print "\n*** " + __file__ + " ***\n"
+
+import startup
+
+from maximus.utils import *
+from unicodedata import *
+
+# CONVERTER TEST
+
+# Create data 1 from an hexadecimal value
+data1 = Data('0x41424344',16)
+print "data 1 =", data1.data
+print "base 2 =", data1.base2
+print "base 10 =", data1.base10
+print "base 16 =", data1.base16
+print "bin =", data1.get_bin(32)
+print "int =", data1.get_int()
+print "hex = ", data1.get_hex(4)
+print "str = ", data1.get_str()
+
+# Create data 2 from a string value
+data2 = Data(s='ABCD')
+print "data 2 =", data2.data
+print "base 2 =", data2.base2
+print "base 10 =", data2.base10
+print "base 16 =", data2.base16
+print "bin =", data2.get_bin(32)
+print "int =", data2.get_int()
+print "hex =", data2.get_hex(4)
+print "str =", data2.get_str()
+
+A = unichr(0x41)
+print "unichr =", A
+B = unicode(0x42)
+print "unicode =", B
+print "decimal =", decimal(unicode(9))
+print "digit =", digit(unicode(8))
+print "numeric =", numeric(unicode(7))
+
+# CRC TEST
+
+data = "123456789"
+if crc8(data) != 0xf4:
+ print "crc8 =", hex(crc8(data))
+ raise Error("crc8")
+if crc24(data) != 0x21cf02:
+ print "crc24 =", hex(crc24(data))
+ raise Error("crc24")
+if crc32(data) != 0xcbf43926: # 0xfc891918 0x5c0ac4 0x200fa5 0x29b1 0x0c73 0x89 0xf3 0x0ea0b1d3 0x78a26f6f 0xe0b759a4
+ print "crc32 =", hex(crc32(data))
+ raise Error("crc32")
+
+
+# DOC TEST
+
+import doctest
+doctest.testmod(converter)
+doctest.testmod(crc)
+doctest.testmod(exception)
+doctest.testmod(format)
+
+
+# UNIT TEST
+
+import unittest
+
+class TestDataFunctions(unittest.TestCase):
+
+ def setUp(self):
+ self.data = Data('0x41424344',16)
+ self.assertEqual(self.data.base2,"1000001010000100100001101000100")
+ self.assertEqual(self.data.base10,1094861636)
+ self.assertEqual(self.data.base16,"0x41424344")
+ self.assertEqual(self.data.data,"ABCD")
+
+ def tearDown(self):
+ pass
+
+ def test_get_bin(self):
+ self.assertEqual(self.data.get_bin(32),"01000001010000100100001101000100")
+
+ def test_get_int(self):
+ i=0x41424344
+ self.assertEqual(self.data.get_int(),1094861636)
+ self.assertEqual(self.data.get_int(),i)
+
+ def test_get_hex(self):
+ self.assertEqual(self.data.get_hex(4),"41424344")
+ self.assertEqual(self.data.get_hex(),"41424344")
+
+ def test_get_str(self):
+ self.assertEqual(self.data.get_str(),"ABCD")
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestDataFunctions)
+
+try:
+ suite.addTest(doctest.DocTestSuite(converter))
+ suite.addTest(doctest.DocTestSuite(crc))
+ suite.addTest(doctest.DocTestSuite(exception))
+ suite.addTest(doctest.DocTestSuite(format))
+except ValueError:
+ print "has no tests"
+
+if __name__ == '__main__':
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)