diff --git a/bindings/python/ns3_module_common.py b/bindings/python/ns3_module_common.py index 849f53104..e4d4aff67 100644 --- a/bindings/python/ns3_module_common.py +++ b/bindings/python/ns3_module_common.py @@ -13,6 +13,14 @@ def register_types(module): module.add_class('DataRate') ## packet.h: ns3::Packet [class] module.add_class('Packet', memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) + ## packet-metadata.h: ns3::PacketMetadata [class] + module.add_class('PacketMetadata') + ## packet-metadata.h: ns3::PacketMetadata::Item [struct] + module.add_class('Item', outer_class=root_module['ns3::PacketMetadata']) + ## packet-metadata.h: ns3::PacketMetadata::Item [enumeration] + module.add_enum('', ['PAYLOAD', 'HEADER', 'TRAILER'], outer_class=root_module['ns3::PacketMetadata::Item']) + ## packet-metadata.h: ns3::PacketMetadata::ItemIterator [class] + module.add_class('ItemIterator', outer_class=root_module['ns3::PacketMetadata']) ## tag.h: ns3::Tag [class] module.add_class('Tag', parent=root_module['ns3::ObjectBase']) ## tag-buffer.h: ns3::TagBuffer [class] @@ -91,6 +99,9 @@ def register_methods(root_module): register_Ns3BufferIterator_methods(root_module, root_module['ns3::Buffer::Iterator']) register_Ns3DataRate_methods(root_module, root_module['ns3::DataRate']) register_Ns3Packet_methods(root_module, root_module['ns3::Packet']) + register_Ns3PacketMetadata_methods(root_module, root_module['ns3::PacketMetadata']) + register_Ns3PacketMetadataItem_methods(root_module, root_module['ns3::PacketMetadata::Item']) + register_Ns3PacketMetadataItemIterator_methods(root_module, root_module['ns3::PacketMetadata::ItemIterator']) register_Ns3Tag_methods(root_module, root_module['ns3::Tag']) register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer']) register_Ns3TagIterator_methods(root_module, root_module['ns3::TagIterator']) @@ -394,6 +405,11 @@ def register_Ns3Packet_methods(root_module, cls): 'ns3::Ptr< ns3::Packet >', [], is_const=True) + ## packet.h: uint32_t ns3::Packet::CopyData(uint8_t * buffer, uint32_t size) const [member function] + cls.add_method('CopyData', + 'uint32_t', + [param('uint8_t *', 'buffer'), param('uint32_t', 'size')], + is_const=True) ## packet.h: ns3::Ptr ns3::Packet::CreateFragment(uint32_t start, uint32_t length) const [member function] cls.add_method('CreateFragment', 'ns3::Ptr< ns3::Packet >', @@ -489,6 +505,119 @@ def register_Ns3Packet_methods(root_module, cls): is_const=True) return +def register_Ns3PacketMetadata_methods(root_module, cls): + ## packet-metadata.h: static void ns3::PacketMetadata::Enable() [member function] + cls.add_method('Enable', + 'void', + [], + is_static=True) + ## packet-metadata.h: static void ns3::PacketMetadata::EnableChecking() [member function] + cls.add_method('EnableChecking', + 'void', + [], + is_static=True) + ## packet-metadata.h: ns3::PacketMetadata::PacketMetadata(uint32_t uid, uint32_t size) [constructor] + cls.add_constructor([param('uint32_t', 'uid'), param('uint32_t', 'size')]) + ## packet-metadata.h: ns3::PacketMetadata::PacketMetadata(ns3::PacketMetadata const & o) [copy constructor] + cls.add_constructor([param('ns3::PacketMetadata const &', 'o')]) + ## packet-metadata.h: void ns3::PacketMetadata::AddHeader(ns3::Header const & header, uint32_t size) [member function] + cls.add_method('AddHeader', + 'void', + [param('ns3::Header const &', 'header'), param('uint32_t', 'size')]) + ## packet-metadata.h: void ns3::PacketMetadata::RemoveHeader(ns3::Header const & header, uint32_t size) [member function] + cls.add_method('RemoveHeader', + 'void', + [param('ns3::Header const &', 'header'), param('uint32_t', 'size')]) + ## packet-metadata.h: void ns3::PacketMetadata::AddTrailer(ns3::Trailer const & trailer, uint32_t size) [member function] + cls.add_method('AddTrailer', + 'void', + [param('ns3::Trailer const &', 'trailer'), param('uint32_t', 'size')]) + ## packet-metadata.h: void ns3::PacketMetadata::RemoveTrailer(ns3::Trailer const & trailer, uint32_t size) [member function] + cls.add_method('RemoveTrailer', + 'void', + [param('ns3::Trailer const &', 'trailer'), param('uint32_t', 'size')]) + ## packet-metadata.h: ns3::PacketMetadata ns3::PacketMetadata::CreateFragment(uint32_t start, uint32_t end) const [member function] + cls.add_method('CreateFragment', + 'ns3::PacketMetadata', + [param('uint32_t', 'start'), param('uint32_t', 'end')], + is_const=True) + ## packet-metadata.h: void ns3::PacketMetadata::AddAtEnd(ns3::PacketMetadata const & o) [member function] + cls.add_method('AddAtEnd', + 'void', + [param('ns3::PacketMetadata const &', 'o')]) + ## packet-metadata.h: void ns3::PacketMetadata::AddPaddingAtEnd(uint32_t end) [member function] + cls.add_method('AddPaddingAtEnd', + 'void', + [param('uint32_t', 'end')]) + ## packet-metadata.h: void ns3::PacketMetadata::RemoveAtStart(uint32_t start) [member function] + cls.add_method('RemoveAtStart', + 'void', + [param('uint32_t', 'start')]) + ## packet-metadata.h: void ns3::PacketMetadata::RemoveAtEnd(uint32_t end) [member function] + cls.add_method('RemoveAtEnd', + 'void', + [param('uint32_t', 'end')]) + ## packet-metadata.h: uint32_t ns3::PacketMetadata::GetUid() const [member function] + cls.add_method('GetUid', + 'uint32_t', + [], + is_const=True) + ## packet-metadata.h: uint32_t ns3::PacketMetadata::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True) + ## packet-metadata.h: void ns3::PacketMetadata::Serialize(ns3::Buffer::Iterator i, uint32_t size) const [member function] + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'i'), param('uint32_t', 'size')], + is_const=True) + ## packet-metadata.h: uint32_t ns3::PacketMetadata::Deserialize(ns3::Buffer::Iterator i) [member function] + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'i')]) + ## packet-metadata.h: ns3::PacketMetadata::ItemIterator ns3::PacketMetadata::BeginItem(ns3::Buffer buffer) const [member function] + cls.add_method('BeginItem', + 'ns3::PacketMetadata::ItemIterator', + [param('ns3::Buffer', 'buffer')], + is_const=True) + return + +def register_Ns3PacketMetadataItem_methods(root_module, cls): + ## packet-metadata.h: ns3::PacketMetadata::Item::isFragment [variable] + cls.add_instance_attribute('isFragment', 'bool', is_const=False) + ## packet-metadata.h: ns3::PacketMetadata::Item::tid [variable] + cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False) + ## packet-metadata.h: ns3::PacketMetadata::Item::currentSize [variable] + cls.add_instance_attribute('currentSize', 'uint32_t', is_const=False) + ## packet-metadata.h: ns3::PacketMetadata::Item::currentTrimedFromStart [variable] + cls.add_instance_attribute('currentTrimedFromStart', 'uint32_t', is_const=False) + ## packet-metadata.h: ns3::PacketMetadata::Item::currentTrimedFromEnd [variable] + cls.add_instance_attribute('currentTrimedFromEnd', 'uint32_t', is_const=False) + ## packet-metadata.h: ns3::PacketMetadata::Item::current [variable] + cls.add_instance_attribute('current', 'ns3::Buffer::Iterator', is_const=False) + ## packet-metadata.h: ns3::PacketMetadata::Item::Item(ns3::PacketMetadata::Item const & arg0) [copy constructor] + cls.add_constructor([param('ns3::PacketMetadata::Item const &', 'arg0')]) + ## packet-metadata.h: ns3::PacketMetadata::Item::Item() [constructor] + cls.add_constructor([]) + return + +def register_Ns3PacketMetadataItemIterator_methods(root_module, cls): + ## packet-metadata.h: ns3::PacketMetadata::ItemIterator::ItemIterator(ns3::PacketMetadata::ItemIterator const & arg0) [copy constructor] + cls.add_constructor([param('ns3::PacketMetadata::ItemIterator const &', 'arg0')]) + ## packet-metadata.h: ns3::PacketMetadata::ItemIterator::ItemIterator(ns3::PacketMetadata const * metadata, ns3::Buffer buffer) [constructor] + cls.add_constructor([param('ns3::PacketMetadata const *', 'metadata'), param('ns3::Buffer', 'buffer')]) + ## packet-metadata.h: bool ns3::PacketMetadata::ItemIterator::HasNext() const [member function] + cls.add_method('HasNext', + 'bool', + [], + is_const=True) + ## packet-metadata.h: ns3::PacketMetadata::Item ns3::PacketMetadata::ItemIterator::Next() [member function] + cls.add_method('Next', + 'ns3::PacketMetadata::Item', + []) + return + def register_Ns3Tag_methods(root_module, cls): ## tag.h: ns3::Tag::Tag(ns3::Tag const & arg0) [copy constructor] cls.add_constructor([param('ns3::Tag const &', 'arg0')]) diff --git a/bindings/python/ns3_module_core.py b/bindings/python/ns3_module_core.py index 593f07a92..e8b412dff 100644 --- a/bindings/python/ns3_module_core.py +++ b/bindings/python/ns3_module_core.py @@ -91,6 +91,10 @@ def register_types(module): module.add_class('BooleanChecker', parent=root_module['ns3::AttributeChecker']) ## boolean.h: ns3::BooleanValue [class] module.add_class('BooleanValue', parent=root_module['ns3::AttributeValue']) + ## callback.h: ns3::CallbackChecker [class] + module.add_class('CallbackChecker', parent=root_module['ns3::AttributeChecker']) + ## callback.h: ns3::CallbackValue [class] + module.add_class('CallbackValue', parent=root_module['ns3::AttributeValue']) ## random-variable.h: ns3::ConstantVariable [class] module.add_class('ConstantVariable', parent=root_module['ns3::RandomVariable']) ## random-variable.h: ns3::DeterministicVariable [class] @@ -236,6 +240,8 @@ def register_methods(root_module): register_Ns3AttributeValue_methods(root_module, root_module['ns3::AttributeValue']) register_Ns3BooleanChecker_methods(root_module, root_module['ns3::BooleanChecker']) register_Ns3BooleanValue_methods(root_module, root_module['ns3::BooleanValue']) + register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker']) + register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue']) register_Ns3ConstantVariable_methods(root_module, root_module['ns3::ConstantVariable']) register_Ns3DeterministicVariable_methods(root_module, root_module['ns3::DeterministicVariable']) register_Ns3DoubleValue_methods(root_module, root_module['ns3::DoubleValue']) @@ -945,11 +951,6 @@ def register_Ns3TypeId_methods(root_module, cls): 'ns3::TypeId', [param('std::string', 'name')], is_static=True) - ## type-id.h: static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function] - cls.add_method('LookupByNameFailSafe', - 'bool', - [param('std::string', 'name'), param('ns3::TypeId *', 'tid', transfer_ownership=False)], - is_static=True) ## type-id.h: ns3::Ptr ns3::TypeId::LookupTraceSourceByName(std::string name) const [member function] cls.add_method('LookupTraceSourceByName', 'ns3::Ptr< ns3::TraceSourceAccessor const >', @@ -1155,6 +1156,41 @@ def register_Ns3BooleanValue_methods(root_module, cls): [param('bool', 'value')]) return +def register_Ns3CallbackChecker_methods(root_module, cls): + ## callback.h: ns3::CallbackChecker::CallbackChecker(ns3::CallbackChecker const & arg0) [copy constructor] + cls.add_constructor([param('ns3::CallbackChecker const &', 'arg0')]) + ## callback.h: ns3::CallbackChecker::CallbackChecker() [constructor] + cls.add_constructor([]) + return + +def register_Ns3CallbackValue_methods(root_module, cls): + ## callback.h: ns3::CallbackValue::CallbackValue(ns3::CallbackValue const & arg0) [copy constructor] + cls.add_constructor([param('ns3::CallbackValue const &', 'arg0')]) + ## callback.h: ns3::CallbackValue::CallbackValue() [constructor] + cls.add_constructor([]) + ## callback.h: ns3::CallbackValue::CallbackValue(ns3::CallbackBase const & base) [constructor] + cls.add_constructor([param('ns3::CallbackBase const &', 'base')]) + ## callback.h: void ns3::CallbackValue::Set(ns3::CallbackBase base) [member function] + cls.add_method('Set', + 'void', + [param('ns3::CallbackBase', 'base')]) + ## callback.h: ns3::Ptr ns3::CallbackValue::Copy() const [member function] + cls.add_method('Copy', + 'ns3::Ptr< ns3::AttributeValue >', + [], + is_const=True, is_virtual=True) + ## callback.h: std::string ns3::CallbackValue::SerializeToString(ns3::Ptr checker) const [member function] + cls.add_method('SerializeToString', + 'std::string', + [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_const=True, is_virtual=True) + ## callback.h: bool ns3::CallbackValue::DeserializeFromString(std::string value, ns3::Ptr checker) [member function] + cls.add_method('DeserializeFromString', + 'bool', + [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')], + is_virtual=True) + return + def register_Ns3ConstantVariable_methods(root_module, cls): ## random-variable.h: ns3::ConstantVariable::ConstantVariable(ns3::ConstantVariable const & arg0) [copy constructor] cls.add_constructor([param('ns3::ConstantVariable const &', 'arg0')]) @@ -1831,7 +1867,7 @@ def register_Ns3TracedValue__Unsigned_int_methods(root_module, cls): cls.add_method('ConnectWithoutContext', 'void', [param('ns3::CallbackBase const &', 'cb')]) - ## traced-value.h: void ns3::TracedValue::Connect(ns3::CallbackBase const & cb, std::string path) [member function] + ## traced-value.h: void ns3::TracedValue::Connect(ns3::CallbackBase const & cb, std::basic_string,std::allocator > path) [member function] cls.add_method('Connect', 'void', [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')]) @@ -1839,7 +1875,7 @@ def register_Ns3TracedValue__Unsigned_int_methods(root_module, cls): cls.add_method('DisconnectWithoutContext', 'void', [param('ns3::CallbackBase const &', 'cb')]) - ## traced-value.h: void ns3::TracedValue::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function] + ## traced-value.h: void ns3::TracedValue::Disconnect(ns3::CallbackBase const & cb, std::basic_string,std::allocator > path) [member function] cls.add_method('Disconnect', 'void', [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')]) @@ -1874,7 +1910,7 @@ def register_functions(root_module): module.add_function('TypeNameGet', 'std::string', [], - template_parameters=['long long']) + template_parameters=['long']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] module.add_function('TypeNameGet', 'std::string', @@ -1894,7 +1930,7 @@ def register_functions(root_module): module.add_function('TypeNameGet', 'std::string', [], - template_parameters=['unsigned long long']) + template_parameters=['unsigned long']) ## type-name.h: extern std::string ns3::TypeNameGet() [free function] module.add_function('TypeNameGet', 'std::string', @@ -1910,14 +1946,22 @@ def register_functions(root_module): 'std::string', [], template_parameters=['unsigned char']) - ## log.h: extern void ns3::LogComponentDisable(char const * name, ns3::LogLevel level) [free function] - module.add_function('LogComponentDisable', - 'void', - [param('char const *', 'name'), param('ns3::LogLevel', 'level')]) ## string.h: extern ns3::Ptr ns3::MakeStringChecker() [free function] module.add_function('MakeStringChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## enum.h: extern ns3::Ptr ns3::MakeEnumChecker(int v1, std::string n1, int v2=0, std::string n2="", int v3=0, std::string n3="", int v4=0, std::string n4="", int v5=0, std::string n5="", int v6=0, std::string n6="", int v7=0, std::string n7="", int v8=0, std::string n8="", int v9=0, std::string n9="", int v10=0, std::string n10="", int v11=0, std::string n11="", int v12=0, std::string n12="") [free function] + module.add_function('MakeEnumChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + [param('int', 'v1'), param('std::string', 'n1'), param('int', 'v2', default_value='0'), param('std::string', 'n2', default_value='""'), param('int', 'v3', default_value='0'), param('std::string', 'n3', default_value='""'), param('int', 'v4', default_value='0'), param('std::string', 'n4', default_value='""'), param('int', 'v5', default_value='0'), param('std::string', 'n5', default_value='""'), param('int', 'v6', default_value='0'), param('std::string', 'n6', default_value='""'), param('int', 'v7', default_value='0'), param('std::string', 'n7', default_value='""'), param('int', 'v8', default_value='0'), param('std::string', 'n8', default_value='""'), param('int', 'v9', default_value='0'), param('std::string', 'n9', default_value='""'), param('int', 'v10', default_value='0'), param('std::string', 'n10', default_value='""'), param('int', 'v11', default_value='0'), param('std::string', 'n11', default_value='""'), param('int', 'v12', default_value='0'), param('std::string', 'n12', default_value='""')]) + ## log.h: extern void ns3::LogComponentEnableAll(ns3::LogLevel level) [free function] + module.add_function('LogComponentEnableAll', + 'void', + [param('ns3::LogLevel', 'level')]) + ## type-id.h: extern ns3::Ptr ns3::MakeTypeIdChecker() [free function] + module.add_function('MakeTypeIdChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## ptr.h: extern ns3::Ptr ns3::Create() [free function] module.add_function('Create', 'ns3::Ptr< ns3::PointerValue >', @@ -1928,14 +1972,6 @@ def register_functions(root_module): 'ns3::Ptr< ns3::ObjectVectorValue >', [], template_parameters=['ns3::ObjectVectorValue']) - ## log.h: extern void ns3::LogComponentEnableAll(ns3::LogLevel level) [free function] - module.add_function('LogComponentEnableAll', - 'void', - [param('ns3::LogLevel', 'level')]) - ## type-id.h: extern ns3::Ptr ns3::MakeTypeIdChecker() [free function] - module.add_function('MakeTypeIdChecker', - 'ns3::Ptr< ns3::AttributeChecker const >', - []) ## object-factory.h: extern ns3::Ptr ns3::MakeObjectFactoryChecker() [free function] module.add_function('MakeObjectFactoryChecker', 'ns3::Ptr< ns3::AttributeChecker const >', @@ -1944,6 +1980,10 @@ def register_functions(root_module): module.add_function('LogComponentDisableAll', 'void', [param('ns3::LogLevel', 'level')]) + ## callback.h: extern ns3::Ptr ns3::MakeCallbackChecker() [free function] + module.add_function('MakeCallbackChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## breakpoint.h: extern void ns3::BreakpointFallback() [free function] module.add_function('BreakpointFallback', 'void', @@ -1952,14 +1992,14 @@ def register_functions(root_module): module.add_function('MakeRandomVariableChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) + ## log.h: extern void ns3::LogComponentDisable(char const * name, ns3::LogLevel level) [free function] + module.add_function('LogComponentDisable', + 'void', + [param('char const *', 'name'), param('ns3::LogLevel', 'level')]) ## log.h: extern void ns3::LogComponentEnable(char const * name, ns3::LogLevel level) [free function] module.add_function('LogComponentEnable', 'void', [param('char const *', 'name'), param('ns3::LogLevel', 'level')]) - ## enum.h: extern ns3::Ptr ns3::MakeEnumChecker(int v1, std::string n1, int v2=0, std::string n2="", int v3=0, std::string n3="", int v4=0, std::string n4="", int v5=0, std::string n5="", int v6=0, std::string n6="", int v7=0, std::string n7="", int v8=0, std::string n8="", int v9=0, std::string n9="", int v10=0, std::string n10="", int v11=0, std::string n11="", int v12=0, std::string n12="") [free function] - module.add_function('MakeEnumChecker', - 'ns3::Ptr< ns3::AttributeChecker const >', - [param('int', 'v1'), param('std::string', 'n1'), param('int', 'v2', default_value='0'), param('std::string', 'n2', default_value='""'), param('int', 'v3', default_value='0'), param('std::string', 'n3', default_value='""'), param('int', 'v4', default_value='0'), param('std::string', 'n4', default_value='""'), param('int', 'v5', default_value='0'), param('std::string', 'n5', default_value='""'), param('int', 'v6', default_value='0'), param('std::string', 'n6', default_value='""'), param('int', 'v7', default_value='0'), param('std::string', 'n7', default_value='""'), param('int', 'v8', default_value='0'), param('std::string', 'n8', default_value='""'), param('int', 'v9', default_value='0'), param('std::string', 'n9', default_value='""'), param('int', 'v10', default_value='0'), param('std::string', 'n10', default_value='""'), param('int', 'v11', default_value='0'), param('std::string', 'n11', default_value='""'), param('int', 'v12', default_value='0'), param('std::string', 'n12', default_value='""')]) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) @@ -2017,10 +2057,6 @@ def register_functions_ns3_Config(module, root_module): module.add_function('SetGlobalFailSafe', 'bool', [param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')]) - ## config.h: extern void ns3::Config::Disconnect(std::string path, ns3::CallbackBase const & cb) [free function] - module.add_function('Disconnect', - 'void', - [param('std::string', 'path'), param('ns3::CallbackBase const &', 'cb')]) ## config.h: extern uint32_t ns3::Config::GetRootNamespaceObjectN() [free function] module.add_function('GetRootNamespaceObjectN', 'uint32_t', @@ -2037,6 +2073,10 @@ def register_functions_ns3_Config(module, root_module): module.add_function('RegisterRootNamespaceObject', 'void', [param('ns3::Ptr< ns3::Object >', 'obj')]) + ## config.h: extern void ns3::Config::Disconnect(std::string path, ns3::CallbackBase const & cb) [free function] + module.add_function('Disconnect', + 'void', + [param('std::string', 'path'), param('ns3::CallbackBase const &', 'cb')]) return def register_functions_ns3_olsr(module, root_module): diff --git a/bindings/python/ns3_module_mobility.py b/bindings/python/ns3_module_mobility.py index 6b44567f4..0b3cbb75e 100644 --- a/bindings/python/ns3_module_mobility.py +++ b/bindings/python/ns3_module_mobility.py @@ -150,21 +150,12 @@ def register_Ns3StaticSpeedHelper_methods(root_module, cls): cls.add_constructor([]) ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position) [constructor] cls.add_constructor([param('ns3::Vector const &', 'position')]) - ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position, ns3::Vector const & speed) [constructor] - cls.add_constructor([param('ns3::Vector const &', 'position'), param('ns3::Vector const &', 'speed')]) - ## static-speed-helper.h: void ns3::StaticSpeedHelper::InitializePosition(ns3::Vector const & position) [member function] - cls.add_method('InitializePosition', + ## static-speed-helper.h: ns3::StaticSpeedHelper::StaticSpeedHelper(ns3::Vector const & position, ns3::Vector const & vel) [constructor] + cls.add_constructor([param('ns3::Vector const &', 'position'), param('ns3::Vector const &', 'vel')]) + ## static-speed-helper.h: void ns3::StaticSpeedHelper::SetPosition(ns3::Vector const & position) [member function] + cls.add_method('SetPosition', 'void', [param('ns3::Vector const &', 'position')]) - ## static-speed-helper.h: void ns3::StaticSpeedHelper::Reset(ns3::Vector const & speed) [member function] - cls.add_method('Reset', - 'void', - [param('ns3::Vector const &', 'speed')]) - ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition(ns3::Rectangle const & bounds) const [member function] - cls.add_method('GetCurrentPosition', - 'ns3::Vector', - [param('ns3::Rectangle const &', 'bounds')], - is_const=True) ## static-speed-helper.h: ns3::Vector ns3::StaticSpeedHelper::GetCurrentPosition() const [member function] cls.add_method('GetCurrentPosition', 'ns3::Vector', @@ -175,10 +166,10 @@ def register_Ns3StaticSpeedHelper_methods(root_module, cls): 'ns3::Vector', [], is_const=True) - ## static-speed-helper.h: void ns3::StaticSpeedHelper::SetSpeed(ns3::Vector const & speed) [member function] - cls.add_method('SetSpeed', + ## static-speed-helper.h: void ns3::StaticSpeedHelper::SetVelocity(ns3::Vector const & vel) [member function] + cls.add_method('SetVelocity', 'void', - [param('ns3::Vector const &', 'speed')]) + [param('ns3::Vector const &', 'vel')]) ## static-speed-helper.h: void ns3::StaticSpeedHelper::Pause() [member function] cls.add_method('Pause', 'void', @@ -187,6 +178,16 @@ def register_Ns3StaticSpeedHelper_methods(root_module, cls): cls.add_method('Unpause', 'void', []) + ## static-speed-helper.h: void ns3::StaticSpeedHelper::UpdateWithBounds(ns3::Rectangle const & rectangle) const [member function] + cls.add_method('UpdateWithBounds', + 'void', + [param('ns3::Rectangle const &', 'rectangle')], + is_const=True) + ## static-speed-helper.h: void ns3::StaticSpeedHelper::Update() const [member function] + cls.add_method('Update', + 'void', + [], + is_const=True) return def register_Ns3Vector_methods(root_module, cls): @@ -631,8 +632,8 @@ def register_Ns3StaticSpeedMobilityModel_methods(root_module, cls): is_static=True) ## static-speed-mobility-model.h: ns3::StaticSpeedMobilityModel::StaticSpeedMobilityModel() [constructor] cls.add_constructor([]) - ## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::SetSpeed(ns3::Vector const & speed) [member function] - cls.add_method('SetSpeed', + ## static-speed-mobility-model.h: void ns3::StaticSpeedMobilityModel::SetVelocity(ns3::Vector const & speed) [member function] + cls.add_method('SetVelocity', 'void', [param('ns3::Vector const &', 'speed')]) ## static-speed-mobility-model.h: ns3::Vector ns3::StaticSpeedMobilityModel::DoGetPosition() const [member function] diff --git a/bindings/python/ns3_module_node.py b/bindings/python/ns3_module_node.py index b73ac1333..ca8fb12b0 100644 --- a/bindings/python/ns3_module_node.py +++ b/bindings/python/ns3_module_node.py @@ -1251,9 +1251,9 @@ def register_Ns3Socket_methods(root_module, cls): cls.add_method('SetAcceptCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::Socket >, ns3::Address const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'connectionRequest'), param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, ns3::Address const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'newConnectionCreated')]) - ## socket.h: bool ns3::Socket::SetDataSentCallback(ns3::Callback, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> dataSent) [member function] + ## socket.h: void ns3::Socket::SetDataSentCallback(ns3::Callback, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> dataSent) [member function] cls.add_method('SetDataSentCallback', - 'bool', + 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::Socket >, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'dataSent')]) ## socket.h: void ns3::Socket::SetSendCallback(ns3::Callback, unsigned int, ns3::empty, ns3::empty, ns3::empty, ns3::empty> sendCb) [member function] cls.add_method('SetSendCallback', @@ -1293,10 +1293,10 @@ def register_Ns3Socket_methods(root_module, cls): 'int', [param('ns3::Address const &', 'address')], is_pure_virtual=True, is_virtual=True) - ## socket.h: int ns3::Socket::Listen(uint32_t queueLimit) [member function] + ## socket.h: int ns3::Socket::Listen() [member function] cls.add_method('Listen', 'int', - [param('uint32_t', 'queueLimit')], + [], is_pure_virtual=True, is_virtual=True) ## socket.h: uint32_t ns3::Socket::GetTxAvailable() const [member function] cls.add_method('GetTxAvailable', @@ -1356,6 +1356,11 @@ def register_Ns3Socket_methods(root_module, cls): cls.add_method('RecvFrom', 'int', [param('uint8_t *', 'buf'), param('uint32_t', 'size'), param('uint32_t', 'flags'), param('ns3::Address &', 'fromAddress')]) + ## socket.h: int ns3::Socket::GetSockName(ns3::Address & address) const [member function] + cls.add_method('GetSockName', + 'int', + [param('ns3::Address &', 'address')], + is_pure_virtual=True, is_const=True, is_virtual=True) ## socket.h: void ns3::Socket::NotifyConnectionSucceeded() [member function] cls.add_method('NotifyConnectionSucceeded', 'void', @@ -2581,18 +2586,10 @@ def register_Ns3SimpleNetDevice_methods(root_module, cls): def register_functions(root_module): module = root_module - ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Mac48Address & ad) [free function] - module.add_function('ReadFrom', - 'void', - [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Mac48Address &', 'ad')]) - ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Address & ad, uint32_t len) [free function] - module.add_function('ReadFrom', - 'void', - [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Address &', 'ad'), param('uint32_t', 'len')]) - ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Ipv4Address & ad) [free function] - module.add_function('ReadFrom', - 'void', - [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Ipv4Address &', 'ad')]) + ## mac48-address.h: extern ns3::Ptr ns3::MakeMac48AddressChecker() [free function] + module.add_function('MakeMac48AddressChecker', + 'ns3::Ptr< ns3::AttributeChecker const >', + []) ## ipv4-address.h: extern ns3::Ptr ns3::MakeIpv4AddressChecker() [free function] module.add_function('MakeIpv4AddressChecker', 'ns3::Ptr< ns3::AttributeChecker const >', @@ -2617,10 +2614,18 @@ def register_functions(root_module): module.add_function('MakeIpv4MaskChecker', 'ns3::Ptr< ns3::AttributeChecker const >', []) - ## mac48-address.h: extern ns3::Ptr ns3::MakeMac48AddressChecker() [free function] - module.add_function('MakeMac48AddressChecker', - 'ns3::Ptr< ns3::AttributeChecker const >', - []) + ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Mac48Address & ad) [free function] + module.add_function('ReadFrom', + 'void', + [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Mac48Address &', 'ad')]) + ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Address & ad, uint32_t len) [free function] + module.add_function('ReadFrom', + 'void', + [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Address &', 'ad'), param('uint32_t', 'len')]) + ## address-utils.h: extern void ns3::ReadFrom(ns3::Buffer::Iterator & i, ns3::Ipv4Address & ad) [free function] + module.add_function('ReadFrom', + 'void', + [param('ns3::Buffer::Iterator &', 'i'), param('ns3::Ipv4Address &', 'ad')]) register_functions_ns3_internal(module.get_submodule('internal'), root_module) register_functions_ns3_TimeStepPrecision(module.get_submodule('TimeStepPrecision'), root_module) register_functions_ns3_Config(module.get_submodule('Config'), root_module) diff --git a/bindings/python/ns3_module_wifi.py b/bindings/python/ns3_module_wifi.py index 7efe34ca3..b3c028a8d 100644 --- a/bindings/python/ns3_module_wifi.py +++ b/bindings/python/ns3_module_wifi.py @@ -507,16 +507,16 @@ def register_Ns3WifiRemoteStation_methods(root_module, cls): 'bool', [param('ns3::Ptr< ns3::Packet const >', 'packet')], is_virtual=True) - ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetNFragments(ns3::Ptr packet) [member function] - cls.add_method('GetNFragments', - 'uint32_t', - [param('ns3::Ptr< ns3::Packet const >', 'packet')], - is_virtual=True) ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentSize(ns3::Ptr packet, uint32_t fragmentNumber) [member function] cls.add_method('GetFragmentSize', 'uint32_t', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint32_t', 'fragmentNumber')], is_virtual=True) + ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetFragmentOffset(ns3::Ptr packet, uint32_t fragmentNumber) [member function] + cls.add_method('GetFragmentOffset', + 'uint32_t', + [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint32_t', 'fragmentNumber')], + is_virtual=True) ## wifi-remote-station-manager.h: bool ns3::WifiRemoteStation::IsLastFragment(ns3::Ptr packet, uint32_t fragmentNumber) [member function] cls.add_method('IsLastFragment', 'bool', diff --git a/bindings/python/ns3module_helpers.cc b/bindings/python/ns3module_helpers.cc index cb2fab4a9..03dc52445 100644 --- a/bindings/python/ns3module_helpers.cc +++ b/bindings/python/ns3module_helpers.cc @@ -188,3 +188,35 @@ error: return NULL; } + +PyObject * +_wrap_TypeId_LookupByNameFailSafe(PyNs3TypeId *PYBINDGEN_UNUSED(dummy), PyObject *args, PyObject *kwargs, + PyObject **return_exception) +{ + bool ok; + const char *name; + Py_ssize_t name_len; + ns3::TypeId tid; + PyNs3TypeId *py_tid; + const char *keywords[] = {"name", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *) "s#", (char **) keywords, &name, &name_len)) { + PyObject *exc_type, *traceback; + PyErr_Fetch(&exc_type, return_exception, &traceback); + Py_XDECREF(exc_type); + Py_XDECREF(traceback); + return NULL; + } + ok = ns3::TypeId::LookupByNameFailSafe(std::string(name, name_len), &tid); + if (!ok) + { + PyErr_Format(PyExc_KeyError, "The ns3 type with name `%s' is not registered", name); + return NULL; + } + + py_tid = PyObject_New(PyNs3TypeId, &PyNs3TypeId_Type); + py_tid->obj = new ns3::TypeId (tid); + PyNs3TypeId_wrapper_registry[(void *) py_tid->obj] = (PyObject *) py_tid; + + return (PyObject *) py_tid; +} diff --git a/bindings/python/ns3modulegen.py b/bindings/python/ns3modulegen.py index 1aa9c8c16..7cd34e182 100755 --- a/bindings/python/ns3modulegen.py +++ b/bindings/python/ns3modulegen.py @@ -85,6 +85,7 @@ def main(): ns3modulegen_core_customizations.Simulator_customizations(root_module) ns3modulegen_core_customizations.CommandLine_customizations(root_module) + ns3modulegen_core_customizations.TypeId_customizations(root_module) for local_module in LOCAL_MODULES: diff --git a/bindings/python/ns3modulegen_core_customizations.py b/bindings/python/ns3modulegen_core_customizations.py index 2766eb07c..abbf5ba80 100644 --- a/bindings/python/ns3modulegen_core_customizations.py +++ b/bindings/python/ns3modulegen_core_customizations.py @@ -424,6 +424,7 @@ static int %(WRAPPER_NAME)s (%(PYSTRUCT)s *self, PyObject *args, PyObject *kwarg return -1; } %(CONSTRUCT_CODE)s + PyNs3ObjectBase_wrapper_registry[(void *) self->obj] = (PyObject *) self; return 0; } ''' % dict(WRAPPER_NAME=wrapper_name, PYSTRUCT=cls.pystruct, CLASS_NAME=cls.full_name, @@ -517,3 +518,10 @@ def Attribute_customizations(module): and param.default_value_type is None: param.default_value_type = 'ns3::EmptyAttributeValue' + +def TypeId_customizations(module): + TypeId = module['ns3::TypeId'] + TypeId.add_custom_method_wrapper("LookupByNameFailSafe", "_wrap_TypeId_LookupByNameFailSafe", + flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"]) + + diff --git a/bindings/python/ns3modulescan.py b/bindings/python/ns3modulescan.py index 942f77496..4b0684879 100644 --- a/bindings/python/ns3modulescan.py +++ b/bindings/python/ns3modulescan.py @@ -48,9 +48,6 @@ type_annotations = { 'decref_method': 'Unref', 'peekref_method': 'GetReferenceCount', }, - '::ns3::PacketMetadata': { - 'ignore': None, - }, '::ns3::AttributeChecker': { 'automatic_type_narrowing': 'true', 'allow_subclassing': 'false', @@ -73,7 +70,7 @@ type_annotations = { 'params': {'info':{'transfer_ownership': 'false'}} }, 'static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function]': { - 'params': {'tid': {'transfer_ownership': 'false'}} + 'ignore': None, # manually wrapped in }, 'bool ns3::TraceSourceAccessor::ConnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': { 'params': {'obj': {'transfer_ownership':'false'}} diff --git a/bindings/python/wscript b/bindings/python/wscript index 9989afe00..4efa378e8 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -22,7 +22,7 @@ else: os.environ['PYTHONPATH'] = LOCAL_PYBINDGEN_PATH ## https://launchpad.net/pybindgen/ -REQUIRED_PYBINDGEN_VERSION = (0, 9, 0, 598) +REQUIRED_PYBINDGEN_VERSION = (0, 9, 0, 600) REQUIRED_PYGCCXML_VERSION = (0, 9, 5) diff --git a/doc/tutorial/building-topologies.texi b/doc/tutorial/building-topologies.texi index 3d632dfd7..90db50d6c 100644 --- a/doc/tutorial/building-topologies.texi +++ b/doc/tutorial/building-topologies.texi @@ -63,7 +63,7 @@ off of the right side. Notice that this is the default network topology since you can actually vary the number of nodes created on the LAN. If you set nCsma to one, there will be a total of two nodes on the LAN (CSMA channel) --- one required node and one ``extra'' node. By default there are -thee ``extra'' nodes as seen below: +three ``extra'' nodes as seen below: @verbatim // Default Network Topology @@ -589,7 +589,7 @@ number of nodes created on the wired and wireless networks. Just as in the number of ``extra'' CSMA nodes. Similarly, you can set @code{nWifi} to control how many @code{STA} (station) nodes are created in the simulation. There will always be one @code{AP} (access point) node on the wireless -network. By default there are thee ``extra'' CSMA nodes and three wireless +network. By default there are three ``extra'' CSMA nodes and three wireless @code{STA} nodes. The code begins by loading module include files just as was done in the diff --git a/doc/tutorial/conceptual-overview.texi b/doc/tutorial/conceptual-overview.texi index 547ba2afe..873eab9b5 100644 --- a/doc/tutorial/conceptual-overview.texi +++ b/doc/tutorial/conceptual-overview.texi @@ -681,7 +681,7 @@ When we previously called the methods, @end verbatim we actually scheduled events in the simulator at 1.0 seconds, 2.0 seconds and -10.0 seconds. When @code{Simulator::Run} is called, the ssytem will begin +10.0 seconds. When @code{Simulator::Run} is called, the system will begin looking through the list of scheduled events and executing them. First it will run the event at 1.0 seconds, which will enable the echo server application. Then it will run the event scheduled for t=2.0 seconds which diff --git a/doc/tutorial/tweaking.texi b/doc/tutorial/tweaking.texi index 9b01449fe..caeac8666 100644 --- a/doc/tutorial/tweaking.texi +++ b/doc/tutorial/tweaking.texi @@ -180,7 +180,7 @@ actually a class name, and there is a single colon there instead of a double colon to remind you in a relatively subtle way to conceptually separate the logging component name from the class name. -It turns out that in come cases, it can be hard to determine which method +It turns out that in some cases, it can be hard to determine which method actually generates a log message. If you look in the text above, you may wonder where the string ``@code{Received 1024 bytes from 10.1.1.2}'' comes from. You can resolve this by ORing the @code{prefix_func} level into the @@ -625,7 +625,7 @@ need to hook the value into the parser. We do this by adding a call to start with the following code, @verbatim - int + int main (int argc, char *argv[]) { uint32_t nPackets = 1; diff --git a/examples/csma-star.cc b/examples/csma-star.cc new file mode 100644 index 000000000..8a1d854d3 --- /dev/null +++ b/examples/csma-star.cc @@ -0,0 +1,201 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" +#include "ns3/global-route-manager.h" + +// Network topology (default) +// +// n2 + + n3 . +// | ... |\ /| ... | . +// ======= \ / ======= . +// CSMA \ / CSMA . +// \ / . +// n1 +--- n0 ---+ n4 . +// | ... | / \ | ... | . +// ======= / \ ======= . +// CSMA / \ CSMA . +// / \ . +// n6 + + n5 . +// | ... | | ... | . +// ======= ======= . +// CSMA CSMA . +// + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("CsmaStar"); + +int +main (int argc, char *argv[]) +{ + // + // Make the random number generators generate reproducible results. + // + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + + // + // Set up some default values for the simulation. + // + Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (137)); + + // ??? try and stick 15kb/s into the data rate + Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("14kb/s")); + + // + // Default number of nodes in the star. Overridable by command line argument. + // + uint32_t nNodes = 7; + + CommandLine cmd; + cmd.AddValue("nNodes", "Number of nodes to place in the star", nNodes); + cmd.Parse (argc, argv); + + NS_LOG_INFO ("Create nodes."); + NodeContainer hubNode; + NodeContainer spokeNodes; + hubNode.Create (1); + Ptr hub = hubNode.Get (0); + spokeNodes.Create (nNodes - 1); + + CsmaHelper csma; + csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps")); + csma.SetChannelAttribute ("Delay", StringValue ("1ms")); + + NS_LOG_INFO ("Build star topology."); + NetDeviceContainer hubDevices, spokeDevices; + csma.InstallStar (hubNode.Get (0), spokeNodes, hubDevices, spokeDevices); + + NodeContainer fillNodes; + + // + // Just to be nasy, hang some more nodes off of the CSMA channel for each + // spoke, so that there are a total of 16 nodes on each channel. Stash + // all of these new devices into a container. + // + NetDeviceContainer fillDevices; + + uint32_t nFill = 14; + for (uint32_t i = 0; i < spokeDevices.GetN (); ++i) + { + Ptr channel = spokeDevices.Get (i)->GetChannel (); + Ptr csmaChannel = channel->GetObject (); + NodeContainer newNodes; + NetDeviceContainer newDevices; + newNodes.Create (nFill); + fillNodes.Add (newNodes); + fillDevices.Add (csma.Install (newNodes, csmaChannel)); + } + + NS_LOG_INFO ("Install internet stack on all nodes."); + InternetStackHelper internet; + internet.Install (NodeContainer (hubNode, spokeNodes, fillNodes)); + + NS_LOG_INFO ("Assign IP Addresses."); + Ipv4AddressHelper address; + + // + // Assign IPv4 interfaces and IP addresses to the devices we previously + // created. Keep track of the resulting addresses, one for the addresses + // of the hub node, and one for addresses on the spoke nodes. Despite the + // name of the class, what is visible to clients is really the address. + // + Ipv4InterfaceContainer hubAddresses; + Ipv4InterfaceContainer spokeAddresses; + + for(uint32_t i = 0; i < spokeNodes.GetN (); ++i) + { + std::ostringstream subnet; + subnet << "10.1." << i << ".0"; + NS_LOG_INFO ("Assign IP Addresses for CSMA subnet " << subnet.str ()); + address.SetBase (subnet.str ().c_str (), "255.255.255.0"); + hubAddresses.Add (address.Assign (hubDevices.Get (i))); + spokeAddresses.Add (address.Assign (spokeDevices.Get (i))); + } + + NS_LOG_INFO ("Create applications."); + // + // Create a packet sink on the star "hub" to receive packets. + // + uint16_t port = 50000; + Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)); + PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress); + ApplicationContainer hubApp = packetSinkHelper.Install (hubNode); + hubApp.Start (Seconds (1.0)); + hubApp.Stop (Seconds (10.0)); + + // + // Create OnOff applications to send TCP to the hub, one on each spoke node. + // + OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ()); + onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + + ApplicationContainer spokeApps; + + for (uint32_t i = 0; i < spokeNodes.GetN (); ++i) + { + AddressValue remoteAddress (InetSocketAddress (hubAddresses.GetAddress (i), port)); + onOffHelper.SetAttribute ("Remote", remoteAddress); + spokeApps.Add (onOffHelper.Install (spokeNodes.Get (i))); + } + + spokeApps.Start (Seconds (1.0)); + spokeApps.Stop (Seconds (10.0)); + + // + // Because we are evil, we also add OnOff applications to send TCP to the hub + // from the fill devices on each CSMA link. The first nFill nodes in the + // fillNodes container are on the CSMA network talking to the zeroth device + // on the hub node. The next nFill nodes are on the CSMA network talking to + // the first device on the hub node, etc. So the ith fillNode is associated + // with the hub address found on the (i / nFill)th device on the hub node. + // + ApplicationContainer fillApps; + + for (uint32_t i = 0; i < fillNodes.GetN (); ++i) + { + AddressValue remoteAddress (InetSocketAddress (hubAddresses.GetAddress (i / nFill), port)); + onOffHelper.SetAttribute ("Remote", remoteAddress); + fillApps.Add (onOffHelper.Install (fillNodes.Get (i))); + } + + fillApps.Start (Seconds (1.0)); + fillApps.Stop (Seconds (10.0)); + + NS_LOG_INFO ("Enable static global routing."); + // + // Turn on global static routing so we can actually be routed across the star. + // + GlobalRouteManager::PopulateRoutingTables (); + + NS_LOG_INFO ("Enable pcap tracing."); + // + // Do pcap tracing on all devices on all nodes. + // + PointToPointHelper::EnablePcapAll ("csma-star"); + + NS_LOG_INFO ("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); + NS_LOG_INFO ("Done."); + + return 0; +} diff --git a/examples/star.cc b/examples/star.cc new file mode 100644 index 000000000..1cc58457d --- /dev/null +++ b/examples/star.cc @@ -0,0 +1,153 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" +#include "ns3/global-route-manager.h" + +// Network topology (default) +// +// n2 n3 n4 . +// \ | / . +// \|/ . +// n1--- n0---n5 . +// /|\ . +// / | \ . +// n8 n7 n6 . +// + + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("Star"); + +int +main (int argc, char *argv[]) +{ + // + // Make the random number generators generate reproducible results. + // + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + + // + // Set up some default values for the simulation. + // + Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (137)); + + // ??? try and stick 15kb/s into the data rate + Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("14kb/s")); + + // + // Default number of nodes in the star. Overridable by command line argument. + // + uint32_t nNodes = 9; + + CommandLine cmd; + cmd.AddValue("nNodes", "Number of nodes to place in the star", nNodes); + cmd.Parse (argc, argv); + + NS_LOG_INFO ("Create nodes."); + NodeContainer hubNode; + NodeContainer spokeNodes; + hubNode.Create (1); + Ptr hub = hubNode.Get (0); + spokeNodes.Create (nNodes - 1); + + NS_LOG_INFO ("Install internet stack on all nodes."); + InternetStackHelper internet; + internet.Install (NodeContainer (hubNode, spokeNodes)); + + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + + NS_LOG_INFO ("Build star topology."); + NetDeviceContainer hubDevices, spokeDevices; + pointToPoint.InstallStar (hubNode.Get (0), spokeNodes, hubDevices, spokeDevices); + + NS_LOG_INFO ("Assign IP Addresses."); + Ipv4AddressHelper address; + + // + // Assign IPv4 interfaces and IP addresses to the devices we previously + // created. Keep track of the resulting addresses, one for the addresses + // of the hub node, and one for addresses on the spoke nodes. Despite the + // name of the class, what is visible to clients is really the address. + // + Ipv4InterfaceContainer hubAddresses; + Ipv4InterfaceContainer spokeAddresses; + + for(uint32_t i = 0; i < spokeNodes.GetN (); ++i) + { + std::ostringstream subnet; + subnet << "10.1.1." << (i << 2); + NS_LOG_INFO ("Assign IP Addresses for point-to-point subnet " << subnet.str ()); + address.SetBase (subnet.str ().c_str (), "255.255.255.252"); + hubAddresses.Add (address.Assign (hubDevices.Get (i))); + spokeAddresses.Add (address.Assign (spokeDevices.Get (i))); + } + + NS_LOG_INFO ("Create applications."); + // + // Create a packet sink on the star "hub" to receive packets. + // + uint16_t port = 50000; + Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)); + PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress); + ApplicationContainer hubApp = packetSinkHelper.Install (hubNode); + hubApp.Start (Seconds (1.0)); + hubApp.Stop (Seconds (10.0)); + + // + // Create OnOff applications to send TCP to the hub, one on each spoke node. + // + OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ()); + onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + + ApplicationContainer spokeApps; + + for (uint32_t i = 0; i < spokeNodes.GetN (); ++i) + { + AddressValue remoteAddress (InetSocketAddress (hubAddresses.GetAddress (i), port)); + onOffHelper.SetAttribute ("Remote", remoteAddress); + spokeApps.Add (onOffHelper.Install (spokeNodes.Get (i))); + } + spokeApps.Start (Seconds (1.0)); + spokeApps.Stop (Seconds (10.0)); + + NS_LOG_INFO ("Enable static global routing."); + // + // Turn on global static routing so we can actually be routed across the star. + // + GlobalRouteManager::PopulateRoutingTables (); + + NS_LOG_INFO ("Enable pcap tracing."); + // + // Do pcap tracing on all devices on all nodes. + // + PointToPointHelper::EnablePcapAll ("star"); + + NS_LOG_INFO ("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); + NS_LOG_INFO ("Done."); + + return 0; +} diff --git a/examples/wscript b/examples/wscript index 34673bb1c..e68afba06 100644 --- a/examples/wscript +++ b/examples/wscript @@ -5,73 +5,81 @@ def build(bld): obj.source = 'hello-simulator.cc' obj = bld.create_ns3_program('mixed-wireless', - ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack']) + ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack']) obj.source = 'mixed-wireless.cc' obj = bld.create_ns3_program('simple-global-routing', - ['point-to-point', 'internet-stack', 'global-routing']) + ['point-to-point', 'internet-stack', 'global-routing']) obj.source = 'simple-global-routing.cc' obj = bld.create_ns3_program('simple-alternate-routing', - ['point-to-point', 'internet-stack', 'global-routing']) + ['point-to-point', 'internet-stack', 'global-routing']) obj.source = 'simple-alternate-routing.cc' obj = bld.create_ns3_program('simple-error-model', - ['point-to-point', 'internet-stack']) + ['point-to-point', 'internet-stack']) obj.source = 'simple-error-model.cc' obj = bld.create_ns3_program('csma-one-subnet', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'csma-one-subnet.cc' obj = bld.create_ns3_program('csma-bridge', - ['bridge', 'csma', 'internet-stack']) + ['bridge', 'csma', 'internet-stack']) obj.source = 'csma-bridge.cc' obj = bld.create_ns3_program('udp-echo', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'udp-echo.cc' obj = bld.create_ns3_program('realtime-udp-echo', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'realtime-udp-echo.cc' obj = bld.create_ns3_program('csma-broadcast', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'csma-broadcast.cc' obj = bld.create_ns3_program('csma-packet-socket', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'csma-packet-socket.cc' obj = bld.create_ns3_program('csma-multicast', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'csma-multicast.cc' obj = bld.create_ns3_program( 'mixed-global-routing', - ['point-to-point', 'internet-stack', 'global-routing' , 'csma-cd']) + ['point-to-point', 'internet-stack', 'global-routing' , 'csma-cd']) obj.source = 'mixed-global-routing.cc' obj = bld.create_ns3_program('simple-point-to-point-olsr', - ['point-to-point', 'internet-stack', 'olsr']) + ['point-to-point', 'internet-stack', 'olsr']) obj.source = 'simple-point-to-point-olsr.cc' obj = bld.create_ns3_program('tcp-large-transfer', - ['point-to-point', 'internet-stack']) + ['point-to-point', 'internet-stack']) obj.source = 'tcp-large-transfer.cc' obj = bld.create_ns3_program('tcp-nsc-lfn', - ['point-to-point', 'internet-stack']) + ['point-to-point', 'internet-stack']) obj.source = 'tcp-nsc-lfn.cc' obj = bld.create_ns3_program('tcp-nsc-zoo', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'tcp-nsc-zoo.cc' obj = bld.create_ns3_program('tcp-star-server', - ['point-to-point', 'internet-stack']) + ['point-to-point', 'internet-stack']) obj.source = 'tcp-star-server.cc' + obj = bld.create_ns3_program('star', + ['point-to-point', 'internet-stack']) + obj.source = 'star.cc' + + obj = bld.create_ns3_program('csma-star', + ['csma', 'internet-stack']) + obj.source = 'csma-star.cc' + obj = bld.create_ns3_program('wifi-adhoc', ['core', 'simulator', 'mobility', 'wifi']) obj.source = 'wifi-adhoc.cc' diff --git a/samples/main-ns2-mob.cc b/samples/main-ns2-mob.cc new file mode 100644 index 000000000..349e42f79 --- /dev/null +++ b/samples/main-ns2-mob.cc @@ -0,0 +1,37 @@ +#include "ns3/core-module.h" +#include "ns3/mobility-module.h" +#include "ns3/simulator-module.h" +#include "ns3/helper-module.h" +#include "ns3/mobility-module.h" +#include + +using namespace ns3; + +static void +CourseChange (std::ostream *os, std::string foo, Ptr mobility) +{ + Vector pos = mobility->GetPosition (); + Vector vel = mobility->GetVelocity (); + *os << Simulator::Now () << " POS: x=" << pos.x << ", y=" << pos.y + << ", z=" << pos.z << "; VEL:" << vel.x << ", y=" << vel.y + << ", z=" << vel.z << std::endl; +} + +int main (int argc, char *argv[]) +{ + Ns2MobilityHelper mobility(argv[1]); + std::ofstream os; + os.open (argv[2]); + NodeContainer stas; + stas.Create (1); + + mobility.Install (); + + Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange", + MakeBoundCallback (&CourseChange, &os)); + + Simulator::Stop (Seconds (10.0)); + Simulator::Run (); + Simulator::Destroy (); + return 0; +} diff --git a/samples/ns2-mob.tr b/samples/ns2-mob.tr new file mode 100644 index 000000000..b45e39cb2 --- /dev/null +++ b/samples/ns2-mob.tr @@ -0,0 +1,7 @@ + +$node_(0) set X_ 0.0 +$node_(0) set Y_ 25.0 +$node_(0) set Z_ 0.0 +$ns_ at 3.0 "$node_(0) setdest 25 0 0" +$ns_ at 4.8 "$node_(0) setdest 0 0 0" +$ns_ at 5.0 "$node_(0) setdest 25 0 0" diff --git a/samples/wscript b/samples/wscript index 351ace697..d1c1e8fa1 100644 --- a/samples/wscript +++ b/samples/wscript @@ -42,4 +42,8 @@ def build(bld): ['core', 'simulator', 'mobility', 'wifi']) obj.source = 'main-propagation-loss.cc' + obj = bld.create_ns3_program('main-ns2-mob', + ['core', 'simulator', 'mobility', 'wifi']) + obj.source = 'main-ns2-mob.cc' + diff --git a/src/applications/packet-sink/packet-sink.cc b/src/applications/packet-sink/packet-sink.cc index 97283c722..507a0c371 100644 --- a/src/applications/packet-sink/packet-sink.cc +++ b/src/applications/packet-sink/packet-sink.cc @@ -87,7 +87,7 @@ void PacketSink::StartApplication() // Called at time specified by Start { m_socket = Socket::CreateSocket (GetNode(), m_tid); m_socket->Bind (m_local); - m_socket->Listen (0); + m_socket->Listen (); } m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this)); diff --git a/src/common/packet-metadata.h b/src/common/packet-metadata.h index 574d2f6e6..a2d5228fc 100644 --- a/src/common/packet-metadata.h +++ b/src/common/packet-metadata.h @@ -157,8 +157,6 @@ public: void Serialize (Buffer::Iterator i, uint32_t size) const; uint32_t Deserialize (Buffer::Iterator i); - static void PrintStats (void); - ItemIterator BeginItem (Buffer buffer) const; private: diff --git a/src/common/packet.cc b/src/common/packet.cc index f2ba95ea8..a5f5e3993 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -296,6 +296,19 @@ Packet::PeekData (void) const return m_buffer.PeekData (); } +uint32_t +Packet::CopyData (uint8_t *buffer, uint32_t size) const +{ + Buffer::Iterator i = m_buffer.Begin (); + uint32_t cur = 0; + while (!i.IsEnd () && cur < size) + { + buffer[cur] = i.ReadU8 (); + cur++; + } + return cur; +} + uint32_t Packet::GetUid (void) const { diff --git a/src/common/packet.h b/src/common/packet.h index 454da94b6..9b0aba9e9 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -280,6 +280,16 @@ public: */ uint8_t const *PeekData (void) const; + /** + * \param buffer a pointer to a byte buffer where the packet data + * should be copied. + * \param size the size of the byte buffer. + * \returns the number of bytes read from the packet + * + * No more than \b size bytes will be copied by this function. + */ + uint32_t CopyData (uint8_t *buffer, uint32_t size) const; + /** * A packet is allocated a new uid when it is created * empty or with zero-filled payload. @@ -437,6 +447,7 @@ std::ostream& operator<< (std::ostream& os, const Packet &packet); * - ns3::Packet::CreateFragment * - ns3::Packet::RemoveAtStart * - ns3::Packet::RemoveAtEnd + * - ns3::Packet::CopyData * * Dirty operations will always be slower than non-dirty operations, * sometimes by several orders of magnitude. However, even the diff --git a/src/common/tag-list.cc b/src/common/tag-list.cc index 4f8fdaf92..fac9ef020 100644 --- a/src/common/tag-list.cc +++ b/src/common/tag-list.cc @@ -72,10 +72,8 @@ TagList::Iterator::Next (void) struct Item item = Item (TagBuffer (m_current+16, m_end)); item.tid.SetUid (m_nextTid); item.size = m_nextSize; - item.start = m_nextStart; - item.end = m_nextEnd; - item.start = std::max (item.start, m_offsetStart); - item.end = std::min (item.end, m_offsetEnd); + item.start = std::max (m_nextStart, m_offsetStart); + item.end = std::min (m_nextEnd, m_offsetEnd); m_current += 4 + 4 + 4 + 4 + item.size; item.buf.TrimAtEnd (m_end - m_current); PrepareForNext (); diff --git a/src/core/abort.h b/src/core/abort.h new file mode 100644 index 000000000..306058df3 --- /dev/null +++ b/src/core/abort.h @@ -0,0 +1,54 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 INRIA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef NS3_ABORT_H +#define NS3_ABORT_H + +#include "fatal-error.h" + +#define NS_ABORT_IF(cond) \ + do { \ + if (cond) \ + { \ + std::cerr << "file=" << __FILE__ << \ + ", line=" << __LINE__ << ", abort on=\""#cond << \ + "\"" << std::endl; \ + int *a = 0; \ + *a = 0; \ + } \ + } while (false) + +#define NS_ABORT_MSG_IF(cond, msg) \ + do { \ + if (cond) \ + { \ + std::cerr << "file=" << __FILE__ << \ + ", line=" << __LINE__ << ", abort on=\""#cond << \ + "\", msg=\"" << msg << "\"" << std::endl; \ + int *a = 0; \ + *a = 0; \ + } \ + } while (false) + +#define NS_ABORT_UNLESS(cond) \ + NS_ABORT_IF(!(cond)) + +#define NS_ABORT_MSG_UNLESS(cond, msg) \ + NS_ABORT_MSG_IF(!(cond),msg) + +#endif /* NS3_ABORT_H */ diff --git a/src/core/attribute-accessor-helper.h b/src/core/attribute-accessor-helper.h index fefce3a3e..cee4bae86 100644 --- a/src/core/attribute-accessor-helper.h +++ b/src/core/attribute-accessor-helper.h @@ -48,6 +48,12 @@ MakeAccessorHelper (T1 a1, T2 a2); namespace ns3 { +template +struct AccessorTrait +{ + typedef typename TypeTraits::ReferencedType>::NonConstType Result; +}; + template class AccessorHelper : public AttributeAccessor { @@ -100,7 +106,13 @@ DoMakeAccessorHelperOne (U T::*memberVariable) {} private: virtual bool DoSet (T *object, const V *v) const { - (object->*m_memberVariable) = U (v->Get ()); + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + (object->*m_memberVariable) = tmp; return true; } virtual bool DoGet (const T *object, V *v) const { @@ -163,7 +175,13 @@ DoMakeAccessorHelperOne (void (T::*setter) (U)) {} private: virtual bool DoSet (T *object, const V *v) const { - (object->*m_setter) (U (v->Get ())); + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + (object->*m_setter) (tmp); return true; } virtual bool DoGet (const T *object, V *v) const { @@ -196,7 +214,13 @@ DoMakeAccessorHelperTwo (void (T::*setter) (U), {} private: virtual bool DoSet (T *object, const W *v) const { - (object->*m_setter) (v->Get ()); + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + (object->*m_setter) (tmp); return true; } virtual bool DoGet (const T *object, W *v) const { @@ -239,7 +263,13 @@ DoMakeAccessorHelperTwo (bool (T::*setter) (U), {} private: virtual bool DoSet (T *object, const W *v) const { - bool ok = (object->*m_setter) (v->Get ()); + typename AccessorTrait::Result tmp; + bool ok = v->GetAccessor (tmp); + if (!ok) + { + return false; + } + ok = (object->*m_setter) (tmp); return ok; } virtual bool DoGet (const T *object, W *v) const { diff --git a/src/core/attribute-helper.h b/src/core/attribute-helper.h index 7e86578a5..8637e6776 100644 --- a/src/core/attribute-helper.h +++ b/src/core/attribute-helper.h @@ -117,6 +117,11 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying) name##Value (const type &value); \ void Set (const type &value); \ type Get (void) const; \ + template \ + bool GetAccessor (T &value) const { \ + value = T (m_value); \ + return true; \ + } \ virtual Ptr Copy (void) const; \ virtual std::string SerializeToString (Ptr checker) const; \ virtual bool DeserializeFromString (std::string value, Ptr checker); \ @@ -220,17 +225,6 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying) return MakeSimpleAttributeChecker (#type "Value", name); \ } \ - -/** - * \ingroup AttributeHelper - * \param type the name of the class - * - * This macro implements the conversion operators to and from - * instances of type Attribute. Typically invoked from xxx.cc. - */ -#define ATTRIBUTE_CONVERTER_IMPLEMENT(type) - - /** * \ingroup AttributeHelper * \param type the name of the class @@ -251,7 +245,6 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying) */ #define ATTRIBUTE_HELPER_CPP(type) \ ATTRIBUTE_CHECKER_IMPLEMENT (type); \ - ATTRIBUTE_CONVERTER_IMPLEMENT (type); \ ATTRIBUTE_VALUE_IMPLEMENT (type); diff --git a/src/core/attribute-test.cc b/src/core/attribute-test.cc index 8b31ca954..b0c3bf74f 100644 --- a/src/core/attribute-test.cc +++ b/src/core/attribute-test.cc @@ -29,6 +29,7 @@ #include "double.h" #include "object-vector.h" #include "traced-value.h" +#include "callback.h" #include "trace-source-accessor.h" #include "pointer.h" @@ -71,9 +72,13 @@ private: void NotifySourceValue (ValueClassTest old, ValueClassTest n) { m_gotValue = n; } + void NotifyCallbackValue (int8_t a) { + m_gotCbValue = a; + } int64_t m_got1; double m_got2; ValueClassTest m_gotValue; + int16_t m_gotCbValue; }; class Derived : public Object @@ -171,6 +176,10 @@ public: PointerValue (), MakePointerAccessor (&AttributeObjectTest::m_ptr), MakePointerChecker ()) + .AddAttribute ("Callback", "help text", + CallbackValue (), + MakeCallbackAccessor (&AttributeObjectTest::m_cbValue), + MakeCallbackChecker ()) ; return tid; @@ -187,6 +196,13 @@ public: m_cb (a,b,c); } + void InvokeCbValue (int8_t a) { + if (!m_cbValue.IsNull ()) + { + m_cbValue (a); + } + } + private: void DoSetTestB (bool v) { m_boolTestA = v; @@ -224,6 +240,7 @@ private: RandomVariable m_random; std::vector > m_vector1; std::vector > m_vector2; + Callback m_cbValue; TracedValue m_intSrc1; TracedValue m_intSrc2; TracedCallback m_cb; @@ -492,6 +509,21 @@ AttributeTest::RunTests (void) derived = ptr.Get (); NS_TEST_ASSERT (derived != 0); + p = CreateObject (); + NS_TEST_ASSERT (p != 0); + m_gotCbValue = 1; + p->InvokeCbValue (2); + CallbackValue cbValue = MakeCallback (&AttributeTest::NotifyCallbackValue, this); + NS_TEST_ASSERT_EQUAL (m_gotCbValue, 1); + NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback", + cbValue)); + p->InvokeCbValue (2); + NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2); + NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback", + CallbackValue (MakeNullCallback ()))); + p->InvokeCbValue (3); + NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2); + return result; } diff --git a/src/core/boolean.h b/src/core/boolean.h index eb15d9506..3fb6096a9 100644 --- a/src/core/boolean.h +++ b/src/core/boolean.h @@ -42,6 +42,8 @@ public: BooleanValue (bool value); void Set (bool value); bool Get (void) const; + template + bool GetAccessor (T &v) const; operator bool () const; @@ -52,6 +54,13 @@ private: bool m_value; }; +template +bool BooleanValue::GetAccessor (T &v) const +{ + v = T (m_value); + return true; +} + std::ostream & operator << (std::ostream &os, const BooleanValue &value); ATTRIBUTE_CHECKER_DEFINE (Boolean); diff --git a/src/core/callback.cc b/src/core/callback.cc new file mode 100644 index 000000000..bc5223cd8 --- /dev/null +++ b/src/core/callback.cc @@ -0,0 +1,38 @@ +#include "callback.h" + +namespace ns3 { + +CallbackValue::CallbackValue () + : m_value () +{} +CallbackValue::CallbackValue (const CallbackBase &base) + : m_value (base) +{} +CallbackValue::~CallbackValue () +{} +void +CallbackValue::Set (CallbackBase base) +{ + m_value = base; +} +Ptr +CallbackValue::Copy (void) const +{ + return Create (m_value); +} +std::string +CallbackValue::SerializeToString (Ptr checker) const +{ + std::ostringstream oss; + oss << PeekPointer (m_value.GetImpl ()); + return oss.str (); +} +bool +CallbackValue::DeserializeFromString (std::string value, Ptr checker) +{ + return false; +} + +ATTRIBUTE_CHECKER_IMPLEMENT (Callback); + +} // namespace ns3 diff --git a/src/core/callback.h b/src/core/callback.h index 30e278478..4a8b15bcb 100644 --- a/src/core/callback.h +++ b/src/core/callback.h @@ -25,6 +25,8 @@ #include "fatal-error.h" #include "empty.h" #include "type-traits.h" +#include "attribute.h" +#include "attribute-helper.h" #include namespace ns3 { @@ -399,7 +401,11 @@ private: return static_cast *> (PeekPointer (m_impl)); } bool DoCheckType (Ptr other) const { - if (dynamic_cast *> (PeekPointer (other)) != 0) + if (other != 0 && dynamic_cast *> (PeekPointer (other)) != 0) + { + return true; + } + else if (other == 0) { return true; } @@ -753,9 +759,45 @@ Callback MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), AR Create > (fnPtr, a); return Callback (impl); } +} // namespace ns3 +namespace ns3 { -}; // namespace ns3 +class CallbackValue : public AttributeValue +{ +public: + CallbackValue (); + CallbackValue (const CallbackBase &base); + virtual ~CallbackValue (); + void Set (CallbackBase base); + template + bool GetAccessor (T &value) const; + virtual Ptr Copy (void) const; + virtual std::string SerializeToString (Ptr checker) const; + virtual bool DeserializeFromString (std::string value, Ptr checker); +private: + CallbackBase m_value; +}; + +ATTRIBUTE_ACCESSOR_DEFINE(Callback); +ATTRIBUTE_CHECKER_DEFINE (Callback); + +} // namespace ns3 + +namespace ns3 { + +template +bool CallbackValue::GetAccessor (T &value) const +{ + if (value.CheckType (m_value)) + { + value.Assign (m_value); + return true; + } + return false; +} + +} // namespace ns3 #endif /* CALLBACK_H */ diff --git a/src/core/config.cc b/src/core/config.cc index db12d72a4..0b42ad0b9 100644 --- a/src/core/config.cc +++ b/src/core/config.cc @@ -30,6 +30,100 @@ NS_LOG_COMPONENT_DEFINE ("Config"); namespace ns3 { +namespace Config { + +MatchContainer::MatchContainer () +{} +MatchContainer::MatchContainer (const std::vector > &objects, + const std::vector &contexts, + std::string path) + : m_objects (objects), + m_contexts (contexts), + m_path (path) +{} +MatchContainer::Iterator +MatchContainer::Begin (void) const +{ + return m_objects.begin (); +} +MatchContainer::Iterator +MatchContainer::End (void) const +{ + return m_objects.end (); +} +uint32_t +MatchContainer::GetN (void) const +{ + return m_objects.size (); +} +Ptr +MatchContainer::Get (uint32_t i) const +{ + return m_objects[i]; +} +std::string +MatchContainer::GetMatchedPath (uint32_t i) const +{ + return m_contexts[i]; +} +std::string +MatchContainer::GetPath (void) const +{ + return m_path; +} + +void +MatchContainer::Set (std::string name, const AttributeValue &value) +{ + for (Iterator tmp = Begin (); tmp != End (); ++tmp) + { + Ptr object = *tmp; + object->SetAttribute (name, value); + } +} +void +MatchContainer::Connect (std::string name, const CallbackBase &cb) +{ + NS_ASSERT (m_objects.size () == m_contexts.size ()); + for (uint32_t i = 0; i < m_objects.size (); ++i) + { + Ptr object = m_objects[i]; + std::string ctx = m_contexts[i] + name; + object->TraceConnect (name, ctx, cb); + } +} +void +MatchContainer::ConnectWithoutContext (std::string name, const CallbackBase &cb) +{ + for (Iterator tmp = Begin (); tmp != End (); ++tmp) + { + Ptr object = *tmp; + object->TraceConnectWithoutContext (name, cb); + } +} +void +MatchContainer::Disconnect (std::string name, const CallbackBase &cb) +{ + NS_ASSERT (m_objects.size () == m_contexts.size ()); + for (uint32_t i = 0; i < m_objects.size (); ++i) + { + Ptr object = m_objects[i]; + std::string ctx = m_contexts[i] + name; + object->TraceDisconnect (name, ctx, cb); + } +} +void +MatchContainer::DisconnectWithoutContext (std::string name, const CallbackBase &cb) +{ + for (Iterator tmp = Begin (); tmp != End (); ++tmp) + { + Ptr object = *tmp; + object->TraceDisconnectWithoutContext (name, cb); + } +} + +} // namespace Config + class ArrayMatcher { public: @@ -125,20 +219,40 @@ public: void Resolve (Ptr root); private: + void Canonicalize (void); void DoResolve (std::string path, Ptr root); void DoArrayResolve (std::string path, const ObjectVectorValue &vector); - void DoResolveOne (Ptr object, std::string name); - std::string GetResolvedPath (std::string name) const; - virtual void DoOne (Ptr object, std::string path, std::string name) = 0; + void DoResolveOne (Ptr object); + std::string GetResolvedPath (void) const; + virtual void DoOne (Ptr object, std::string path) = 0; std::vector m_workStack; std::string m_path; }; Resolver::Resolver (std::string path) : m_path (path) -{} +{ + Canonicalize (); +} Resolver::~Resolver () {} +void +Resolver::Canonicalize (void) +{ + // ensure that we start and end with a '/' + std::string::size_type tmp = m_path.find ("/"); + if (tmp != 0) + { + // no slash at start + m_path = "/" + m_path; + } + tmp = m_path.find_last_of ("/"); + if (tmp != (m_path.size () - 1)) + { + // no slash at end + m_path = m_path + "/"; + } +} void Resolver::Resolve (Ptr root) @@ -147,40 +261,34 @@ Resolver::Resolve (Ptr root) } std::string -Resolver::GetResolvedPath (std::string name) const +Resolver::GetResolvedPath (void) const { - std::string fullPath = ""; + std::string fullPath = "/"; for (std::vector::const_iterator i = m_workStack.begin (); i != m_workStack.end (); i++) { - fullPath += "/" + *i; + fullPath += *i + "/"; } - fullPath += "/" + name; return fullPath; } void -Resolver::DoResolveOne (Ptr object, std::string name) +Resolver::DoResolveOne (Ptr object) { - NS_LOG_DEBUG ("resolved="< root) const ObjectVectorChecker *vectorChecker = dynamic_cast (PeekPointer (info.checker)); if (vectorChecker != 0) { - NS_LOG_DEBUG ("GetAttribute(vector)="< obj); void UnregisterRootNamespaceObject (Ptr obj); @@ -298,110 +403,86 @@ public: Ptr GetRootNamespaceObject (uint32_t i) const; private: + void ParsePath (std::string path, std::string *root, std::string *leaf) const; typedef std::vector > Roots; Roots m_roots; }; +void +ConfigImpl::ParsePath (std::string path, std::string *root, std::string *leaf) const +{ + std::string::size_type slash = path.find_last_of ("/"); + NS_ASSERT (slash != std::string::npos); + *root = path.substr (0, slash); + *leaf = path.substr (slash+1, path.size ()-(slash+1)); + NS_LOG_FUNCTION (path << *root << *leaf); +} + void ConfigImpl::Set (std::string path, const AttributeValue &value) { - class SetResolver : public Resolver - { - public: - SetResolver (std::string path, const AttributeValue &value) - : Resolver (path), - m_value (value.Copy ()) {} - private: - virtual void DoOne (Ptr object, std::string path, std::string name) { - object->SetAttribute (name, *m_value); - } - Ptr m_value; - } resolver = SetResolver (path, value); - for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++) - { - resolver.Resolve (*i); - } + std::string root, leaf; + ParsePath (path, &root, &leaf); + Config::MatchContainer container = LookupMatches (root); + container.Set (leaf, value); } void ConfigImpl::ConnectWithoutContext (std::string path, const CallbackBase &cb) { - class ConnectResolver : public Resolver - { - public: - ConnectResolver (std::string path, const CallbackBase &cb) - : Resolver (path), - m_cb (cb) {} - private: - virtual void DoOne (Ptr object, std::string path, std::string name) { - object->TraceConnectWithoutContext (name, m_cb); - } - CallbackBase m_cb; - } resolver = ConnectResolver (path, cb); - for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++) - { - resolver.Resolve (*i); - } + std::string root, leaf; + ParsePath (path, &root, &leaf); + Config::MatchContainer container = LookupMatches (root); + container.ConnectWithoutContext (leaf, cb); } void ConfigImpl::DisconnectWithoutContext (std::string path, const CallbackBase &cb) { - class DisconnectResolver : public Resolver - { - public: - DisconnectResolver (std::string path, const CallbackBase &cb) - : Resolver (path), - m_cb (cb) {} - private: - virtual void DoOne (Ptr object, std::string path, std::string name) { - object->TraceDisconnectWithoutContext (name, m_cb); - } - CallbackBase m_cb; - } resolver = DisconnectResolver (path, cb); - for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++) - { - resolver.Resolve (*i); - } + std::string root, leaf; + ParsePath (path, &root, &leaf); + Config::MatchContainer container = LookupMatches (root); + container.DisconnectWithoutContext (leaf, cb); } void ConfigImpl::Connect (std::string path, const CallbackBase &cb) { - class ConnectWithContextResolver : public Resolver - { - public: - ConnectWithContextResolver (std::string path, const CallbackBase &cb) - : Resolver (path), - m_cb (cb) {} - private: - virtual void DoOne (Ptr object, std::string path, std::string name) { - object->TraceConnect (name, path, m_cb); - } - CallbackBase m_cb; - } resolver = ConnectWithContextResolver (path, cb); - for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++) - { - resolver.Resolve (*i); - } + std::string root, leaf; + ParsePath (path, &root, &leaf); + Config::MatchContainer container = LookupMatches (root); + container.Connect (leaf, cb); } void ConfigImpl::Disconnect (std::string path, const CallbackBase &cb) { - class DisconnectWithContextResolver : public Resolver + std::string root, leaf; + ParsePath (path, &root, &leaf); + Config::MatchContainer container = LookupMatches (root); + container.Disconnect (leaf, cb); +} + +Config::MatchContainer +ConfigImpl::LookupMatches (std::string path) +{ + NS_LOG_FUNCTION (path); + class LookupMatchesResolver : public Resolver { public: - DisconnectWithContextResolver (std::string path, const CallbackBase &cb) - : Resolver (path), - m_cb (cb) {} - private: - virtual void DoOne (Ptr object, std::string path, std::string name) { - object->TraceDisconnect (name, path, m_cb); + LookupMatchesResolver (std::string path) + : Resolver (path) + {} + virtual void DoOne (Ptr object, std::string path) { + m_objects.push_back (object); + m_contexts.push_back (path); } - CallbackBase m_cb; - } resolver = DisconnectWithContextResolver (path, cb); + std::vector > m_objects; + std::vector m_contexts; + } resolver = LookupMatchesResolver (path); for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++) { resolver.Resolve (*i); } + return Config::MatchContainer (resolver.m_objects, resolver.m_contexts, path); } + void ConfigImpl::RegisterRootNamespaceObject (Ptr obj) { @@ -472,6 +553,10 @@ Disconnect (std::string path, const CallbackBase &cb) { Singleton::Get ()->Disconnect (path, cb); } +Config::MatchContainer LookupMatches (std::string path) +{ + return Singleton::Get ()->LookupMatches (path); +} void RegisterRootNamespaceObject (Ptr obj) { diff --git a/src/core/config.h b/src/core/config.h index 256b491ef..9da9b03b9 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -22,6 +22,7 @@ #include "ptr.h" #include +#include namespace ns3 { @@ -110,6 +111,35 @@ void Connect (std::string path, const CallbackBase &cb); */ void Disconnect (std::string path, const CallbackBase &cb); +class MatchContainer +{ +public: + typedef std::vector >::const_iterator Iterator; + MatchContainer (); + MatchContainer (const std::vector > &objects, + const std::vector &contexts, + std::string path); + + MatchContainer::Iterator Begin (void) const; + MatchContainer::Iterator End (void) const; + uint32_t GetN (void) const; + Ptr Get (uint32_t i) const; + std::string GetMatchedPath (uint32_t i) const; + std::string GetPath (void) const; + + void Set (std::string name, const AttributeValue &value); + void Connect (std::string name, const CallbackBase &cb); + void ConnectWithoutContext (std::string name, const CallbackBase &cb); + void Disconnect (std::string name, const CallbackBase &cb); + void DisconnectWithoutContext (std::string name, const CallbackBase &cb); +private: + std::vector > m_objects; + std::vector m_contexts; + std::string m_path; +}; + +MatchContainer LookupMatches (std::string path); + /** * \param obj a new root object * diff --git a/src/core/enum.cc b/src/core/enum.cc index 58cc9fcc8..0e1d7812d 100644 --- a/src/core/enum.cc +++ b/src/core/enum.cc @@ -39,7 +39,6 @@ EnumValue::Get (void) const { return m_v; } - Ptr EnumValue::Copy (void) const { diff --git a/src/core/enum.h b/src/core/enum.h index d9eeb521f..b3baf2cd7 100644 --- a/src/core/enum.h +++ b/src/core/enum.h @@ -41,6 +41,8 @@ public: EnumValue (int v); void Set (int v); int Get (void) const; + template + bool GetAccessor (T &v) const; virtual Ptr Copy (void) const; virtual std::string SerializeToString (Ptr checker) const; @@ -50,6 +52,13 @@ private: int m_v; }; +template +bool EnumValue::GetAccessor (T &v) const +{ + v = T (m_v); + return true; +} + class EnumChecker : public AttributeChecker { public: diff --git a/src/core/pointer.h b/src/core/pointer.h index 5fcb28718..4b0e4d671 100644 --- a/src/core/pointer.h +++ b/src/core/pointer.h @@ -50,6 +50,9 @@ public: template Ptr Get (void) const; + template + bool GetAccessor (Ptr &v) const; + template operator Ptr () const; @@ -61,23 +64,6 @@ private: Ptr m_value; }; -template -Ptr -MakePointerAccessor (Ptr T::*memberVariable); -template -Ptr -MakePointerAccessor (void (T::*setter) (Ptr)); -template -Ptr -MakePointerAccessor (Ptr (T::*getter) (void) const); -template -Ptr -MakePointerAccessor (void (T::*setter) (Ptr), - Ptr (T::*getter) (void) const); -template -Ptr -MakePointerAccessor (Ptr (T::*getter) (void) const, - void (T::*setter) (Ptr)); class PointerChecker : public AttributeChecker { @@ -142,57 +128,8 @@ class APointerChecker : public PointerChecker } }; -/******************************************************** - * The Accessor associated to - * PointerValue - ********************************************************/ - -template -class PointerAccessor : public AttributeAccessor -{ -public: - virtual ~PointerAccessor () {} - virtual bool Set (ObjectBase * object, const AttributeValue &val) const { - T *obj = dynamic_cast (object); - if (obj == 0) - { - return false; - } - const PointerValue *value = dynamic_cast (&val); - if (value == 0) - { - return false; - } - Ptr ptr = dynamic_cast (PeekPointer (value->GetObject ())); - if (ptr == 0) - { - return false; - } - DoSet (obj, ptr); - return true; - } - virtual bool Get (const ObjectBase * object, AttributeValue &val) const { - const T *obj = dynamic_cast (object); - if (obj == 0) - { - return false; - } - PointerValue *value = dynamic_cast (&val); - if (value == 0) - { - return false; - } - value->Set (DoGet (obj)); - return true; - } -private: - virtual void DoSet (T *object, Ptr value) const = 0; - virtual Ptr DoGet (const T *object) const = 0; -}; - } // namespace internal - template PointerValue::PointerValue (const Ptr &object) { @@ -220,112 +157,21 @@ PointerValue::operator Ptr () const return Get (); } - -template -Ptr -MakePointerAccessor (Ptr T::*memberVariable) +template +bool +PointerValue::GetAccessor (Ptr &v) const { - struct MemberVariable : public internal::PointerAccessor - { - Ptr T::*m_memberVariable; - virtual void DoSet (T *object, Ptr value) const { - (object->*m_memberVariable) = value; - } - virtual Ptr DoGet (const T *object) const { - return object->*m_memberVariable; - } - virtual bool HasGetter (void) const { - return true; - } - virtual bool HasSetter (void) const { - return true; - } - } *spec = new MemberVariable (); - spec->m_memberVariable = memberVariable; - return Ptr (spec, false); -} - -template -Ptr -MakePointerAccessor (void (T::*setter) (Ptr)) -{ - struct MemberMethod : public internal::PointerAccessor - { - void (T::*m_setter) (Ptr); - virtual void DoSet (T *object, Ptr value) const { - (object->*m_setter) (value); - } - virtual Ptr DoGet (const T *object) const { - return 0; - //return (object->*m_getter) (); - } - virtual bool HasGetter (void) const { + Ptr ptr = dynamic_cast (PeekPointer (m_value)); + if (ptr == 0) + { return false; } - virtual bool HasSetter (void) const { - return true; - } - } *spec = new MemberMethod (); - spec->m_setter = setter; - return Ptr (spec, false); + v = ptr; + return true; } -template -Ptr -MakePointerAccessor (Ptr (T::*getter) (void) const) -{ - struct MemberMethod : public internal::PointerAccessor - { - Ptr (T::*m_getter) (void) const; - virtual void DoSet (T *object, Ptr value) const { - //(object->*m_setter) (value); - } - virtual Ptr DoGet (const T *object) const { - return (object->*m_getter) (); - } - virtual bool HasGetter (void) const { - return true; - } - virtual bool HasSetter (void) const { - return false; - } - } *spec = new MemberMethod (); - spec->m_getter = getter; - return Ptr (spec, false); -} -template -Ptr -MakePointerAccessor (void (T::*setter) (Ptr), - Ptr (T::*getter) (void) const) -{ - return MakePointerAccessor (getter, setter); -} -template -Ptr -MakePointerAccessor (Ptr (T::*getter) (void) const, - void (T::*setter) (Ptr)) -{ - struct MemberMethod : public internal::PointerAccessor - { - void (T::*m_setter) (Ptr); - Ptr (T::*m_getter) (void) const; - virtual void DoSet (T *object, Ptr value) const { - (object->*m_setter) (value); - } - virtual Ptr DoGet (const T *object) const { - return (object->*m_getter) (); - } - virtual bool HasGetter (void) const { - return true; - } - virtual bool HasSetter (void) const { - return true; - } - } *spec = new MemberMethod (); - spec->m_setter = setter; - spec->m_getter = getter; - return Ptr (spec, false); -} + +ATTRIBUTE_ACCESSOR_DEFINE (Pointer); template Ptr diff --git a/src/core/ptr.cc b/src/core/ptr.cc index 3c852821a..41e0539ed 100644 --- a/src/core/ptr.cc +++ b/src/core/ptr.cc @@ -249,8 +249,8 @@ PtrTest::RunTests (void) Ptr p4 = CallTestConst (p1); Ptr p5 = p4; //p4 = p5; You cannot make a const pointer be a non-const pointer. - // but if you use const_pointer_cast, you can. - p4 = const_pointer_cast (p5); + // but if you use ConstCast, you can. + p4 = ConstCast (p5); p5 = p1; Ptr p; if (p == 0) diff --git a/src/core/ptr.h b/src/core/ptr.h index 2bcbf3c60..4861ceb4b 100644 --- a/src/core/ptr.h +++ b/src/core/ptr.h @@ -341,13 +341,38 @@ bool operator < (const Ptr &lhs, const Ptr &rhs) return PeekPointer (lhs) < PeekPointer (rhs); } +template +bool operator <= (const Ptr &lhs, const Ptr &rhs) +{ + return PeekPointer (lhs) <= PeekPointer (rhs); +} + +template +bool operator > (const Ptr &lhs, const Ptr &rhs) +{ + return PeekPointer (lhs) > PeekPointer (rhs); +} + +template +bool operator >= (const Ptr &lhs, const Ptr &rhs) +{ + return PeekPointer (lhs) >= PeekPointer (rhs); +} + template Ptr -const_pointer_cast (Ptr const&p) +ConstCast (Ptr const&p) { return Ptr (const_cast (PeekPointer (p))); } +template +Ptr +DynamicCast (Ptr const&p) +{ + return Ptr (dynamic_cast (PeekPointer (p))); +} + /**************************************************** * Member method implementations. diff --git a/src/core/string.cc b/src/core/string.cc index fbd70e2be..ae5619244 100644 --- a/src/core/string.cc +++ b/src/core/string.cc @@ -3,7 +3,6 @@ namespace ns3 { ATTRIBUTE_CHECKER_IMPLEMENT_WITH_NAME (String, "std::string"); -ATTRIBUTE_CONVERTER_IMPLEMENT (String); ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME (std::string, String); } // namespace ns3 diff --git a/src/core/system-thread.h b/src/core/system-thread.h index 2ec613b40..480eb2f63 100644 --- a/src/core/system-thread.h +++ b/src/core/system-thread.h @@ -84,6 +84,10 @@ public: * method provided to do this is Join (). If you call Join() you will block * until the SystemThread run method returns. * + * @warning The SystemThread uses SIGALRM to wake threads that are possibly + * blocked on IO. + * @see Shutdown + * * @warning I've made the system thread class look like a normal ns3 object * with smart pointers, and living in the heap. This makes it very easy to * manage threads from a single master thread context. You should be very @@ -128,9 +132,47 @@ public: */ void Join (void); + /** + * @brief Indicates to a managed thread doing cooperative multithreading that + * its managing thread wants it to exit. + * + * It is often the case that we want a thread to be off doing work until such + * time as its job is done (typically when the simulation is done). We then + * want the thread to exit itself. This method provides a consistent way for + * the managing thread to communicate with the managed thread. After the + * manager thread calls this method, the Break() method will begin returning + * true, telling the managed thread to exit. + * + * This alone isn't really enough to merit these events, but in Unix, if a + * worker thread is doing blocking IO, it will need to be woken up from that + * read somehow. This method also provides that functionality, by sending a + * SIGALRM signal to the possibly blocked thread. + * + * @warning Uses SIGALRM to notifiy threads possibly blocked on IO. Beware + * if you are using signals. + * @see Break + */ + void Shutdown (void); + + /** + * @brief Indicates to a thread doing cooperative multithreading that + * its managing thread wants it to exit. + * + * It is often the case that we want a thread to be off doing work until such + * time as its job is done. We then want the thread to exit itself. This + * method allows a thread to query whether or not it should be running. + * Typically, the worker thread is running in a forever-loop, and will need to + * "break" out of that loop to exit -- thus the name. + * + * @see Shutdown + * @returns true if thread is expected to exit (break out of the forever-loop) + */ + bool Break (void); + private: SystemThreadImpl * m_impl; mutable uint32_t m_count; + bool m_break; }; void diff --git a/src/core/unix-system-thread.cc b/src/core/unix-system-thread.cc index c607b3b43..16eb5ff43 100644 --- a/src/core/unix-system-thread.cc +++ b/src/core/unix-system-thread.cc @@ -20,6 +20,7 @@ #include #include +#include #include "fatal-error.h" #include "system-thread.h" #include "log.h" @@ -49,11 +50,14 @@ public: void Start (void); void Join (void); + void Shutdown (void); + bool Break (void); private: static void *DoRun (void *arg); Callback m_callback; pthread_t m_thread; + bool m_break; void * m_ret; }; @@ -61,6 +65,13 @@ SystemThreadImpl::SystemThreadImpl (Callback callback) : m_callback (callback) { NS_LOG_FUNCTION_NOARGS (); + // Make sure we have a SIGALRM handler which does not terminate + // our process. + struct sigaction act; + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + act.sa_handler = SIG_IGN; + sigaction (SIGALRM, &act, 0); } void @@ -92,6 +103,26 @@ SystemThreadImpl::Join (void) } } + void +SystemThreadImpl::Shutdown (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + m_break = true; + + // send a SIGALRM signal on the target thread to make sure that it + // will unblock. + pthread_kill (m_thread, SIGALRM); +} + + bool +SystemThreadImpl::Break (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + return m_break; +} + void * SystemThreadImpl::DoRun (void *arg) { @@ -136,4 +167,18 @@ SystemThread::Join (void) m_impl->Join (); } + void +SystemThread::Shutdown (void) +{ + NS_LOG_FUNCTION_NOARGS (); + m_impl->Shutdown (); +} + + bool +SystemThread::Break (void) +{ + NS_LOG_FUNCTION_NOARGS (); + return m_impl->Break (); +} + } // namespace ns3 diff --git a/src/core/wscript b/src/core/wscript index 39b7846e9..586b0ee95 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -72,6 +72,7 @@ def build(bld): 'traced-callback.cc', 'trace-source-accessor.cc', 'config.cc', + 'callback.cc', ] core.uselib = 'RT' @@ -115,7 +116,8 @@ def build(bld): 'trace-source-accessor.h', 'config.h', 'object-vector.h', - 'deprecated.h' + 'deprecated.h', + 'abort.h', ] if sys.platform == 'win32': diff --git a/src/devices/wifi/dca-txop.cc b/src/devices/wifi/dca-txop.cc index 24e3f64a2..a9d3f6790 100644 --- a/src/devices/wifi/dca-txop.cc +++ b/src/devices/wifi/dca-txop.cc @@ -305,12 +305,6 @@ DcaTxop::NeedFragmentation (void) return station->NeedFragmentation (m_currentPacket); } -uint32_t -DcaTxop::GetNFragments (void) -{ - WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - return station->GetNFragments (m_currentPacket); -} void DcaTxop::NextFragment (void) { @@ -337,12 +331,19 @@ DcaTxop::GetNextFragmentSize (void) return station->GetFragmentSize (m_currentPacket, m_fragmentNumber + 1); } +uint32_t +DcaTxop::GetFragmentOffset (void) +{ + WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); + return station->GetFragmentOffset (m_currentPacket, m_fragmentNumber); +} + Ptr DcaTxop::GetFragmentPacket (WifiMacHeader *hdr) { *hdr = m_currentHdr; hdr->SetFragmentNumber (m_fragmentNumber); - uint32_t startOffset = m_fragmentNumber * GetFragmentSize (); + uint32_t startOffset = GetFragmentOffset (); Ptr fragment; if (IsLastFragment ()) { diff --git a/src/devices/wifi/dca-txop.h b/src/devices/wifi/dca-txop.h index 22d01ad09..7765520b2 100644 --- a/src/devices/wifi/dca-txop.h +++ b/src/devices/wifi/dca-txop.h @@ -137,9 +137,9 @@ private: bool NeedRtsRetransmission (void); bool NeedDataRetransmission (void); bool NeedFragmentation (void); - uint32_t GetNFragments (void); uint32_t GetNextFragmentSize (void); uint32_t GetFragmentSize (void); + uint32_t GetFragmentOffset (void); WifiRemoteStation *GetStation (Mac48Address to) const; bool IsLastFragment (void); void NextFragment (void); diff --git a/src/devices/wifi/mac-low.cc b/src/devices/wifi/mac-low.cc index 35eeb6636..e36f15738 100644 --- a/src/devices/wifi/mac-low.cc +++ b/src/devices/wifi/mac-low.cc @@ -1055,7 +1055,7 @@ MacLow::GetStation (Mac48Address ad) const void MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr); /* send a CTS when you receive a RTS * right after SIFS. */ diff --git a/src/devices/wifi/nqap-wifi-mac.cc b/src/devices/wifi/nqap-wifi-mac.cc index 8d4f61c4c..f5f6c5016 100644 --- a/src/devices/wifi/nqap-wifi-mac.cc +++ b/src/devices/wifi/nqap-wifi-mac.cc @@ -76,6 +76,9 @@ NqapWifiMac::NqapWifiMac () m_dca->SetTxFailedCallback (MakeCallback (&NqapWifiMac::TxFailed, this)); m_beaconDca = CreateObject (); + m_beaconDca->SetAifsn(1); + m_beaconDca->SetMinCw(0); + m_beaconDca->SetMaxCw(0); m_beaconDca->SetLow (m_low); m_beaconDca->SetManager (m_dcfManager); } diff --git a/src/devices/wifi/nqsta-wifi-mac.cc b/src/devices/wifi/nqsta-wifi-mac.cc index 1b956b4ca..2f94f52d8 100644 --- a/src/devices/wifi/nqsta-wifi-mac.cc +++ b/src/devices/wifi/nqsta-wifi-mac.cc @@ -479,7 +479,10 @@ NqstaWifiMac::Receive (Ptr packet, WifiMacHeader const *hdr) } else if (hdr->IsData ()) { - ForwardUp (packet, hdr->GetAddr2 (), hdr->GetAddr1 ()); + if (hdr->GetAddr3 () != GetAddress ()) + { + ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ()); + } } else if (hdr->IsProbeReq () || hdr->IsAssocReq ()) diff --git a/src/devices/wifi/wifi-mac.cc b/src/devices/wifi/wifi-mac.cc index f070ef214..844eb6ef1 100644 --- a/src/devices/wifi/wifi-mac.cc +++ b/src/devices/wifi/wifi-mac.cc @@ -75,7 +75,8 @@ WifiMac::GetTypeId (void) .SetParent () .AddAttribute ("CtsTimeout", "When this timeout expires, the RTS/CTS handshake has failed.", TimeValue (GetDefaultCtsAckTimeout ()), - MakeTimeAccessor (&WifiMac::m_ctsTimeout), + MakeTimeAccessor (&WifiMac::SetCtsTimeout, + &WifiMac::GetCtsTimeout), MakeTimeChecker ()) .AddAttribute ("AckTimeout", "When this timeout expires, the DATA/ACK handshake has failed.", TimeValue (GetDefaultCtsAckTimeout ()), @@ -120,31 +121,11 @@ WifiMac::GetTypeId (void) return tid; } -void -WifiMac::SetPifs (Time pifs) -{ - m_pifs = pifs; -} -void -WifiMac::SetCtsTimeout (Time ctsTimeout) -{ - m_ctsTimeout = ctsTimeout; -} void WifiMac::SetMaxPropagationDelay (Time delay) { m_maxPropagationDelay = delay; } -Time -WifiMac::GetPifs (void) const -{ - return m_pifs; -} -Time -WifiMac::GetCtsTimeout (void) const -{ - return m_ctsTimeout; -} Time WifiMac::GetMsduLifetime (void) const diff --git a/src/devices/wifi/wifi-mac.h b/src/devices/wifi/wifi-mac.h index 3c9112b22..217c367fe 100644 --- a/src/devices/wifi/wifi-mac.h +++ b/src/devices/wifi/wifi-mac.h @@ -187,8 +187,6 @@ private: static Time GetDefaultCtsAckDelay (void); static Time GetDefaultCtsAckTimeout (void); - Time m_pifs; - Time m_ctsTimeout; Time m_maxPropagationDelay; uint32_t m_maxMsduSize; }; diff --git a/src/devices/wifi/wifi-remote-station-manager.cc b/src/devices/wifi/wifi-remote-station-manager.cc index cab82289d..9744587d5 100644 --- a/src/devices/wifi/wifi-remote-station-manager.cc +++ b/src/devices/wifi/wifi-remote-station-manager.cc @@ -656,6 +656,13 @@ WifiRemoteStation::GetFragmentSize (Ptr packet, uint32_t fragmentN return GetManager ()->GetFragmentationThreshold (); } } +uint32_t +WifiRemoteStation::GetFragmentOffset (Ptr packet, uint32_t fragmentNumber) +{ + NS_ASSERT (fragmentNumber < GetNFragments (packet)); + uint32_t fragmentOffset = fragmentNumber * GetManager ()->GetFragmentationThreshold (); + return fragmentOffset; +} bool WifiRemoteStation::IsLastFragment (Ptr packet, uint32_t fragmentNumber) diff --git a/src/devices/wifi/wifi-remote-station-manager.h b/src/devices/wifi/wifi-remote-station-manager.h index 2c89e04dc..00e23f485 100644 --- a/src/devices/wifi/wifi-remote-station-manager.h +++ b/src/devices/wifi/wifi-remote-station-manager.h @@ -226,17 +226,18 @@ public: * \returns true if this packet should be fragmented, false otherwise. */ virtual bool NeedFragmentation (Ptr packet); - /** - * \param packet the packet to send - * \returns the number of fragments which should be used for this packet. - */ - virtual uint32_t GetNFragments (Ptr packet); /** * \param packet the packet to send * \param fragmentNumber the fragment index of the next fragment to send (starts at zero). * \returns the size of the corresponding fragment. */ virtual uint32_t GetFragmentSize (Ptr packet, uint32_t fragmentNumber); + /** + * \param packet the packet to send + * \param fragmentNumber the fragment index of the next fragment to send (starts at zero). + * \returns the offset within the original packet where this fragment starts. + */ + virtual uint32_t GetFragmentOffset (Ptr packet, uint32_t fragmentNumber); /** * \param packet the packet to send * \param fragmentNumber the fragment index of the next fragment to send (starts at zero). @@ -262,6 +263,7 @@ private: virtual Ptr GetManager (void) const = 0; virtual WifiMode DoGetDataMode (uint32_t size) = 0; virtual WifiMode DoGetRtsMode (void) = 0; + uint32_t GetNFragments (Ptr packet); protected: virtual void DoReportRtsFailed (void) = 0; virtual void DoReportDataFailed (void) = 0; diff --git a/src/helper/csma-helper.cc b/src/helper/csma-helper.cc index d5d2b379b..b3ee71a60 100644 --- a/src/helper/csma-helper.cc +++ b/src/helper/csma-helper.cc @@ -39,10 +39,10 @@ CsmaHelper::CsmaHelper () void CsmaHelper::SetQueue (std::string type, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3, - std::string n4, const AttributeValue &v4) + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4) { m_queueFactory.SetTypeId (type); m_queueFactory.Set (n1, v1); @@ -78,6 +78,13 @@ void CsmaHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid) { std::ostringstream oss; + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/"; + Config::MatchContainer matches = Config::LookupMatches (oss.str ()); + if (matches.GetN () == 0) + { + return; + } + oss.str (""); oss << filename << "-" << nodeid << "-" << deviceid << ".pcap"; Ptr pcap = Create (); pcap->Open (oss.str ()); @@ -106,9 +113,9 @@ CsmaHelper::EnablePcap (std::string filename, NodeContainer n) { Ptr node = *i; for (uint32_t j = 0; j < node->GetNDevices (); ++j) - { - devs.Add (node->GetDevice (j)); - } + { + devs.Add (node->GetDevice (j)); + } } EnablePcap (filename, devs); } @@ -153,9 +160,9 @@ CsmaHelper::EnableAscii (std::ostream &os, NodeContainer n) { Ptr node = *i; for (uint32_t j = 0; j < node->GetNDevices (); ++j) - { - devs.Add (node->GetDevice (j)); - } + { + devs.Add (node->GetDevice (j)); + } } EnableAscii (os, devs); } @@ -192,6 +199,19 @@ CsmaHelper::Install (const NodeContainer &c, Ptr channel) return container; } +void +CsmaHelper::InstallStar (Ptr hub, NodeContainer spokes, + NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices) +{ + for (uint32_t i = 0; i < spokes.GetN (); ++i) + { + NodeContainer nodes (hub, spokes.Get (i)); + NetDeviceContainer nd = Install (nodes); + hubDevices.Add (nd.Get (0)); + spokeDevices.Add (nd.Get (1)); + } +} + void CsmaHelper::EnqueueEvent (Ptr writer, Ptr packet) { diff --git a/src/helper/csma-helper.h b/src/helper/csma-helper.h index 89cb7f138..9ffa4a51b 100644 --- a/src/helper/csma-helper.h +++ b/src/helper/csma-helper.h @@ -57,10 +57,10 @@ public: * CsmaNetDevice created through CsmaHelper::Install. */ void SetQueue (std::string type, - std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), - std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), - std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), - std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue ()); + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue ()); /** * \param n1 the name of the attribute to set @@ -179,6 +179,39 @@ public: */ NetDeviceContainer Install (const NodeContainer &c, Ptr channel); + /** + * \brief Make a star network topology. + * + * Given a pointer to a node that will become the hub of the star, and a + * NodeContainer containing pointers to the nodes that will become the + * spokes; we construct CSMA net devices on the hub (corresponding to the + * spokes) and store them in the hubDevices NetDeviceContainer. We add a + * net device to each spoke node and store them in the spokeDevices + * NetDeviceContainer. A CSMA is created for each spoke. + * + * Usually when one thinks of a star network, one thinks of point-to-point + * links. We're just using a single pair of devices on a multi-point-to-point + * network "drops" as the link. You are free to add any number of other + * devices on the link if you want. + * + * The ordering of the devices in the hubDevices container is according to + * the order of the spokes container -- that is, hubDevices[0] will be the + * net device used on the hub that talks to spokes[0]. the container entry + * spokeDevices[0] will have the device that hubDevices[0] talks to -- those + * two devices are the ones that connect hub to spokes[0]. + * + * \param hub The central node of the star network + * \param spokes A NodeContainer of the nodes that will be the spoke (leaf) + * nodes + * \param hubDevices A NetDeviceContainer that will be filled with pointers + * to the point-to-point net devices created on the hub. + * \param spokeDevices A NetDeviceContainer that will be filled with pointers + * to the point-to-point net devices created on each of + * the spokes. + */ + void InstallStar (Ptr hub, NodeContainer spokes, + NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices); + private: static void RxEvent (Ptr writer, Ptr packet); static void EnqueueEvent (Ptr writer, Ptr packet); diff --git a/src/helper/ipv4-interface-container.cc b/src/helper/ipv4-interface-container.cc index 9b57609f3..d31174e30 100644 --- a/src/helper/ipv4-interface-container.cc +++ b/src/helper/ipv4-interface-container.cc @@ -6,11 +6,21 @@ namespace ns3 { Ipv4InterfaceContainer::Ipv4InterfaceContainer () {} +void +Ipv4InterfaceContainer::Add (Ipv4InterfaceContainer other) +{ + for (InterfaceVector::const_iterator i = other.m_interfaces.begin (); i != other.m_interfaces.end (); i++) + { + m_interfaces.push_back (*i); + } +} + uint32_t Ipv4InterfaceContainer::GetN (void) const { return m_interfaces.size (); } + Ipv4Address Ipv4InterfaceContainer::GetAddress (uint32_t i) const { diff --git a/src/helper/ipv4-interface-container.h b/src/helper/ipv4-interface-container.h index 7c38fac15..ed544bef8 100644 --- a/src/helper/ipv4-interface-container.h +++ b/src/helper/ipv4-interface-container.h @@ -20,6 +20,11 @@ public: */ Ipv4InterfaceContainer (); + /** + * Concatenate the entries in the other container with ours. + */ + void Add (Ipv4InterfaceContainer other); + /** * \returns the number of interfaces stored in this Ipv4InterfaceContainer. */ @@ -31,7 +36,9 @@ public: void Add (Ptr ipv4, uint32_t interface); private: - std::vector,uint32_t> > m_interfaces; + + typedef std::vector,uint32_t> > InterfaceVector; + InterfaceVector m_interfaces; }; } // namespace ns3 diff --git a/src/helper/mobility-helper.cc b/src/helper/mobility-helper.cc index 9c0bb22fa..ad595f4d2 100644 --- a/src/helper/mobility-helper.cc +++ b/src/helper/mobility-helper.cc @@ -47,15 +47,15 @@ MobilityHelper::SetPositionAllocator (Ptr allocator) } void MobilityHelper::SetPositionAllocator (std::string type, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3, - std::string n4, const AttributeValue &v4, - std::string n5, const AttributeValue &v5, - std::string n6, const AttributeValue &v6, - std::string n7, const AttributeValue &v7, - std::string n8, const AttributeValue &v8, - std::string n9, const AttributeValue &v9) + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7, + std::string n8, const AttributeValue &v8, + std::string n9, const AttributeValue &v9) { ObjectFactory pos; pos.SetTypeId (type); @@ -73,15 +73,15 @@ MobilityHelper::SetPositionAllocator (std::string type, void MobilityHelper::SetMobilityModel (std::string type, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3, - std::string n4, const AttributeValue &v4, - std::string n5, const AttributeValue &v5, - std::string n6, const AttributeValue &v6, - std::string n7, const AttributeValue &v7, - std::string n8, const AttributeValue &v8, - std::string n9, const AttributeValue &v9) + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7, + std::string n8, const AttributeValue &v8, + std::string n9, const AttributeValue &v9) { m_mobility.SetTypeId (type); m_mobility.Set (n1, v1); @@ -122,29 +122,29 @@ MobilityHelper::Install (NodeContainer c) Ptr object = *i; Ptr model = object->GetObject (); if (model == 0) - { - model = m_mobility.Create ()->GetObject (); - if (model == 0) - { - NS_FATAL_ERROR ("The requested mobility model is not a mobility model: \""<< - m_mobility.GetTypeId ().GetName ()<<"\""); - } - if (m_mobilityStack.empty ()) - { - NS_LOG_DEBUG ("node="<AggregateObject (hierarchical); - NS_LOG_DEBUG ("node="<AggregateObject (hierarchical); + NS_LOG_DEBUG ("node="< model = GetMobilityModel (line.substr (startNodeId + 1, - endNodeId - startNodeId), - store); - if (model == 0) - { - continue; - } - if (startNodeId == 6) - { - double value = ReadDouble (line.substr (endNodeId + 9, std::string::npos)); - std::string coordinate = line.substr (endNodeId + 6, 1); + { + std::string line; + getline (file, line); + std::string::size_type startNodeId = line.find_first_of ("("); + std::string::size_type endNodeId = line.find_first_of (")"); + if (startNodeId == std::string::npos || + endNodeId == std::string::npos) + { + continue; + } + Ptr model = GetMobilityModel (line.substr (startNodeId + 1, + endNodeId - startNodeId), + store); + if (model == 0) + { + continue; + } + if (startNodeId == 6) + { + double value = ReadDouble (line.substr (endNodeId + 9, std::string::npos)); + std::string coordinate = line.substr (endNodeId + 6, 1); Vector position = model->GetPosition (); - if (coordinate == "X") - { + if (coordinate == "X") + { position.x = value; - NS_LOG_DEBUG ("X=" << value); - } - else if (coordinate == "Y") - { + NS_LOG_DEBUG ("X=" << value); + } + else if (coordinate == "Y") + { position.y = value; - NS_LOG_DEBUG ("Y=" << value); - } - else if (coordinate == "Z") - { + NS_LOG_DEBUG ("Y=" << value); + } + else if (coordinate == "Z") + { position.z = value; - NS_LOG_DEBUG ("Z=" << value); - } + NS_LOG_DEBUG ("Z=" << value); + } else { continue; } model->SetPosition (position); - } - else - { - double at = ReadDouble (line.substr (8, startNodeId - 17)); - std::string::size_type xSpeedEnd = line.find_first_of (" ", endNodeId + 10); - std::string::size_type ySpeedEnd = line.find_first_of (" ", xSpeedEnd + 1); - double xSpeed = ReadDouble (line.substr (endNodeId + 10, xSpeedEnd - endNodeId - 10)); - double ySpeed = ReadDouble (line.substr (xSpeedEnd + 1, ySpeedEnd - xSpeedEnd - 1)); - double zSpeed = ReadDouble (line.substr (ySpeedEnd + 1, std::string::npos)); - NS_LOG_DEBUG ("at=" << at << "xSpeed=" << xSpeed << ", ySpeed=" << ySpeed << ", zSpeed=" << zSpeed); - Simulator::Schedule (Seconds (at), &StaticSpeedMobilityModel::SetSpeed, model, - Vector (xSpeed, ySpeed, zSpeed)); - } - } + } + else + { + std::string::size_type atEnd = line.find_first_of (" ", 8); + std::string atStr = line.substr (8, atEnd-8); + NS_LOG_DEBUG (atStr); + double at = ReadDouble (atStr); + std::string::size_type xSpeedEnd = line.find_first_of (" ", endNodeId + 10); + std::string::size_type ySpeedEnd = line.find_first_of (" ", xSpeedEnd + 1); + double xSpeed = ReadDouble (line.substr (endNodeId + 10, xSpeedEnd - endNodeId - 10)); + double ySpeed = ReadDouble (line.substr (xSpeedEnd + 1, ySpeedEnd - xSpeedEnd - 1)); + double zSpeed = ReadDouble (line.substr (ySpeedEnd + 1, std::string::npos)); + NS_LOG_DEBUG ("at=" << at << "xSpeed=" << xSpeed << ", ySpeed=" << ySpeed << ", zSpeed=" << zSpeed); + Simulator::Schedule (Seconds (at), &StaticSpeedMobilityModel::SetVelocity, model, + Vector (xSpeed, ySpeed, zSpeed)); + } + } file.close(); } } diff --git a/src/helper/ns2-mobility-helper.h b/src/helper/ns2-mobility-helper.h index 809a51125..795f16392 100644 --- a/src/helper/ns2-mobility-helper.h +++ b/src/helper/ns2-mobility-helper.h @@ -90,14 +90,14 @@ Ns2MobilityHelper::Install (T begin, T end) const MyObjectStore (T begin, T end) : m_begin (begin), m_end (end) - {} + {} virtual Ptr Get (uint32_t i) const { T iterator = m_begin; iterator += i; if (iterator >= m_end) - { - return 0; - } + { + return 0; + } return *iterator; } private: diff --git a/src/helper/olsr-helper.cc b/src/helper/olsr-helper.cc index 656e276ca..86f85ffd3 100644 --- a/src/helper/olsr-helper.cc +++ b/src/helper/olsr-helper.cc @@ -30,14 +30,14 @@ OlsrHelper::OlsrHelper () void OlsrHelper::SetAgent (std::string tid, - std::string n0, const AttributeValue &v0, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3, - std::string n4, const AttributeValue &v4, - std::string n5, const AttributeValue &v5, - std::string n6, const AttributeValue &v6, - std::string n7, const AttributeValue &v7) + std::string n0, const AttributeValue &v0, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7) { m_agentFactory.SetTypeId (tid); m_agentFactory.Set (n0, v0); diff --git a/src/helper/olsr-helper.h b/src/helper/olsr-helper.h index d2eaea80d..3a37167e5 100644 --- a/src/helper/olsr-helper.h +++ b/src/helper/olsr-helper.h @@ -38,14 +38,14 @@ public: * \brief Set default OLSR routing agent attributes */ void SetAgent (std::string tid, - std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), - std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), - std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), - std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), - std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), - std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), - std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), - std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); + std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); /** * \brief Enable OLSR routing for a set of nodes diff --git a/src/helper/point-to-point-helper.cc b/src/helper/point-to-point-helper.cc index ed951b56e..ae45b7ca6 100644 --- a/src/helper/point-to-point-helper.cc +++ b/src/helper/point-to-point-helper.cc @@ -39,10 +39,10 @@ PointToPointHelper::PointToPointHelper () void PointToPointHelper::SetQueue (std::string type, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3, - std::string n4, const AttributeValue &v4) + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4) { m_queueFactory.SetTypeId (type); m_queueFactory.Set (n1, v1); @@ -78,6 +78,13 @@ void PointToPointHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid) { std::ostringstream oss; + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/"; + Config::MatchContainer matches = Config::LookupMatches (oss.str ()); + if (matches.GetN () == 0) + { + return; + } + oss.str (""); oss << filename << "-" << nodeid << "-" << deviceid << ".pcap"; Ptr pcap = Create (); pcap->Open (oss.str ()); @@ -106,9 +113,9 @@ PointToPointHelper::EnablePcap (std::string filename, NodeContainer n) { Ptr node = *i; for (uint32_t j = 0; j < node->GetNDevices (); ++j) - { - devs.Add (node->GetDevice (j)); - } + { + devs.Add (node->GetDevice (j)); + } } EnablePcap (filename, devs); } @@ -153,9 +160,9 @@ PointToPointHelper::EnableAscii (std::ostream &os, NodeContainer n) { Ptr node = *i; for (uint32_t j = 0; j < node->GetNDevices (); ++j) - { - devs.Add (node->GetDevice (j)); - } + { + devs.Add (node->GetDevice (j)); + } } EnableAscii (os, devs); } @@ -172,6 +179,7 @@ PointToPointHelper::Install (NodeContainer c) NS_ASSERT (c.GetN () == 2); return Install (c.Get (0), c.Get (1)); } + NetDeviceContainer PointToPointHelper::Install (Ptr a, Ptr b) { @@ -196,6 +204,18 @@ PointToPointHelper::Install (Ptr a, Ptr b) return container; } +void +PointToPointHelper::InstallStar (Ptr hub, NodeContainer spokes, + NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices) +{ + for (uint32_t i = 0; i < spokes.GetN (); ++i) + { + NetDeviceContainer nd = Install (hub, spokes.Get (i)); + hubDevices.Add (nd.Get (0)); + spokeDevices.Add (nd.Get (1)); + } +} + void PointToPointHelper::EnqueueEvent (Ptr writer, Ptr packet) { diff --git a/src/helper/point-to-point-helper.h b/src/helper/point-to-point-helper.h index a86daf52a..4b53cf4c1 100644 --- a/src/helper/point-to-point-helper.h +++ b/src/helper/point-to-point-helper.h @@ -57,10 +57,10 @@ public: * PointToPointNetDevice created through PointToPointHelper::Install. */ void SetQueue (std::string type, - std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), - std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), - std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), - std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue ()); + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue ()); /** * \param name the name of the attribute to set @@ -170,6 +170,7 @@ public: * ns3::NetDevice with the ns3::Node and ns3::PointToPointChannel. */ NetDeviceContainer Install (NodeContainer c); + /** * \param a first node * \param b second node @@ -178,6 +179,34 @@ public: */ NetDeviceContainer Install (Ptr a, Ptr b); + /** + * \brief Make a star network topology. + * + * Given a pointer to a node that will become the hub of the star, and a + * NodeContainer containing pointers to the nodes that will become the + * spokes; we construct point to point net devices on the hub (corresponding + * to the spokes) and store them in the hubDevices NetDeviceContainer. We + * add a net device to each spoke node and store them in the spokeDevices + * NetDeviceContainer. A point-to-point channel is created for each spoke. + * + * The ordering of the devices in the hubDevices container is according to + * the order of the spokes container -- that is, hubDevices[0] will be the + * net device used on the hub that talks to spokes[0]. the container entry + * spokeDevices[0] will have the device that hubDevices[0] talks to -- those + * two devices are the ones that connect hub to spokes[0]. + * + * \param hub The central node of the star network + * \param spokes A NodeContainer of the nodes that will be the spoke (leaf) + * nodes + * \param hubDevices A NetDeviceContainer that will be filled with pointers + * to the point-to-point net devices created on the hub. + * \param spokeDevices A NetDeviceContainer that will be filled with pointers + * to the point-to-point net devices created on each of + * the spokes. + */ + void InstallStar (Ptr hub, NodeContainer spokes, + NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices); + private: void EnablePcap (Ptr node, Ptr device, Ptr queue); void EnableAscii (Ptr node, Ptr device); diff --git a/src/helper/wifi-helper.cc b/src/helper/wifi-helper.cc index dd4a122c3..ce5f07701 100644 --- a/src/helper/wifi-helper.cc +++ b/src/helper/wifi-helper.cc @@ -40,30 +40,30 @@ NS_LOG_COMPONENT_DEFINE ("WifiHelper"); namespace ns3 { static void PcapPhyTxEvent (Ptr writer, Ptr packet, - WifiMode mode, WifiPreamble preamble, - uint8_t txLevel) + WifiMode mode, WifiPreamble preamble, + uint8_t txLevel) { writer->WritePacket (packet); } static void PcapPhyRxEvent (Ptr writer, - Ptr packet, double snr, WifiMode mode, - enum WifiPreamble preamble) + Ptr packet, double snr, WifiMode mode, + enum WifiPreamble preamble) { writer->WritePacket (packet); } static void AsciiPhyTxEvent (std::ostream *os, std::string context, - Ptr packet, - WifiMode mode, WifiPreamble preamble, - uint8_t txLevel) + Ptr packet, + WifiMode mode, WifiPreamble preamble, + uint8_t txLevel) { *os << "+ " << Simulator::Now () << " " << context << " " << *packet << std::endl; } static void AsciiPhyRxOkEvent (std::ostream *os, std::string context, - Ptr packet, double snr, WifiMode mode, - enum WifiPreamble preamble) + Ptr packet, double snr, WifiMode mode, + enum WifiPreamble preamble) { *os << "r " << Simulator::Now () << " " << context << " " << *packet << std::endl; } @@ -78,14 +78,14 @@ WifiHelper::WifiHelper () void WifiHelper::SetRemoteStationManager (std::string type, - std::string n0, const AttributeValue &v0, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3, - std::string n4, const AttributeValue &v4, - std::string n5, const AttributeValue &v5, - std::string n6, const AttributeValue &v6, - std::string n7, const AttributeValue &v7) + std::string n0, const AttributeValue &v0, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7) { m_stationManager = ObjectFactory (); m_stationManager.SetTypeId (type); @@ -101,14 +101,14 @@ WifiHelper::SetRemoteStationManager (std::string type, void WifiHelper::SetMac (std::string type, - std::string n0, const AttributeValue &v0, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3, - std::string n4, const AttributeValue &v4, - std::string n5, const AttributeValue &v5, - std::string n6, const AttributeValue &v6, - std::string n7, const AttributeValue &v7) + std::string n0, const AttributeValue &v0, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7) { m_mac = ObjectFactory (); m_mac.SetTypeId (type); @@ -124,14 +124,14 @@ WifiHelper::SetMac (std::string type, void WifiHelper::SetPhy (std::string type, - std::string n0, const AttributeValue &v0, - std::string n1, const AttributeValue &v1, - std::string n2, const AttributeValue &v2, - std::string n3, const AttributeValue &v3, - std::string n4, const AttributeValue &v4, - std::string n5, const AttributeValue &v5, - std::string n6, const AttributeValue &v6, - std::string n7, const AttributeValue &v7) + std::string n0, const AttributeValue &v0, + std::string n1, const AttributeValue &v1, + std::string n2, const AttributeValue &v2, + std::string n3, const AttributeValue &v3, + std::string n4, const AttributeValue &v4, + std::string n5, const AttributeValue &v5, + std::string n6, const AttributeValue &v6, + std::string n7, const AttributeValue &v7) { m_phy = ObjectFactory (); m_phy.SetTypeId (type); @@ -149,6 +149,13 @@ void WifiHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid) { std::ostringstream oss; + oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/"; + Config::MatchContainer matches = Config::LookupMatches (oss.str ()); + if (matches.GetN () == 0) + { + return; + } + oss.str (""); oss << filename << "-" << nodeid << "-" << deviceid << ".pcap"; Ptr pcap = Create (); pcap->Open (oss.str ()); @@ -177,9 +184,9 @@ WifiHelper::EnablePcap (std::string filename, NodeContainer n) { Ptr node = *i; for (uint32_t j = 0; j < node->GetNDevices (); ++j) - { - devs.Add (node->GetDevice (j)); - } + { + devs.Add (node->GetDevice (j)); + } } EnablePcap (filename, devs); } @@ -218,9 +225,9 @@ WifiHelper::EnableAscii (std::ostream &os, NodeContainer n) { Ptr node = *i; for (uint32_t j = 0; j < node->GetNDevices (); ++j) - { - devs.Add (node->GetDevice (j)); - } + { + devs.Add (node->GetDevice (j)); + } } EnableAscii (os, devs); } diff --git a/src/helper/wifi-helper.h b/src/helper/wifi-helper.h index 72cc4a198..271563462 100644 --- a/src/helper/wifi-helper.h +++ b/src/helper/wifi-helper.h @@ -65,14 +65,14 @@ public: * in the requested station manager. */ void SetRemoteStationManager (std::string type, - std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), - std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), - std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), - std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), - std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), - std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), - std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), - std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); + std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); /** * \param type the type of ns3::WifiMac to create. @@ -97,14 +97,14 @@ public: * in the requested mac. */ void SetMac (std::string type, - std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), - std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), - std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), - std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), - std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), - std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), - std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), - std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); + std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); /** * \param phyType the type of ns3::WifiPhy to create. @@ -129,14 +129,14 @@ public: * in the requested phy. */ void SetPhy (std::string phyType, - std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), - std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), - std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), - std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), - std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), - std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), - std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), - std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); + std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), + std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), + std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), + std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), + std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), + std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), + std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), + std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); diff --git a/src/internet-stack/arp-l3-protocol.cc b/src/internet-stack/arp-l3-protocol.cc index 43e597e62..e99d233d0 100644 --- a/src/internet-stack/arp-l3-protocol.cc +++ b/src/internet-stack/arp-l3-protocol.cc @@ -89,7 +89,7 @@ ArpL3Protocol::DoDispose (void) Ptr ArpL3Protocol::CreateCache (Ptr device, Ptr interface) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this << device << interface); Ptr ipv4 = m_node->GetObject (); Ptr cache = CreateObject (); cache->SetDevice (device, interface); @@ -103,7 +103,7 @@ ArpL3Protocol::CreateCache (Ptr device, Ptr interface) Ptr ArpL3Protocol::FindCache (Ptr device) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this << device); for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++) { if ((*i)->GetDevice () == device) @@ -120,7 +120,7 @@ void ArpL3Protocol::Receive(Ptr device, Ptr p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this << device << p->GetSize () << protocol << from << to << packetType); Ptr packet = p->Copy (); @@ -199,7 +199,7 @@ ArpL3Protocol::Lookup (Ptr packet, Ipv4Address destination, Ptr cache, Address *hardwareDestination) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this << packet << destination << device << cache); ArpCache::Entry *entry = cache->Lookup (destination); if (entry != 0) { @@ -265,7 +265,7 @@ ArpL3Protocol::Lookup (Ptr packet, Ipv4Address destination, void ArpL3Protocol::SendArpRequest (Ptr cache, Ipv4Address to) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this << cache << to); ArpHeader arp; NS_LOG_LOGIC ("ARP: sending request from node "<GetId ()<< " || src: " << cache->GetDevice ()->GetAddress () << @@ -284,7 +284,7 @@ ArpL3Protocol::SendArpRequest (Ptr cache, Ipv4Address to) void ArpL3Protocol::SendArpReply (Ptr cache, Ipv4Address toIp, Address toMac) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION (this << cache << toIp << toMac); ArpHeader arp; NS_LOG_LOGIC ("ARP: sending reply from node "<GetId ()<< "|| src: " << cache->GetDevice ()->GetAddress () << diff --git a/src/internet-stack/nsc-tcp-socket-impl.cc b/src/internet-stack/nsc-tcp-socket-impl.cc index 3023f49d2..cbb4d777a 100644 --- a/src/internet-stack/nsc-tcp-socket-impl.cc +++ b/src/internet-stack/nsc-tcp-socket-impl.cc @@ -64,6 +64,8 @@ NscTcpSocketImpl::GetTypeId () : m_endPoint (0), m_node (0), m_tcp (0), + m_localAddress (Ipv4Address::GetZero ()), + m_localPort (0), m_peerAddress ("0.0.0.0", 0), m_errno (ERROR_NOTERROR), m_shutdownSend (false), @@ -328,34 +330,19 @@ NscTcpSocketImpl::Send (const Ptr p, uint32_t flags) return -1; } - bool txEmpty = m_txBuffer.empty(); + uint32_t sent = p->GetSize (); if (m_state == ESTABLISHED) { - if (txEmpty) - { - m_txBuffer.push(p); - m_txBufferSize += p->GetSize (); - } - if (!SendPendingData()) - { - if (m_errno == ERROR_AGAIN) - { - return txEmpty ? p->GetSize () : -1; - } - if (txEmpty) - { - m_txBuffer.pop (); - m_txBufferSize = 0; - } - return -1; - } + m_txBuffer.push(p); + m_txBufferSize += sent; + SendPendingData(); } else { // SYN_SET -- Queue Data m_txBuffer.push(p); - m_txBufferSize += p->GetSize (); + m_txBufferSize += sent; } - return p->GetSize (); + return sent; } else { @@ -395,9 +382,9 @@ NscTcpSocketImpl::GetTxAvailable (void) const } int -NscTcpSocketImpl::Listen (uint32_t q) +NscTcpSocketImpl::Listen (void) { - NS_LOG_FUNCTION (this << q); + NS_LOG_FUNCTION (this); m_nscTcpSocket->listen(m_localPort); m_state = LISTEN; return 0; @@ -434,6 +421,7 @@ NscTcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags) NS_LOG_FUNCTION_NOARGS (); if (m_deliveryQueue.empty() ) { + m_errno = ERROR_AGAIN; return 0; } Ptr p = m_deliveryQueue.front (); @@ -444,6 +432,7 @@ NscTcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags) } else { + m_errno = ERROR_AGAIN; p = 0; } return p; @@ -466,6 +455,14 @@ NscTcpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags, return packet; } +int +NscTcpSocketImpl::GetSockName (Address &address) const +{ + NS_LOG_FUNCTION_NOARGS (); + address = InetSocketAddress(m_localAddress, m_localPort); + return 0; +} + uint32_t NscTcpSocketImpl::GetRxAvailable (void) const { @@ -627,6 +624,7 @@ bool NscTcpSocketImpl::SendPendingData (void) size_t size, written = 0; do { + NS_ASSERT (!m_txBuffer.empty ()); Ptr &p = m_txBuffer.front (); size = p->GetSize (); NS_ASSERT (size > 0); @@ -635,12 +633,6 @@ bool NscTcpSocketImpl::SendPendingData (void) ret = m_nscTcpSocket->send_data((const char *)p->PeekData (), size); if (ret <= 0) { - m_errno = GetNativeNs3Errno(ret); - if (m_errno != ERROR_AGAIN) - { - NS_LOG_WARN ("Error (" << ret << ") " << - "during send_data, ns-3 errno set to" << m_errno); - } break; } written += ret; diff --git a/src/internet-stack/nsc-tcp-socket-impl.h b/src/internet-stack/nsc-tcp-socket-impl.h index 61689f88a..fa142615c 100644 --- a/src/internet-stack/nsc-tcp-socket-impl.h +++ b/src/internet-stack/nsc-tcp-socket-impl.h @@ -73,7 +73,7 @@ public: virtual int ShutdownSend (void); virtual int ShutdownRecv (void); virtual int Connect(const Address &address); - virtual int Listen(uint32_t queueLimit); + virtual int Listen(void); virtual uint32_t GetTxAvailable (void) const; virtual int Send (Ptr p, uint32_t flags); virtual int SendTo(Ptr p, uint32_t flags, const Address &toAddress); @@ -81,6 +81,7 @@ public: virtual Ptr Recv (uint32_t maxSize, uint32_t flags); virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress); + virtual int GetSockName (Address &address) const; private: void NSCWakeup(void); diff --git a/src/internet-stack/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc index d9deccc1b..bf058bc3f 100644 --- a/src/internet-stack/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -62,6 +62,8 @@ TcpSocketImpl::GetTypeId () m_endPoint (0), m_node (0), m_tcp (0), + m_localAddress (Ipv4Address::GetZero ()), + m_localPort (0), m_errno (ERROR_NOTERROR), m_shutdownSend (false), m_shutdownRecv (false), @@ -454,9 +456,9 @@ TcpSocketImpl::GetTxAvailable (void) const } int -TcpSocketImpl::Listen (uint32_t q) +TcpSocketImpl::Listen (void) { - NS_LOG_FUNCTION (this << q); + NS_LOG_FUNCTION (this); Actions_t action = ProcessEvent (APP_LISTEN); ProcessAction (action); return 0; @@ -553,6 +555,14 @@ TcpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags, return packet; } +int +TcpSocketImpl::GetSockName (Address &address) const +{ + NS_LOG_FUNCTION_NOARGS (); + address = InetSocketAddress(m_localAddress, m_localPort); + return 0; +} + void TcpSocketImpl::ForwardUp (Ptr packet, Ipv4Address ipv4, uint16_t port) { @@ -1915,7 +1925,7 @@ TcpSocketImplTest::SetupDefaultSim () InetSocketAddress serverremoteaddr (Ipv4Address(ipaddr0), port); listeningSock->Bind(serverlocaladdr); - listeningSock->Listen (0); + listeningSock->Listen (); sock1->Connect(serverremoteaddr); } diff --git a/src/internet-stack/tcp-socket-impl.h b/src/internet-stack/tcp-socket-impl.h index 123d588ec..81d75fce6 100644 --- a/src/internet-stack/tcp-socket-impl.h +++ b/src/internet-stack/tcp-socket-impl.h @@ -86,7 +86,7 @@ public: virtual int ShutdownSend (void); virtual int ShutdownRecv (void); virtual int Connect(const Address &address); - virtual int Listen(uint32_t queueLimit); + virtual int Listen(void); virtual uint32_t GetTxAvailable (void) const; virtual int Send (Ptr p, uint32_t flags); virtual int SendTo(Ptr p, uint32_t flags, const Address &toAddress); @@ -94,6 +94,7 @@ public: virtual Ptr Recv (uint32_t maxSize, uint32_t flags); virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress); + virtual int GetSockName (Address &address) const; private: friend class Tcp; diff --git a/src/internet-stack/udp-socket-impl.cc b/src/internet-stack/udp-socket-impl.cc index 939e1984f..3feb6b3f5 100644 --- a/src/internet-stack/udp-socket-impl.cc +++ b/src/internet-stack/udp-socket-impl.cc @@ -216,7 +216,7 @@ UdpSocketImpl::Connect(const Address & address) } int -UdpSocketImpl::Listen (uint32_t queueLimit) +UdpSocketImpl::Listen (void) { m_errno = Socket::ERROR_OPNOTSUPP; return -1; @@ -345,6 +345,7 @@ UdpSocketImpl::DoSendTo (Ptr p, Ipv4Address dest, uint16_t port) m_udp->Send (p->Copy (), addri, bcast, m_endPoint->GetLocalPort (), port); NotifyDataSent (p->GetSize ()); + NotifySend (GetTxAvailable ()); } NS_LOG_LOGIC ("Limited broadcast end."); return p->GetSize(); @@ -355,6 +356,7 @@ UdpSocketImpl::DoSendTo (Ptr p, Ipv4Address dest, uint16_t port) m_udp->Send (p->Copy (), ipv4->GetAddress (localIfIndex), dest, m_endPoint->GetLocalPort (), port); NotifyDataSent (p->GetSize ()); + NotifySend (GetTxAvailable ()); return p->GetSize();; } else @@ -435,6 +437,21 @@ UdpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags, return packet; } +int +UdpSocketImpl::GetSockName (Address &address) const +{ + NS_LOG_FUNCTION_NOARGS (); + if (m_endPoint != 0) + { + address = InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->GetLocalPort()); + } + else + { + address = InetSocketAddress(Ipv4Address::GetZero(), 0); + } + return 0; +} + void UdpSocketImpl::ForwardUp (Ptr packet, Ipv4Address ipv4, uint16_t port) { diff --git a/src/internet-stack/udp-socket-impl.h b/src/internet-stack/udp-socket-impl.h index 31f0f8bc7..03fae2e56 100644 --- a/src/internet-stack/udp-socket-impl.h +++ b/src/internet-stack/udp-socket-impl.h @@ -65,7 +65,7 @@ public: virtual int ShutdownSend (void); virtual int ShutdownRecv (void); virtual int Connect(const Address &address); - virtual int Listen (uint32_t queueLimit); + virtual int Listen (void); virtual uint32_t GetTxAvailable (void) const; virtual int Send (Ptr p, uint32_t flags); virtual int SendTo (Ptr p, uint32_t flags, const Address &address); @@ -73,6 +73,7 @@ public: virtual Ptr Recv (uint32_t maxSize, uint32_t flags); virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress); + virtual int GetSockName (Address &address) const; private: // Attributes set through UdpSocket base class diff --git a/src/mobility/random-direction-2d-mobility-model.cc b/src/mobility/random-direction-2d-mobility-model.cc index 3ae572073..221118cf7 100644 --- a/src/mobility/random-direction-2d-mobility-model.cc +++ b/src/mobility/random-direction-2d-mobility-model.cc @@ -76,8 +76,9 @@ RandomDirection2dMobilityModel::Start (void) void RandomDirection2dMobilityModel::BeginPause (void) { - Time pause = Seconds (m_pause.GetValue ()); + m_helper.Update (); m_helper.Pause (); + Time pause = Seconds (m_pause.GetValue ()); m_event = Simulator::Schedule (pause, &RandomDirection2dMobilityModel::ResetDirectionAndSpeed, this); NotifyCourseChange (); } @@ -86,12 +87,14 @@ void RandomDirection2dMobilityModel::SetDirectionAndSpeed (double direction) { NS_LOG_FUNCTION_NOARGS (); + m_helper.UpdateWithBounds (m_bounds); + Vector position = m_helper.GetCurrentPosition (); double speed = m_speed.GetValue (); const Vector vector (std::cos (direction) * speed, std::sin (direction) * speed, 0.0); - Vector position = m_helper.GetCurrentPosition (m_bounds); - m_helper.Reset (vector); + m_helper.SetVelocity (vector); + m_helper.Unpause (); Vector next = m_bounds.CalculateIntersection (position, vector); Time delay = Seconds (CalculateDistance (position, next) / speed); m_event = Simulator::Schedule (delay, @@ -103,7 +106,8 @@ RandomDirection2dMobilityModel::ResetDirectionAndSpeed (void) { double direction = UniformVariable::GetSingleValue (0, PI); - Vector position = m_helper.GetCurrentPosition (m_bounds); + m_helper.UpdateWithBounds (m_bounds); + Vector position = m_helper.GetCurrentPosition (); switch (m_bounds.GetClosestSide (position)) { case Rectangle::RIGHT: @@ -124,12 +128,13 @@ RandomDirection2dMobilityModel::ResetDirectionAndSpeed (void) Vector RandomDirection2dMobilityModel::DoGetPosition (void) const { - return m_helper.GetCurrentPosition (m_bounds); + m_helper.UpdateWithBounds (m_bounds); + return m_helper.GetCurrentPosition (); } void RandomDirection2dMobilityModel::DoSetPosition (const Vector &position) { - m_helper.InitializePosition (position); + m_helper.SetPosition (position); Simulator::Remove (m_event); m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::Start, this); } diff --git a/src/mobility/random-walk-2d-mobility-model.cc b/src/mobility/random-walk-2d-mobility-model.cc index 59824a4f1..e426a6575 100644 --- a/src/mobility/random-walk-2d-mobility-model.cc +++ b/src/mobility/random-walk-2d-mobility-model.cc @@ -80,12 +80,14 @@ RandomWalk2dMobilityModel::RandomWalk2dMobilityModel () void RandomWalk2dMobilityModel::Start (void) { + m_helper.Update (); double speed = m_speed.GetValue (); double direction = m_direction.GetValue (); Vector vector (std::cos (direction) * speed, std::sin (direction) * speed, 0.0); - m_helper.Reset (vector); + m_helper.SetVelocity (vector); + m_helper.Unpause (); Time delayLeft; if (m_mode == RandomWalk2dMobilityModel::MODE_TIME) @@ -124,7 +126,8 @@ RandomWalk2dMobilityModel::DoWalk (Time delayLeft) void RandomWalk2dMobilityModel::Rebound (Time delayLeft) { - Vector position = m_helper.GetCurrentPosition (m_bounds); + m_helper.UpdateWithBounds (m_bounds); + Vector position = m_helper.GetCurrentPosition (); Vector speed = m_helper.GetVelocity (); switch (m_bounds.GetClosestSide (position)) { @@ -137,7 +140,8 @@ RandomWalk2dMobilityModel::Rebound (Time delayLeft) speed.y = - speed.y; break; } - m_helper.Reset (speed); + m_helper.SetVelocity (speed); + m_helper.Unpause (); DoWalk (delayLeft); } @@ -150,13 +154,14 @@ RandomWalk2dMobilityModel::DoDispose (void) Vector RandomWalk2dMobilityModel::DoGetPosition (void) const { - return m_helper.GetCurrentPosition (m_bounds); + m_helper.UpdateWithBounds (m_bounds); + return m_helper.GetCurrentPosition (); } void RandomWalk2dMobilityModel::DoSetPosition (const Vector &position) { NS_ASSERT (m_bounds.IsInside (position)); - m_helper.InitializePosition (position); + m_helper.SetPosition (position); Simulator::Remove (m_event); m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this); } diff --git a/src/mobility/random-waypoint-mobility-model.cc b/src/mobility/random-waypoint-mobility-model.cc index fd29f82e9..a7c6e1537 100644 --- a/src/mobility/random-waypoint-mobility-model.cc +++ b/src/mobility/random-waypoint-mobility-model.cc @@ -62,6 +62,7 @@ RandomWaypointMobilityModel::RandomWaypointMobilityModel () void RandomWaypointMobilityModel::BeginWalk (void) { + m_helper.Update (); Vector m_current = m_helper.GetCurrentPosition (); Vector destination = m_position->GetNext (); double speed = m_speed.GetValue (); @@ -70,7 +71,7 @@ RandomWaypointMobilityModel::BeginWalk (void) double dz = (destination.z - m_current.z); double k = speed / std::sqrt (dx*dx + dy*dy + dz*dz); - m_helper.Reset (Vector (k*dx, k*dy, k*dz)); + m_helper.SetVelocity (Vector (k*dx, k*dy, k*dz)); Time travelDelay = Seconds (CalculateDistance (destination, m_current) / speed); m_event = Simulator::Schedule (travelDelay, &RandomWaypointMobilityModel::Start, this); @@ -80,21 +81,23 @@ RandomWaypointMobilityModel::BeginWalk (void) void RandomWaypointMobilityModel::Start (void) { - Time pause = Seconds (m_pause.GetValue ()); + m_helper.Update (); m_helper.Pause (); - NotifyCourseChange (); + Time pause = Seconds (m_pause.GetValue ()); m_event = Simulator::Schedule (pause, &RandomWaypointMobilityModel::BeginWalk, this); + NotifyCourseChange (); } Vector RandomWaypointMobilityModel::DoGetPosition (void) const { + m_helper.Update (); return m_helper.GetCurrentPosition (); } void RandomWaypointMobilityModel::DoSetPosition (const Vector &position) { - m_helper.InitializePosition (position); + m_helper.SetPosition (position); Simulator::Remove (m_event); Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this); } diff --git a/src/mobility/static-speed-helper.cc b/src/mobility/static-speed-helper.cc index d781494f6..0a207b77b 100644 --- a/src/mobility/static-speed-helper.cc +++ b/src/mobility/static-speed-helper.cc @@ -29,67 +29,56 @@ StaticSpeedHelper::StaticSpeedHelper (const Vector &position) : m_position (position) {} StaticSpeedHelper::StaticSpeedHelper (const Vector &position, - const Vector &speed) + const Vector &vel) : m_position (position), - m_speed (speed), + m_velocity (vel), m_paused (true) {} void -StaticSpeedHelper::InitializePosition (const Vector &position) +StaticSpeedHelper::SetPosition (const Vector &position) { m_position = position; - m_speed.x = 0.0; - m_speed.y = 0.0; - m_speed.z = 0.0; + m_velocity = Vector (0.0, 0.0, 0.0); m_lastUpdate = Simulator::Now (); - m_paused = true; } Vector StaticSpeedHelper::GetCurrentPosition (void) const { - Update (); return m_position; } Vector StaticSpeedHelper::GetVelocity (void) const { - return m_paused? Vector (0.0, 0.0, 0.0) : m_speed; + return m_paused? Vector (0.0, 0.0, 0.0) : m_velocity; } void -StaticSpeedHelper::SetSpeed (const Vector &speed) +StaticSpeedHelper::SetVelocity (const Vector &vel) { - Update (); - m_speed = speed; + m_velocity = vel; + m_lastUpdate = Simulator::Now (); } void StaticSpeedHelper::Update (void) const { - if (m_paused) - { - return; - } Time now = Simulator::Now (); NS_ASSERT (m_lastUpdate <= now); Time deltaTime = now - m_lastUpdate; m_lastUpdate = now; + if (m_paused) + { + return; + } double deltaS = deltaTime.GetSeconds (); - m_position.x += m_speed.x * deltaS; - m_position.y += m_speed.y * deltaS; - m_position.z += m_speed.z * deltaS; + m_position.x += m_velocity.x * deltaS; + m_position.y += m_velocity.y * deltaS; + m_position.z += m_velocity.z * deltaS; } -void -StaticSpeedHelper::Reset (const Vector &speed) -{ - Update (); - m_speed = speed; - Unpause (); -} void -StaticSpeedHelper::UpdateFull (const Rectangle &bounds) const +StaticSpeedHelper::UpdateWithBounds (const Rectangle &bounds) const { Update (); m_position.x = std::min (bounds.xMax, m_position.x); @@ -98,28 +87,16 @@ StaticSpeedHelper::UpdateFull (const Rectangle &bounds) const m_position.y = std::max (bounds.yMin, m_position.y); } -Vector -StaticSpeedHelper::GetCurrentPosition (const Rectangle &bounds) const -{ - UpdateFull (bounds); - return m_position; -} - void StaticSpeedHelper::Pause (void) { - Update (); m_paused = true; } void StaticSpeedHelper::Unpause (void) { - if (m_paused) - { - m_lastUpdate = Simulator::Now (); - m_paused = false; - } + m_paused = false; } } // namespace ns3 diff --git a/src/mobility/static-speed-helper.h b/src/mobility/static-speed-helper.h index d743460f4..e2c149231 100644 --- a/src/mobility/static-speed-helper.h +++ b/src/mobility/static-speed-helper.h @@ -33,23 +33,21 @@ class StaticSpeedHelper StaticSpeedHelper (); StaticSpeedHelper (const Vector &position); StaticSpeedHelper (const Vector &position, - const Vector &speed); - void InitializePosition (const Vector &position); + const Vector &vel); - void Reset (const Vector &speed); - Vector GetCurrentPosition (const Rectangle &bounds) const; + void SetPosition (const Vector &position); Vector GetCurrentPosition (void) const; Vector GetVelocity (void) const; - void SetSpeed (const Vector &speed); + void SetVelocity (const Vector &vel); void Pause (void); void Unpause (void); - private: + void UpdateWithBounds (const Rectangle &rectangle) const; void Update (void) const; - void UpdateFull (const Rectangle &rectangle) const; + private: mutable Time m_lastUpdate; mutable Vector m_position; - Vector m_speed; + Vector m_velocity; bool m_paused; }; diff --git a/src/mobility/static-speed-mobility-model.cc b/src/mobility/static-speed-mobility-model.cc index 4dcc77012..50e153328 100644 --- a/src/mobility/static-speed-mobility-model.cc +++ b/src/mobility/static-speed-mobility-model.cc @@ -39,9 +39,11 @@ StaticSpeedMobilityModel::~StaticSpeedMobilityModel () {} void -StaticSpeedMobilityModel::SetSpeed (const Vector &speed) +StaticSpeedMobilityModel::SetVelocity (const Vector &speed) { - m_helper.SetSpeed (speed); + m_helper.Update (); + m_helper.SetVelocity (speed); + m_helper.Unpause (); NotifyCourseChange (); } @@ -49,12 +51,13 @@ StaticSpeedMobilityModel::SetSpeed (const Vector &speed) Vector StaticSpeedMobilityModel::DoGetPosition (void) const { + m_helper.Update (); return m_helper.GetCurrentPosition (); } void StaticSpeedMobilityModel::DoSetPosition (const Vector &position) { - m_helper.InitializePosition (position); + m_helper.SetPosition (position); NotifyCourseChange (); } Vector diff --git a/src/mobility/static-speed-mobility-model.h b/src/mobility/static-speed-mobility-model.h index 3da5b466e..b222f1268 100644 --- a/src/mobility/static-speed-mobility-model.h +++ b/src/mobility/static-speed-mobility-model.h @@ -49,7 +49,7 @@ public: * Set the current speed now to (dx,dy,dz) * Unit is meters/s */ - void SetSpeed (const Vector &speed); + void SetVelocity (const Vector &speed); private: virtual Vector DoGetPosition (void) const; virtual void DoSetPosition (const Vector &position); diff --git a/src/node/channel.h b/src/node/channel.h index 750a8ef20..1e4a0cd6a 100644 --- a/src/node/channel.h +++ b/src/node/channel.h @@ -14,8 +14,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef CHANNEL_H -#define CHANNEL_H +#ifndef NS3_CHANNEL_H +#define NS3_CHANNEL_H #include #include @@ -69,4 +69,4 @@ private: }; // namespace ns3 -#endif /* CHANNEL_H */ +#endif /* NS3_CHANNEL_H */ diff --git a/src/node/ipv4-header.cc b/src/node/ipv4-header.cc index 48c9d1f30..393921c4d 100644 --- a/src/node/ipv4-header.cc +++ b/src/node/ipv4-header.cc @@ -221,6 +221,7 @@ Ipv4Header::Print (std::ostream &os) const os << "tos 0x" << std::hex << m_tos << std::dec << " " << "ttl " << m_ttl << " " << "id " << m_identification << " " + << "protocol " << m_protocol << " " << "offset " << m_fragmentOffset << " " << "flags [" << flags << "] " << "length: " << (m_payloadSize + 5 * 4) diff --git a/src/node/packet-socket.cc b/src/node/packet-socket.cc index 59cabb99d..6aef802e6 100644 --- a/src/node/packet-socket.cc +++ b/src/node/packet-socket.cc @@ -57,6 +57,8 @@ PacketSocket::PacketSocket () : m_rxAvailable (0) m_shutdownSend = false; m_shutdownRecv = false; m_errno = ERROR_NOTERROR; + m_isSingleDevice = false; + m_device = 0; } void @@ -222,7 +224,7 @@ PacketSocket::Connect(const Address &ad) return -1; } int -PacketSocket::Listen(uint32_t queueLimit) +PacketSocket::Listen(void) { m_errno = Socket::ERROR_OPNOTSUPP; return -1; @@ -329,6 +331,7 @@ PacketSocket::SendTo (Ptr p, uint32_t flags, const Address &address) if (!error) { NotifyDataSent (p->GetSize ()); + NotifySend (GetTxAvailable ()); } if (error) @@ -428,4 +431,27 @@ PacketSocket::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress) return packet; } +int +PacketSocket::GetSockName (Address &address) const +{ + NS_LOG_FUNCTION_NOARGS (); + PacketSocketAddress ad = PacketSocketAddress::ConvertFrom(address); + + ad.SetProtocol (m_protocol); + if (m_isSingleDevice) + { + Ptr device = m_node->GetDevice (ad.GetSingleDevice ()); + ad.SetPhysicalAddress(device->GetAddress()); + ad.SetSingleDevice (m_device); + } + else + { + ad.SetPhysicalAddress(Address()); + ad.SetAllDevices (); + } + address = ad; + + return 0; +} + }//namespace ns3 diff --git a/src/node/packet-socket.h b/src/node/packet-socket.h index 1218de2c3..3835a7132 100644 --- a/src/node/packet-socket.h +++ b/src/node/packet-socket.h @@ -93,7 +93,7 @@ public: virtual int ShutdownSend (void); virtual int ShutdownRecv (void); virtual int Connect(const Address &address); - virtual int Listen(uint32_t queueLimit); + virtual int Listen(void); virtual uint32_t GetTxAvailable (void) const; virtual int Send (Ptr p, uint32_t flags); virtual int SendTo(Ptr p, uint32_t flags, const Address &toAddress); @@ -101,6 +101,7 @@ public: virtual Ptr Recv (uint32_t maxSize, uint32_t flags); virtual Ptr RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress); + virtual int GetSockName (Address &address) const; private: void ForwardUp (Ptr device, Ptr packet, diff --git a/src/node/socket.cc b/src/node/socket.cc index d133e936f..c7f9511e5 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -71,12 +71,11 @@ Socket::SetAcceptCallback ( m_newConnectionCreated = newConnectionCreated; } -bool +void Socket::SetDataSentCallback (Callback, uint32_t> dataSent) { NS_LOG_FUNCTION_NOARGS (); m_dataSent = dataSent; - return true; } void @@ -100,12 +99,6 @@ Socket::Send (Ptr p) return Send (p, 0); } - -int Socket::Listen (uint32_t queueLimit) -{ - return 0; //XXX the base class version does nothing -} - int Socket::Send (const uint8_t* buf, uint32_t size, uint32_t flags) { diff --git a/src/node/socket.h b/src/node/socket.h index 36e1773b4..6287895a4 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -141,13 +141,8 @@ public: * \param dataSent Callback for the event that data is sent from the * underlying transport protocol. This callback is passed a * pointer to the socket, and the number of bytes sent. - * \returns whether or not this socket supports this callback. Note - * that this is a non-standard socket call. Some socket - * implementations in ns-3 may not support this call, so the - * user should check this return value to confirm that the - * callback is supported. */ - bool SetDataSentCallback (Callback, + void SetDataSentCallback (Callback, uint32_t> dataSent); /** * \brief Notify application when space in transmit buffer is added @@ -222,7 +217,7 @@ public: * \param queueLimit maximum number of incoming request to queue * \returns 0 on success, -1 on error (in which case errno is set). */ - virtual int Listen (uint32_t queueLimit) = 0; + virtual int Listen (void) = 0; /** * \brief Returns the number of bytes which can be sent in a single call @@ -492,6 +487,10 @@ public: */ int RecvFrom (uint8_t* buf, uint32_t size, uint32_t flags, Address &fromAddress); + /** + * \returns the address name this socket is associated with. + */ + virtual int GetSockName (Address &address) const = 0; protected: void NotifyConnectionSucceeded (void); diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index fda9be7ec..387bd1907 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -266,6 +266,10 @@ int main (int argc, char *argv[]) iss.str (nAscii); iss >> n; } + if (strncmp ("--enable-printing", argv[0], strlen ("--enable-printing")) == 0) + { + Packet::EnablePrinting (); + } argc--; argv++; } @@ -282,13 +286,5 @@ int main (int argc, char *argv[]) runBench (&benchC, n, "c"); runBench (&benchD, n, "d"); - Packet::EnablePrinting (); - runBench (&benchA, n, "meta-a"); - runBench (&benchB, n, "meta-b"); - runBench (&benchC, n, "meta-c"); - runBench (&benchD, n, "meta-d"); - - - return 0; } diff --git a/utils/python-unit-tests.py b/utils/python-unit-tests.py index 43ce5a53e..4ea16dd2d 100644 --- a/utils/python-unit-tests.py +++ b/utils/python-unit-tests.py @@ -57,7 +57,6 @@ class TestSimulator(unittest.TestCase): self.assertEqual(v1, ns3.Seconds(50)) def testConfig(self): - ns3.Config.Set("ns3::OnOffApplication::PacketSize", ns3.UintegerValue(123)) ns3.Config.SetDefault("ns3::OnOffApplication::PacketSize", ns3.UintegerValue(123)) # hm.. no Config.Get? @@ -118,5 +117,11 @@ class TestSimulator(unittest.TestCase): self.assert_(c1 is c2) + def testTypeId(self): + typeId1 = ns3.TypeId.LookupByNameFailSafe("ns3::UdpSocketFactory") + self.assertEqual(typeId1.GetName (), "ns3::UdpSocketFactory") + + self.assertRaises(KeyError, ns3.TypeId.LookupByNameFailSafe, "__InvalidTypeName__") + if __name__ == '__main__': unittest.main()