lte: LTE model refactoring to support carrier aggregation
authorDanilo Abrignani <dabrignani@gmail.com>
Thu, 02 Feb 2017 09:33:08 +0100
changeset 12602 2b0e3e9eb4e4
parent 12601 dc33a0ccc21e
child 12603 7b4fce01467c
lte: LTE model refactoring to support carrier aggregation
src/lte/bindings/modulegen__gcc_ILP32.py
src/lte/bindings/modulegen__gcc_LP64.py
src/lte/helper/cc-helper.cc
src/lte/helper/cc-helper.h
src/lte/helper/lte-helper.cc
src/lte/helper/lte-helper.h
src/lte/helper/mac-stats-calculator.cc
src/lte/helper/phy-rx-stats-calculator.cc
src/lte/helper/phy-stats-calculator.cc
src/lte/helper/phy-tx-stats-calculator.cc
src/lte/model/lte-ccm-rrc-sap.h
src/lte/model/lte-enb-mac.cc
src/lte/model/lte-enb-net-device.cc
src/lte/model/lte-enb-rrc.cc
src/lte/model/lte-enb-rrc.h
src/lte/model/lte-rrc-sap.h
src/lte/model/lte-ue-net-device.cc
src/lte/model/lte-ue-phy.cc
src/lte/model/lte-ue-rrc.cc
src/lte/model/lte-ue-rrc.h
src/lte/model/no-op-component-carrier-manager.cc
src/lte/model/no-op-component-carrier-manager.h
--- a/src/lte/bindings/modulegen__gcc_ILP32.py	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/bindings/modulegen__gcc_ILP32.py	Thu Feb 02 09:33:08 2017 +0100
@@ -1475,12 +1475,12 @@
     module.add_container('std::vector< ns3::Ipv6Address >', 'ns3::Ipv6Address', container_type=u'vector')
     module.add_container('std::vector< double >', 'double', container_type=u'vector')
     module.add_container('ns3::Bands', 'ns3::BandInfo', container_type=u'vector')
-    module.add_container('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrier > >', ('unsigned char', 'ns3::Ptr< ns3::ComponentCarrier >'), container_type=u'map')
+    module.add_container('std::map< unsigned char, ns3::ComponentCarrier >', ('unsigned char', 'ns3::ComponentCarrier'), container_type=u'map')
     module.add_container('std::map< unsigned int, unsigned int >', ('unsigned int', 'unsigned int'), container_type=u'map')
-    module.add_container('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrierEnb > >', ('unsigned char', 'ns3::Ptr< ns3::ComponentCarrierEnb >'), container_type=u'map')
     module.add_container('std::list< ns3::Ptr< ns3::LteControlMessage > >', 'ns3::Ptr< ns3::LteControlMessage >', container_type=u'list')
     module.add_container('std::list< ns3::UlDciLteControlMessage >', 'ns3::UlDciLteControlMessage', container_type=u'list')
     module.add_container('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrierUe > >', ('unsigned char', 'ns3::Ptr< ns3::ComponentCarrierUe >'), container_type=u'map')
+    module.add_container('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrierEnb > >', ('unsigned char', 'ns3::Ptr< ns3::ComponentCarrierEnb >'), container_type=u'map')
     typehandlers.add_type_alias(u'std::map< ns3::ImsiLcidPair_t, unsigned int, std::less< ns3::ImsiLcidPair_t >, std::allocator< std::pair< ns3::ImsiLcidPair_t const, unsigned int > > >', u'ns3::Uint32Map')
     typehandlers.add_type_alias(u'std::map< ns3::ImsiLcidPair_t, unsigned int, std::less< ns3::ImsiLcidPair_t >, std::allocator< std::pair< ns3::ImsiLcidPair_t const, unsigned int > > >*', u'ns3::Uint32Map*')
     typehandlers.add_type_alias(u'std::map< ns3::ImsiLcidPair_t, unsigned int, std::less< ns3::ImsiLcidPair_t >, std::allocator< std::pair< ns3::ImsiLcidPair_t const, unsigned int > > >&', u'ns3::Uint32Map&')
@@ -5678,9 +5678,9 @@
                    'ns3::LteMacSapUser *', 
                    [param('ns3::LteEnbCmacSapProvider::LcInfo', 'lcInfo'), param('ns3::LteMacSapUser *', 'rlcMacSapUser')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## lte-ccm-rrc-sap.h (module 'lte'): std::vector<unsigned short, std::allocator<unsigned short> > ns3::LteCcmRrcSapProvider::ReleaseDataRadioBearer(uint16_t rnti, uint8_t lcid) [member function]
+    ## lte-ccm-rrc-sap.h (module 'lte'): std::vector<unsigned char, std::allocator<unsigned char> > ns3::LteCcmRrcSapProvider::ReleaseDataRadioBearer(uint16_t rnti, uint8_t lcid) [member function]
     cls.add_method('ReleaseDataRadioBearer', 
-                   'std::vector< unsigned short >', 
+                   'std::vector< unsigned char >', 
                    [param('uint16_t', 'rnti'), param('uint8_t', 'lcid')], 
                    is_pure_virtual=True, is_virtual=True)
     ## lte-ccm-rrc-sap.h (module 'lte'): void ns3::LteCcmRrcSapProvider::RemoveUe(uint16_t rnti) [member function]
@@ -13294,18 +13294,18 @@
     cls.add_constructor([param('ns3::CcHelper const &', 'arg0')])
     ## cc-helper.h (module 'lte'): ns3::CcHelper::CcHelper() [constructor]
     cls.add_constructor([])
-    ## cc-helper.h (module 'lte'): ns3::Ptr<ns3::ComponentCarrier> ns3::CcHelper::DoCreateSingleCc(uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary) [member function]
+    ## cc-helper.h (module 'lte'): ns3::ComponentCarrier ns3::CcHelper::DoCreateSingleCc(uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary) [member function]
     cls.add_method('DoCreateSingleCc', 
-                   'ns3::Ptr< ns3::ComponentCarrier >', 
+                   'ns3::ComponentCarrier', 
                    [param('uint16_t', 'ulBandwidth'), param('uint16_t', 'dlBandwidth'), param('uint32_t', 'ulEarfcn'), param('uint32_t', 'dlEarfcn'), param('bool', 'isPrimary')])
     ## cc-helper.h (module 'lte'): void ns3::CcHelper::DoDispose() [member function]
     cls.add_method('DoDispose', 
                    'void', 
                    [], 
                    is_virtual=True)
-    ## cc-helper.h (module 'lte'): std::map<unsigned char, ns3::Ptr<ns3::ComponentCarrier>, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::Ptr<ns3::ComponentCarrier> > > > ns3::CcHelper::EquallySpacedCcs() [member function]
+    ## cc-helper.h (module 'lte'): std::map<unsigned char, ns3::ComponentCarrier, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::ComponentCarrier> > > ns3::CcHelper::EquallySpacedCcs() [member function]
     cls.add_method('EquallySpacedCcs', 
-                   'std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrier > >', 
+                   'std::map< unsigned char, ns3::ComponentCarrier >', 
                    [])
     ## cc-helper.h (module 'lte'): uint16_t ns3::CcHelper::GetDlBandwidth() [member function]
     cls.add_method('GetDlBandwidth', 
@@ -16136,10 +16136,14 @@
     cls.add_method('AddX2Neighbour', 
                    'void', 
                    [param('uint16_t', 'cellId')])
-    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::ConfigureCell(uint8_t ulBandwidth, uint8_t dlBandwidth, uint16_t ulEarfcn, uint16_t dlEarfcn, uint16_t cellId) [member function]
+    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::ConfigureCarriers(std::map<unsigned char, ns3::ComponentCarrier, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::ComponentCarrier> > > ccPhyConf, uint16_t numberOfCarriers) [member function]
+    cls.add_method('ConfigureCarriers', 
+                   'void', 
+                   [param('std::map< unsigned char, ns3::ComponentCarrier >', 'ccPhyConf'), param('uint16_t', 'numberOfCarriers')])
+    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::ConfigureCell(uint16_t cellId) [member function]
     cls.add_method('ConfigureCell', 
                    'void', 
-                   [param('uint8_t', 'ulBandwidth'), param('uint8_t', 'dlBandwidth'), param('uint16_t', 'ulEarfcn'), param('uint16_t', 'dlEarfcn'), param('uint16_t', 'cellId')])
+                   [param('uint16_t', 'cellId')])
     ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::ConnectionRejectedTimeout(uint16_t rnti) [member function]
     cls.add_method('ConnectionRejectedTimeout', 
                    'void', 
@@ -16271,10 +16275,10 @@
     cls.add_method('SetLteEnbCmacSapProvider', 
                    'void', 
                    [param('ns3::LteEnbCmacSapProvider *', 's')])
-    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::SetLteEnbCmacSapProvider(ns3::LteEnbCmacSapProvider * s, uint16_t pos) [member function]
+    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::SetLteEnbCmacSapProvider(ns3::LteEnbCmacSapProvider * s, uint8_t pos) [member function]
     cls.add_method('SetLteEnbCmacSapProvider', 
                    'void', 
-                   [param('ns3::LteEnbCmacSapProvider *', 's'), param('uint16_t', 'pos')])
+                   [param('ns3::LteEnbCmacSapProvider *', 's'), param('uint8_t', 'pos')])
     ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::SetLteEnbCphySapProvider(ns3::LteEnbCphySapProvider * s) [member function]
     cls.add_method('SetLteEnbCphySapProvider', 
                    'void', 
@@ -16315,18 +16319,11 @@
     cls.add_method('SetSrsPeriodicity', 
                    'void', 
                    [param('uint32_t', 'p')])
-    ## lte-enb-rrc.h (module 'lte'): ns3::LteEnbRrc::m_componentCarrierEnbMap [variable]
-    cls.add_instance_attribute('m_componentCarrierEnbMap', 'std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrierEnb > >', is_const=False)
     ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::DoDispose() [member function]
     cls.add_method('DoDispose', 
                    'void', 
                    [], 
                    visibility='protected', is_virtual=True)
-    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::DoInitialize() [member function]
-    cls.add_method('DoInitialize', 
-                   'void', 
-                   [], 
-                   visibility='protected', is_virtual=True)
     return
 
 def register_Ns3LteEnbRrcProtocolIdeal_methods(root_module, cls):
@@ -17458,6 +17455,11 @@
                    'ns3::Ptr< ns3::SpectrumChannel >', 
                    [], 
                    is_const=True)
+    ## lte-helper.h (module 'lte'): ns3::Ptr<ns3::SpectrumChannel> ns3::LteHelper::GetDownlinkSpectrumChannel(uint8_t carrierId) const [member function]
+    cls.add_method('GetDownlinkSpectrumChannel', 
+                   'ns3::Ptr< ns3::SpectrumChannel >', 
+                   [param('uint8_t', 'carrierId')], 
+                   is_const=True)
     ## lte-helper.h (module 'lte'): std::string ns3::LteHelper::GetEnbComponentCarrierManagerType() const [member function]
     cls.add_method('GetEnbComponentCarrierManagerType', 
                    'std::string', 
@@ -17513,10 +17515,10 @@
     cls.add_method('InstallUeDevice', 
                    'ns3::NetDeviceContainer', 
                    [param('ns3::NodeContainer', 'c')])
-    ## lte-helper.h (module 'lte'): void ns3::LteHelper::SetCcPhyParams(std::map<unsigned char, ns3::Ptr<ns3::ComponentCarrier>, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::Ptr<ns3::ComponentCarrier> > > > ccmap) [member function]
+    ## lte-helper.h (module 'lte'): void ns3::LteHelper::SetCcPhyParams(std::map<unsigned char, ns3::ComponentCarrier, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::ComponentCarrier> > > ccmap) [member function]
     cls.add_method('SetCcPhyParams', 
                    'void', 
-                   [param('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrier > >', 'ccmap')])
+                   [param('std::map< unsigned char, ns3::ComponentCarrier >', 'ccmap')])
     ## lte-helper.h (module 'lte'): void ns3::LteHelper::SetEnbAntennaModelAttribute(std::string n, ns3::AttributeValue const & v) [member function]
     cls.add_method('SetEnbAntennaModelAttribute', 
                    'void', 
@@ -18878,10 +18880,18 @@
     cls.add_method('GetLteUeCmacSapUser', 
                    'ns3::LteUeCmacSapUser *', 
                    [])
+    ## lte-ue-rrc.h (module 'lte'): ns3::LteUeCmacSapUser * ns3::LteUeRrc::GetLteUeCmacSapUser(uint8_t index) [member function]
+    cls.add_method('GetLteUeCmacSapUser', 
+                   'ns3::LteUeCmacSapUser *', 
+                   [param('uint8_t', 'index')])
     ## lte-ue-rrc.h (module 'lte'): ns3::LteUeCphySapUser * ns3::LteUeRrc::GetLteUeCphySapUser() [member function]
     cls.add_method('GetLteUeCphySapUser', 
                    'ns3::LteUeCphySapUser *', 
                    [])
+    ## lte-ue-rrc.h (module 'lte'): ns3::LteUeCphySapUser * ns3::LteUeRrc::GetLteUeCphySapUser(uint8_t index) [member function]
+    cls.add_method('GetLteUeCphySapUser', 
+                   'ns3::LteUeCphySapUser *', 
+                   [param('uint8_t', 'index')])
     ## lte-ue-rrc.h (module 'lte'): ns3::LteUeRrcSapProvider * ns3::LteUeRrc::GetLteUeRrcSapProvider() [member function]
     cls.add_method('GetLteUeRrcSapProvider', 
                    'ns3::LteUeRrcSapProvider *', 
@@ -18911,6 +18921,10 @@
                    'uint32_t', 
                    [], 
                    is_const=True)
+    ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::InitializeSap() [member function]
+    cls.add_method('InitializeSap', 
+                   'void', 
+                   [])
     ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetAsSapUser(ns3::LteAsSapUser * s) [member function]
     cls.add_method('SetAsSapUser', 
                    'void', 
@@ -18935,10 +18949,18 @@
     cls.add_method('SetLteUeCmacSapProvider', 
                    'void', 
                    [param('ns3::LteUeCmacSapProvider *', 's')])
+    ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetLteUeCmacSapProvider(ns3::LteUeCmacSapProvider * s, uint8_t index) [member function]
+    cls.add_method('SetLteUeCmacSapProvider', 
+                   'void', 
+                   [param('ns3::LteUeCmacSapProvider *', 's'), param('uint8_t', 'index')])
     ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetLteUeCphySapProvider(ns3::LteUeCphySapProvider * s) [member function]
     cls.add_method('SetLteUeCphySapProvider', 
                    'void', 
                    [param('ns3::LteUeCphySapProvider *', 's')])
+    ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetLteUeCphySapProvider(ns3::LteUeCphySapProvider * s, uint8_t index) [member function]
+    cls.add_method('SetLteUeCphySapProvider', 
+                   'void', 
+                   [param('ns3::LteUeCphySapProvider *', 's'), param('uint8_t', 'index')])
     ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetLteUeRrcSapUser(ns3::LteUeRrcSapUser * s) [member function]
     cls.add_method('SetLteUeRrcSapUser', 
                    'void', 
@@ -19513,9 +19535,9 @@
                    'void', 
                    [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'rnti'), param('uint8_t', 'lcid')], 
                    visibility='protected', is_virtual=True)
-    ## no-op-component-carrier-manager.h (module 'lte'): std::vector<unsigned short, std::allocator<unsigned short> > ns3::NoOpComponentCarrierManager::DoReleaseDataRadioBearer(uint16_t rnti, uint8_t lcid) [member function]
+    ## no-op-component-carrier-manager.h (module 'lte'): std::vector<unsigned char, std::allocator<unsigned char> > ns3::NoOpComponentCarrierManager::DoReleaseDataRadioBearer(uint16_t rnti, uint8_t lcid) [member function]
     cls.add_method('DoReleaseDataRadioBearer', 
-                   'std::vector< unsigned short >', 
+                   'std::vector< unsigned char >', 
                    [param('uint16_t', 'rnti'), param('uint8_t', 'lcid')], 
                    visibility='protected', is_virtual=True)
     ## no-op-component-carrier-manager.h (module 'lte'): void ns3::NoOpComponentCarrierManager::DoRemoveUe(uint16_t rnti) [member function]
--- a/src/lte/bindings/modulegen__gcc_LP64.py	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/bindings/modulegen__gcc_LP64.py	Thu Feb 02 09:33:08 2017 +0100
@@ -1475,12 +1475,12 @@
     module.add_container('std::vector< ns3::Ipv6Address >', 'ns3::Ipv6Address', container_type=u'vector')
     module.add_container('std::vector< double >', 'double', container_type=u'vector')
     module.add_container('ns3::Bands', 'ns3::BandInfo', container_type=u'vector')
-    module.add_container('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrier > >', ('unsigned char', 'ns3::Ptr< ns3::ComponentCarrier >'), container_type=u'map')
+    module.add_container('std::map< unsigned char, ns3::ComponentCarrier >', ('unsigned char', 'ns3::ComponentCarrier'), container_type=u'map')
     module.add_container('std::map< unsigned int, unsigned int >', ('unsigned int', 'unsigned int'), container_type=u'map')
-    module.add_container('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrierEnb > >', ('unsigned char', 'ns3::Ptr< ns3::ComponentCarrierEnb >'), container_type=u'map')
     module.add_container('std::list< ns3::Ptr< ns3::LteControlMessage > >', 'ns3::Ptr< ns3::LteControlMessage >', container_type=u'list')
     module.add_container('std::list< ns3::UlDciLteControlMessage >', 'ns3::UlDciLteControlMessage', container_type=u'list')
     module.add_container('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrierUe > >', ('unsigned char', 'ns3::Ptr< ns3::ComponentCarrierUe >'), container_type=u'map')
+    module.add_container('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrierEnb > >', ('unsigned char', 'ns3::Ptr< ns3::ComponentCarrierEnb >'), container_type=u'map')
     typehandlers.add_type_alias(u'std::map< ns3::ImsiLcidPair_t, unsigned int, std::less< ns3::ImsiLcidPair_t >, std::allocator< std::pair< ns3::ImsiLcidPair_t const, unsigned int > > >', u'ns3::Uint32Map')
     typehandlers.add_type_alias(u'std::map< ns3::ImsiLcidPair_t, unsigned int, std::less< ns3::ImsiLcidPair_t >, std::allocator< std::pair< ns3::ImsiLcidPair_t const, unsigned int > > >*', u'ns3::Uint32Map*')
     typehandlers.add_type_alias(u'std::map< ns3::ImsiLcidPair_t, unsigned int, std::less< ns3::ImsiLcidPair_t >, std::allocator< std::pair< ns3::ImsiLcidPair_t const, unsigned int > > >&', u'ns3::Uint32Map&')
@@ -5678,9 +5678,9 @@
                    'ns3::LteMacSapUser *', 
                    [param('ns3::LteEnbCmacSapProvider::LcInfo', 'lcInfo'), param('ns3::LteMacSapUser *', 'rlcMacSapUser')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## lte-ccm-rrc-sap.h (module 'lte'): std::vector<unsigned short, std::allocator<unsigned short> > ns3::LteCcmRrcSapProvider::ReleaseDataRadioBearer(uint16_t rnti, uint8_t lcid) [member function]
+    ## lte-ccm-rrc-sap.h (module 'lte'): std::vector<unsigned char, std::allocator<unsigned char> > ns3::LteCcmRrcSapProvider::ReleaseDataRadioBearer(uint16_t rnti, uint8_t lcid) [member function]
     cls.add_method('ReleaseDataRadioBearer', 
-                   'std::vector< unsigned short >', 
+                   'std::vector< unsigned char >', 
                    [param('uint16_t', 'rnti'), param('uint8_t', 'lcid')], 
                    is_pure_virtual=True, is_virtual=True)
     ## lte-ccm-rrc-sap.h (module 'lte'): void ns3::LteCcmRrcSapProvider::RemoveUe(uint16_t rnti) [member function]
@@ -13294,18 +13294,18 @@
     cls.add_constructor([param('ns3::CcHelper const &', 'arg0')])
     ## cc-helper.h (module 'lte'): ns3::CcHelper::CcHelper() [constructor]
     cls.add_constructor([])
-    ## cc-helper.h (module 'lte'): ns3::Ptr<ns3::ComponentCarrier> ns3::CcHelper::DoCreateSingleCc(uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary) [member function]
+    ## cc-helper.h (module 'lte'): ns3::ComponentCarrier ns3::CcHelper::DoCreateSingleCc(uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary) [member function]
     cls.add_method('DoCreateSingleCc', 
-                   'ns3::Ptr< ns3::ComponentCarrier >', 
+                   'ns3::ComponentCarrier', 
                    [param('uint16_t', 'ulBandwidth'), param('uint16_t', 'dlBandwidth'), param('uint32_t', 'ulEarfcn'), param('uint32_t', 'dlEarfcn'), param('bool', 'isPrimary')])
     ## cc-helper.h (module 'lte'): void ns3::CcHelper::DoDispose() [member function]
     cls.add_method('DoDispose', 
                    'void', 
                    [], 
                    is_virtual=True)
-    ## cc-helper.h (module 'lte'): std::map<unsigned char, ns3::Ptr<ns3::ComponentCarrier>, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::Ptr<ns3::ComponentCarrier> > > > ns3::CcHelper::EquallySpacedCcs() [member function]
+    ## cc-helper.h (module 'lte'): std::map<unsigned char, ns3::ComponentCarrier, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::ComponentCarrier> > > ns3::CcHelper::EquallySpacedCcs() [member function]
     cls.add_method('EquallySpacedCcs', 
-                   'std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrier > >', 
+                   'std::map< unsigned char, ns3::ComponentCarrier >', 
                    [])
     ## cc-helper.h (module 'lte'): uint16_t ns3::CcHelper::GetDlBandwidth() [member function]
     cls.add_method('GetDlBandwidth', 
@@ -16136,10 +16136,14 @@
     cls.add_method('AddX2Neighbour', 
                    'void', 
                    [param('uint16_t', 'cellId')])
-    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::ConfigureCell(uint8_t ulBandwidth, uint8_t dlBandwidth, uint16_t ulEarfcn, uint16_t dlEarfcn, uint16_t cellId) [member function]
+    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::ConfigureCarriers(std::map<unsigned char, ns3::ComponentCarrier, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::ComponentCarrier> > > ccPhyConf, uint16_t numberOfCarriers) [member function]
+    cls.add_method('ConfigureCarriers', 
+                   'void', 
+                   [param('std::map< unsigned char, ns3::ComponentCarrier >', 'ccPhyConf'), param('uint16_t', 'numberOfCarriers')])
+    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::ConfigureCell(uint16_t cellId) [member function]
     cls.add_method('ConfigureCell', 
                    'void', 
-                   [param('uint8_t', 'ulBandwidth'), param('uint8_t', 'dlBandwidth'), param('uint16_t', 'ulEarfcn'), param('uint16_t', 'dlEarfcn'), param('uint16_t', 'cellId')])
+                   [param('uint16_t', 'cellId')])
     ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::ConnectionRejectedTimeout(uint16_t rnti) [member function]
     cls.add_method('ConnectionRejectedTimeout', 
                    'void', 
@@ -16271,10 +16275,10 @@
     cls.add_method('SetLteEnbCmacSapProvider', 
                    'void', 
                    [param('ns3::LteEnbCmacSapProvider *', 's')])
-    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::SetLteEnbCmacSapProvider(ns3::LteEnbCmacSapProvider * s, uint16_t pos) [member function]
+    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::SetLteEnbCmacSapProvider(ns3::LteEnbCmacSapProvider * s, uint8_t pos) [member function]
     cls.add_method('SetLteEnbCmacSapProvider', 
                    'void', 
-                   [param('ns3::LteEnbCmacSapProvider *', 's'), param('uint16_t', 'pos')])
+                   [param('ns3::LteEnbCmacSapProvider *', 's'), param('uint8_t', 'pos')])
     ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::SetLteEnbCphySapProvider(ns3::LteEnbCphySapProvider * s) [member function]
     cls.add_method('SetLteEnbCphySapProvider', 
                    'void', 
@@ -16315,18 +16319,11 @@
     cls.add_method('SetSrsPeriodicity', 
                    'void', 
                    [param('uint32_t', 'p')])
-    ## lte-enb-rrc.h (module 'lte'): ns3::LteEnbRrc::m_componentCarrierEnbMap [variable]
-    cls.add_instance_attribute('m_componentCarrierEnbMap', 'std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrierEnb > >', is_const=False)
     ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::DoDispose() [member function]
     cls.add_method('DoDispose', 
                    'void', 
                    [], 
                    visibility='protected', is_virtual=True)
-    ## lte-enb-rrc.h (module 'lte'): void ns3::LteEnbRrc::DoInitialize() [member function]
-    cls.add_method('DoInitialize', 
-                   'void', 
-                   [], 
-                   visibility='protected', is_virtual=True)
     return
 
 def register_Ns3LteEnbRrcProtocolIdeal_methods(root_module, cls):
@@ -17458,6 +17455,11 @@
                    'ns3::Ptr< ns3::SpectrumChannel >', 
                    [], 
                    is_const=True)
+    ## lte-helper.h (module 'lte'): ns3::Ptr<ns3::SpectrumChannel> ns3::LteHelper::GetDownlinkSpectrumChannel(uint8_t carrierId) const [member function]
+    cls.add_method('GetDownlinkSpectrumChannel', 
+                   'ns3::Ptr< ns3::SpectrumChannel >', 
+                   [param('uint8_t', 'carrierId')], 
+                   is_const=True)
     ## lte-helper.h (module 'lte'): std::string ns3::LteHelper::GetEnbComponentCarrierManagerType() const [member function]
     cls.add_method('GetEnbComponentCarrierManagerType', 
                    'std::string', 
@@ -17513,10 +17515,10 @@
     cls.add_method('InstallUeDevice', 
                    'ns3::NetDeviceContainer', 
                    [param('ns3::NodeContainer', 'c')])
-    ## lte-helper.h (module 'lte'): void ns3::LteHelper::SetCcPhyParams(std::map<unsigned char, ns3::Ptr<ns3::ComponentCarrier>, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::Ptr<ns3::ComponentCarrier> > > > ccmap) [member function]
+    ## lte-helper.h (module 'lte'): void ns3::LteHelper::SetCcPhyParams(std::map<unsigned char, ns3::ComponentCarrier, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, ns3::ComponentCarrier> > > ccmap) [member function]
     cls.add_method('SetCcPhyParams', 
                    'void', 
-                   [param('std::map< unsigned char, ns3::Ptr< ns3::ComponentCarrier > >', 'ccmap')])
+                   [param('std::map< unsigned char, ns3::ComponentCarrier >', 'ccmap')])
     ## lte-helper.h (module 'lte'): void ns3::LteHelper::SetEnbAntennaModelAttribute(std::string n, ns3::AttributeValue const & v) [member function]
     cls.add_method('SetEnbAntennaModelAttribute', 
                    'void', 
@@ -18878,10 +18880,18 @@
     cls.add_method('GetLteUeCmacSapUser', 
                    'ns3::LteUeCmacSapUser *', 
                    [])
+    ## lte-ue-rrc.h (module 'lte'): ns3::LteUeCmacSapUser * ns3::LteUeRrc::GetLteUeCmacSapUser(uint8_t index) [member function]
+    cls.add_method('GetLteUeCmacSapUser', 
+                   'ns3::LteUeCmacSapUser *', 
+                   [param('uint8_t', 'index')])
     ## lte-ue-rrc.h (module 'lte'): ns3::LteUeCphySapUser * ns3::LteUeRrc::GetLteUeCphySapUser() [member function]
     cls.add_method('GetLteUeCphySapUser', 
                    'ns3::LteUeCphySapUser *', 
                    [])
+    ## lte-ue-rrc.h (module 'lte'): ns3::LteUeCphySapUser * ns3::LteUeRrc::GetLteUeCphySapUser(uint8_t index) [member function]
+    cls.add_method('GetLteUeCphySapUser', 
+                   'ns3::LteUeCphySapUser *', 
+                   [param('uint8_t', 'index')])
     ## lte-ue-rrc.h (module 'lte'): ns3::LteUeRrcSapProvider * ns3::LteUeRrc::GetLteUeRrcSapProvider() [member function]
     cls.add_method('GetLteUeRrcSapProvider', 
                    'ns3::LteUeRrcSapProvider *', 
@@ -18911,6 +18921,10 @@
                    'uint32_t', 
                    [], 
                    is_const=True)
+    ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::InitializeSap() [member function]
+    cls.add_method('InitializeSap', 
+                   'void', 
+                   [])
     ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetAsSapUser(ns3::LteAsSapUser * s) [member function]
     cls.add_method('SetAsSapUser', 
                    'void', 
@@ -18935,10 +18949,18 @@
     cls.add_method('SetLteUeCmacSapProvider', 
                    'void', 
                    [param('ns3::LteUeCmacSapProvider *', 's')])
+    ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetLteUeCmacSapProvider(ns3::LteUeCmacSapProvider * s, uint8_t index) [member function]
+    cls.add_method('SetLteUeCmacSapProvider', 
+                   'void', 
+                   [param('ns3::LteUeCmacSapProvider *', 's'), param('uint8_t', 'index')])
     ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetLteUeCphySapProvider(ns3::LteUeCphySapProvider * s) [member function]
     cls.add_method('SetLteUeCphySapProvider', 
                    'void', 
                    [param('ns3::LteUeCphySapProvider *', 's')])
+    ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetLteUeCphySapProvider(ns3::LteUeCphySapProvider * s, uint8_t index) [member function]
+    cls.add_method('SetLteUeCphySapProvider', 
+                   'void', 
+                   [param('ns3::LteUeCphySapProvider *', 's'), param('uint8_t', 'index')])
     ## lte-ue-rrc.h (module 'lte'): void ns3::LteUeRrc::SetLteUeRrcSapUser(ns3::LteUeRrcSapUser * s) [member function]
     cls.add_method('SetLteUeRrcSapUser', 
                    'void', 
@@ -19513,9 +19535,9 @@
                    'void', 
                    [param('ns3::Ptr< ns3::Packet >', 'p'), param('uint16_t', 'rnti'), param('uint8_t', 'lcid')], 
                    visibility='protected', is_virtual=True)
-    ## no-op-component-carrier-manager.h (module 'lte'): std::vector<unsigned short, std::allocator<unsigned short> > ns3::NoOpComponentCarrierManager::DoReleaseDataRadioBearer(uint16_t rnti, uint8_t lcid) [member function]
+    ## no-op-component-carrier-manager.h (module 'lte'): std::vector<unsigned char, std::allocator<unsigned char> > ns3::NoOpComponentCarrierManager::DoReleaseDataRadioBearer(uint16_t rnti, uint8_t lcid) [member function]
     cls.add_method('DoReleaseDataRadioBearer', 
-                   'std::vector< unsigned short >', 
+                   'std::vector< unsigned char >', 
                    [param('uint16_t', 'rnti'), param('uint8_t', 'lcid')], 
                    visibility='protected', is_virtual=True)
     ## no-op-component-carrier-manager.h (module 'lte'): void ns3::NoOpComponentCarrierManager::DoRemoveUe(uint16_t rnti) [member function]
--- a/src/lte/helper/cc-helper.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/helper/cc-helper.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -161,18 +161,18 @@
   return m_ulBandwidth;
 }
 
-Ptr<ComponentCarrier>
+ComponentCarrier
 CcHelper::DoCreateSingleCc (uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary)
 {
   return CreateSingleCc (ulBandwidth, dlBandwidth, ulEarfcn, dlEarfcn, isPrimary);
 }
 
-std::map< uint8_t, Ptr<ComponentCarrier> >
+std::map< uint8_t, ComponentCarrier >
 CcHelper::EquallySpacedCcs ()
 {
-  std::map< uint8_t, Ptr<ComponentCarrier> > ccmap;
+  std::map< uint8_t, ComponentCarrier > ccmap;
 
-  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
+  for (uint8_t i = 0; i < m_numberOfComponentCarriers; i++)
     {
       bool pc =false;
       uint32_t ul = m_ulEarfcn + i * m_ulBandwidth;
@@ -181,40 +181,40 @@
         {
           pc = true;
         }
-      Ptr<ComponentCarrier> cc = CreateSingleCc (m_ulBandwidth, m_dlBandwidth, ul, dl, pc);
-      ccmap.insert (std::pair<uint8_t,Ptr<ComponentCarrier> >(i, cc));
+      ComponentCarrier cc = CreateSingleCc (m_ulBandwidth, m_dlBandwidth, ul, dl, pc);
+      ccmap.insert (std::pair<uint8_t, ComponentCarrier >(i, cc));
 
       NS_LOG_INFO(" ulBandwidth:"<<m_ulBandwidth<<" , dlBandwidth: "<<m_dlBandwidth<<" , ul:"<<ul<<" , dl:"<<dl);
     }
 
   return ccmap;
 }
-Ptr<ComponentCarrier>
+ComponentCarrier
 CcHelper::CreateSingleCc (uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary)
 {
-  Ptr <ComponentCarrier> cc =  CreateObject<ComponentCarrier> ();
+  ComponentCarrier cc;
   if ( m_ulEarfcn != 0)
     {
-      cc->SetUlEarfcn (ulEarfcn);
+      cc.SetUlEarfcn (ulEarfcn);
     }
   else 
     {
-      uint16_t ul = cc->GetUlEarfcn () + ulEarfcn;
-      cc->SetUlEarfcn (ul);
+      uint16_t ul = cc.GetUlEarfcn () + ulEarfcn;
+      cc.SetUlEarfcn (ul);
     }
   if ( m_dlEarfcn != 0)
     {
-      cc->SetDlEarfcn (dlEarfcn);
+      cc.SetDlEarfcn (dlEarfcn);
     }
   else 
     {
-      uint16_t dl = cc->GetDlEarfcn () + dlEarfcn;
-      cc->SetDlEarfcn (dl);
+      uint16_t dl = cc.GetDlEarfcn () + dlEarfcn;
+      cc.SetDlEarfcn (dl);
     }
-  cc->SetDlBandwidth (dlBandwidth);
-  cc->SetUlBandwidth (ulBandwidth);
+  cc.SetDlBandwidth (dlBandwidth);
+  cc.SetUlBandwidth (ulBandwidth);
 
-  cc->SetAsPrimary (isPrimary);
+  cc.SetAsPrimary (isPrimary);
 
   return cc;
 
--- a/src/lte/helper/cc-helper.h	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/helper/cc-helper.h	Thu Feb 02 09:33:08 2017 +0100
@@ -67,7 +67,7 @@
   static TypeId GetTypeId (void);
   virtual void DoDispose (void);
 
-  Ptr<ComponentCarrier> DoCreateSingleCc (uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary);
+  ComponentCarrier DoCreateSingleCc (uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary);
 
   /**
   * Set an attribute for the Component Carrier to be created.
@@ -89,7 +89,7 @@
   * you will create a intra-channel Carrier Aggregation scheme.
   */
 
-  std::map< uint8_t, Ptr<ComponentCarrier> > EquallySpacedCcs ();
+  std::map< uint8_t, ComponentCarrier > EquallySpacedCcs ();
 
   void SetNumberOfComponentCarriers (uint16_t nCc);
   void SetUlEarfcn (uint32_t ulEarfcn);
@@ -116,7 +116,7 @@
    * \param pc - this identify if this is the Primary Component Carrier (PCC) - only one PCC is allowed 
    * \return pointer to the created object
    */
-  Ptr<ComponentCarrier> CreateSingleCc (uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary);
+  ComponentCarrier CreateSingleCc (uint16_t ulBandwidth, uint16_t dlBandwidth, uint32_t ulEarfcn, uint32_t dlEarfcn, bool isPrimary);
 
   /// Factory for each Carrier Component.
   ObjectFactory m_ccFactory;
--- a/src/lte/helper/lte-helper.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/helper/lte-helper.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -17,6 +17,8 @@
  *
  * Author: Nicola Baldo <nbaldo@cttc.es> (re-wrote from scratch this helper)
  *         Giuseppe Piro <g.piro@poliba.it> (parts of the PHY & channel  creation & configuration copied from the GSoC 2011 code)
+ * Modified by: Danilo Abrignani <danilo.abrignani@unibo.it> (Carrier Aggregation - GSoC 2015)
+ *              Biljana Bojovic <biljana.bojovic@cttc.es> (Carrier Aggregation) 
  */
 
 
@@ -90,45 +92,7 @@
 LteHelper::DoInitialize (void)
 {
   NS_LOG_FUNCTION (this);
-  m_downlinkChannel = m_channelFactory.Create<SpectrumChannel> ();
-  m_uplinkChannel = m_channelFactory.Create<SpectrumChannel> ();
-
-  m_downlinkPathlossModel = m_dlPathlossModelFactory.Create ();
-  Ptr<SpectrumPropagationLossModel> dlSplm = m_downlinkPathlossModel->GetObject<SpectrumPropagationLossModel> ();
-  if (dlSplm != 0)
-    {
-      NS_LOG_LOGIC (this << " using a SpectrumPropagationLossModel in DL");
-      m_downlinkChannel->AddSpectrumPropagationLossModel (dlSplm);
-    }
-  else
-    {
-      NS_LOG_LOGIC (this << " using a PropagationLossModel in DL");
-      Ptr<PropagationLossModel> dlPlm = m_downlinkPathlossModel->GetObject<PropagationLossModel> ();
-      NS_ASSERT_MSG (dlPlm != 0, " " << m_downlinkPathlossModel << " is neither PropagationLossModel nor SpectrumPropagationLossModel");
-      m_downlinkChannel->AddPropagationLossModel (dlPlm);
-    }
-
-  m_uplinkPathlossModel = m_ulPathlossModelFactory.Create ();
-  Ptr<SpectrumPropagationLossModel> ulSplm = m_uplinkPathlossModel->GetObject<SpectrumPropagationLossModel> ();
-  if (ulSplm != 0)
-    {
-      NS_LOG_LOGIC (this << " using a SpectrumPropagationLossModel in UL");
-      m_uplinkChannel->AddSpectrumPropagationLossModel (ulSplm);
-    }
-  else
-    {
-      NS_LOG_LOGIC (this << " using a PropagationLossModel in UL");
-      Ptr<PropagationLossModel> ulPlm = m_uplinkPathlossModel->GetObject<PropagationLossModel> ();
-      NS_ASSERT_MSG (ulPlm != 0, " " << m_uplinkPathlossModel << " is neither PropagationLossModel nor SpectrumPropagationLossModel");
-      m_uplinkChannel->AddPropagationLossModel (ulPlm);
-    }
-  if (!m_fadingModelType.empty ())
-    {
-      m_fadingModule = m_fadingModelFactory.Create<SpectrumPropagationLossModel> ();
-      m_fadingModule->Initialize ();
-      m_downlinkChannel->AddSpectrumPropagationLossModel (m_fadingModule);
-      m_uplinkChannel->AddSpectrumPropagationLossModel (m_fadingModule);
-    }
+  ChannelModelInitialization ();
   m_phyStats = CreateObject<PhyStatsCalculator> ();
   m_phyTxStats = CreateObject<PhyTxStatsCalculator> ();
   m_phyRxStats = CreateObject<PhyRxStatsCalculator> ();
@@ -221,7 +185,7 @@
                    MakeStringAccessor (&LteHelper::SetUeComponentCarrierManagerType,
                                        &LteHelper::GetUeComponentCarrierManagerType),
                    MakeStringChecker ())
-    /*.AddAttribute ("UseCa",
+    .AddAttribute ("UseCa",
                    "If true, Carrier Aggregation feature is enabled and a valid Component Carrier Map is expected."
                    "If false, single carrier simulation.",
                    BooleanValue (false),
@@ -232,7 +196,7 @@
                    "If it is more than one and m_useCa is false, it will raise an error ",
                    UintegerValue (1),
                    MakeUintegerAccessor (&LteHelper::m_noOfCcs),
-                   MakeUintegerChecker<uint16_t> (1, 3))*/
+                   MakeUintegerChecker<uint16_t> (1, 3))
   ;
   return tid;
 }
@@ -241,23 +205,84 @@
 LteHelper::DoDispose ()
 {
   NS_LOG_FUNCTION (this);
-  m_downlinkChannel = 0;
-  m_uplinkChannel = 0;
+  m_downlinkChannel.clear ();
+  m_uplinkChannel.clear ();
+  m_componentCarrierPhyParams.clear();
   Object::DoDispose ();
 }
 
 Ptr<SpectrumChannel>
 LteHelper::GetUplinkSpectrumChannel (void) const
 {
-  return m_uplinkChannel;
+  return m_uplinkChannel.at(0);
 }
 
 Ptr<SpectrumChannel>
 LteHelper::GetDownlinkSpectrumChannel (void) const
 {
-  return m_downlinkChannel;
+  return m_downlinkChannel.at(0);
+}
+
+Ptr<SpectrumChannel>
+LteHelper::GetDownlinkSpectrumChannel (uint8_t carrierId) const
+{
+  return m_downlinkChannel.at(carrierId);
 }
 
+void
+LteHelper::ChannelModelInitialization (void)
+{
+  // Channel Object (i.e. Ptr<SpectrumChannel>) are within a vector
+  // PathLossModel Objects are vectors --> in InstallSingleEnb we will set the frequency
+  NS_LOG_FUNCTION (this << m_noOfCcs);
+
+  for (uint16_t i = 0; i < m_noOfCcs; i++)
+    {
+      Ptr<SpectrumChannel> downlinkChannelElem = m_channelFactory.Create<SpectrumChannel> ();
+      Ptr<SpectrumChannel> uplinkChannelElem = m_channelFactory.Create<SpectrumChannel> ();
+
+      Ptr<Object> m_downlinkPathlossModelElem = m_dlPathlossModelFactory.Create ();
+      Ptr<SpectrumPropagationLossModel> dlSplm = m_downlinkPathlossModelElem->GetObject<SpectrumPropagationLossModel> ();
+      if (dlSplm != 0)
+        {
+          NS_LOG_LOGIC (this << " using a SpectrumPropagationLossModel in DL");
+          downlinkChannelElem->AddSpectrumPropagationLossModel (dlSplm);
+        }
+      else
+        {
+          NS_LOG_LOGIC (this << " using a PropagationLossModel in DL");
+          Ptr<PropagationLossModel> dlPlm = m_downlinkPathlossModelElem->GetObject<PropagationLossModel> ();
+          NS_ASSERT_MSG (dlPlm != 0, " " << m_downlinkPathlossModelElem << " is neither PropagationLossModel nor SpectrumPropagationLossModel");
+          downlinkChannelElem->AddPropagationLossModel (dlPlm);
+        }
+
+      Ptr<Object> m_uplinkPathlossModelElem = m_ulPathlossModelFactory.Create ();
+      Ptr<SpectrumPropagationLossModel> ulSplm = m_uplinkPathlossModelElem->GetObject<SpectrumPropagationLossModel> ();
+      if (ulSplm != 0)
+        {
+          NS_LOG_LOGIC (this << " using a SpectrumPropagationLossModel in UL");
+          uplinkChannelElem->AddSpectrumPropagationLossModel (ulSplm);
+        }
+      else
+        {
+          NS_LOG_LOGIC (this << " using a PropagationLossModel in UL");
+          Ptr<PropagationLossModel> ulPlm = m_uplinkPathlossModelElem->GetObject<PropagationLossModel> ();
+          NS_ASSERT_MSG (ulPlm != 0, " " << m_uplinkPathlossModelElem << " is neither PropagationLossModel nor SpectrumPropagationLossModel");
+          uplinkChannelElem->AddPropagationLossModel (ulPlm);
+        }
+      if (!m_fadingModelType.empty ())
+        {
+          m_fadingModule = m_fadingModelFactory.Create<SpectrumPropagationLossModel> ();
+          m_fadingModule->Initialize ();
+          downlinkChannelElem->AddSpectrumPropagationLossModel (m_fadingModule);
+          uplinkChannelElem->AddSpectrumPropagationLossModel (m_fadingModule);
+        }
+      m_downlinkChannel.push_back (downlinkChannelElem);
+      m_uplinkChannel.push_back (uplinkChannelElem);
+      m_uplinkPathlossModel.push_back (m_uplinkPathlossModelElem);
+      m_downlinkPathlossModel.push_back (m_downlinkPathlossModelElem);
+    }
+}
 
 void 
 LteHelper::SetEpcHelper (Ptr<EpcHelper> h)
@@ -465,7 +490,7 @@
 }
 
 void
-LteHelper::SetCcPhyParams ( std::map< uint8_t, Ptr<ComponentCarrier> > ccMapParams)
+LteHelper::SetCcPhyParams ( std::map< uint8_t, ComponentCarrier> ccMapParams)
 {
   NS_LOG_FUNCTION (this);
   m_componentCarrierPhyParams = ccMapParams;
@@ -508,47 +533,87 @@
   NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num eNBs exceeded");
   uint16_t cellId = ++m_cellIdCounter;
 
-  Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
-  Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
+  Ptr<LteEnbNetDevice> dev = m_enbNetDeviceFactory.Create<LteEnbNetDevice> ();
+  Ptr<LteHandoverAlgorithm> handoverAlgorithm = m_handoverAlgorithmFactory.Create<LteHandoverAlgorithm> ();
 
-  Ptr<LteEnbPhy> phy = CreateObject<LteEnbPhy> (dlPhy, ulPhy);
+  if (m_componentCarrierPhyParams.size() == 0)
+    {
+      DoComponentCarrierConfigure (dev->GetUlEarfcn (), dev->GetDlEarfcn (), dev->GetUlBandwidth (), dev->GetDlBandwidth ());
+    }
 
-  Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
-  dlPhy->SetHarqPhyModule (harq);
-  ulPhy->SetHarqPhyModule (harq);
-  phy->SetHarqPhyModule (harq);
+  NS_ASSERT_MSG(m_componentCarrierPhyParams.size()!=0, "Cannot create enb ccm map.");
+  // create component carrier map for this eNb device
+  std::map<uint8_t,Ptr<ComponentCarrierEnb> > ccMap;
+  for (std::map<uint8_t, ComponentCarrier >::iterator it = m_componentCarrierPhyParams.begin (); it != m_componentCarrierPhyParams.end (); ++it)
+    {
+      Ptr <ComponentCarrierEnb> cc =  CreateObject<ComponentCarrierEnb> ();
+      cc->SetUlBandwidth(it->second.GetUlBandwidth());
+      cc->SetDlBandwidth(it->second.GetDlBandwidth());
+      cc->SetDlEarfcn(it->second.GetDlEarfcn());
+      cc->SetUlEarfcn(it->second.GetUlEarfcn());
+      cc->SetAsPrimary(it->second.IsPrimary());
+      ccMap [it->first] =  cc;
+    }
+  NS_ABORT_MSG_IF (m_useCa && ccMap.size()<2, "You have to either specify carriers or disable carrier aggregation");
 
-  Ptr<LteChunkProcessor> pCtrl = Create<LteChunkProcessor> ();
-  pCtrl->AddCallback (MakeCallback (&LteEnbPhy::GenerateCtrlCqiReport, phy));
-  ulPhy->AddCtrlSinrChunkProcessor (pCtrl); // for evaluating SRS UL-CQI
+  for (std::map<uint8_t,Ptr<ComponentCarrierEnb> >::iterator it = ccMap.begin (); it != ccMap.end (); ++it)
+    {
+      NS_LOG_DEBUG (this << "component carrier map size " << (uint16_t) ccMap.size ());
+      Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
+      Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
+      Ptr<LteEnbPhy> phy = CreateObject<LteEnbPhy> (dlPhy, ulPhy);
 
-  Ptr<LteChunkProcessor> pData = Create<LteChunkProcessor> ();
-  pData->AddCallback (MakeCallback (&LteEnbPhy::GenerateDataCqiReport, phy));
-  pData->AddCallback (MakeCallback (&LteSpectrumPhy::UpdateSinrPerceived, ulPhy));
-  ulPhy->AddDataSinrChunkProcessor (pData); // for evaluating PUSCH UL-CQI
+      Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
+      dlPhy->SetHarqPhyModule (harq);
+      ulPhy->SetHarqPhyModule (harq);
+      phy->SetHarqPhyModule (harq);
+
+      Ptr<LteChunkProcessor> pCtrl = Create<LteChunkProcessor> ();
+      pCtrl->AddCallback (MakeCallback (&LteEnbPhy::GenerateCtrlCqiReport, phy));
+      ulPhy->AddCtrlSinrChunkProcessor (pCtrl);   // for evaluating SRS UL-CQI
 
-  Ptr<LteChunkProcessor> pInterf = Create<LteChunkProcessor> ();
-  pInterf->AddCallback (MakeCallback (&LteEnbPhy::ReportInterference, phy));
-  ulPhy->AddInterferenceDataChunkProcessor (pInterf); // for interference power tracing
+      Ptr<LteChunkProcessor> pData = Create<LteChunkProcessor> ();
+      pData->AddCallback (MakeCallback (&LteEnbPhy::GenerateDataCqiReport, phy));
+      pData->AddCallback (MakeCallback (&LteSpectrumPhy::UpdateSinrPerceived, ulPhy));
+      ulPhy->AddDataSinrChunkProcessor (pData);   // for evaluating PUSCH UL-CQI
 
-  dlPhy->SetChannel (m_downlinkChannel);
-  ulPhy->SetChannel (m_uplinkChannel);
+      Ptr<LteChunkProcessor> pInterf = Create<LteChunkProcessor> ();
+      pInterf->AddCallback (MakeCallback (&LteEnbPhy::ReportInterference, phy));
+      ulPhy->AddInterferenceDataChunkProcessor (pInterf);   // for interference power tracing
+
+      dlPhy->SetChannel (m_downlinkChannel.at (it->first));
+      ulPhy->SetChannel (m_uplinkChannel.at (it->first));
+
+      Ptr<MobilityModel> mm = n->GetObject<MobilityModel> ();
+      NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallEnbDevice ()");
+      dlPhy->SetMobility (mm);
+      ulPhy->SetMobility (mm);
 
-  Ptr<MobilityModel> mm = n->GetObject<MobilityModel> ();
-  NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
-  dlPhy->SetMobility (mm);
-  ulPhy->SetMobility (mm);
+      Ptr<AntennaModel> antenna = (m_enbAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
+      NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
+      dlPhy->SetAntenna (antenna);
+      ulPhy->SetAntenna (antenna);
 
-  Ptr<AntennaModel> antenna = (m_enbAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
-  NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
-  dlPhy->SetAntenna (antenna);
-  ulPhy->SetAntenna (antenna);
+      Ptr<LteEnbMac> mac = CreateObject<LteEnbMac> ();
+      Ptr<FfMacScheduler> sched = m_schedulerFactory.Create<FfMacScheduler> ();
+      Ptr<LteFfrAlgorithm> ffrAlgorithm = m_ffrAlgorithmFactory.Create<LteFfrAlgorithm> ();
+      it->second->SetMac (mac);
+      it->second->SetFfMacScheduler (sched);
+      it->second->SetFfrAlgorithm (ffrAlgorithm);
+  
+      it->second->SetPhy (phy);
 
-  Ptr<LteEnbMac> mac = CreateObject<LteEnbMac> ();
-  Ptr<FfMacScheduler> sched = m_schedulerFactory.Create<FfMacScheduler> ();
-  Ptr<LteFfrAlgorithm> ffrAlgorithm = m_ffrAlgorithmFactory.Create<LteFfrAlgorithm> ();
-  Ptr<LteHandoverAlgorithm> handoverAlgorithm = m_handoverAlgorithmFactory.Create<LteHandoverAlgorithm> ();
+    }
+
   Ptr<LteEnbRrc> rrc = CreateObject<LteEnbRrc> ();
+  Ptr<LteEnbComponentCarrierManager> ccmEnbManager = m_enbComponentCarrierManagerFactory.Create<LteEnbComponentCarrierManager> ();
+  rrc->ConfigureCarriers(m_componentCarrierPhyParams, m_noOfCcs);
+  
+  //ComponentCarrierManager SAP
+  rrc->SetLteCcmRrcSapProvider (ccmEnbManager->GetLteCcmRrcSapProvider ());
+  ccmEnbManager->SetLteCcmRrcSapUser (rrc->GetLteCcmRrcSapUser ());
+  ccmEnbManager->SetNumberOfComponentCarriers (m_noOfCcs);
+  ccmEnbManager->SetRrc(rrc);
 
   if (m_useIdealRrc)
     {
@@ -578,42 +643,73 @@
         }
     }
 
-  rrc->SetLteEnbCmacSapProvider (mac->GetLteEnbCmacSapProvider ());
-  mac->SetLteEnbCmacSapUser (rrc->GetLteEnbCmacSapUser ());
-  rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());
-
   rrc->SetLteHandoverManagementSapProvider (handoverAlgorithm->GetLteHandoverManagementSapProvider ());
   handoverAlgorithm->SetLteHandoverManagementSapUser (rrc->GetLteHandoverManagementSapUser ());
-
-  mac->SetFfMacSchedSapProvider (sched->GetFfMacSchedSapProvider ());
-  mac->SetFfMacCschedSapProvider (sched->GetFfMacCschedSapProvider ());
+ 
+  // This RRC attribute is used to connect each new RLC instance with the MAC layer
+  // (for function such as TransmitPdu, ReportBufferStatusReport).
+  // Since in this new architecture, the component carrier manager acts a proxy, it
+  // will have its own LteMacSapProvider interface, RLC will see it as through original MAC
+  // interface LteMacSapProvider, but the function call will go now through LteEnbComponentCarrierManager
+  // instance that needs to implement functions of this interface, and its task will be to
+  // forward these calls to the specific MAC of some of the instances of component carriers. This
+  // decision will depend on the specific implementation of the component carrier manager.
+  rrc->SetLteMacSapProvider (ccmEnbManager->GetLteMacSapProvider ());
 
-  sched->SetFfMacSchedSapUser (mac->GetFfMacSchedSapUser ());
-  sched->SetFfMacCschedSapUser (mac->GetFfMacCschedSapUser ());
+  bool ccmTest;
+  for (std::map<uint8_t,Ptr<ComponentCarrierEnb> >::iterator it = ccMap.begin (); it != ccMap.end (); ++it)
+    {
+      it->second->GetPhy ()->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser (it->first));
+      rrc->SetLteEnbCphySapProvider (it->second->GetPhy ()->GetLteEnbCphySapProvider (), it->first);
+
+      rrc->SetLteEnbCmacSapProvider (it->second->GetMac ()->GetLteEnbCmacSapProvider (),it->first );
+      it->second->GetMac ()->SetLteEnbCmacSapUser (rrc->GetLteEnbCmacSapUser (it->first));
 
-  phy->SetLteEnbPhySapUser (mac->GetLteEnbPhySapUser ());
-  mac->SetLteEnbPhySapProvider (phy->GetLteEnbPhySapProvider ());
-
-  phy->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser ());
-  rrc->SetLteEnbCphySapProvider (phy->GetLteEnbCphySapProvider ());
+      it->second->GetPhy ()->SetComponentCarrierId (it->first);
+      it->second->GetMac ()->SetComponentCarrierId (it->first);
+      //FFR SAP
+      it->second->GetFfMacScheduler ()->SetLteFfrSapProvider (it->second->GetFfrAlgorithm ()->GetLteFfrSapProvider ());
+      it->second->GetFfrAlgorithm ()->SetLteFfrSapUser (it->second->GetFfMacScheduler ()->GetLteFfrSapUser ());
+      rrc->SetLteFfrRrcSapProvider (it->second->GetFfrAlgorithm ()->GetLteFfrRrcSapProvider (), it->first);
+      it->second->GetFfrAlgorithm ()->SetLteFfrRrcSapUser (rrc->GetLteFfrRrcSapUser (it->first));
+      //FFR SAP END
 
-  //FFR SAP
-  sched->SetLteFfrSapProvider (ffrAlgorithm->GetLteFfrSapProvider ());
-  ffrAlgorithm->SetLteFfrSapUser (sched->GetLteFfrSapUser ());
+      // PHY <--> MAC SAP
+      it->second->GetPhy ()->SetLteEnbPhySapUser (it->second->GetMac ()->GetLteEnbPhySapUser ());
+      it->second->GetMac ()->SetLteEnbPhySapProvider (it->second->GetPhy ()->GetLteEnbPhySapProvider ());
+      // PHY <--> MAC SAP END
+
+      //Scheduler SAP
+      it->second->GetMac ()->SetFfMacSchedSapProvider (it->second->GetFfMacScheduler ()->GetFfMacSchedSapProvider ());
+      it->second->GetMac ()->SetFfMacCschedSapProvider (it->second->GetFfMacScheduler ()->GetFfMacCschedSapProvider ());
+
+      it->second->GetFfMacScheduler ()->SetFfMacSchedSapUser (it->second->GetMac ()->GetFfMacSchedSapUser ());
+      it->second->GetFfMacScheduler ()->SetFfMacCschedSapUser (it->second->GetMac ()->GetFfMacCschedSapUser ());
+      // Scheduler SAP END
+
+      it->second->GetMac ()->SetLteCcmMacSapUser (ccmEnbManager->GetLteCcmMacSapUser ());
+      ccmEnbManager->SetCcmMacSapProviders (it->first, it->second->GetMac ()->GetLteCcmMacSapProvider ());
 
-  rrc->SetLteFfrRrcSapProvider (ffrAlgorithm->GetLteFfrRrcSapProvider ());
-  ffrAlgorithm->SetLteFfrRrcSapUser (rrc->GetLteFfrRrcSapUser ());
-  //FFR SAP END
+      // insert the pointer to the LteMacSapProvider interface of the MAC layer of the specific component carrier
+      ccmTest = ccmEnbManager->SetMacSapProvider (it->first, it->second->GetMac ()->GetLteMacSapProvider());
+
+      if (ccmTest == false)
+        {
+          NS_FATAL_ERROR ("Error in SetComponentCarrierMacSapProviders");
+        }
+    }
 
-  Ptr<LteEnbNetDevice> dev = m_enbNetDeviceFactory.Create<LteEnbNetDevice> ();
+
+
   dev->SetNode (n);
-  dev->SetAttribute ("CellId", UintegerValue (cellId)); 
-  dev->SetAttribute ("LteEnbPhy", PointerValue (phy));
-  dev->SetAttribute ("LteEnbMac", PointerValue (mac));
-  dev->SetAttribute ("FfMacScheduler", PointerValue (sched));
+  dev->SetAttribute ("CellId", UintegerValue (cellId));
+  dev->SetAttribute ("LteEnbComponentCarrierManager", PointerValue (ccmEnbManager));
+  dev->SetCcMap (ccMap);
+  std::map<uint8_t,Ptr<ComponentCarrierEnb> >::iterator it = ccMap.begin ();
+  dev->SetAttribute ("FfMacScheduler", PointerValue (it->second->GetFfMacScheduler ()));
   dev->SetAttribute ("LteEnbRrc", PointerValue (rrc)); 
   dev->SetAttribute ("LteHandoverAlgorithm", PointerValue (handoverAlgorithm));
-  dev->SetAttribute ("LteFfrAlgorithm", PointerValue (ffrAlgorithm));
+  dev->SetAttribute ("LteFfrAlgorithm", PointerValue (it->second->GetFfrAlgorithm ()));
 
   if (m_isAnrEnabled)
     {
@@ -623,35 +719,41 @@
       dev->SetAttribute ("LteAnr", PointerValue (anr));
     }
 
-  phy->SetDevice (dev);
-  dlPhy->SetDevice (dev);
-  ulPhy->SetDevice (dev);
-
-  n->AddDevice (dev);
-  ulPhy->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteEnbPhy::PhyPduReceived, phy));
-  ulPhy->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteEnbPhy::ReceiveLteControlMessageList, phy));
-  ulPhy->SetLtePhyUlHarqFeedbackCallback (MakeCallback (&LteEnbPhy::ReceiveLteUlHarqFeedback, phy));
-  rrc->SetForwardUpCallback (MakeCallback (&LteEnbNetDevice::Receive, dev));
+  for (it = ccMap.begin (); it != ccMap.end (); ++it)
+    {
+      Ptr<LteEnbPhy> ccPhy = it->second->GetPhy ();
+      ccPhy->SetDevice (dev);
+      ccPhy->GetUlSpectrumPhy ()->SetDevice (dev);
+      ccPhy->GetDlSpectrumPhy ()->SetDevice (dev);
+      ccPhy->GetUlSpectrumPhy ()->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteEnbPhy::PhyPduReceived, ccPhy));
+      ccPhy->GetUlSpectrumPhy ()->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteEnbPhy::ReceiveLteControlMessageList, ccPhy));
+      ccPhy->GetUlSpectrumPhy ()->SetLtePhyUlHarqFeedbackCallback (MakeCallback (&LteEnbPhy::ReceiveLteUlHarqFeedback, ccPhy));
+      NS_LOG_LOGIC ("set the propagation model frequencies");
+      double dlFreq = LteSpectrumValueHelper::GetCarrierFrequency (it->second->m_dlEarfcn);
+      NS_LOG_LOGIC ("DL freq: " << dlFreq);
+      bool dlFreqOk = m_downlinkPathlossModel.at (it->first)->SetAttributeFailSafe ("Frequency", DoubleValue (dlFreq));
+      if (!dlFreqOk)
+        {
+          NS_LOG_WARN ("DL propagation model does not have a Frequency attribute");
+        }
 
-  NS_LOG_LOGIC ("set the propagation model frequencies");
-  double dlFreq = LteSpectrumValueHelper::GetCarrierFrequency (dev->GetDlEarfcn ());
-  NS_LOG_LOGIC ("DL freq: " << dlFreq);
-  bool dlFreqOk = m_downlinkPathlossModel->SetAttributeFailSafe ("Frequency", DoubleValue (dlFreq));
-  if (!dlFreqOk)
+      double ulFreq = LteSpectrumValueHelper::GetCarrierFrequency (it->second->m_ulEarfcn);
+
+      NS_LOG_LOGIC ("UL freq: " << ulFreq);
+      bool ulFreqOk = m_uplinkPathlossModel.at(it->first)->SetAttributeFailSafe ("Frequency", DoubleValue (ulFreq));
+      if (!ulFreqOk)
+        {
+          NS_LOG_WARN ("UL propagation model does not have a Frequency attribute");
+        }
+    }  //end for
+  rrc->SetForwardUpCallback (MakeCallback (&LteEnbNetDevice::Receive, dev));
+  dev->Initialize ();
+  n->AddDevice (dev);
+
+  for (it = ccMap.begin (); it != ccMap.end (); ++it)
     {
-      NS_LOG_WARN ("DL propagation model does not have a Frequency attribute");
+      m_uplinkChannel.at (it->first)->AddRx (it->second->GetPhy ()->GetUlSpectrumPhy ());
     }
-  double ulFreq = LteSpectrumValueHelper::GetCarrierFrequency (dev->GetUlEarfcn ());
-  NS_LOG_LOGIC ("UL freq: " << ulFreq);
-  bool ulFreqOk = m_uplinkPathlossModel->SetAttributeFailSafe ("Frequency", DoubleValue (ulFreq));
-  if (!ulFreqOk)
-    {
-      NS_LOG_WARN ("UL propagation model does not have a Frequency attribute");
-    }
-
-  dev->Initialize ();
-
-  m_uplinkChannel->AddRx (ulPhy);
 
   if (m_epcHelper != 0)
     {
@@ -677,63 +779,94 @@
 LteHelper::InstallSingleUeDevice (Ptr<Node> n)
 {
   NS_LOG_FUNCTION (this);
-  Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
-  Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
 
-  Ptr<LteUePhy> phy = CreateObject<LteUePhy> (dlPhy, ulPhy);
+  NS_ABORT_MSG_IF (m_componentCarrierPhyParams.size() == 0 && m_useCa, "If CA is enabled, before call this method you need to install Enbs --> InstallEnbDevice()");
 
-  Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
-  dlPhy->SetHarqPhyModule (harq);
-  ulPhy->SetHarqPhyModule (harq);
-  phy->SetHarqPhyModule (harq);
-
-  Ptr<LteChunkProcessor> pRs = Create<LteChunkProcessor> ();
-  pRs->AddCallback (MakeCallback (&LteUePhy::ReportRsReceivedPower, phy));
-  dlPhy->AddRsPowerChunkProcessor (pRs);
-
-  Ptr<LteChunkProcessor> pInterf = Create<LteChunkProcessor> ();
-  pInterf->AddCallback (MakeCallback (&LteUePhy::ReportInterference, phy));
-  dlPhy->AddInterferenceCtrlChunkProcessor (pInterf); // for RSRQ evaluation of UE Measurements
+  Ptr<LteUeNetDevice> dev = m_ueNetDeviceFactory.Create<LteUeNetDevice> ();
+  std::map<uint8_t, Ptr<ComponentCarrierUe> > ueCcMap;
 
-  Ptr<LteChunkProcessor> pCtrl = Create<LteChunkProcessor> ();
-  pCtrl->AddCallback (MakeCallback (&LteSpectrumPhy::UpdateSinrPerceived, dlPhy));
-  dlPhy->AddCtrlSinrChunkProcessor (pCtrl);
-
-  Ptr<LteChunkProcessor> pData = Create<LteChunkProcessor> ();
-  pData->AddCallback (MakeCallback (&LteSpectrumPhy::UpdateSinrPerceived, dlPhy));
-  dlPhy->AddDataSinrChunkProcessor (pData);
-
-  if (m_usePdschForCqiGeneration)
+  for (std::map< uint8_t, ComponentCarrier >::iterator it = m_componentCarrierPhyParams.begin() ; it != m_componentCarrierPhyParams.end(); ++it)
     {
-      // CQI calculation based on PDCCH for signal and PDSCH for interference
-      pCtrl->AddCallback (MakeCallback (&LteUePhy::GenerateMixedCqiReport, phy));
-      Ptr<LteChunkProcessor> pDataInterf = Create<LteChunkProcessor> ();      
-      pDataInterf->AddCallback (MakeCallback (&LteUePhy::ReportDataInterference, phy));
-      dlPhy->AddInterferenceDataChunkProcessor (pDataInterf);
-    }
-  else
-    {
-      // CQI calculation based on PDCCH for both signal and interference
-      pCtrl->AddCallback (MakeCallback (&LteUePhy::GenerateCtrlCqiReport, phy));
+      Ptr <ComponentCarrierUe> cc =  CreateObject<ComponentCarrierUe> ();
+      cc->SetUlBandwidth ( it->second.GetUlBandwidth ());
+      cc->SetDlBandwidth ( it->second.GetDlBandwidth ());
+      cc->SetDlEarfcn ( it->second.GetDlEarfcn ());
+      cc->SetUlEarfcn ( it->second.GetUlEarfcn ());
+      cc->SetAsPrimary (it->second.IsPrimary());
+      Ptr<LteUeMac> mac = CreateObject<LteUeMac> ();
+      cc->SetMac (mac);
+      // cc->GetPhy ()->Initialize (); // it is initialized within the LteUeNetDevice::DoInitialize ()
+      ueCcMap.insert (std::pair<uint8_t, Ptr<ComponentCarrierUe> > (it->first, cc));
     }
 
+  for (std::map<uint8_t, Ptr<ComponentCarrierUe> >::iterator it = ueCcMap.begin (); it != ueCcMap.end (); ++it)
+    {
+      Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
+      Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
 
+      Ptr<LteUePhy> phy = CreateObject<LteUePhy> (dlPhy, ulPhy);
+
+      Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
+      dlPhy->SetHarqPhyModule (harq);
+      ulPhy->SetHarqPhyModule (harq);
+      phy->SetHarqPhyModule (harq);
 
-  dlPhy->SetChannel (m_downlinkChannel);
-  ulPhy->SetChannel (m_uplinkChannel);
+      Ptr<LteChunkProcessor> pRs = Create<LteChunkProcessor> ();
+      pRs->AddCallback (MakeCallback (&LteUePhy::ReportRsReceivedPower, phy));
+      dlPhy->AddRsPowerChunkProcessor (pRs);
+
+      Ptr<LteChunkProcessor> pInterf = Create<LteChunkProcessor> ();
+      pInterf->AddCallback (MakeCallback (&LteUePhy::ReportInterference, phy));
+      dlPhy->AddInterferenceCtrlChunkProcessor (pInterf);   // for RSRQ evaluation of UE Measurements
+
+      Ptr<LteChunkProcessor> pCtrl = Create<LteChunkProcessor> ();
+      pCtrl->AddCallback (MakeCallback (&LteSpectrumPhy::UpdateSinrPerceived, dlPhy));
+      dlPhy->AddCtrlSinrChunkProcessor (pCtrl);
+
+      Ptr<LteChunkProcessor> pData = Create<LteChunkProcessor> ();
+      pData->AddCallback (MakeCallback (&LteSpectrumPhy::UpdateSinrPerceived, dlPhy));
+      dlPhy->AddDataSinrChunkProcessor (pData);
 
-  Ptr<MobilityModel> mm = n->GetObject<MobilityModel> ();
-  NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
-  dlPhy->SetMobility (mm);
-  ulPhy->SetMobility (mm);
+      if (m_usePdschForCqiGeneration)
+        {
+          // CQI calculation based on PDCCH for signal and PDSCH for interference
+          pCtrl->AddCallback (MakeCallback (&LteUePhy::GenerateMixedCqiReport, phy));
+          Ptr<LteChunkProcessor> pDataInterf = Create<LteChunkProcessor> ();
+          pDataInterf->AddCallback (MakeCallback (&LteUePhy::ReportDataInterference, phy));
+          dlPhy->AddInterferenceDataChunkProcessor (pDataInterf);
+        }
+      else
+        {
+          // CQI calculation based on PDCCH for both signal and interference
+          pCtrl->AddCallback (MakeCallback (&LteUePhy::GenerateCtrlCqiReport, phy));
+        }
+
+      dlPhy->SetChannel (m_downlinkChannel.at (it->first));
+      ulPhy->SetChannel (m_uplinkChannel.at (it->first));
 
-  Ptr<AntennaModel> antenna = (m_ueAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
-  NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
-  dlPhy->SetAntenna (antenna);
-  ulPhy->SetAntenna (antenna);
+      Ptr<MobilityModel> mm = n->GetObject<MobilityModel> ();
+      NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
+      dlPhy->SetMobility (mm);
+      ulPhy->SetMobility (mm);
+
+      Ptr<AntennaModel> antenna = (m_ueAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
+      NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
+      dlPhy->SetAntenna (antenna);
+      ulPhy->SetAntenna (antenna);
 
-  Ptr<LteUeMac> mac = CreateObject<LteUeMac> ();
+      it->second->SetPhy(phy);
+    }
+  Ptr<LteUeComponentCarrierManager> ccmUe = m_ueComponentCarrierManagerFactory.Create<LteUeComponentCarrierManager> ();
+  ccmUe->SetNumberOfComponentCarriers (m_noOfCcs);
+
   Ptr<LteUeRrc> rrc = CreateObject<LteUeRrc> ();
+  rrc->m_numberOfComponentCarriers = m_noOfCcs;
+  // run intializeSap to create the proper number of sap provider/users
+  rrc->InitializeSap();
+  rrc->SetLteMacSapProvider (ccmUe->GetLteMacSapProvider ());
+  // setting ComponentCarrierManager SAP
+  rrc->SetLteCcmRrcSapProvider (ccmUe->GetLteCcmRrcSapProvider ());
+  ccmUe->SetLteCcmRrcSapUser (rrc->GetLteCcmRrcSapUser ());
 
   if (m_useIdealRrc)
     {
@@ -761,37 +894,54 @@
   nas->SetAsSapProvider (rrc->GetAsSapProvider ());
   rrc->SetAsSapUser (nas->GetAsSapUser ());
 
-  rrc->SetLteUeCmacSapProvider (mac->GetLteUeCmacSapProvider ());
-  mac->SetLteUeCmacSapUser (rrc->GetLteUeCmacSapUser ());
-  rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());
+  for (std::map<uint8_t, Ptr<ComponentCarrierUe> >::iterator it = ueCcMap.begin (); it != ueCcMap.end (); ++it)
+    {
+      rrc->SetLteUeCmacSapProvider (it->second->GetMac ()->GetLteUeCmacSapProvider (), it->first);
+      it->second->GetMac ()->SetLteUeCmacSapUser (rrc->GetLteUeCmacSapUser (it->first));
+      it->second->GetMac ()->SetComponentCarrierId (it->first);
 
-  phy->SetLteUePhySapUser (mac->GetLteUePhySapUser ());
-  mac->SetLteUePhySapProvider (phy->GetLteUePhySapProvider ());
+      it->second->GetPhy ()->SetLteUeCphySapUser (rrc->GetLteUeCphySapUser (it->first));
+      rrc->SetLteUeCphySapProvider (it->second->GetPhy ()->GetLteUeCphySapProvider (), it->first);
+      it->second->GetPhy ()->SetComponentCarrierId (it->first);
+      
+      it->second->GetPhy ()->SetLteUePhySapUser (it->second->GetMac ()->GetLteUePhySapUser ());
+      it->second->GetMac ()->SetLteUePhySapProvider (it->second->GetPhy ()->GetLteUePhySapProvider ());
+      
+      bool ccmTest = ccmUe->SetComponentCarrierMacSapProviders (it->first, it->second->GetMac ()->GetLteMacSapProvider());
 
-  phy->SetLteUeCphySapUser (rrc->GetLteUeCphySapUser ());
-  rrc->SetLteUeCphySapProvider (phy->GetLteUeCphySapProvider ());
+      if (ccmTest == false)
+        {
+          NS_FATAL_ERROR ("Error in SetComponentCarrierMacSapProviders");
+        }
+    }
 
   NS_ABORT_MSG_IF (m_imsiCounter >= 0xFFFFFFFF, "max num UEs exceeded");
   uint64_t imsi = ++m_imsiCounter;
 
-  Ptr<LteUeNetDevice> dev = m_ueNetDeviceFactory.Create<LteUeNetDevice> ();
+
   dev->SetNode (n);
   dev->SetAttribute ("Imsi", UintegerValue (imsi));
-  dev->SetAttribute ("LteUePhy", PointerValue (phy));
-  dev->SetAttribute ("LteUeMac", PointerValue (mac));
+  dev->SetCcMap (ueCcMap);
   dev->SetAttribute ("LteUeRrc", PointerValue (rrc));
   dev->SetAttribute ("EpcUeNas", PointerValue (nas));
+  dev->SetAttribute ("LteUeComponentCarrierManager", PointerValue (ccmUe));
 
-  phy->SetDevice (dev);
-  dlPhy->SetDevice (dev);
-  ulPhy->SetDevice (dev);
+  for (std::map<uint8_t, Ptr<ComponentCarrierUe> >::iterator it = ueCcMap.begin (); it != ueCcMap.end (); ++it)
+    {
+      Ptr<LteUePhy> ccPhy = it->second->GetPhy ();
+      ccPhy->SetDevice (dev);
+      ccPhy->GetUlSpectrumPhy ()->SetDevice (dev);
+      ccPhy->GetDlSpectrumPhy ()->SetDevice (dev);
+      ccPhy->GetDlSpectrumPhy ()->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteUePhy::PhyPduReceived, ccPhy));
+      ccPhy->GetDlSpectrumPhy ()->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteUePhy::ReceiveLteControlMessageList, ccPhy));
+      ccPhy->GetDlSpectrumPhy ()->SetLtePhyRxPssCallback (MakeCallback (&LteUePhy::ReceivePss, ccPhy));
+      ccPhy->GetDlSpectrumPhy ()->SetLtePhyDlHarqFeedbackCallback (MakeCallback (&LteUePhy::ReceiveLteDlHarqFeedback, ccPhy));
+    }
+
   nas->SetDevice (dev);
 
   n->AddDevice (dev);
-  dlPhy->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteUePhy::PhyPduReceived, phy));
-  dlPhy->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteUePhy::ReceiveLteControlMessageList, phy));
-  dlPhy->SetLtePhyRxPssCallback (MakeCallback (&LteUePhy::ReceivePss, phy));
-  dlPhy->SetLtePhyDlHarqFeedbackCallback (MakeCallback (&LteUePhy::ReceiveLteDlHarqFeedback, phy));
+
   nas->SetForwardUpCallback (MakeCallback (&LteUeNetDevice::Receive, dev));
 
   if (m_epcHelper != 0)
@@ -1134,6 +1284,19 @@
   enbRrc->DoSendReleaseDataRadioBearer (imsi,rnti,bearerId);
 }
 
+void
+LteHelper::DoComponentCarrierConfigure (uint32_t ulEarfcn, uint32_t dlEarfcn, uint8_t ulbw, uint8_t dlbw)
+{
+  NS_ASSERT_MSG (m_componentCarrierPhyParams.size()==0, "Cc map already exists.");
+  Ptr<CcHelper> ccHelper = CreateObject<CcHelper> ();
+  ccHelper->SetNumberOfComponentCarriers (m_noOfCcs);
+  ccHelper->SetUlEarfcn (ulEarfcn);
+  ccHelper->SetDlEarfcn (dlEarfcn);
+  ccHelper->SetDlBandwidth (dlbw);
+  ccHelper->SetUlBandwidth (ulbw);
+  m_componentCarrierPhyParams = ccHelper->EquallySpacedCcs ();
+  m_componentCarrierPhyParams.at(0).SetAsPrimary(true);
+}
 
 void 
 LteHelper::ActivateDataRadioBearer (NetDeviceContainer ueDevices, EpsBearer bearer)
@@ -1219,16 +1382,22 @@
       Ptr<LteEnbNetDevice> lteEnb = DynamicCast<LteEnbNetDevice> (netDevice);
       if (lteEnb)
         {
-          Ptr<LteSpectrumPhy> dlPhy = lteEnb->GetPhy ()->GetDownlinkSpectrumPhy ();
-          Ptr<LteSpectrumPhy> ulPhy = lteEnb->GetPhy ()->GetUplinkSpectrumPhy ();
+          std::map< uint8_t, Ptr <ComponentCarrierEnb> > tmpMap = lteEnb->GetCcMap ();
+          std::map< uint8_t, Ptr <ComponentCarrierEnb> >::iterator it;
+          it = tmpMap.begin ();
+          Ptr<LteSpectrumPhy> dlPhy = it->second->GetPhy ()->GetDownlinkSpectrumPhy ();
+          Ptr<LteSpectrumPhy> ulPhy = it->second->GetPhy ()->GetUplinkSpectrumPhy ();
           currentStream += dlPhy->AssignStreams (currentStream);
           currentStream += ulPhy->AssignStreams (currentStream);
         }
       Ptr<LteUeNetDevice> lteUe = DynamicCast<LteUeNetDevice> (netDevice);
       if (lteUe)
         {
-          Ptr<LteSpectrumPhy> dlPhy = lteUe->GetPhy ()->GetDownlinkSpectrumPhy ();
-          Ptr<LteSpectrumPhy> ulPhy = lteUe->GetPhy ()->GetUplinkSpectrumPhy ();
+          std::map< uint8_t, Ptr <ComponentCarrierUe> > tmpMap = lteUe->GetCcMap ();
+          std::map< uint8_t, Ptr <ComponentCarrierUe> >::iterator it;
+          it = tmpMap.begin ();
+          Ptr<LteSpectrumPhy> dlPhy = it->second->GetPhy ()->GetDownlinkSpectrumPhy ();
+          Ptr<LteSpectrumPhy> ulPhy = it->second->GetPhy ()->GetUplinkSpectrumPhy ();
           Ptr<LteUeMac> ueMac = lteUe->GetMac ();
           currentStream += dlPhy->AssignStreams (currentStream);
           currentStream += ulPhy->AssignStreams (currentStream);
@@ -1253,28 +1422,28 @@
 void
 LteHelper::EnableDlTxPhyTraces (void)
 {
-  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/DlPhyTransmission",
+  Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMap/*/LteEnbPhy/DlPhyTransmission",
                    MakeBoundCallback (&PhyTxStatsCalculator::DlPhyTransmissionCallback, m_phyTxStats));
 }
 
 void
 LteHelper::EnableUlTxPhyTraces (void)
 {
-  Config::Connect ("/NodeList/*/DeviceList/*/LteUePhy/UlPhyTransmission",
+  Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/LteUePhy/UlPhyTransmission",
                    MakeBoundCallback (&PhyTxStatsCalculator::UlPhyTransmissionCallback, m_phyTxStats));
 }
 
 void
 LteHelper::EnableDlRxPhyTraces (void)
 {
-  Config::Connect ("/NodeList/*/DeviceList/*/LteUePhy/DlSpectrumPhy/DlPhyReception",
+  Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/LteUePhy/DlSpectrumPhy/DlPhyReception",
                    MakeBoundCallback (&PhyRxStatsCalculator::DlPhyReceptionCallback, m_phyRxStats));
 }
 
 void
 LteHelper::EnableUlRxPhyTraces (void)
 {
-  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/UlSpectrumPhy/UlPhyReception",
+  Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMap/*/LteEnbPhy/UlSpectrumPhy/UlPhyReception",
                    MakeBoundCallback (&PhyRxStatsCalculator::UlPhyReceptionCallback, m_phyRxStats));
 }
 
@@ -1291,7 +1460,7 @@
 LteHelper::EnableDlMacTraces (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbMac/DlScheduling",
+  Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMap/*/LteEnbMac/DlScheduling",
                    MakeBoundCallback (&MacStatsCalculator::DlSchedulingCallback, m_macStats));
 }
 
@@ -1299,7 +1468,7 @@
 LteHelper::EnableUlMacTraces (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbMac/UlScheduling",
+  Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMap/*/LteEnbMac/UlScheduling",
                    MakeBoundCallback (&MacStatsCalculator::UlSchedulingCallback, m_macStats));
 }
 
@@ -1307,7 +1476,7 @@
 LteHelper::EnableDlPhyTraces (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  Config::Connect ("/NodeList/*/DeviceList/*/LteUePhy/ReportCurrentCellRsrpSinr",
+  Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/LteUePhy/ReportCurrentCellRsrpSinr",
                    MakeBoundCallback (&PhyStatsCalculator::ReportCurrentCellRsrpSinrCallback, m_phyStats));
 }
 
@@ -1315,9 +1484,9 @@
 LteHelper::EnableUlPhyTraces (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/ReportUeSinr",
+  Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMap/*/LteEnbPhy/ReportUeSinr",
                    MakeBoundCallback (&PhyStatsCalculator::ReportUeSinr, m_phyStats));
-  Config::Connect ("/NodeList/*/DeviceList/*/LteEnbPhy/ReportInterference",
+  Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMap/*/LteEnbPhy/ReportInterference",
                    MakeBoundCallback (&PhyStatsCalculator::ReportInterference, m_phyStats));
 
 }
--- a/src/lte/helper/lte-helper.h	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/helper/lte-helper.h	Thu Feb 02 09:33:08 2017 +0100
@@ -16,6 +16,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Nicola Baldo <nbaldo@cttc.es>
+ * Modified by: Danilo Abrignani <danilo.abrignani@unibo.it> (Carrier Aggregation - GSoC 2015)
+ *              Biljana Bojovic <biljana.bojovic@cttc.es> (Carrier Aggregation) 
  */
 
 #ifndef LTE_HELPER_H
@@ -273,7 +275,7 @@
    *
    * \param ccmap, the component carrier map
    */
-   void SetCcPhyParams (std::map< uint8_t, Ptr<ComponentCarrier> > ccmap);
+   void SetCcPhyParams (std::map< uint8_t, ComponentCarrier> ccmap);
 
   /**
    * Set the type of spectrum channel to be used in both DL and UL.
@@ -658,12 +660,20 @@
    */
   Ptr<SpectrumChannel> GetDownlinkSpectrumChannel (void) const;
 
+  /**
+   *
+   * \return a pointer to the SpectrumChannel instance used for the downlink on a given carrier
+   */
+  Ptr<SpectrumChannel> GetDownlinkSpectrumChannel (uint8_t carrierId) const;
+
 
 protected:
   // inherited from Object
   virtual void DoInitialize (void);
 
 private:
+
+  void DoComponentCarrierConfigure (uint32_t ulEarfcn, uint32_t dlEarfcn, uint8_t ulbw, uint8_t dlbw);
   /**
    * Create an eNodeB device (LteEnbNetDevice) on the given node.
    * \param n the node where the device is to be installed
@@ -706,15 +716,20 @@
    */
   void DoDeActivateDedicatedEpsBearer (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice, uint8_t bearerId);
 
+  void ChannelModelInitialization (void);
+
+  /**
+   * \brief This function create the component carrier based on provided configuration parameters
+   */
 
   /// The downlink LTE channel used in the simulation.
-  Ptr<SpectrumChannel> m_downlinkChannel;
+  std::vector <Ptr<SpectrumChannel> > m_downlinkChannel;
   /// The uplink LTE channel used in the simulation.
-  Ptr<SpectrumChannel> m_uplinkChannel;
+  std::vector< Ptr<SpectrumChannel> > m_uplinkChannel;
   /// The path loss model used in the downlink channel.
-  Ptr<Object> m_downlinkPathlossModel;
+  std::vector< Ptr<Object> >  m_downlinkPathlossModel;
   /// The path loss model used in the uplink channel.
-  Ptr<Object> m_uplinkPathlossModel;
+  std::vector< Ptr<Object> > m_uplinkPathlossModel;
 
   /// Factory of MAC scheduler object.
   ObjectFactory m_schedulerFactory;
@@ -811,14 +826,14 @@
    * If it is false, the component carrier will be created within the LteHelper
    * this is to mantain the backwards compatibility with user script
    */
-  //bool m_useCa;
+  bool m_useCa;
 
   /**
    * This contains all the information about each component carrier
    */
-  std::map< uint8_t, Ptr<ComponentCarrier> > m_componentCarrierPhyParams;
+  std::map< uint8_t, ComponentCarrier > m_componentCarrierPhyParams;
 
-  //uint16_t m_noOfCcs;
+  uint16_t m_noOfCcs;
 
 };   // end of `class LteHelper`
 
--- a/src/lte/helper/mac-stats-calculator.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/helper/mac-stats-calculator.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -181,17 +181,17 @@
   NS_LOG_FUNCTION (macStats << path);
   uint64_t imsi = 0;
   std::ostringstream pathAndRnti;
-  pathAndRnti << path << "/" << dlSchedulingCallbackInfo.rnti;
+  std::string pathEnb  = path.substr (0, path.find ("/ComponentCarrierMap"));
+  pathAndRnti << pathEnb << "/LteEnbRrc/UeMap/" << dlSchedulingCallbackInfo.rnti;
   if (macStats->ExistsImsiPath (pathAndRnti.str ()) == true)
     {
       imsi = macStats->GetImsiPath (pathAndRnti.str ());
     }
   else
     {
-      imsi = FindImsiFromEnbMac (path, dlSchedulingCallbackInfo.rnti);
+      imsi = FindImsiFromEnbRlcPath (pathAndRnti.str ());
       macStats->SetImsiPath (pathAndRnti.str (), imsi);
     }
-
   uint16_t cellId = 0;
   if (macStats->ExistsCellIdPath (pathAndRnti.str ()) == true)
     {
@@ -199,7 +199,7 @@
     }
   else
     {
-      cellId = FindCellIdFromEnbMac (path, dlSchedulingCallbackInfo.rnti);
+      cellId = FindCellIdFromEnbRlcPath (pathAndRnti.str ());
       macStats->SetCellIdPath (pathAndRnti.str (), cellId);
     }
 
@@ -215,14 +215,15 @@
 
   uint64_t imsi = 0;
   std::ostringstream pathAndRnti;
-  pathAndRnti << path << "/" << rnti;
+  std::string pathEnb  = path.substr (0, path.find ("/ComponentCarrierMap"));
+  pathAndRnti << pathEnb << "/LteEnbRrc/UeMap/" << rnti;
   if (macStats->ExistsImsiPath (pathAndRnti.str ()) == true)
     {
       imsi = macStats->GetImsiPath (pathAndRnti.str ());
     }
   else
     {
-      imsi = FindImsiFromEnbMac (path, rnti);
+      imsi = FindImsiFromEnbRlcPath (pathAndRnti.str ());
       macStats->SetImsiPath (pathAndRnti.str (), imsi);
     }
   uint16_t cellId = 0;
@@ -232,7 +233,7 @@
     }
   else
     {
-      cellId = FindCellIdFromEnbMac (path, rnti);
+      cellId = FindCellIdFromEnbRlcPath (pathAndRnti.str ());
       macStats->SetCellIdPath (pathAndRnti.str (), cellId);
     }
 
--- a/src/lte/helper/phy-rx-stats-calculator.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/helper/phy-rx-stats-calculator.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -186,13 +186,14 @@
   uint64_t imsi = 0;
   std::ostringstream pathAndRnti;
   pathAndRnti << path << "/" << params.m_rnti;
+  std::string pathUePhy  = path.substr (0, path.find ("/ComponentCarrierMapUe"));
   if (phyRxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
     {
       imsi = phyRxStats->GetImsiPath (pathAndRnti.str ());
     }
   else
     {
-      imsi = FindImsiForUe (path, params.m_rnti);
+      imsi = FindImsiFromLteNetDevice (pathUePhy);
       phyRxStats->SetImsiPath (pathAndRnti.str (), imsi);
     }
 
@@ -207,14 +208,15 @@
   NS_LOG_FUNCTION (phyRxStats << path);
   uint64_t imsi = 0;
   std::ostringstream pathAndRnti;
-  pathAndRnti << path << "/" << params.m_rnti;
+  std::string pathEnb  = path.substr (0, path.find ("/ComponentCarrierMap"));
+  pathAndRnti << pathEnb << "/LteEnbRrc/UeMap/" << params.m_rnti;
   if (phyRxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
     {
       imsi = phyRxStats->GetImsiPath (pathAndRnti.str ());
     }
   else
     {
-      imsi = FindImsiForEnb (path, params.m_rnti);
+      imsi = FindImsiFromEnbRlcPath (pathAndRnti.str ());
       phyRxStats->SetImsiPath (pathAndRnti.str (), imsi);
     }
 
--- a/src/lte/helper/phy-stats-calculator.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/helper/phy-stats-calculator.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -229,14 +229,14 @@
 {
   NS_LOG_FUNCTION (phyStats << path);
   uint64_t imsi = 0;
-  std::string pathUePhy  = path.substr (0, path.find ("/ReportCurrentCellRsrpSinr"));
+  std::string pathUePhy  = path.substr (0, path.find ("/ComponentCarrierMapUe"));
   if (phyStats->ExistsImsiPath (pathUePhy) == true)
     {
       imsi = phyStats->GetImsiPath (pathUePhy);
     }
   else
     {
-      imsi = FindImsiFromUePhy (pathUePhy);
+      imsi = FindImsiFromLteNetDevice (pathUePhy);
       phyStats->SetImsiPath (pathUePhy, imsi);
     }
 
@@ -252,8 +252,8 @@
   uint64_t imsi = 0;
   std::ostringstream pathAndRnti;
   pathAndRnti << path << "/" << rnti;
-  std::string pathEnbMac  = path.substr (0, path.find ("LteEnbPhy/ReportUeSinr"));
-  pathEnbMac += "LteEnbMac/DlScheduling";
+  std::string pathEnbMac  = path.substr (0, path.find ("/ComponentCarrierMap"));
+  pathEnbMac += "/LteEnbMac/DlScheduling";
   if (phyStats->ExistsImsiPath (pathAndRnti.str ()) == true)
     {
       imsi = phyStats->GetImsiPath (pathAndRnti.str ());
--- a/src/lte/helper/phy-tx-stats-calculator.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/helper/phy-tx-stats-calculator.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -186,14 +186,15 @@
   NS_LOG_FUNCTION (phyTxStats << path);
   uint64_t imsi = 0;
   std::ostringstream pathAndRnti;
-  pathAndRnti << path << "/" << params.m_rnti;
+  std::string pathEnb  = path.substr (0, path.find ("/ComponentCarrierMap"));
+  pathAndRnti << pathEnb << "/LteEnbRrc/UeMap/" << params.m_rnti;
   if (phyTxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
     {
       imsi = phyTxStats->GetImsiPath (pathAndRnti.str ());
     }
   else
     {
-      imsi = FindImsiForEnb (path, params.m_rnti);
+      imsi = FindImsiFromEnbRlcPath (pathAndRnti.str ());
       phyTxStats->SetImsiPath (pathAndRnti.str (), imsi);
     }
 
@@ -209,13 +210,14 @@
   uint64_t imsi = 0;
   std::ostringstream pathAndRnti;
   pathAndRnti << path << "/" << params.m_rnti;
+  std::string pathUePhy  = path.substr (0, path.find ("/ComponentCarrierMapUe"));
   if (phyTxStats->ExistsImsiPath (pathAndRnti.str ()) == true)
     {
       imsi = phyTxStats->GetImsiPath (pathAndRnti.str ());
     }
   else
     {
-      imsi = FindImsiForUe (path, params.m_rnti);
+      imsi = FindImsiFromLteNetDevice (pathUePhy);
       phyTxStats->SetImsiPath (pathAndRnti.str (), imsi);
     }
 
--- a/src/lte/model/lte-ccm-rrc-sap.h	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-ccm-rrc-sap.h	Thu Feb 02 09:33:08 2017 +0100
@@ -124,7 +124,7 @@
    *                where the bearer is enabled
    */
 
-  virtual std::vector<uint16_t> ReleaseDataRadioBearer (uint16_t rnti, uint8_t lcid) = 0;
+  virtual std::vector<uint8_t> ReleaseDataRadioBearer (uint16_t rnti, uint8_t lcid) = 0;
 
   /**
    * \brief Add the Signal Bearer for a specif Ue in LteEnbComponenCarrierManager
@@ -213,7 +213,7 @@
   virtual void AddLc (LteEnbCmacSapProvider::LcInfo lcInfo, LteMacSapUser* msu);
   virtual void RemoveUe (uint16_t rnti);
   virtual std::vector<LteCcmRrcSapProvider::LcsConfig> SetupDataRadioBearer (EpsBearer bearer, uint8_t bearerId, uint16_t rnti, uint8_t lcid, uint8_t lcGroup, LteMacSapUser *msu);
-  virtual std::vector<uint16_t> ReleaseDataRadioBearer (uint16_t rnti, uint8_t lcid);
+  virtual std::vector<uint8_t> ReleaseDataRadioBearer (uint16_t rnti, uint8_t lcid);
   virtual LteMacSapUser* ConfigureSignalBearer(LteEnbCmacSapProvider::LcInfo lcInfo,  LteMacSapUser* rlcMacSapUser);
 
 private:
@@ -257,7 +257,7 @@
 }
 
 template <class C>
-std::vector<uint16_t> MemberLteCcmRrcSapProvider<C>::ReleaseDataRadioBearer (uint16_t rnti, uint8_t lcid)
+std::vector<uint8_t> MemberLteCcmRrcSapProvider<C>::ReleaseDataRadioBearer (uint16_t rnti, uint8_t lcid)
 {
   return m_owner->DoReleaseDataRadioBearer (rnti, lcid);
 }
--- a/src/lte/model/lte-enb-mac.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-enb-mac.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -691,8 +691,7 @@
 LteEnbMac::ReceiveBsrMessage  (MacCeListElement_s bsr)
 {
   NS_LOG_FUNCTION (this);
-
-  m_ulCeReceived.push_back (bsr);
+  m_ccmMacSapUser->UlReceiveMacCe (bsr, m_componentCarrierId);
 }
 
 void
--- a/src/lte/model/lte-enb-net-device.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-enb-net-device.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -156,7 +156,8 @@
 LteEnbNetDevice::LteEnbNetDevice ()
   : m_isConstructed (false),
     m_isConfigured (false),
-    m_anr (0)
+    m_anr (0),
+    m_componentCarrierManager(0)
 {
   NS_LOG_FUNCTION (this);
 }
@@ -171,12 +172,6 @@
 {
   NS_LOG_FUNCTION (this);
 
-  m_mac->Dispose ();
-  m_mac = 0;
-
-  m_scheduler->Dispose ();
-  m_scheduler = 0;
-
   m_rrc->Dispose ();
   m_rrc = 0;
 
@@ -188,13 +183,16 @@
       m_anr->Dispose ();
       m_anr = 0;
     }
-
-  m_ffrAlgorithm->Dispose ();
-  m_ffrAlgorithm = 0;
-
-  m_phy->Dispose ();
-  m_phy = 0;
-
+  m_componentCarrierManager->Dispose();
+  m_componentCarrierManager = 0;
+  // ComponentCarrierEnb::DoDispose() will call DoDispose
+  // of its PHY, MAC, FFR and scheduler instance
+  for (uint32_t i = 0; i < m_ccMap.size (); i++)
+    {
+      m_ccMap.at (i)->Dispose ();
+      m_ccMap.at (i) = 0;
+    }
+   
   LteNetDevice::DoDispose ();
 }
 
@@ -203,13 +201,13 @@
 Ptr<LteEnbMac>
 LteEnbNetDevice::GetMac () const
 {
-  return m_mac;
+  return m_ccMap.at (0)->GetMac ();
 }
 
 Ptr<LteEnbPhy>
 LteEnbNetDevice::GetPhy () const
 {
-  return m_phy;
+  return m_ccMap.at (0)->GetPhy ();
 }
 
 Ptr<LteEnbMac>
@@ -368,9 +366,13 @@
   NS_LOG_FUNCTION (this);
   m_isConstructed = true;
   UpdateConfig ();
-  m_phy->Initialize ();
-  m_mac->Initialize ();
+  std::map< uint8_t, Ptr<ComponentCarrierEnb> >::iterator it;
+  for (it = m_ccMap.begin (); it != m_ccMap.end (); ++it)
+    {
+       it->second->Initialize ();
+    }
   m_rrc->Initialize ();
+  m_componentCarrierManager->Initialize();
   m_handoverAlgorithm->Initialize ();
 
   if (m_anr != 0)
@@ -402,7 +404,7 @@
         {
           NS_LOG_LOGIC (this << " Configure cell " << m_cellId);
           // we have to make sure that this function is called only once
-          m_rrc->ConfigureCell (m_ulBandwidth, m_dlBandwidth, m_ulEarfcn, m_dlEarfcn, m_cellId);
+          m_rrc->ConfigureCell (m_cellId);
           m_isConfigured = true;
         }
 
--- a/src/lte/model/lte-enb-rrc.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-enb-rrc.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -166,8 +166,12 @@
   m_physicalConfigDedicated.havePdschConfigDedicated = true;
   m_physicalConfigDedicated.pdschConfigDedicated.pa = LteRrcSap::PdschConfigDedicated::dB0;
 
-  m_rrc->m_cmacSapProvider->AddUe (m_rnti);
-  m_rrc->m_cphySapProvider->AddUe (m_rnti);
+  
+  for (uint8_t i = 0; i < m_rrc->m_numberOfComponentCarriers; i++)
+    {
+      m_rrc->m_cmacSapProvider.at (i)->AddUe (m_rnti);
+      m_rrc->m_cphySapProvider.at (i)->AddUe (m_rnti);
+    }
 
   // setup the eNB side of SRB0
   {
@@ -187,8 +191,11 @@
     lcinfo.rnti = m_rnti;
     lcinfo.lcId = lcid;
     // leave the rest of lcinfo empty as CCCH (LCID 0) is pre-configured
-    m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
     // MacSapUserForRlc in the ComponentCarrierManager MacSapUser
+    LteMacSapUser* lteMacSapUser = m_rrc->m_ccmRrcSapProvider->ConfigureSignalBearer(lcinfo, rlc->GetLteMacSapUser ()); 
+    // Signal Channel are only on Primary Carrier
+    m_rrc->m_cmacSapProvider.at (0)->AddLc (lcinfo, lteMacSapUser);
+    m_rrc->m_ccmRrcSapProvider->AddLc (lcinfo, lteMacSapUser);
   }
 
   // setup the eNB side of SRB1; the UE side will be set up upon RRC connection establishment
@@ -226,7 +233,11 @@
     lcinfo.mbrDl = 1e6;
     lcinfo.gbrUl = 1e4;
     lcinfo.gbrDl = 1e4;
-    m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
+    // MacSapUserForRlc in the ComponentCarrierManager MacSapUser
+    LteMacSapUser* MacSapUserForRlc = m_rrc->m_ccmRrcSapProvider->ConfigureSignalBearer(lcinfo, rlc->GetLteMacSapUser ()); 
+    // Signal Channel are only on Primary Carrier
+    m_rrc->m_cmacSapProvider.at (0)->AddLc (lcinfo, MacSapUserForRlc);
+    m_rrc->m_ccmRrcSapProvider->AddLc (lcinfo, MacSapUserForRlc);
   }
 
   LteEnbRrcSapUser::SetupUeParameters ueParams;
@@ -238,12 +249,14 @@
   LteEnbCmacSapProvider::UeConfig req;
   req.m_rnti = m_rnti;
   req.m_transmissionMode = m_physicalConfigDedicated.antennaInfo.transmissionMode;
-  m_rrc->m_cmacSapProvider->UeUpdateConfigurationReq (req);
 
   // configure PHY
-  m_rrc->m_cphySapProvider->SetTransmissionMode (m_rnti, m_physicalConfigDedicated.antennaInfo.transmissionMode);
-  m_rrc->m_cphySapProvider->SetSrsConfigurationIndex (m_rnti, m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex);
-
+  for (uint16_t i = 0; i < m_rrc->m_numberOfComponentCarriers; i++)
+    {
+      m_rrc->m_cmacSapProvider.at (i)->UeUpdateConfigurationReq (req);
+      m_rrc->m_cphySapProvider.at (i)->SetTransmissionMode (m_rnti, m_physicalConfigDedicated.antennaInfo.transmissionMode);
+      m_rrc->m_cphySapProvider.at (i)->SetSrsConfigurationIndex (m_rnti, m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex);
+    }
   // schedule this UeManager instance to be deleted if the UE does not give any sign of life within a reasonable time
   Time maxConnectionDelay;
   switch (m_state)
@@ -383,17 +396,30 @@
       drbInfo->m_pdcp = pdcp;
     }
 
-  LteEnbCmacSapProvider::LcInfo lcinfo;
-  lcinfo.rnti = m_rnti;
-  lcinfo.lcId = lcid;
-  lcinfo.lcGroup = m_rrc->GetLogicalChannelGroup (bearer);
-  lcinfo.qci = bearer.qci;
-  lcinfo.isGbr = bearer.IsGbr ();
-  lcinfo.mbrUl = bearer.gbrQosInfo.mbrUl;
-  lcinfo.mbrDl = bearer.gbrQosInfo.mbrDl;
-  lcinfo.gbrUl = bearer.gbrQosInfo.gbrUl;
-  lcinfo.gbrDl = bearer.gbrQosInfo.gbrDl;
-  m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
+  std::vector<LteCcmRrcSapProvider::LcsConfig> lcOnCcMapping = m_rrc->m_ccmRrcSapProvider->SetupDataRadioBearer (bearer, bearerId, m_rnti, lcid, m_rrc->GetLogicalChannelGroup (bearer), rlc->GetLteMacSapUser ());
+  // LteEnbCmacSapProvider::LcInfo lcinfo;
+  // lcinfo.rnti = m_rnti;
+  // lcinfo.lcId = lcid;
+  // lcinfo.lcGroup = m_rrc->GetLogicalChannelGroup (bearer);
+  // lcinfo.qci = bearer.qci;
+  // lcinfo.isGbr = bearer.IsGbr ();
+  // lcinfo.mbrUl = bearer.gbrQosInfo.mbrUl;
+  // lcinfo.mbrDl = bearer.gbrQosInfo.mbrDl;
+  // lcinfo.gbrUl = bearer.gbrQosInfo.gbrUl;
+  // lcinfo.gbrDl = bearer.gbrQosInfo.gbrDl;
+  // use a for cycle to send the AddLc to the appropriate Mac Sap
+  // if the sap is not initialized the appropriated method has to be called
+  std::vector<LteCcmRrcSapProvider::LcsConfig>::iterator itLcOnCcMapping = lcOnCcMapping.begin ();
+  NS_ASSERT_MSG (itLcOnCcMapping != lcOnCcMapping.end (), "Problem");
+  for (itLcOnCcMapping = lcOnCcMapping.begin (); itLcOnCcMapping != lcOnCcMapping.end (); ++itLcOnCcMapping)
+    {
+      NS_LOG_DEBUG (this << " RNTI " << itLcOnCcMapping->lc.rnti << "Lcid " << (uint16_t) itLcOnCcMapping->lc.lcId << " lcGroup " << (uint16_t) itLcOnCcMapping->lc.lcGroup << " ComponentCarrierId " << itLcOnCcMapping->componentCarrierId);
+      uint8_t index = itLcOnCcMapping->componentCarrierId;
+      LteEnbCmacSapProvider::LcInfo lcinfo = itLcOnCcMapping->lc;
+      LteMacSapUser *msu = itLcOnCcMapping->msu;
+      m_rrc->m_cmacSapProvider.at (index)->AddLc (lcinfo, msu);
+      m_rrc->m_ccmRrcSapProvider->AddLc (lcinfo, msu);
+    }
 
   if (rlcTypeId == LteRlcAm::GetTypeId ())
     {
@@ -464,8 +490,13 @@
   m_rrc->m_x2uTeidInfoMap.erase (it->second->m_gtpTeid);
 
   m_drbMap.erase (it);
-  m_rrc->m_cmacSapProvider->ReleaseLc (m_rnti, lcid);
-
+  std::vector<uint8_t> ccToRelease = m_rrc->m_ccmRrcSapProvider->ReleaseDataRadioBearer (m_rnti, lcid);
+  std::vector<uint8_t>::iterator itCcToRelease = ccToRelease.begin ();
+  NS_ASSERT_MSG (itCcToRelease != ccToRelease.end (), "request to remove radio bearer with unknown drbid (ComponentCarrierManager)");
+  for (itCcToRelease = ccToRelease.begin (); itCcToRelease != ccToRelease.end (); ++itCcToRelease)
+    {
+      m_rrc->m_cmacSapProvider.at (*itCcToRelease)->ReleaseLc (m_rnti, lcid);
+    }
   LteRrcSap::RadioResourceConfigDedicated rrcd;
   rrcd.havePhysicalConfigDedicated = false;
   rrcd.drbToReleaseList.push_back (drbid);
@@ -559,7 +590,7 @@
         hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.cellIdentity = m_rrc->m_cellId;
         hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication = m_rrc->m_sib1.cellAccessRelatedInfo.csgIndication;
         hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity = m_rrc->m_sib1.cellAccessRelatedInfo.csgIdentity;
-        LteEnbCmacSapProvider::RachConfig rc = m_rrc->m_cmacSapProvider->GetRachConfig ();
+        LteEnbCmacSapProvider::RachConfig rc = m_rrc->m_cmacSapProvider.at (0)->GetRachConfig ();
         hpi.asConfig.sourceSystemInformationBlockType2.radioResourceConfigCommon.rachConfigCommon.preambleInfo.numberOfRaPreambles = rc.numberOfRaPreambles;
         hpi.asConfig.sourceSystemInformationBlockType2.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo.preambleTransMax = rc.preambleTransMax;
         hpi.asConfig.sourceSystemInformationBlockType2.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo.raResponseWindowSize = rc.raResponseWindowSize;
@@ -898,13 +929,15 @@
           LteEnbCmacSapProvider::UeConfig req;
           req.m_rnti = m_rnti;
           req.m_transmissionMode = m_physicalConfigDedicated.antennaInfo.transmissionMode;
-          m_rrc->m_cmacSapProvider->UeUpdateConfigurationReq (req);
-
-          // configure PHY
-          m_rrc->m_cphySapProvider->SetTransmissionMode (req.m_rnti, req.m_transmissionMode);
-
-          double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double (m_physicalConfigDedicated.pdschConfigDedicated);
-          m_rrc->m_cphySapProvider->SetPa (m_rnti, paDouble);
+          for (uint8_t i = 0; i < m_rrc->m_numberOfComponentCarriers; i++)
+            {
+              m_rrc->m_cmacSapProvider.at (i)->UeUpdateConfigurationReq (req);
+
+              // configure PHY
+              m_rrc->m_cphySapProvider.at (i)->SetTransmissionMode (req.m_rnti, req.m_transmissionMode);
+              double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double (m_physicalConfigDedicated.pdschConfigDedicated);
+              m_rrc->m_cphySapProvider.at (i)->SetPa (m_rnti, paDouble);
+            }
 
           m_needPhyMacConfiguration = false;
         }
@@ -1012,6 +1045,14 @@
                                                             msg.measResults);
     }
 
+  if ((m_rrc->m_ccmRrcSapProvider != 0)
+      && (m_rrc->m_componentCarrierMeasIds.find (measId) != m_rrc->m_componentCarrierMeasIds.end ()))
+    {
+      // this measurement was requested by the handover algorithm
+      m_rrc->m_ccmRrcSapProvider->ReportUeMeas (m_rnti,
+                                                msg.measResults);
+    }
+
   if ((m_rrc->m_anrSapProvider != 0)
       && (m_rrc->m_anrMeasIds.find (measId) != m_rrc->m_anrMeasIds.end ()))
     {
@@ -1019,13 +1060,26 @@
       m_rrc->m_anrSapProvider->ReportUeMeas (msg.measResults);
     }
 
-  if ((m_rrc->m_ffrRrcSapProvider != 0)
+  if ((m_rrc->m_ffrRrcSapProvider.at (0) != 0)
       && (m_rrc->m_ffrMeasIds.find (measId) != m_rrc->m_ffrMeasIds.end ()))
     {
       // this measurement was requested by the FFR function
-      m_rrc->m_ffrRrcSapProvider->ReportUeMeas (m_rnti, msg.measResults);
+      m_rrc->m_ffrRrcSapProvider.at (0)->ReportUeMeas (m_rnti, msg.measResults);
     }
-
+  if (msg.measResults.haveScellsMeas == true)
+    {
+      for (std::list <LteRrcSap::MeasResultScell>::iterator it = msg.measResults.measScellResultList.measResultScell.begin ();
+           it != msg.measResults.measScellResultList.measResultScell.end ();
+           ++it)
+        {
+          m_rrc->m_ffrRrcSapProvider.at (it->servFreqId)->ReportUeMeas (m_rnti, msg.measResults);
+          /// ToDo: implement on Ffr algorithm the code to properly parsing the new measResults message format
+          /// alternatevely it is needed to 'repack' properly the measResults message before sending to Ffr 
+        }
+    }
+
+  ///Report any measurements to ComponentCarrierManager, so it can react to any change or activate the SCC
+  m_rrc->m_ccmRrcSapProvider->ReportUeMeas (m_rnti, msg.measResults);
   // fire a trace source
   m_rrc->m_recvMeasurementReportTrace (m_imsi, m_rrc->m_cellId, m_rnti, msg);
 
@@ -1090,7 +1144,10 @@
 {
   NS_LOG_FUNCTION (this);
   m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex = srsConfIndex;
-  m_rrc->m_cphySapProvider->SetSrsConfigurationIndex (m_rnti, srsConfIndex);
+  for (uint16_t i = 0; i < m_rrc->m_numberOfComponentCarriers; i++)
+    {
+      m_rrc->m_cphySapProvider.at (i)->SetSrsConfigurationIndex (m_rnti, srsConfIndex);
+    }
   switch (m_state)
     {
     case INITIAL_RANDOM_ACCESS:
@@ -1326,26 +1383,26 @@
   std::list<LteRrcSap::SCellToAddMod> SccCon;
 
   // sCellToReleaseList is always empty since no Scc is released
-  std::map<uint8_t, Ptr<ComponentCarrierEnb> >::iterator it = m_rrc->m_componentCarrierEnbMap.begin();
+  std::map<uint8_t, ComponentCarrier >::iterator it = m_rrc->m_componentCarrierPhyConf.begin();
 
   it++;
-  for (;it!=m_rrc->m_componentCarrierEnbMap.end(); it++)
+  for (;it!=m_rrc->m_componentCarrierPhyConf.end(); it++)
     {
 
       uint8_t ccId = it->first;
-      Ptr<ComponentCarrierEnb> eNbCcm = it->second;
+      ComponentCarrier eNbCcm = it->second;
       LteRrcSap::SCellToAddMod component;
       component.sCellIndex = ccId;
       component.cellIdentification.physCellId = m_rrc->m_cellId;
-      component.cellIdentification.dlCarrierFreq = eNbCcm->m_dlEarfcn;
+      component.cellIdentification.dlCarrierFreq = eNbCcm.m_dlEarfcn;
       component.radioResourceConfigCommonSCell.haveNonUlConfiguration = true;
-      component.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth = eNbCcm->m_dlBandwidth;
+      component.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth = eNbCcm.m_dlBandwidth;
       component.radioResourceConfigCommonSCell.nonUlConfiguration.antennaInfoCommon.antennaPortsCount = 0;
-      component.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon.referenceSignalPower = m_rrc->m_cphySapProvider->GetReferenceSignalPower ();
+      component.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon.referenceSignalPower = m_rrc->m_cphySapProvider.at (0)->GetReferenceSignalPower ();
       component.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon.pb = 0;
       component.radioResourceConfigCommonSCell.haveUlConfiguration = true;
-      component.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq = eNbCcm->m_ulEarfcn;
-      component.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth = eNbCcm->m_ulBandwidth;
+      component.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq = eNbCcm.m_ulEarfcn;
+      component.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth = eNbCcm.m_ulBandwidth;
       component.radioResourceConfigCommonSCell.ulConfiguration.ulPowerControlCommonSCell.alpha = 0;
       //component.radioResourceConfigCommonSCell.ulConfiguration.soundingRsUlConfigCommon.type = LteRrcSap::SoundingRsUlConfigDedicated::SETUP;
       component.radioResourceConfigCommonSCell.ulConfiguration.soundingRsUlConfigCommon.srsBandwidthConfig = 0;
@@ -1405,22 +1462,30 @@
     m_srsCurrentPeriodicityId (0),
     m_lastAllocatedConfigurationIndex (0),
     m_reconfigureUes (false),
-    m_numberOfComponentCarriers (0)
+    m_numberOfComponentCarriers (0),
+    m_carriersConfigured (false)
 {
   NS_LOG_FUNCTION (this);
-  m_cmacSapUser = new EnbRrcMemberLteEnbCmacSapUser (this);
+  m_cmacSapUser.push_back (new EnbRrcMemberLteEnbCmacSapUser (this));
   m_handoverManagementSapUser = new MemberLteHandoverManagementSapUser<LteEnbRrc> (this);
   m_anrSapUser = new MemberLteAnrSapUser<LteEnbRrc> (this);
-  m_ffrRrcSapUser = new MemberLteFfrRrcSapUser<LteEnbRrc> (this);
+  m_ffrRrcSapUser.push_back (new MemberLteFfrRrcSapUser<LteEnbRrc> (this));
   m_rrcSapProvider = new MemberLteEnbRrcSapProvider<LteEnbRrc> (this);
   m_x2SapUser = new EpcX2SpecificEpcX2SapUser<LteEnbRrc> (this);
   m_s1SapUser = new MemberEpcEnbS1SapUser<LteEnbRrc> (this);
-  m_cphySapUser = new MemberLteEnbCphySapUser<LteEnbRrc> (this);
+  m_cphySapUser.push_back (new MemberLteEnbCphySapUser<LteEnbRrc> (this));
   m_ccmRrcSapUser = new MemberLteCcmRrcSapUser <LteEnbRrc>(this);
+  m_cphySapProvider.push_back (0);
+  m_cmacSapProvider.push_back (0);
+  m_ffrRrcSapProvider.push_back (0);
 }
 
-void LteEnbRrc::DoInitialize()
+void LteEnbRrc::ConfigureCarriers(std::map<uint8_t, ComponentCarrier > ccPhyConf, uint16_t numberOfComponentCarriers)
 {
+  NS_ASSERT_MSG (!m_carriersConfigured, "Secondary carriers can be configured only once.");
+  m_componentCarrierPhyConf = ccPhyConf;
+  m_numberOfComponentCarriers = numberOfComponentCarriers;
+
   if (m_numberOfComponentCarriers < MIN_NO_CC || m_numberOfComponentCarriers > MAX_NO_CC)
     {
       // this check is neede in order to maintain backward compatibility with scripts and tests
@@ -1429,11 +1494,23 @@
       // In this case m_numberOfComponentCarriers is set to 1
       m_numberOfComponentCarriers = MIN_NO_CC;
     }
+    
+    if (m_numberOfComponentCarriers > MIN_NO_CC)
+      {
+         for ( uint8_t i = 1; i < m_numberOfComponentCarriers ; i++)
+           {
+             m_cphySapUser.push_back (new MemberLteEnbCphySapUser<LteEnbRrc> (this));
+             m_cmacSapUser.push_back (new EnbRrcMemberLteEnbCmacSapUser (this));
+             m_ffrRrcSapUser.push_back (new MemberLteFfrRrcSapUser<LteEnbRrc> (this));
+             m_cphySapProvider.push_back (0);
+             m_cmacSapProvider.push_back (0);
+             m_ffrRrcSapProvider.push_back (0);
+           } 
+      }
+  m_carriersConfigured = true;
   Object::DoInitialize ();
 }
 
-
-
 LteEnbRrc::~LteEnbRrc ()
 {
   NS_LOG_FUNCTION (this);
@@ -1444,16 +1521,29 @@
 LteEnbRrc::DoDispose ()
 {
   NS_LOG_FUNCTION (this);
-  m_ueMap.clear ();
-  delete m_cmacSapUser;
+  for ( uint8_t i = 0; i < m_numberOfComponentCarriers ; i++)
+    {
+      delete m_cphySapUser[i];
+      delete m_cmacSapUser[i];
+      delete m_ffrRrcSapUser[i];
+    }
+  //delete m_cphySapUser;        
+  m_cphySapUser.erase (m_cphySapUser.begin (),m_cphySapUser.end ());
+  m_cphySapUser.clear ();  
+  //delete m_cmacSapUser;
+  m_cmacSapUser.erase (m_cmacSapUser.begin (),m_cmacSapUser.end ());
+  m_cmacSapUser.clear ();  
+  //delete m_ffrRrcSapUser;
+  m_ffrRrcSapUser.erase (m_ffrRrcSapUser.begin (),m_ffrRrcSapUser.end ());
+  m_ffrRrcSapUser.clear ();
+  m_ueMap.clear ();  
   delete m_handoverManagementSapUser;
   delete m_ccmRrcSapUser;
   delete m_anrSapUser;
-  delete m_ffrRrcSapUser;
   delete m_rrcSapProvider;
   delete m_x2SapUser;
   delete m_s1SapUser;
-  delete m_cphySapUser;
+
 }
 
 TypeId
@@ -1633,14 +1723,28 @@
 LteEnbRrc::SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s)
 {
   NS_LOG_FUNCTION (this << s);
-  m_cmacSapProvider = s;
+  m_cmacSapProvider.at (0) = s;
+}
+
+void
+LteEnbRrc::SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s, uint8_t pos)
+{
+  NS_LOG_FUNCTION (this << s);
+  m_cmacSapProvider.at (pos) = s;
 }
 
 LteEnbCmacSapUser*
 LteEnbRrc::GetLteEnbCmacSapUser ()
 {
   NS_LOG_FUNCTION (this);
-  return m_cmacSapUser;
+  return m_cmacSapUser.at (0);
+}
+
+LteEnbCmacSapUser*
+LteEnbRrc::GetLteEnbCmacSapUser (uint8_t pos)
+{
+  NS_LOG_FUNCTION (this);
+  return m_cmacSapUser.at (pos);
 }
 
 void
@@ -1689,14 +1793,29 @@
 LteEnbRrc::SetLteFfrRrcSapProvider (LteFfrRrcSapProvider * s)
 {
   NS_LOG_FUNCTION (this << s);
-  m_ffrRrcSapProvider = s;
+  m_ffrRrcSapProvider.at (0) = s;
+}
+
+void
+LteEnbRrc::SetLteFfrRrcSapProvider (LteFfrRrcSapProvider * s, uint8_t index)
+{
+  NS_LOG_FUNCTION (this << s);
+  m_ffrRrcSapProvider.at (index) = s;
 }
 
 LteFfrRrcSapUser*
 LteEnbRrc::GetLteFfrRrcSapUser ()
 {
   NS_LOG_FUNCTION (this);
-  return m_ffrRrcSapUser;
+  return m_ffrRrcSapUser.at (0);
+}
+
+LteFfrRrcSapUser*
+LteEnbRrc::GetLteFfrRrcSapUser (uint8_t index)
+{
+  NS_LOG_FUNCTION (this);
+  NS_ASSERT_MSG (index < m_numberOfComponentCarriers, "Invalid component carrier index:"<<index<<" provided in order to obtain FfrRrcSapUser.");
+  return m_ffrRrcSapUser.at (index);
 }
 
 void
@@ -1737,14 +1856,28 @@
 LteEnbRrc::SetLteEnbCphySapProvider (LteEnbCphySapProvider * s)
 {
   NS_LOG_FUNCTION (this << s);
-  m_cphySapProvider = s;
+  m_cphySapProvider.at(0) = s;
 }
 
 LteEnbCphySapUser*
 LteEnbRrc::GetLteEnbCphySapUser ()
 {
   NS_LOG_FUNCTION (this);
-  return m_cphySapUser;
+  return m_cphySapUser.at(0);
+}
+
+void
+LteEnbRrc::SetLteEnbCphySapProvider (LteEnbCphySapProvider * s, uint8_t pos)
+{
+  NS_LOG_FUNCTION (this << s);
+  m_cphySapProvider.at(pos) = s;
+}
+
+LteEnbCphySapUser*
+LteEnbRrc::GetLteEnbCphySapUser (uint8_t pos)
+{
+  NS_LOG_FUNCTION (this);
+  return m_cphySapUser.at(pos);
 }
 
 bool
@@ -1854,23 +1987,32 @@
 }
 
 void
-LteEnbRrc::ConfigureCell (uint8_t ulBandwidth, uint8_t dlBandwidth,
-                          uint16_t ulEarfcn, uint16_t dlEarfcn, uint16_t cellId)
+LteEnbRrc::ConfigureCell (uint16_t cellId)
 {
+  std::map<uint8_t, ComponentCarrier >::iterator it = m_componentCarrierPhyConf.begin ();
+  uint8_t ulBandwidth = it->second.m_ulBandwidth;
+  uint8_t dlBandwidth = it->second.m_dlBandwidth;
+  uint32_t ulEarfcn = it->second.m_ulEarfcn;
+  uint32_t dlEarfcn = it->second.m_dlEarfcn;
   NS_LOG_FUNCTION (this << (uint16_t) ulBandwidth << (uint16_t) dlBandwidth
                         << ulEarfcn << dlEarfcn << cellId);
   NS_ASSERT (!m_configured);
-  m_cmacSapProvider->ConfigureMac (ulBandwidth, dlBandwidth);
-  m_cphySapProvider->SetBandwidth (ulBandwidth, dlBandwidth);
-  m_cphySapProvider->SetEarfcn (ulEarfcn, dlEarfcn);
+
+  for (it = m_componentCarrierPhyConf.begin (); it != m_componentCarrierPhyConf.end (); ++it)
+    {
+      m_cphySapProvider[it->first]->SetBandwidth (it->second.m_ulBandwidth, it->second.m_dlBandwidth);
+      m_cphySapProvider[it->first]->SetEarfcn (it->second.m_ulEarfcn, it->second.m_dlEarfcn);
+      m_cphySapProvider[it->first]->SetCellId (cellId);
+      m_cmacSapProvider[it->first]->ConfigureMac (it->second.m_ulBandwidth, it->second.m_dlBandwidth);
+      m_ffrRrcSapProvider[it->first]->SetCellId (cellId);
+      m_ffrRrcSapProvider[it->first]->SetBandwidth (it->second.m_ulBandwidth, it->second.m_dlBandwidth);
+    }
+
   m_dlEarfcn = dlEarfcn;
   m_ulEarfcn = ulEarfcn;
   m_dlBandwidth = dlBandwidth;
   m_ulBandwidth = ulBandwidth;
   m_cellId = cellId;
-  m_cphySapProvider->SetCellId (cellId);
-  m_ffrRrcSapProvider->SetCellId (cellId);
-  m_ffrRrcSapProvider->SetBandwidth(ulBandwidth, dlBandwidth);
 
   /*
    * Initializing the list of UE measurement configuration (m_ueMeasConfig).
@@ -1898,8 +2040,6 @@
   // Enabling MIB transmission
   LteRrcSap::MasterInformationBlock mib;
   mib.dlBandwidth = m_dlBandwidth;
-  m_cphySapProvider->SetMasterInformationBlock (mib);
-
   // Enabling SIB1 transmission with default values
   m_sib1.cellAccessRelatedInfo.cellIdentity = cellId;
   m_sib1.cellAccessRelatedInfo.csgIndication = false;
@@ -1907,8 +2047,12 @@
   m_sib1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity = 0; // not used
   m_sib1.cellSelectionInfo.qQualMin = -34; // not used, set as minimum value
   m_sib1.cellSelectionInfo.qRxLevMin = m_qRxLevMin; // set as minimum value
-  m_cphySapProvider->SetSystemInformationBlockType1 (m_sib1);
-
+
+  for (it = m_componentCarrierPhyConf.begin (); it != m_componentCarrierPhyConf.end (); ++it)
+    {
+      m_cphySapProvider.at (it->first)->SetMasterInformationBlock (mib);
+      m_cphySapProvider.at (it->first)->SetSystemInformationBlockType1 (m_sib1);
+    }
   /*
    * Enabling transmission of other SIB. The first time System Information is
    * transmitted is arbitrarily assumed to be at +0.016s, and then it will be
@@ -1929,7 +2073,16 @@
 
   // update SIB1 too
   m_sib1.cellAccessRelatedInfo.cellIdentity = cellId;
-  m_cphySapProvider->SetSystemInformationBlockType1 (m_sib1);
+  m_cphySapProvider.at (0)->SetSystemInformationBlockType1 (m_sib1);
+}
+
+void
+LteEnbRrc::SetCellId (uint16_t cellId, uint8_t ccIndex)
+{
+  m_cellId = cellId;
+  // update SIB1 too
+  m_sib1.cellAccessRelatedInfo.cellIdentity = cellId;
+  m_cphySapProvider[ccIndex]->SetSystemInformationBlockType1 (m_sib1);
 }
 
 bool
@@ -2100,7 +2253,7 @@
     }
 
   uint16_t rnti = AddUe (UeManager::HANDOVER_JOINING);
-  LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue anrcrv = m_cmacSapProvider->AllocateNcRaPreamble (rnti);
+  LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue anrcrv = m_cmacSapProvider.at (0)->AllocateNcRaPreamble (rnti);
   if (anrcrv.valid == false)
     {
       NS_LOG_INFO (this << " failed to allocate a preamble for non-contention based RA => cannot accept HO");
@@ -2143,7 +2296,7 @@
   handoverCommand.mobilityControlInfo.rachConfigDedicated.raPreambleIndex = anrcrv.raPreambleId;
   handoverCommand.mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex = anrcrv.raPrachMaskIndex;
 
-  LteEnbCmacSapProvider::RachConfig rc = m_cmacSapProvider->GetRachConfig ();
+  LteEnbCmacSapProvider::RachConfig rc = m_cmacSapProvider.at (0)->GetRachConfig ();
   handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.preambleInfo.numberOfRaPreambles = rc.numberOfRaPreambles;
   handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo.preambleTransMax = rc.preambleTransMax;
   handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo.raResponseWindowSize = rc.raResponseWindowSize;
@@ -2238,7 +2391,7 @@
 
   NS_LOG_LOGIC ("Number of cellInformationItems = " << params.cellInformationList.size ());
 
-  m_ffrRrcSapProvider->RecvLoadInformation(params);
+  m_ffrRrcSapProvider.at (0)->RecvLoadInformation (params);
 }
 
 void
@@ -2414,6 +2567,7 @@
   NS_ASSERT_MSG (found, "no more RNTIs available (do you have more than 65535 UEs in a cell?)");
   m_lastAllocatedRnti = rnti;
   Ptr<UeManager> ueManager = CreateObject<UeManager> (this, rnti, state);
+  m_ccmRrcSapProvider-> AddUe (rnti, (uint8_t)state);
   m_ueMap.insert (std::pair<uint16_t, Ptr<UeManager> > (rnti, ueManager));
   ueManager->Initialize ();
   NS_LOG_DEBUG (this << " New UE RNTI " << rnti << " cellId " << m_cellId << " srs CI " << ueManager->GetSrsConfigurationIndex ());
@@ -2429,12 +2583,16 @@
   NS_ASSERT_MSG (it != m_ueMap.end (), "request to remove UE info with unknown rnti " << rnti);
   uint16_t srsCi = (*it).second->GetSrsConfigurationIndex ();
   m_ueMap.erase (it);
-  m_cmacSapProvider->RemoveUe (rnti);
-  m_cphySapProvider->RemoveUe (rnti);
+  for (uint8_t i = 0; i < m_numberOfComponentCarriers; i++)
+    {
+      m_cmacSapProvider.at (i)->RemoveUe (rnti);
+      m_cphySapProvider.at (i)->RemoveUe (rnti);
+    }
   if (m_s1SapProvider != 0)
     {
       m_s1SapProvider->UeContextRelease (rnti);
     }
+  m_ccmRrcSapProvider-> RemoveUe (rnti);
   // need to do this after UeManager has been deleted
   RemoveSrsConfigurationIndex (srsCi); 
 }
@@ -2491,7 +2649,7 @@
   NS_LOG_FUNCTION (this << csgId << csgIndication);
   m_sib1.cellAccessRelatedInfo.csgIdentity = csgId;
   m_sib1.cellAccessRelatedInfo.csgIndication = csgIndication;
-  m_cphySapProvider->SetSystemInformationBlockType1 (m_sib1);
+  m_cphySapProvider.at (0)->SetSystemInformationBlockType1 (m_sib1);
 }
 
 void
@@ -2646,10 +2804,10 @@
   si.haveSib2 = true;
   si.sib2.freqInfo.ulCarrierFreq = m_ulEarfcn;
   si.sib2.freqInfo.ulBandwidth = m_ulBandwidth;
-  si.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower = m_cphySapProvider->GetReferenceSignalPower();
+  si.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower = m_cphySapProvider.at (0)->GetReferenceSignalPower ();
   si.sib2.radioResourceConfigCommon.pdschConfigCommon.pb = 0;
 
-  LteEnbCmacSapProvider::RachConfig rc = m_cmacSapProvider->GetRachConfig ();
+  LteEnbCmacSapProvider::RachConfig rc = m_cmacSapProvider.at (0)->GetRachConfig ();
   LteRrcSap::RachConfigCommon rachConfigCommon;
   rachConfigCommon.preambleInfo.numberOfRaPreambles = rc.numberOfRaPreambles;
   rachConfigCommon.raSupervisionInfo.preambleTransMax = rc.preambleTransMax;
--- a/src/lte/model/lte-enb-rrc.h	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-enb-rrc.h	Thu Feb 02 09:33:08 2017 +0100
@@ -556,12 +556,10 @@
 
   // inherited from Object
 protected:
-  virtual void DoInitialize ();
   virtual void DoDispose (void);
 public:
   static TypeId GetTypeId (void);
 
-
   /**
    * Set the X2 SAP this RRC should interact with
    * \param s the X2 SAP Provider to be used by this RRC entity
@@ -582,7 +580,7 @@
    */
   void SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s);
 
-  void SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s, uint16_t pos);
+  void SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s, uint8_t pos);
 
   /** 
    * Get the CMAC SAP offered by this RRC
@@ -767,11 +765,9 @@
    *
    * \warning Raises an error when executed more than once.
    */
-  void ConfigureCell (uint8_t ulBandwidth,
-                      uint8_t dlBandwidth,
-                      uint16_t ulEarfcn, 
-                      uint16_t dlEarfcn,
-                      uint16_t cellId);
+  void ConfigureCell (uint16_t cellId);
+
+  void ConfigureCarriers (std::map<uint8_t, ComponentCarrier > ccPhyConf, uint16_t numberOfCarriers);
 
   /** 
    * set the cell id of this eNB
@@ -1025,8 +1021,6 @@
    */
   uint32_t GetSrsPeriodicity () const;
 
-  std::map<uint8_t, Ptr<ComponentCarrierEnb> > m_componentCarrierEnbMap;
-
   /**
    * \brief Associate this RRC entity with a particular CSG information.
    * \param csgId the intended Closed Subscriber Group identity
@@ -1108,9 +1102,9 @@
   EpcX2SapProvider* m_x2SapProvider;
 
   /// Receive API calls from the eNodeB MAC instance.
-  LteEnbCmacSapUser* m_cmacSapUser;
+  std::vector<LteEnbCmacSapUser*> m_cmacSapUser;
   /// Interface to the eNodeB MAC instance.
-  LteEnbCmacSapProvider* m_cmacSapProvider;
+  std::vector<LteEnbCmacSapProvider*> m_cmacSapProvider;
 
   /// Receive API calls from the handover algorithm instance.
   LteHandoverManagementSapUser* m_handoverManagementSapUser;
@@ -1128,9 +1122,9 @@
   LteAnrSapProvider* m_anrSapProvider;
 
   /// Receive API calls from the FFR algorithm instance.
-  LteFfrRrcSapUser* m_ffrRrcSapUser;
+  std::vector<LteFfrRrcSapUser*> m_ffrRrcSapUser;
   /// Interface to the FFR algorithm instance.
-  LteFfrRrcSapProvider* m_ffrRrcSapProvider;
+  std::vector<LteFfrRrcSapProvider*> m_ffrRrcSapProvider;
 
   /// Interface to send messages to UE over the RRC protocol.
   LteEnbRrcSapUser* m_rrcSapUser;
@@ -1145,10 +1139,10 @@
   /// Interface to receive messages from core network over the S1 protocol.
   EpcEnbS1SapUser* m_s1SapUser;
 
-  /// Receive API calls from the eNodeB PHY instance.
-  LteEnbCphySapUser* m_cphySapUser;
-  /// Interface to the eNodeB PHY instance.
-  LteEnbCphySapProvider* m_cphySapProvider;
+  /// Receive API calls from the eNodeB PHY instances.
+  std::vector<LteEnbCphySapUser*> m_cphySapUser;
+  /// Interface to the eNodeB PHY instances.
+  std::vector<LteEnbCphySapProvider*> m_cphySapProvider;
 
   /// True if ConfigureCell() has been completed.
   bool m_configured;
@@ -1316,6 +1310,10 @@
 
   uint16_t m_numberOfComponentCarriers;
 
+  bool m_carriersConfigured;
+
+  std::map<uint8_t, ComponentCarrier> m_componentCarrierPhyConf;
+
 }; // end of `class LteEnbRrc`
 
 
--- a/src/lte/model/lte-rrc-sap.h	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-rrc-sap.h	Thu Feb 02 09:33:08 2017 +0100
@@ -135,7 +135,7 @@
 
   struct PdschConfigCommon
   {
-	int8_t referenceSignalPower;  // INTEGER (-60..50),
+    int8_t referenceSignalPower;  // INTEGER (-60..50),
     int8_t pb;                    // INTEGER (0..3),
   };
 
--- a/src/lte/model/lte-ue-net-device.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-ue-net-device.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -136,14 +136,17 @@
 {
   NS_LOG_FUNCTION (this);
   m_targetEnb = 0;
-  m_mac->Dispose ();
-  m_mac = 0;
+
   m_rrc->Dispose ();
   m_rrc = 0;
-  m_phy->Dispose ();
-  m_phy = 0;
+  
   m_nas->Dispose ();
   m_nas = 0;
+  for (uint32_t i = 0; i < m_ccMap.size (); i++)
+    {
+      m_ccMap.at (i)->Dispose ();
+    }
+  m_componentCarrierManager->Dispose ();
   LteNetDevice::DoDispose ();
 }
 
@@ -175,7 +178,7 @@
 LteUeNetDevice::GetMac (void) const
 {
   NS_LOG_FUNCTION (this);
-  return m_mac;
+  return m_ccMap.at (0)->GetMac ();
 }
 
 
@@ -191,7 +194,7 @@
 LteUeNetDevice::GetPhy (void) const
 {
   NS_LOG_FUNCTION (this);
-  return m_phy;
+  return m_ccMap.at (0)->GetPhy ();
 }
 
 Ptr<LteUeComponentCarrierManager>
@@ -277,8 +280,13 @@
   NS_LOG_FUNCTION (this);
   m_isConstructed = true;
   UpdateConfig ();
-  m_phy->Initialize ();
-  m_mac->Initialize ();
+
+  std::map< uint8_t, Ptr<ComponentCarrierUe> >::iterator it;
+  for (it = m_ccMap.begin (); it != m_ccMap.end (); ++it)
+    {
+      it->second->GetPhy ()->Initialize ();
+      it->second->GetMac ()->Initialize ();
+    }
   m_rrc->Initialize ();
 }
 
--- a/src/lte/model/lte-ue-phy.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-ue-phy.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -612,7 +612,7 @@
 
   NS_ASSERT (m_state != CELL_SEARCH);
   NS_ASSERT (m_cellId > 0);
-  
+
   SpectrumValue mixedSinr = (m_rsReceivedPower * m_paLinear);
   if (m_dataInterferencePowerUpdated)
     {
--- a/src/lte/model/lte-ue-rrc.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-ue-rrc.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -125,8 +125,7 @@
 
 
 LteUeRrc::LteUeRrc ()
-  : m_cphySapProvider (0),
-    m_cmacSapProvider (0),
+  : m_cmacSapProvider (0),
     m_rrcSapUser (0),
     m_macSapProvider (0),
     m_asSapUser (0),
@@ -141,18 +140,19 @@
     m_hasReceivedSib1 (false),
     m_hasReceivedSib2 (false),
     m_csgWhiteList (0),
-    m_numberOfComponentCarriers (0)
+    m_numberOfComponentCarriers (MIN_NO_CC)
 {
   NS_LOG_FUNCTION (this);
-  m_cphySapUser = new MemberLteUeCphySapUser<LteUeRrc> (this);
-  m_cmacSapUser = new UeMemberLteUeCmacSapUser (this);
+  m_cphySapUser.push_back (new MemberLteUeCphySapUser<LteUeRrc> (this));
+  m_cmacSapUser.push_back (new UeMemberLteUeCmacSapUser (this));
+  m_cphySapProvider.push_back(0);
+  m_cmacSapProvider.push_back(0);
   m_rrcSapProvider = new MemberLteUeRrcSapProvider<LteUeRrc> (this);
   m_drbPdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<LteUeRrc> (this);
   m_asSapProvider = new MemberLteAsSapProvider<LteUeRrc> (this);
   m_ccmRrcSapUser = new MemberLteUeCcmRrcSapUser<LteUeRrc> (this);
 }
 
-
 LteUeRrc::~LteUeRrc ()
 {
   NS_LOG_FUNCTION (this);
@@ -162,12 +162,21 @@
 LteUeRrc::DoDispose ()
 {
   NS_LOG_FUNCTION (this);
-  delete m_cphySapUser;
-  delete m_cmacSapUser;
+  for ( uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
+   {
+      delete m_cphySapUser.at(i);
+      delete m_cmacSapUser.at(i);
+   }
+  m_cphySapUser.clear ();
+  m_cmacSapUser.clear ();
   delete m_rrcSapProvider;
   delete m_drbPdcpSapUser;
   delete m_asSapProvider;
   delete m_ccmRrcSapUser;
+  m_cphySapProvider.erase(m_cphySapProvider.begin(), m_cphySapProvider.end());
+  m_cphySapProvider.clear();
+  m_cmacSapProvider.erase(m_cmacSapProvider.begin(), m_cmacSapProvider.end());
+  m_cmacSapProvider.clear();
   m_drbMap.clear ();
 }
 
@@ -271,28 +280,56 @@
 LteUeRrc::SetLteUeCphySapProvider (LteUeCphySapProvider * s)
 {
   NS_LOG_FUNCTION (this << s);
-  m_cphySapProvider = s;
+  m_cphySapProvider.at(0) = s;
+}
+
+void
+LteUeRrc::SetLteUeCphySapProvider (LteUeCphySapProvider * s, uint8_t index)
+{
+  NS_LOG_FUNCTION (this << s);
+  m_cphySapProvider.at(index) = s;
 }
 
 LteUeCphySapUser*
 LteUeRrc::GetLteUeCphySapUser ()
 {
   NS_LOG_FUNCTION (this);
-  return m_cphySapUser;
+  return m_cphySapUser.at(0);
+}
+
+LteUeCphySapUser*
+LteUeRrc::GetLteUeCphySapUser (uint8_t index)
+{
+  NS_LOG_FUNCTION (this);
+  return m_cphySapUser.at(index);
 }
 
 void
 LteUeRrc::SetLteUeCmacSapProvider (LteUeCmacSapProvider * s)
 {
   NS_LOG_FUNCTION (this << s);
-  m_cmacSapProvider = s;
+  m_cmacSapProvider.at (0) = s;
+}
+
+void
+LteUeRrc::SetLteUeCmacSapProvider (LteUeCmacSapProvider * s, uint8_t index)
+{
+  NS_LOG_FUNCTION (this << s);
+  m_cmacSapProvider.at (index) = s;
 }
 
 LteUeCmacSapUser*
 LteUeRrc::GetLteUeCmacSapUser ()
 {
   NS_LOG_FUNCTION (this);
-  return m_cmacSapUser;
+  return m_cmacSapUser.at (0);
+}
+
+LteUeCmacSapUser*
+LteUeRrc::GetLteUeCmacSapUser (uint8_t index)
+{
+  NS_LOG_FUNCTION (this);
+  return m_cmacSapUser.at (index);
 }
 
 void
@@ -439,9 +476,30 @@
   lcConfig.prioritizedBitRateKbps = 65535; // maximum
   lcConfig.bucketSizeDurationMs = 65535; // maximum
   lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
-
-  m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
-
+  m_cmacSapProvider.at(0)->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
+}
+
+void
+LteUeRrc::InitializeSap (void)
+{
+  if (m_numberOfComponentCarriers < MIN_NO_CC || m_numberOfComponentCarriers > MAX_NO_CC)
+    {
+      // this check is neede in order to maintain backward compatibility with scripts and tests
+      // if case lte-helper is not used (like in several tests) the m_numberOfComponentCarriers
+      // is not set and then an error is rised
+      // In this case m_numberOfComponentCarriers is set to 1
+      m_numberOfComponentCarriers = MIN_NO_CC;
+    }
+  if (m_numberOfComponentCarriers > MIN_NO_CC )
+    {
+      for ( uint16_t i = 1; i < m_numberOfComponentCarriers; i++)
+        {
+          m_cphySapUser.push_back(new MemberLteUeCphySapUser<LteUeRrc> (this));
+          m_cmacSapUser.push_back(new UeMemberLteUeCmacSapUser (this));
+          m_cphySapProvider.push_back(0);
+          m_cmacSapProvider.push_back(0);
+        }
+    }
 }
 
 
@@ -519,7 +577,7 @@
   NS_LOG_FUNCTION (this << rnti);
   m_rnti = rnti;
   m_srb0->m_rlc->SetRnti (m_rnti);
-  m_cphySapProvider->SetRnti (m_rnti);
+  m_cphySapProvider.at(0)->SetRnti (m_rnti);
 }
 
 void
@@ -617,7 +675,7 @@
   NS_ASSERT_MSG (m_state == IDLE_START,
                  "cannot start cell selection from state " << ToString (m_state));
   m_dlEarfcn = dlEarfcn;
-  m_cphySapProvider->StartCellSearch (dlEarfcn);
+  m_cphySapProvider.at(0)->StartCellSearch (dlEarfcn);
   SwitchToState (IDLE_CELL_SEARCH);
 }
 
@@ -631,7 +689,7 @@
     case IDLE_START:
       m_cellId = cellId;
       m_dlEarfcn = dlEarfcn;
-      m_cphySapProvider->SynchronizeWithEnb (m_cellId, m_dlEarfcn);
+      m_cphySapProvider.at(0)->SynchronizeWithEnb (m_cellId, m_dlEarfcn);
       SwitchToState (IDLE_WAIT_MIB);
       break;
 
@@ -713,7 +771,7 @@
                                         LteRrcSap::MasterInformationBlock msg)
 { 
   m_dlBandwidth = msg.dlBandwidth;
-  m_cphySapProvider->SetDlBandwidth (msg.dlBandwidth);
+  m_cphySapProvider.at(0)->SetDlBandwidth (msg.dlBandwidth);
   m_hasReceivedMib = true;
   m_mibReceivedTrace (m_imsi, m_cellId, m_rnti, cellId);
 
@@ -864,9 +922,9 @@
           rc.numberOfRaPreambles = msg.sib2.radioResourceConfigCommon.rachConfigCommon.preambleInfo.numberOfRaPreambles;
           rc.preambleTransMax = msg.sib2.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo.preambleTransMax;
           rc.raResponseWindowSize = msg.sib2.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo.raResponseWindowSize;
-          m_cmacSapProvider->ConfigureRach (rc);
-          m_cphySapProvider->ConfigureUplink (m_ulEarfcn, m_ulBandwidth);
-          m_cphySapProvider->ConfigureReferenceSignalPower(msg.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower);
+          m_cmacSapProvider.at (0)->ConfigureRach (rc);
+          m_cphySapProvider.at (0)->ConfigureUplink (m_ulEarfcn, m_ulBandwidth);
+          m_cphySapProvider.at (0)->ConfigureReferenceSignalPower (msg.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower);
           if (m_state == IDLE_WAIT_SIB2)
             {
               NS_ASSERT (m_connectionPending);
@@ -922,19 +980,19 @@
           SwitchToState (CONNECTED_HANDOVER);
           const LteRrcSap::MobilityControlInfo& mci = msg.mobilityControlInfo;
           m_handoverStartTrace (m_imsi, m_cellId, m_rnti, mci.targetPhysCellId);
-          m_cmacSapProvider->Reset ();
-          m_cphySapProvider->Reset ();
+          m_cmacSapProvider.at(0)->Reset ();
+          m_cphySapProvider.at(0)->Reset ();
           m_cellId = mci.targetPhysCellId;
           NS_ASSERT (mci.haveCarrierFreq);
           NS_ASSERT (mci.haveCarrierBandwidth);
-          m_cphySapProvider->SynchronizeWithEnb (m_cellId, mci.carrierFreq.dlCarrierFreq);
-          m_cphySapProvider->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
-          m_cphySapProvider->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth); 
+          m_cphySapProvider.at(0)->SynchronizeWithEnb (m_cellId, mci.carrierFreq.dlCarrierFreq);
+          m_cphySapProvider.at(0)->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
+          m_cphySapProvider.at(0)->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
           m_rnti = msg.mobilityControlInfo.newUeIdentity;
           m_srb0->m_rlc->SetRnti (m_rnti);
           NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
-          m_cmacSapProvider->StartNonContentionBasedRandomAccessProcedure (m_rnti, mci.rachConfigDedicated.raPreambleIndex, mci.rachConfigDedicated.raPrachMaskIndex);
-          m_cphySapProvider->SetRnti (m_rnti);
+          m_cmacSapProvider.at(0)->StartNonContentionBasedRandomAccessProcedure (m_rnti, mci.rachConfigDedicated.raPreambleIndex, mci.rachConfigDedicated.raPrachMaskIndex);
+          m_cphySapProvider.at(0)->SetRnti (m_rnti);
           m_lastRrcTransactionIdentifier = msg.rrcTransactionIdentifier;
           NS_ASSERT (msg.haveRadioResourceConfigDedicated);
 
@@ -1044,7 +1102,7 @@
   NS_LOG_FUNCTION (this);
   m_connectionTimeout.Cancel ();
 
-  m_cmacSapProvider->Reset ();       // reset the MAC
+  m_cmacSapProvider.at (0)->Reset ();       // reset the MAC
   m_hasReceivedSib2 = false;         // invalidate the previously received SIB2
   SwitchToState (IDLE_CAMPED_NORMALLY);
   m_asSapUser->NotifyConnectionFailed ();  // inform upper layer
@@ -1088,7 +1146,7 @@
     {
       NS_LOG_LOGIC (this << " cell " << maxRsrpCellId
                          << " is the strongest untried surrounding cell");
-      m_cphySapProvider->SynchronizeWithEnb (maxRsrpCellId, m_dlEarfcn);
+      m_cphySapProvider.at(0)->SynchronizeWithEnb (maxRsrpCellId, m_dlEarfcn);
       SwitchToState (IDLE_WAIT_MIB_SIB1);
     }
 
@@ -1133,8 +1191,8 @@
   if (isSuitableCell)
     {
       m_cellId = cellId;
-      m_cphySapProvider->SynchronizeWithEnb (cellId, m_dlEarfcn);
-      m_cphySapProvider->SetDlBandwidth (m_dlBandwidth);
+      m_cphySapProvider.at(0)->SynchronizeWithEnb (cellId, m_dlEarfcn);
+      m_cphySapProvider.at(0)->SetDlBandwidth (m_dlBandwidth);
       m_initialCellSelectionEndOkTrace (m_imsi, cellId);
       SwitchToState (IDLE_CAMPED_NORMALLY);
     }
@@ -1172,8 +1230,6 @@
       LteRrcSap::SCellToAddMod scell = *it;
       uint8_t ccId = scell.sCellIndex;
 
-      if (ccId>=m_numberOfComponentCarriers)
-        break;
 
       uint8_t ulBand = scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth;
       uint32_t ulEarfcn = scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq;
@@ -1182,18 +1238,18 @@
       uint8_t txMode = scell.radioResourceConfigDedicateSCell.physicalConfigDedicatedSCell.antennaInfo.transmissionMode;
       uint8_t srsIndex = scell.radioResourceConfigDedicateSCell.physicalConfigDedicatedSCell.soundingRsUlConfigDedicated.srsConfigIndex;
 
-      m_cphySapProvider->SynchronizeWithEnb (m_cellId, dlEarfcn);
-      m_cphySapProvider->SetDlBandwidth (dlBand);
-      m_cphySapProvider->ConfigureUplink (ulEarfcn, ulBand);
-      m_cphySapProvider->ConfigureReferenceSignalPower (scell.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon.referenceSignalPower);
-      m_cphySapProvider->SetTransmissionMode (txMode);
-      m_cphySapProvider->SetRnti(m_rnti);
-      m_cmacSapProvider->SetRnti(m_rnti);
+      m_cphySapProvider.at (ccId)->SynchronizeWithEnb (m_cellId, dlEarfcn);
+      m_cphySapProvider.at (ccId)->SetDlBandwidth (dlBand);
+      m_cphySapProvider.at (ccId)->ConfigureUplink (ulEarfcn, ulBand);
+      m_cphySapProvider.at (ccId)->ConfigureReferenceSignalPower (scell.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon.referenceSignalPower);
+      m_cphySapProvider.at (ccId)->SetTransmissionMode (txMode);
+      m_cphySapProvider.at (ccId)->SetRnti(m_rnti);
+      m_cmacSapProvider.at (ccId)->SetRnti(m_rnti);
       // update PdschConfigDedicated (i.e. P_A value)
       LteRrcSap::PdschConfigDedicated pdschConfigDedicated = scell.radioResourceConfigDedicateSCell.physicalConfigDedicatedSCell.pdschConfigDedicated;
       double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double (pdschConfigDedicated);
-      m_cphySapProvider->SetPa (paDouble);
-      m_cphySapProvider->SetSrsConfigurationIndex (srsIndex);
+      m_cphySapProvider.at (ccId)->SetPa (paDouble);
+      m_cphySapProvider.at (ccId)->SetSrsConfigurationIndex (srsIndex);
     }
 }
 
@@ -1205,11 +1261,11 @@
 
   if (pcd.haveAntennaInfoDedicated)
     {
-      m_cphySapProvider->SetTransmissionMode (pcd.antennaInfo.transmissionMode);
+      m_cphySapProvider.at(0)->SetTransmissionMode (pcd.antennaInfo.transmissionMode);
     }
   if (pcd.haveSoundingRsUlConfigDedicated)
     {
-      m_cphySapProvider->SetSrsConfigurationIndex (pcd.soundingRsUlConfigDedicated.srsConfigIndex);
+      m_cphySapProvider.at(0)->SetSrsConfigurationIndex (pcd.soundingRsUlConfigDedicated.srsConfigIndex);
     }
 
   if (pcd.havePdschConfigDedicated)
@@ -1217,7 +1273,7 @@
       // update PdschConfigDedicated (i.e. P_A value)
       m_pdschConfigDedicated = pcd.pdschConfigDedicated;
       double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double (m_pdschConfigDedicated);
-      m_cphySapProvider->SetPa (paDouble);
+      m_cphySapProvider.at(0)->SetPa (paDouble);
     }
 
   std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
@@ -1259,9 +1315,7 @@
           lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
           lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
           lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
-      
-          m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
-      
+          m_cmacSapProvider.at (0)->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
           ++stamIt;
           NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
           
@@ -1351,9 +1405,12 @@
           lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
           lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;      
 
-          m_cmacSapProvider->AddLc (dtamIt->logicalChannelIdentity,
+          for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
+          {
+            m_cmacSapProvider.at (i)->AddLc (dtamIt->logicalChannelIdentity,
                                     lcConfig,
                                     rlc->GetLteMacSapUser ());
+          }
           rlc->Initialize ();
         }
       else
@@ -1376,7 +1433,10 @@
       m_drbMap.erase (it);      
       m_bid2DrbidMap.erase (drbid);
       //Remove LCID
-      m_cmacSapProvider->RemoveLc (drbid + 2);
+      for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
+       {
+         m_cmacSapProvider.at (i)->RemoveLc (drbid + 2);
+       }
     }
 }
 
@@ -2856,7 +2916,7 @@
   NS_ASSERT (m_hasReceivedSib2);
   m_connectionPending = false; // reset the flag
   SwitchToState (IDLE_RANDOM_ACCESS);
-  m_cmacSapProvider->StartContentionBasedRandomAccessProcedure ();
+  m_cmacSapProvider.at (0)->StartContentionBasedRandomAccessProcedure ();
 }
 
 void 
@@ -2864,11 +2924,11 @@
 {
   NS_LOG_FUNCTION (this << m_imsi);
   m_asSapUser->NotifyConnectionReleased ();
-  m_cmacSapProvider->RemoveLc (1);
+  m_cmacSapProvider.at (0)->RemoveLc (1);
   std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it;
   for (it = m_drbMap.begin (); it != m_drbMap.end (); ++it)
     {
-      m_cmacSapProvider->RemoveLc (it->second->m_logicalChannelIdentity);
+      m_cmacSapProvider.at (0)->RemoveLc (it->second->m_logicalChannelIdentity);
     }
   m_drbMap.clear ();
   m_bid2DrbidMap.clear ();
@@ -2880,7 +2940,7 @@
 LteUeRrc::ConnectionTimeout ()
 {
   NS_LOG_FUNCTION (this << m_imsi);
-  m_cmacSapProvider->Reset ();       // reset the MAC
+  m_cmacSapProvider.at (0)->Reset ();       // reset the MAC
   m_hasReceivedSib2 = false;         // invalidate the previously received SIB2
   SwitchToState (IDLE_CAMPED_NORMALLY);
   m_connectionTimeoutTrace (m_imsi, m_cellId, m_rnti);
--- a/src/lte/model/lte-ue-rrc.h	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/lte-ue-rrc.h	Thu Feb 02 09:33:08 2017 +0100
@@ -132,12 +132,15 @@
 public:
   static TypeId GetTypeId (void);
 
+  void InitializeSap (void);
+
   /**
    * set the CPHY SAP this RRC should use to interact with the PHY
    *
    * \param s the CPHY SAP Provider
    */
   void SetLteUeCphySapProvider (LteUeCphySapProvider * s);
+  void SetLteUeCphySapProvider (LteUeCphySapProvider * s, uint8_t index);
 
   /**
    *
@@ -145,20 +148,22 @@
    * \return s the CPHY SAP User interface offered to the PHY by this RRC
    */
   LteUeCphySapUser* GetLteUeCphySapUser ();
+  LteUeCphySapUser* GetLteUeCphySapUser (uint8_t index);
 
   /**
    * set the CMAC SAP this RRC should interact with
-   *
+   * \brief This function is overloaded to maintain backward compatibility 
    * \param s the CMAC SAP Provider to be used by this RRC
    */
   void SetLteUeCmacSapProvider (LteUeCmacSapProvider * s);
+  void SetLteUeCmacSapProvider (LteUeCmacSapProvider * s, uint8_t index);
 
   /**
-   *
-   *
+   * \brief This function is overloaded to maintain backward compatibility 
    * \return s the CMAC SAP User interface offered to the MAC by this RRC
    */
   LteUeCmacSapUser* GetLteUeCmacSapUser ();
+  LteUeCmacSapUser* GetLteUeCmacSapUser (uint8_t index);
 
 
   /**
@@ -576,11 +581,11 @@
 
   std::map<uint8_t, uint8_t> m_bid2DrbidMap;
 
-  LteUeCphySapUser* m_cphySapUser;
-  LteUeCphySapProvider* m_cphySapProvider;
+  std::vector<LteUeCphySapUser*> m_cphySapUser;
+  std::vector<LteUeCphySapProvider*> m_cphySapProvider;
 
-  LteUeCmacSapUser* m_cmacSapUser;
-  LteUeCmacSapProvider* m_cmacSapProvider;
+  std::vector<LteUeCmacSapUser*> m_cmacSapUser;
+  std::vector<LteUeCmacSapProvider*> m_cmacSapProvider;
 
   LteUeRrcSapUser* m_rrcSapUser;
   LteUeRrcSapProvider* m_rrcSapProvider;
--- a/src/lte/model/no-op-component-carrier-manager.cc	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/no-op-component-carrier-manager.cc	Thu Feb 02 09:33:08 2017 +0100
@@ -303,7 +303,7 @@
 
 }
 
-std::vector<uint16_t>
+std::vector<uint8_t>
 NoOpComponentCarrierManager::DoReleaseDataRadioBearer (uint16_t rnti, uint8_t lcid)
 {
   NS_LOG_FUNCTION (this);
@@ -319,7 +319,7 @@
   NS_LOG_DEBUG (this << " remove lcid " << (uint16_t) lcid << " for rnti " << rnti);
   lcIt = lcsIt->second.find (lcid);
   NS_ASSERT_MSG (lcIt != lcsIt->second.end (), " Logical Channel not found");
-  std::vector<uint16_t> res;
+  std::vector<uint8_t> res;
   for (uint16_t i = 0; i < eccIt->second; i++)
     {
       res.insert (res.end (), i);
--- a/src/lte/model/no-op-component-carrier-manager.h	Thu Feb 02 06:12:05 2017 +0100
+++ b/src/lte/model/no-op-component-carrier-manager.h	Thu Feb 02 09:33:08 2017 +0100
@@ -68,7 +68,7 @@
   virtual void DoReceivePdu (Ptr<Packet> p, uint16_t rnti, uint8_t lcid);
   virtual void DoNotifyHarqDeliveryFailure ();
   virtual void DoRemoveUe (uint16_t rnti);
-  virtual std::vector<uint16_t> DoReleaseDataRadioBearer (uint16_t rnti, uint8_t lcid);
+  virtual std::vector<uint8_t> DoReleaseDataRadioBearer (uint16_t rnti, uint8_t lcid);
   virtual LteMacSapUser* DoConfigureSignalBearer(LteEnbCmacSapProvider::LcInfo lcinfo,  LteMacSapUser* msu);
   /*
    * \brief Forwards uplink BSR to CCM, called by MAC through CCM SAP interface..