diff --git a/.nedfolders b/.nedfolders index b490062879a716f7dafc4481055d6b3b5cd05b14..9708d34fd888c89fb126cb4b97d7664cee7a3be3 100644 --- a/.nedfolders +++ b/.nedfolders @@ -3,50 +3,43 @@ src -inet.examples.mpls -inet.applications.voiptool -inet.world.httptools --inet.applications.dhcp +-inet.nodes.xmipv6 -inet.applications.httptools +-inet.applications.dhcp +-inet.networklayer.rsvp_te -inet.transport.tcp_lwip --inet.networklayer.autorouting.ipv6 -inet.transport.tcp_nsc --inet.examples.inet --inet.examples.httptools.direct --inet.examples.diffserv --inet.networklayer.xmipv6 --inet.examples.traci_launchd --inet.examples.sctp --inet.examples.httptools.socket --inet.examples.manetrouting --inet.examples.emulation --inet.networklayer.ted --inet.nodes.ipv6 --inet.networklayer.manetrouting --inet.networklayer.icmpv6 --inet.examples.adhoc --inet.nodes.xmipv6 --inet.networklayer.rsvp_te +-inet.networklayer.autorouting.ipv6 -inet.networklayer.diffserv -inet.transport.rtp --inet.examples.mobileipv6 -inet.examples.dhcp +-inet.examples.mobileipv6 -inet.nodes.mpls -inet.world.traci +-inet.examples.httptools.direct -inet.examples.traci --inet.examples.ethernet -inet.examples.ipv6 --inet.examples.ospfv2 +-inet.examples.diffserv -inet.nodes.bgp +-inet.examples.ospfv2 +-inet.networklayer.xmipv6 +-inet.examples.traci_launchd -inet.examples.rtp -inet.networklayer.ospfv2 --inet.examples.mobility +-inet.examples.manetrouting +-inet.examples.httptools.socket -inet.networklayer.bgpv4 -inet.applications.traci --inet.examples.voiptool -inet.networklayer.ipv6tunneling --inet.networklayer.ipv6 --inet.networklayer.ldp +-inet.examples.voiptool +-inet.networklayer.ted -inet.nodes.httptools +-inet.networklayer.ldp +-inet.networklayer.ipv6 -inet.networklayer.mpls -inet.examples.bgpv4 +-inet.nodes.ipv6 +-inet.networklayer.manetrouting -inet.applications.rtpapp +-inet.networklayer.icmpv6 -inet.nodes.ospfv2 --inet.examples.wireless diff --git a/examples/_4gsim/out.txt b/examples/_4gsim/out.txt new file mode 100644 index 0000000000000000000000000000000000000000..963873cc5cb5aafcac302aec5f60246574fa49b8 --- /dev/null +++ b/examples/_4gsim/out.txt @@ -0,0 +1,180 @@ +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +42 0 0 0 0 0 0 0 0 0 0 0 0 0 +42 0 0 0 41 0 0 0 0 0 0 0 0 0 +42 0 0 0 0 0 0 0 0 0 0 0 0 0 +42 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +42 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +42 0 0 0 0 40 39 0 0 0 0 0 0 0 +42 0 0 0 41 40 39 0 0 0 0 0 0 0 +42 0 0 0 0 40 39 0 0 0 0 0 0 0 +42 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +42 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 41 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 41 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 41 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 41 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 41 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 41 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +42 0 0 0 0 40 39 0 0 0 0 0 0 0 +42 0 0 0 41 40 39 0 0 0 0 0 0 0 +42 0 0 0 0 40 39 0 0 0 0 0 0 0 +42 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +42 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 41 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 41 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +41 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 0 40 39 0 0 0 0 0 0 0 +37 0 0 0 41 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +37 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 41 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 41 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 41 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 41 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +42 0 0 0 0 0 0 0 0 0 0 0 0 0 +42 0 0 0 41 0 0 0 0 0 0 0 0 0 +42 0 0 0 0 0 0 0 0 0 0 0 0 0 +42 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +42 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 41 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 41 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 41 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 41 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 +41 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/src/linklayer/lte/mac/MACScheduler.cc b/src/linklayer/lte/mac/MACScheduler.cc index b6f6f7b8881c75c0736570836be984020b91d309..e7ed09b03f17d96b158ff2bc96ec9e0d38fa83e4 100644 --- a/src/linklayer/lte/mac/MACScheduler.cc +++ b/src/linklayer/lte/mac/MACScheduler.cc @@ -14,6 +14,7 @@ // #include "MACScheduler.h" +#include "RRC.h" #include "LTEControlInfo_m.h" Define_Module(MACScheduler); @@ -21,6 +22,9 @@ Define_Module(MACScheduler); MACScheduler::MACScheduler() { prachCfgIndex = 64; dlBandwith = 6; + dlCyclPref = CTRL_CP_NORMAL; + nrOfSubcarriers = 12; + nrOfAntennas = 1; } MACScheduler::~MACScheduler() { @@ -54,6 +58,22 @@ unsigned char MACScheduler::getRBGSize() { return 4; } +unsigned char MACScheduler::getReNrInReg(unsigned char l) { + if (l == 0) + return 6; + else if (l == 1 && nrOfAntennas == 4) + return 6; + else if (l == 1 && nrOfAntennas != 4) + return 4; + else if (l == 2) + return 4; + else if (l == 3 && dlCyclPref == CTRL_CP_NORMAL) + return 4; + else if (l == 3 && dlCyclPref == CTRL_CP_EXTENDED) + return 6; + return 0; +} + unsigned MACScheduler::getRIV(unsigned char lCRB, unsigned char rbStart) { if ((lCRB - 1) < floor(dlBandwith / 2)) return dlBandwith * (lCRB - 1) + rbStart; @@ -61,6 +81,23 @@ unsigned MACScheduler::getRIV(unsigned char lCRB, unsigned char rbStart) { return dlBandwith * (dlBandwith - lCRB + 1) + (dlBandwith - 1 - rbStart); } +unsigned char MACScheduler::getNrOfDlSymbForDci(unsigned short nReg) { + unsigned char l = 0; + unsigned short nrOfResInSymb = dlBandwith * nrOfSubcarriers; + unsigned short nrOfRegsInSymb = nrOfResInSymb / getReNrInReg(l); + nrOfRegsInSymb -= 4; // first symbol has also PCFICH resource elements which don't count + if (nReg < nrOfRegsInSymb) + return 1; + l++; + + for (; l < 4; l++) { + nrOfRegsInSymb += nrOfResInSymb / getReNrInReg(l); + if (nReg < nrOfRegsInSymb) + return l + 1; + } + return 0; +} + void MACScheduler::processScheduleDlTriggerRequest(SchedDlTriggerReq *triggReq) { // EV << "MACScheduler: Received SCHED_DL_TRIGGER_REQ. Processing the request.\n"; unsigned char sf = triggReq->getSf(); @@ -70,6 +107,8 @@ void MACScheduler::processScheduleDlTriggerRequest(SchedDlTriggerReq *triggReq) unsigned char rbStart = 0; memset(rbBitmap, false, dlBandwith); + unsigned short nReg = 0; + unsigned nrBldBcastList = 0; SchedDlConfigInd *cfgInd = new SchedDlConfigInd(); cfgInd->setSf(sf); @@ -135,6 +174,8 @@ void MACScheduler::processScheduleDlTriggerRequest(SchedDlTriggerReq *triggReq) dciEl.setTbsIdx(iTBS); bcastEl.setDci(dciEl); + nReg += 18; + cfgInd->setBldBcastListArraySize(++nrBldBcastList); cfgInd->setBldBcastList(nrBldBcastList - 1, bcastEl); } @@ -169,6 +210,8 @@ void MACScheduler::processScheduleDlTriggerRequest(SchedDlTriggerReq *triggReq) // cfgInd->setBldRarList(0, rarEl); // } + cfgInd->setNrOfPdcchSymb(getNrOfDlSymbForDci(nReg)); + nb->fireChangeNotification(SCHED_DL_CONFIG_IND, cfgInd); } @@ -223,6 +266,10 @@ void MACScheduler::receiveChangeNotification(int category, const cPolymorphic *d EV << "MACScheduler: Received CSCHED_CELL_CONFIG_REQ. Processing the request.\n"; CSchedCellConfigReq *cellCfg = check_and_cast(details); + dlCyclPref = cellCfg->getDlCyclPrefLen(); + + nrOfAntennas = cellCfg->getAntennaPortsCount(); + siCfg = cellCfg->getSiConfig(); dlBandwith = cellCfg->getDlBandwith(); diff --git a/src/linklayer/lte/mac/MACScheduler.h b/src/linklayer/lte/mac/MACScheduler.h index 1018f60952dd7ea7ae908ff355fe083597bd3080..d3100c7e02cf1c433758663c76c582729f51e214 100644 --- a/src/linklayer/lte/mac/MACScheduler.h +++ b/src/linklayer/lte/mac/MACScheduler.h @@ -31,6 +31,9 @@ static const unsigned tbSizeTable[N_PRB_SIZE][I_TBS_SIZE] = { class MACScheduler : public cSimpleModule, INotifiable { private: // Cell configuration + unsigned char dlCyclPref; + unsigned char nrOfAntennas; + unsigned char nrOfSubcarriers; SiConfiguration siCfg; // Random Access configuration @@ -47,6 +50,8 @@ private: unsigned char getRBGSize(); unsigned getRIV(unsigned char lCRB, unsigned char rbStart); + unsigned char getReNrInReg(unsigned char l); + unsigned char getNrOfDlSymbForDci(unsigned short nReg); void processScheduleDlTriggerRequest(SchedDlTriggerReq *triggReq); void processScheduleUlTriggerRequest(SchedUlTriggerReq *triggReq); diff --git a/src/linklayer/lte/mac/MACenb.cc b/src/linklayer/lte/mac/MACenb.cc index 867d3ab74161c3c409f0ca14e4e1ddf1111bab4a..cd2fde624122a20f2d0e9560ee11f9ff02e62e97 100644 --- a/src/linklayer/lte/mac/MACenb.cc +++ b/src/linklayer/lte/mac/MACenb.cc @@ -104,6 +104,7 @@ void MACenb::receiveChangeNotification(int category, const cPolymorphic *details DlConfigRequest *dlReq = new DlConfigRequest(); dlReq->setSfn(sfn); dlReq->setSf(sf); + dlReq->setNrPdcchSymb(cfgInd->getNrOfPdcchSymb()); // prepare tx request for physical layer (sent only if tx is scheduled) TxRequest *txReq = new TxRequest(); @@ -216,8 +217,9 @@ void MACenb::receiveChangeNotification(int category, const cPolymorphic *details if (pduIndex > 0) nb->fireChangeNotification(TXRequest, txReq); - else - delete txReq; + + delete dlReq; + delete txReq; } else if (category == RACHIndication) { // TODO check RACH type diff --git a/src/linklayer/lte/mac/SchedulerCommand.msg b/src/linklayer/lte/mac/SchedulerCommand.msg index 54d6d9fd69bbc7fde546afb94e1d8f9c505add96..b3386974c5a2bd2d6367cea0d64544c20a387f55 100644 --- a/src/linklayer/lte/mac/SchedulerCommand.msg +++ b/src/linklayer/lte/mac/SchedulerCommand.msg @@ -19,9 +19,9 @@ enum SchedulerCommandType CSCHED_CELL_CONFIG_REQ = 201; SCHED_DL_TRIGGER_REQ = 202; SCHED_DL_CONFIG_IND = 203; - SCHED_UL_TRIGGER_REQ = 204; - SCHED_UL_CONFIG_IND = 205; - SCHED_DL_RACH_INFO_REQ = 206; + SCHED_UL_TRIGGER_REQ = 204; + SCHED_UL_CONFIG_IND = 205; + SCHED_DL_RACH_INFO_REQ = 206; } class SchedulerCommand @@ -37,8 +37,8 @@ class SiMessageListElement class SiConfiguration { unsigned short sib1Length; // in bytes - unsigned char siWdwLen; - SiMessageListElement siMsgList[]; + unsigned char siWdwLen; + SiMessageListElement siMsgList[]; } class RaConfiguration @@ -52,10 +52,12 @@ class RaConfiguration class CSchedCellConfigReq extends SchedulerCommand { + unsigned char dlCyclPrefLen; + unsigned char antennaPortsCount; SiConfiguration siConfig; unsigned char dlBandwith; unsigned char prachCfgIndex; - RaConfiguration raConfig; + RaConfiguration raConfig; } enum HarqStatus @@ -81,8 +83,8 @@ class SchedDlTriggerReq extends SchedulerCommand class SchedUlTriggerReq extends SchedulerCommand { - unsigned short tti; - bool rapComplete; + unsigned short tti; + bool rapComplete; } class RlcPduListElement @@ -105,18 +107,18 @@ enum VRBFormatType class DlDciListElement { - unsigned short rnti; - unsigned int rbBitmap; - unsigned char rbShift; - unsigned char resAlloc; - unsigned char nrOfTbs; - unsigned short tbsSize[2]; - unsigned char mcs[2]; - unsigned char rv[2]; - unsigned char format; - unsigned char tpc; - unsigned char vrbFormat; - unsigned char tbsIdx; + unsigned short rnti; + unsigned int rbBitmap; + unsigned char rbShift; + unsigned char resAlloc; + unsigned char nrOfTbs; + unsigned short tbsSize[2]; + unsigned char mcs[2]; + unsigned char rv[2]; + unsigned char format; + unsigned char tpc; + unsigned char vrbFormat; + unsigned char tbsIdx; } class BuildDataListElement diff --git a/src/linklayer/lte/phy/PHY.cc b/src/linklayer/lte/phy/PHY.cc index 50562e3246cf59f8dfd956c7e3cdab3381d9a791..6012bf34be9ed10c6adbccae868a3b52256ab7c8 100644 --- a/src/linklayer/lte/phy/PHY.cc +++ b/src/linklayer/lte/phy/PHY.cc @@ -15,28 +15,24 @@ #include "PHY.h" #include "RRC.h" +#include PHY::PHY() : rs(this->getId()) { // TODO Auto-generated constructor stub - sfn = 0; - sf = 0; symbolTimer = NULL; - symb = 0; - slot = 0; - nRBsc = 12; - nDLsymb = 7; - - nDLrb = 255; + nDLrb = 255; ncp = 255; n1id = 255; n2id = 255; nCellId = 65535; - - symbPeriod = 1e-3 / nDLsymb; + p = 1; dlSubframe = NULL; dlBuffer = NULL; + allRegs = NULL; + + cfi = 0; } PHY::~PHY() { @@ -56,6 +52,24 @@ PHY::~PHY() { delete [] dlBuffer[l]; delete [] dlBuffer; } + + if (allRegs) { + for (unsigned char l = 0; l < 4; l++) { + for (unsigned short k = 0; k < nRBsc * nDLrb; k++) { + if (allRegs[l][k]) { + REGs regs = allRegs[l][k]; + unsigned char regNr = getRegNrInRegs(l); + for (unsigned char r = 0; r < regNr; r++) { + REG reg = regs[r]; + delete [] reg; + } + delete [] regs; + } + } + delete [] allRegs[l]; + } + delete [] allRegs; + } } void PHY::initialize(int stage) { @@ -106,123 +120,87 @@ const char *PHY::eventName(int event) { #undef CASE } -bool PHY::operator<(const reg &l, const reg &r) { - +unsigned char PHY::getRegNrInRegs(unsigned char l) { + if (l == 0) + return 2; + else if (l == 1 && p == 4) + return 2; + else if (l == 1 && p != 4) + return 3; + else if (l == 2) + return 3; + else if (l == 3 && ncp == PHY_CP_NORMAL) + return 3; + else if (l == 3 && ncp == PHY_CP_EXTENDED) + return 2; + return 0; } -void PHY::stateEntered(int category, const cPolymorphic *details) { - switch(fsm.getState()) { - case IDLE: { - ParamResponse *paramResp = new ParamResponse(); - paramResp->setErrorCode(MsgOk); - paramResp->setTlvsArraySize(1); - paramResp->setTlvs(0, createPhyCommandTlv(PhyState, 1, IDLE)); - nb->fireChangeNotification(PARAMResponse, paramResp); - break; - } - case CONFIGURED: { - if (category == CONFIGRequest) { - ConfigRequest *cfgReq = check_and_cast(details); - for (unsigned i = 0; i < cfgReq->getTlvsArraySize(); i++) { - if (cfgReq->getTlvs(i).getTag() == SfnSf) { - sfn = cfgReq->getTlvs(i).getValue() / 10; - sf = cfgReq->getTlvs(i).getValue() % 10; - } - if (cfgReq->getTlvs(i).getTag() == DlCyclicPrefixType) { - ncp = cfgReq->getTlvs(i).getValue() == RRC_CP_NORMAL ? PHY_CP_NORMAL : PHY_CP_EXTENDED; - } - if (cfgReq->getTlvs(i).getTag() == DlChannelBandwith) { - nDLrb = cfgReq->getTlvs(i).getValue(); - } - if (cfgReq->getTlvs(i).getTag() == PhysicalCellId) { - nCellId = cfgReq->getTlvs(i).getValue(); - n1id = nCellId / 3; - n2id = nCellId % 3; - } - } - ConfigResponse *cfgResp = new ConfigResponse(); - cfgResp->setErrorCode(MsgOk); - nb->fireChangeNotification(CONFIGResponse, cfgResp); - } - break; - } - case RUNNING: { - if (category == STARTRequest) { - dlSubframe = new PHYSymbol*[nDLsymb * 2]; - for (unsigned char i = 0; i < nDLsymb * 2; i++) - dlSubframe[i] = NULL; - - dlBuffer = new PHYFramePtr*[nDLsymb * 2]; - for (unsigned char l = 0; l < nDLsymb * 2; l++) { - dlBuffer[l] = new PHYFramePtr[nRBsc * nDLrb]; - for (unsigned short k = 0; k < nRBsc * nDLrb; k++) - dlBuffer[l][k] = NULL; - } - - this->cancelEvent(symbolTimer); - this->scheduleAt(simTime(), symbolTimer); - } - break; - } - default: - EV << "LTE-PHYenb: Unknown state.\n"; - break; - } +unsigned char PHY::getReNrInReg(unsigned char l) { + if (l == 0) + return 6; + else if (l == 1 && p == 4) + return 6; + else if (l == 1 && p != 4) + return 4; + else if (l == 2) + return 4; + else if (l == 3 && ncp == PHY_CP_NORMAL) + return 4; + else if (l == 3 && ncp == PHY_CP_EXTENDED) + return 6; + return 0; } -void PHY::receiveChangeNotification(int category, const cPolymorphic *details) { - Enter_Method_Silent(); - - int oldState = fsm.getState(); - - switch(oldState) { - case IDLE: - switch(category) { - case PARAMRequest: { - break; - } - case CONFIGRequest: { - FSM_Goto(fsm, CONFIGURED); - break; - } - default: - EV << "LTE-PHY: Received unexpected event.\n"; - break; - } - break; - case CONFIGURED: - switch(category) { - case STARTRequest: { - FSM_Goto(fsm, RUNNING); - break; - } - default: - EV << "LTE-PHY: Received unexpected event.\n"; - break; - } - break; - case RUNNING: - switch(category) { - case DLCONFIGRequest: { - break; - } - case TXRequest : { - break; - } -// default: -// EV << "LTE-PHY: Received unexpected event.\n"; -// break; - } - break; - default: - EV << "LTE-PHY: Unknown state.\n"; - break; - } +REG PHY::findExactReg(unsigned char l, unsigned short k0) { + unsigned char regNr = getRegNrInRegs(l); + for (unsigned char r = 0; r < regNr; r++) { + if ((k0 >= r * (12 / regNr)) && (allRegs[l][k0 - r * (12 / regNr)] != NULL)) { + REGs regs = allRegs[l][k0 - r * (12 / regNr)]; + return regs[r]; + } + } + return NULL; +} -// if (oldState != fsm.getState()) -// EV << "LTE-PHY: PSM-Transition: " << stateName(oldState) << " --> " << stateName(fsm.getState()) << " (event was: " << eventName(category) << ")\n"; -// else -// EV << "LTE-PHY: Staying in state: " << stateName(fsm.getState()) << " (event was: " << eventName(category) << ")\n"; +void PHY::configureRegs() { + allRegs = new REGs*[4]; + for (unsigned char l = 0; l < 4; l++) { + allRegs[l] = new REGs[nRBsc * nDLrb]; + for (unsigned short k = 0; k < nRBsc * nDLrb; k++) { + if (k % nRBsc == 0) { + unsigned short k0 = k; + unsigned char regNr = getRegNrInRegs(l); + REGs regs = new REG[regNr]; +// EV << "(\n"; + for (unsigned char r = 0; r < regNr; r++) { +// EV << "("; + unsigned char reNr = getReNrInReg(l); + REG reg = new RE[reNr]; + for (unsigned char kRel = 0; kRel < reNr; kRel++) { + reg[kRel].k = k0 + r * (12 / regNr) + kRel; + reg[kRel].l = l; +// EV << "(" << (unsigned)reg[kRel].k << "," << (unsigned)reg[kRel].l << "), "; + } + regs[r] = reg; +// EV << "),\n"; + } + allRegs[l][k] = regs; +// EV << ")\n"; + } else + allRegs[l][k] = NULL; + } + } +} - stateEntered(category, details); +void PHY::printSubframe() { + std::ofstream file; + file.open("out.txt"); + for (unsigned short k = 0; k < nDLrb * nRBsc; k++) { + for (unsigned char l = 0; l < nDLsymb * 2; l++) { + file << (unsigned)dlSubframe[l]->getRes(k) << "\t"; + } + file << endl; + } + file.close(); } diff --git a/src/linklayer/lte/phy/PHY.h b/src/linklayer/lte/phy/PHY.h index a68bae7c66d4a900232ceca1826c86b2de53e622..f59b6285d41a983845dd790434b2f17e62a88b7f 100644 --- a/src/linklayer/lte/phy/PHY.h +++ b/src/linklayer/lte/phy/PHY.h @@ -39,6 +39,16 @@ enum PHYCyclicPrefix { PHY_CP_NORMAL = 1 }; +typedef PHYFrame* PHYFramePtr; + +typedef struct { + unsigned short k; + unsigned char l; +} RE; + +typedef RE* REG; // RE_0, RE_1, RE_2, RE_3 and if available RE_4 RE_5 +typedef REG* REGs; // REG_0, REG_1 and if available REG_2 + class PHY : public ChannelAccess { protected: unsigned short sfn; @@ -58,20 +68,15 @@ protected: unsigned char ncp; // cyclic prefix - PHYSymbol **dlSubframe; // symbol[nDLsymb] + unsigned char p; // number of antenna ports - typedef PHYFrame *PHYFramePtr; - PHYFramePtr **dlBuffer; // frame[nDLsymb * 2][nRBsc * nDLrb] + unsigned char cfi; - struct reg { - unsigned short k; - unsigned char l; - }; + PHYSymbol **dlSubframe; // symbol[nDLsymb] - bool operator<(const reg &l, const reg &r); + PHYFramePtr **dlBuffer; // frame[nDLsymb * 2][nRBsc * nDLrb] - typedef std::map REGroups; - REGroups regs; + REGs **allRegs; // REGs[k0][l] cFSM fsm; @@ -81,12 +86,19 @@ protected: NotificationBoard *nb; + unsigned char getRegNrInRegs(unsigned char l); + unsigned char getReNrInReg(unsigned char l); + REG findExactReg(unsigned char l, unsigned short k0); + void configureRegs(); + const char *stateName(int state); const char *eventName(int event); - virtual void receiveChangeNotification(int category, const cPolymorphic *details); + virtual void receiveChangeNotification(int category, const cPolymorphic *details) = 0; + + virtual void stateEntered(int category, const cPolymorphic *details) = 0; - virtual void stateEntered(int category, const cPolymorphic *details); + void printSubframe(); public: PHY(); virtual ~PHY(); diff --git a/src/linklayer/lte/phy/PHYCommand.h b/src/linklayer/lte/phy/PHYCommand.h index 14cda24b7db3e5063eb5b8d2a8917c8caedc43ef..29137bec171d6a9c7f40ed61ed3e6985f64557ed 100644 --- a/src/linklayer/lte/phy/PHYCommand.h +++ b/src/linklayer/lte/phy/PHYCommand.h @@ -53,6 +53,8 @@ public: * Method for pushing DlConfigRequestPduPtr to vector. */ void pushPdu(DlConfigRequestPduPtr pdu) { pdus.push_back(pdu); } + DlConfigRequestPduPtr backPdu() { return pdus.back(); } + void popPdu() { pdus.pop_back(); } }; #endif /* PHYCOMMAND_H_ */ diff --git a/src/linklayer/lte/phy/PHYCommand.msg b/src/linklayer/lte/phy/PHYCommand.msg index 8ad4da7ccd89b636e8c1a5950b5dfa83404fa8ff..78b778762211a024a1763d185817b10ad17637a5 100644 --- a/src/linklayer/lte/phy/PHYCommand.msg +++ b/src/linklayer/lte/phy/PHYCommand.msg @@ -48,6 +48,7 @@ enum PhyCommandTlvTag { DlCyclicPrefixType = 4; DlChannelBandwith = 6; + TxAntennaPorts = 7; PhysicalCellId = 16; DlBwSupp = 40; UlBwSupp = 41; diff --git a/src/linklayer/lte/phy/PHYFrame.msg b/src/linklayer/lte/phy/PHYFrame.msg index 803e34e4b13a0c965c2bd2d60998d12e523ca24e..5435bea1282e86fe32b2116362905a82d32c2cc5 100644 --- a/src/linklayer/lte/phy/PHYFrame.msg +++ b/src/linklayer/lte/phy/PHYFrame.msg @@ -32,11 +32,6 @@ message TransportBlock extends PhysicalResourceBlock } -message DCIFormat extends PhysicalResourceBlock -{ - -} - message RAPreamble extends PhysicalResourceBlock { unsigned char rapid; @@ -73,14 +68,27 @@ message SSSSignal extends PHYFrame message ReferenceSignal extends PHYFrame { channel = RS; - unsigned char cellId; + unsigned char cellId; unsigned char ncp; // cyclic prefix } message PCFICHMessage extends PHYFrame { channel = PCFICH; - unsigned char pdcchSymbols; + unsigned char cfi; +} + +message DCIFormat extends PHYFrame +{ + channel = PDCCH; + unsigned short rnti; // scrambled in CRC + unsigned char rntiType; + unsigned char formatFlag; + bool vrbFlag; + unsigned int rbCoding; + unsigned char mcs; + unsigned char rv; + unsigned char tpc; } message PBCHMessage extends PHYFrame diff --git a/src/linklayer/lte/phy/PHYenb.cc b/src/linklayer/lte/phy/PHYenb.cc index 83444bf977ec5009307d33f810645cd260f6264c..109423b03e14ba53821afb460a3af85524f70a1e 100644 --- a/src/linklayer/lte/phy/PHYenb.cc +++ b/src/linklayer/lte/phy/PHYenb.cc @@ -14,6 +14,7 @@ // #include "PHYenb.h" +#include "RRC.h" #include "LTEChannelControl.h" Define_Module(PHYenb); @@ -23,6 +24,16 @@ PHYenb::PHYenb() : PHY() { ulBandwith = 6; hasBCHPdu = false; + + sfn = 0; + sf = 0; + symb = 0; + slot = 0; + + nRBsc = 12; + nDLsymb = 7; + + symbPeriod = 1e-3 / nDLsymb; } PHYenb::~PHYenb() { @@ -77,7 +88,7 @@ void PHYenb::handleMessage(cMessage *msg) { sendSymbol(); - this->cancelEvent(symbolTimer); + this->cancelEvent(symbolTimer); this->scheduleAt(simTime() + symbPeriod, symbolTimer); symb = (symb + 1) % nDLsymb; @@ -169,7 +180,7 @@ void PHYenb::buildSubframe() { dlBuffer[nDLsymb - 2][k - 1] = sss; } - // RS + // TODO repair RS PHYSymbol *symbol1 = dlSubframe[0]; PHYSymbol *symbol2 = dlSubframe[nDLsymb - 3]; unsigned char v1 = 0; @@ -199,15 +210,87 @@ void PHYenb::buildSubframe() { } // PCFICH - PHYSymbol *symbol = dlSubframe[0]; - unsigned char pcfichOffset = (nRBsc / 2) * (nCellId % (2 * nDLrb)); - for (unsigned i = 0; i < 4; i++) { - unsigned short k = (pcfichOffset + (unsigned)(i * nDLrb / 2) * nRBsc / 2) % (nDLrb * nRBsc); - symbol->setRes(k, PCFICH); + if (dciBuffer.size() != 0 && cfi != 0) { + PHYSymbol *symbol = dlSubframe[0]; + unsigned char pcfichOffset = (nRBsc / 2) * (nCellId % (2 * nDLrb)); + unsigned short kLast = 0; + for (unsigned i = 0; i < 4; i++) { + unsigned short k = (pcfichOffset + (unsigned)(i * nDLrb / 2) * nRBsc / 2) % (nDLrb * nRBsc); + REG reg = findExactReg(0, k); + if (reg) { + unsigned char kRel = 0; + for (; kRel < getReNrInReg(0); kRel++) { + if (!symbol->getRes(reg[kRel].k)) // avoid resource elements assigned for RS + symbol->setRes(reg[kRel].k, PCFICH); + } + kLast = reg[kRel - 1].k; + } else { + EV << "LTE-PHYenb: !!! Error in PCFICH, resource element (k,l) does not represent a resource element group !!!\n"; + } + } + PCFICHMessage *pcfichMsg = new PCFICHMessage(); + pcfichMsg->setCfi(cfi); + dlBuffer[0][kLast] = pcfichMsg; + } + + // PDCCH + if (dciBuffer.size() != 0 && cfi != 0) { +// unsigned char m = 0; + unsigned short k = 0; + DlConfigRequestDciDlPdu *dciDlPdu = NULL; + unsigned char dciSize = 0; + + while (k < nDLrb * nRBsc && dciBuffer.size() != 0) { + unsigned char l = 0; + while (l < cfi && dciBuffer.size() != 0) { + PHYSymbol *symbol = dlSubframe[l]; + REG reg = findExactReg(l, k); + + if (reg && symbol->getRes(k) != PCFICH) { // TODO PHICH + // symbol preparation + unsigned short kLast = 0; + unsigned char kRel = 0; + for (; kRel < getReNrInReg(l); kRel++) { + if (!symbol->getRes(reg[kRel].k)) // avoid resource elements assigned for RS + symbol->setRes(reg[kRel].k, PDCCH); + } + kLast = reg[kRel - 1].k; + + // data transmission + dciDlPdu = dciBuffer.back(); + if (dciSize == 0) { + if (dciDlPdu->getType() == DCI_FORMAT_1 || dciDlPdu->getType() == DCI_FORMAT_1A) + dciSize = 18; + } + dciSize--; + if (dciSize == 0) { + DCIFormat *dci = new DCIFormat(); + dci->setRnti(dciDlPdu->getRnti()); // scrambled in CRC + dci->setRntiType(dciDlPdu->getRntiType()); + dci->setFormatFlag(dciDlPdu->getType()); + dci->setVrbFlag(dciDlPdu->getVrbFlag()); + dci->setRbCoding(dciDlPdu->getRbCoding()); + // TODO 2 transport blocks + dci->setMcs(dciDlPdu->getMcs1()); + dci->setRv(dciDlPdu->getRv1()); + dci->setTpc(dciDlPdu->getTpc()); + dlBuffer[l][kLast] = dci; + + dciBuffer.pop_back(); + delete dciDlPdu; + } +// m++; + } + l++; + } + k++; + } } } void PHYenb::cleanup() { + cfi = 0; + if (sfn % 4 == 0 && sf == 0) { hasBCHPdu = false; } @@ -234,29 +317,102 @@ void PHYenb::setData(unsigned short k, PHYFrame *frame) { } void PHYenb::stateEntered(int category, const cPolymorphic *details) { - PHY::stateEntered(category, details); + switch(fsm.getState()) { + case IDLE: { + ParamResponse *paramResp = new ParamResponse(); + paramResp->setErrorCode(MsgOk); + paramResp->setTlvsArraySize(1); + paramResp->setTlvs(0, createPhyCommandTlv(PhyState, 1, IDLE)); + nb->fireChangeNotification(PARAMResponse, paramResp); + break; + } + case CONFIGURED: { + if (category == CONFIGRequest) { + ConfigRequest *cfgReq = check_and_cast(details); + for (unsigned i = 0; i < cfgReq->getTlvsArraySize(); i++) { + if (cfgReq->getTlvs(i).getTag() == SfnSf) { + sfn = cfgReq->getTlvs(i).getValue() / 10; + sf = cfgReq->getTlvs(i).getValue() % 10; + } + if (cfgReq->getTlvs(i).getTag() == DlCyclicPrefixType) { + ncp = cfgReq->getTlvs(i).getValue() == CTRL_CP_NORMAL ? PHY_CP_NORMAL : PHY_CP_EXTENDED; + } + if (cfgReq->getTlvs(i).getTag() == TxAntennaPorts) { + p = cfgReq->getTlvs(i).getValue(); + } + if (cfgReq->getTlvs(i).getTag() == DlChannelBandwith) { + nDLrb = cfgReq->getTlvs(i).getValue(); + } + if (cfgReq->getTlvs(i).getTag() == PhysicalCellId) { + nCellId = cfgReq->getTlvs(i).getValue(); + n1id = nCellId / 3; + n2id = nCellId % 3; + } + } + ConfigResponse *cfgResp = new ConfigResponse(); + cfgResp->setErrorCode(MsgOk); + nb->fireChangeNotification(CONFIGResponse, cfgResp); + } + break; + } + case RUNNING: { + if (category == STARTRequest) { + dlSubframe = new PHYSymbol*[nDLsymb * 2]; + for (unsigned char i = 0; i < nDLsymb * 2; i++) + dlSubframe[i] = NULL; + + dlBuffer = new PHYFramePtr*[nDLsymb * 2]; + for (unsigned char l = 0; l < nDLsymb * 2; l++) { + dlBuffer[l] = new PHYFramePtr[nRBsc * nDLrb]; + for (unsigned short k = 0; k < nRBsc * nDLrb; k++) + dlBuffer[l][k] = NULL; + } + + configureRegs(); + + this->cancelEvent(symbolTimer); + this->scheduleAt(simTime(), symbolTimer); + } else if (category == DLCONFIGRequest) { + DlConfigRequest *dlCfgReq = check_and_cast(details); + cfi = dlCfgReq->getNrPdcchSymb(); + + while (dlCfgReq->getPdusArraySize() != 0) { + DlConfigRequestPduPtr pdu = dlCfgReq->backPdu(); + EV << "LTE-PHYenb: Received DLCONFIGRequest for PDU with type = " << (unsigned)pdu->getType() << ".\n"; + + // DCI request from upper layer + if (pdu->getType() == DciDlPdu) { + DlConfigRequestDciDlPdu *dciDlPdu = check_and_cast(pdu); + dciBuffer.push_back(dciDlPdu); + } else { + delete pdu; + } + // if (pdu->getType() == BchPdu) { + // hasBCHPdu = true; + // unsigned char pbchOffset = nDLrb * nRBsc / 2 - 36; + // + // PBCHMessage *frame = new PBCHMessage(); + // frame->setCellId(nCellId); + // dlBuffer[nDLsymb + 3][pbchOffset + 71] = frame; + // dlCfgReq[pdu->getPduIndex()] = frame; + // } else if (pdu->getType() == DciDlPdu) { + //// sendDCIFormat(pdu); + // } else { + //// dlCfgReqs[pdu->getPduIndex()] = pdu; + // } + dlCfgReq->popPdu(); + } + } + break; + } + default: + EV << "LTE-PHYenb: Unknown state.\n"; + break; + } if (fsm.getState() == RUNNING) { if (category == DLCONFIGRequest) { -// DlConfigRequest *dlCfgReq = check_and_cast(details); -// for (unsigned i = 0; i < dlCfgReq->getPdusArraySize(); i++) { -// DlConfigRequestPduPtr pdu = dlCfgReq->getPdus(i)->dup(); -// EV << "LTE-PHYenb: Received DLCONFIGRequest for PDU with type = " << (unsigned)pdu->getType() << ".\n"; -// -// if (pdu->getType() == BchPdu) { -// hasBCHPdu = true; -// unsigned char pbchOffset = nDLrb * nRBsc / 2 - 36; -// -// PBCHMessage *frame = new PBCHMessage(); -// frame->setCellId(nCellId); -// dlBuffer[nDLsymb + 3][pbchOffset + 71] = frame; -// dlCfgReq[pdu->getPduIndex()] = frame; -// } else if (pdu->getType() == DciDlPdu) { -//// sendDCIFormat(pdu); -// } else { -//// dlCfgReqs[pdu->getPduIndex()] = pdu; -// } -// } + } else if (category == TXRequest) { // TxRequest *txReq = check_and_cast(details); // for (unsigned i = 0; i < txReq->getPdusArraySize(); i++) { @@ -272,7 +428,65 @@ void PHYenb::stateEntered(int category, const cPolymorphic *details) { // } } } - delete details; +// delete details; + +} + +void PHYenb::receiveChangeNotification(int category, const cPolymorphic *details) { + Enter_Method_Silent(); + + int oldState = fsm.getState(); + + switch(oldState) { + case IDLE: + switch(category) { + case PARAMRequest: { + break; + } + case CONFIGRequest: { + FSM_Goto(fsm, CONFIGURED); + break; + } + default: + EV << "LTE-PHYenb: Received unexpected event.\n"; + break; + } + break; + case CONFIGURED: + switch(category) { + case STARTRequest: { + FSM_Goto(fsm, RUNNING); + break; + } + default: + EV << "LTE-PHYenb: Received unexpected event.\n"; + break; + } + break; + case RUNNING: + switch(category) { + case DLCONFIGRequest: { + break; + } + case TXRequest : { + break; + } + default: + EV << "LTE-PHYenb: Received unexpected event.\n"; + break; + } + break; + default: + EV << "LTE-PHYenb: Unknown state.\n"; + break; + } + +// if (oldState != fsm.getState()) +// EV << "LTE-PHY: PSM-Transition: " << stateName(oldState) << " --> " << stateName(fsm.getState()) << " (event was: " << eventName(category) << ")\n"; +// else +// EV << "LTE-PHY: Staying in state: " << stateName(fsm.getState()) << " (event was: " << eventName(category) << ")\n"; + + stateEntered(category, details); } void PHYenb::sendBufferedData() { @@ -318,13 +532,13 @@ void PHYenb::sendBufferedData() { } void PHYenb::sendDCIFormat(DlConfigRequestPduPtr pdu) { - DlConfigRequestDciDlPdu *dciPdu = check_and_cast(pdu); - DCIFormat *dci = new DCIFormat(); - dci->setName("DCIFormat"); - dci->setRnti(dciPdu->getRnti()); -// dci->setRntiType(dciPdu->getRntiType()); - dci->setChannelNumber(PDCCH); - sendToChannel(dci); +// DlConfigRequestDciDlPdu *dciPdu = check_and_cast(pdu); +// DCIFormat *dci = new DCIFormat(); +// dci->setName("DCIFormat"); +// dci->setRnti(dciPdu->getRnti()); +//// dci->setRntiType(dciPdu->getRntiType()); +// dci->setChannelNumber(PDCCH); +// sendToChannel(dci); } // //bool PHYenb::findAndRemoveDlConfigRequestPdu(unsigned short pduIndex) { diff --git a/src/linklayer/lte/phy/PHYenb.h b/src/linklayer/lte/phy/PHYenb.h index a91b21fb57131110c2d859b98c0ce915119c9fcd..80022b71289543e029b433a059445647764850f9 100644 --- a/src/linklayer/lte/phy/PHYenb.h +++ b/src/linklayer/lte/phy/PHYenb.h @@ -34,6 +34,9 @@ private: // bool findAndRemoveDlConfigRequestPdu(unsigned short pduIndex); // bool findAndRemoveTxRequestPdu(unsigned msgId); + typedef std::list DCIBuffer; + DCIBuffer dciBuffer; + void sendDCIFormat(DlConfigRequestPduPtr pdu); void buildSubframe(); @@ -43,6 +46,8 @@ private: void setData(unsigned short k, PHYFrame *frame); virtual void stateEntered(int category, const cPolymorphic *details); + + virtual void receiveChangeNotification(int category, const cPolymorphic *details); public: PHYenb(); virtual ~PHYenb(); diff --git a/src/linklayer/lte/phy/PHYue.cc b/src/linklayer/lte/phy/PHYue.cc index 76785c5f62d1f18f9ecdfcc9211d48c1c9fdd7be..2ca1e33397d47ea2889497c251254d974e332626 100644 --- a/src/linklayer/lte/phy/PHYue.cc +++ b/src/linklayer/lte/phy/PHYue.cc @@ -22,7 +22,14 @@ PHYue::PHYue() : PHY() { start = false; delayTimer = NULL; pbchSubcarriers = 0; - syncState = NONE; + nrOfPss = 0; + cellSync = 0; + nRBsc = 255; + nDLsymb = 255; + sf = 255; + symb = 255; + slot = 255; + dciSize = 0; } PHYue::~PHYue() { @@ -89,24 +96,32 @@ void PHYue::handleRadioMessage(cMessage *msg) { unsigned short k = 0; while (k < symbol->getResArraySize()) { - // check for PSS - if (symbol->getRes(k) == PSS) { - k += 62; - if (syncState == NONE) + if (cellSync < 3) { + if (symbol->getRes(k) == PSS) { + k += 62; processPSS(k - 1); - } else if (symbol->getRes(k) == SSS) { - k += 62; - if (syncState == PSS_RECEIVED) + } else if (symbol->getRes(k) == SSS) { + k += 62; processSSS(k - 1); - } else if (symbol->getRes(k) == RS) { - k++; - if (syncState == SSS_RECEIVED) + } else if (symbol->getRes(k) == RS) { + k++; processReferenceSignal(k - 1); + } else { + k++; + } } else { - k++; + if (symbol->getRes(k) == PCFICH) { + k += getReNrInReg(0); + processPCFICH(k - 1); + } else if (symbol->getRes(k) == PDCCH) { + k += getReNrInReg(symb); + processPDCCH(k - 1); + } else { + k++; + } } } - + symb = (symb + 1) % nDLsymb; // if (syncState == NONE) { // for (unsigned char i = 0; i < symbol->getResArraySize(); i++) { @@ -204,13 +219,27 @@ void PHYue::processPSS(unsigned char k) { if (msg) { EV << "LTE-PHYue: Received Primary Synchronization Signal.\n"; PSSSignal *pss = check_and_cast(msg); - n2id = pss->getCellIdInGroup(); - slot = 0; - symb = 1; - EV << "LTE-PHYue: Setting slot = " << (unsigned)slot << " and symb = " << (unsigned)symb << ".\n"; + n2id = pss->getCellIdInGroup(); + + if (cellSync == 0) { + if (nrOfPss == 0) { + symb = 1; + + EV << "LTE-PHYue: Setting symb = " << (unsigned)symb << ".\n"; + } else { + nDLsymb = symb / 10; + symb = nDLsymb - 1; + + EV << "LTE-PHYue: Setting symb = " << (unsigned)symb << " with total number of symbols = " << (unsigned)nDLsymb << ".\n"; + + cellSync++; + } + + } + + nrOfPss = (nrOfPss + 1) % 2; - syncState = PSS_RECEIVED; delete msg; } } @@ -221,18 +250,18 @@ void PHYue::processSSS(unsigned char k) { EV << "LTE-PHYue: Received Secondary Synchronization signal.\n"; SSSSignal *sss = check_and_cast(msg); - n1id = sss->getCellGroupId(); - nCellId = 3 * n1id + n2id; + if (cellSync == 1) { + n1id = sss->getCellGroupId(); + nCellId = 3 * n1id + n2id; + + sf = sss->getSf(); // UE knows the subframe because in reality the sequences for subframe 0 and 5 differ - sf = sss->getSf(); // UE knows the subframe because in reality the sequences for subframe 0 and 5 differ - slot = sf * 2; - symb++; - nDLsymb = symb / 10; - symb = nDLsymb - 2; - EV << "LTE-PHYue: Setting number of symbols = " << (unsigned)nDLsymb << ".\n"; - EV << "LTE-PHYue: Resetting slot = " << (unsigned)slot << " and symb = " << (unsigned)symb << ".\n"; + slot = sf * 2; - syncState = SSS_RECEIVED; + EV << "LTE-PHYue: Resetting slot = " << (unsigned)slot << ".\n"; + + cellSync++; + } delete msg; } } @@ -242,18 +271,65 @@ void PHYue::processReferenceSignal(unsigned char k) { if (msg) { EV << "LTE-PHYue: Received Reference Signal.\n"; ReferenceSignal *refSig = check_and_cast(msg); - if (refSig->getCellId() == nCellId) { - ncp = refSig->getNcp(); - if (ncp == 1 && (nDLsymb == 7 || nDLsymb == 6)) - nRBsc = 12; - else if (ncp == 1 && nDLsymb == 3) - nRBsc = 24; - syncState = SYNCHRONIZED; + + if (cellSync == 2) { + if (refSig->getCellId() == nCellId) { + ncp = refSig->getNcp(); + if (ncp == 1 && (nDLsymb == 7 || nDLsymb == 6)) + nRBsc = 12; + else if (ncp == 1 && nDLsymb == 3) + nRBsc = 24; + + configureRegs(); + + cellSync++; + + EV << "LTE-PHYue: Physical layer synchronized with the cell.\n"; + } } delete msg; } } +void PHYue::processPCFICH(unsigned char k) { + cMessage *msg = getData(k); + if (msg) { + EV << "LTE-PHYue: Received PCFICH message.\n"; + PCFICHMessage *pcfichMsg = check_and_cast(msg); + cfi = pcfichMsg->getCfi(); + + EV << "LTE-PHYue: Number of symbols used for PDCCH transmission = " << (unsigned)cfi << ".\n"; + delete msg; + } +} + +void PHYue::processPDCCH(unsigned char k) { + cMessage *msg = getData(k); + + dciSize++; + + if (msg) { + EV << "LTE-PHYue: Received PDCCH message.\n"; + DCIFormat *dci = check_and_cast(msg); + + // check cfi + if (symb < cfi) { + EV << "LTE-PHYue: PDCCH message out of allocation space. Discarding the message.\n"; + delete msg; + return; + } + + // check size + if ((dci->getFormatFlag() == DCI_FORMAT_1 || dci->getFormatFlag() == DCI_FORMAT_1A) && (dciSize != 18)) { + EV << "LTE-PHYue: PDCCH message has wrong size. Discarding the message.\n"; + delete msg; + return; + } + + + } +} + void PHYue::processPBCH() { EV << "LTE-PHYue: Processing Physical Broadcast Channel.\n"; // unsigned char dc = frame->getResArraySize() / 2; @@ -268,27 +344,29 @@ void PHYue::processPBCH() { } void PHYue::stateEntered(int category, const cPolymorphic *details) { - PHY::stateEntered(category, details); - - if (fsm.getState() == RUNNING) { - if (category == ULCONFIGRequest) { - - } else if (category == RACHRequest) { - RachRequest *rachReq = check_and_cast(details); - for (unsigned i = 0; i < rachReq->getPreamblesArraySize(); i++) { // normally it should be only one preamble - RachPreamble preamble = rachReq->getPreambles(i); - RAPreamble *raPreamble = new RAPreamble(); - raPreamble->setName("RAPreamble"); - raPreamble->setChannelNumber(PRACH); - raPreamble->setRnti(preamble.getRnti()); - raPreamble->setRntiType(RaRnti); - raPreamble->setRapid(preamble.getPreamble()); - this->sendToChannel(raPreamble); - } - } - } +// if (fsm.getState() == RUNNING) { +// if (category == ULCONFIGRequest) { +// +// } else if (category == RACHRequest) { +// RachRequest *rachReq = check_and_cast(details); +// for (unsigned i = 0; i < rachReq->getPreamblesArraySize(); i++) { // normally it should be only one preamble +// RachPreamble preamble = rachReq->getPreambles(i); +// RAPreamble *raPreamble = new RAPreamble(); +// raPreamble->setName("RAPreamble"); +// raPreamble->setChannelNumber(PRACH); +// raPreamble->setRnti(preamble.getRnti()); +// raPreamble->setRntiType(RaRnti); +// raPreamble->setRapid(preamble.getPreamble()); +// this->sendToChannel(raPreamble); +// } +// } +// } } void PHYue::sendBufferedData() { } + +void PHYue::receiveChangeNotification(int category, const cPolymorphic *details) { + +} diff --git a/src/linklayer/lte/phy/PHYue.h b/src/linklayer/lte/phy/PHYue.h index d8b72579c4753a2f3e211cdcb40e778bd0f0b18a..af94321c3d147e349cd6bff899d88e641293d594 100644 --- a/src/linklayer/lte/phy/PHYue.h +++ b/src/linklayer/lte/phy/PHYue.h @@ -19,31 +19,35 @@ #include "PHY.h" #include "SubscriberTableAccess.h" -enum SyncState -{ - NONE, - PSS_RECEIVED, - SSS_RECEIVED, - SYNCHRONIZED +enum PHYueEvent { + CellFound }; class PHYue : public PHY { private: - unsigned char syncState; unsigned pbchSubcarriers; cMessage *delayTimer; bool start; + unsigned char nrOfPss; + unsigned char cellSync; + + unsigned char dciSize; + SubscriberTable *subT; cMessage *getData(unsigned short k); void processPSS(unsigned char k); void processSSS(unsigned char k); void processReferenceSignal(unsigned char k); + void processPCFICH(unsigned char k); + void processPDCCH(unsigned char k); void processPBCH(); virtual void stateEntered(int category, const cPolymorphic *details); + + virtual void receiveChangeNotification(int category, const cPolymorphic *details); public: PHYue(); virtual ~PHYue(); diff --git a/src/linklayer/lte/rrc/RRC.cc b/src/linklayer/lte/rrc/RRC.cc index 69508247d797f57fa29f5a90c32fa7ed51958524..8f04496ef0f0535c1c6a459fb564465ddcf89638 100644 --- a/src/linklayer/lte/rrc/RRC.cc +++ b/src/linklayer/lte/rrc/RRC.cc @@ -41,6 +41,7 @@ RRC::RRC() { dlBandwithSel = 255; cyclicPrefix = 255; phyCellId = 65535; + nrOfAntennas = 1; } RRC::~RRC() { diff --git a/src/linklayer/lte/rrc/RRC.h b/src/linklayer/lte/rrc/RRC.h index 7759a10b71551a610421e95e41e6d8e6ba837e06..3f248d9f40e2a0ae26bd8e62e5d63940789df9c2 100644 --- a/src/linklayer/lte/rrc/RRC.h +++ b/src/linklayer/lte/rrc/RRC.h @@ -39,8 +39,8 @@ static const unsigned macContResolTimers[8] = { 8, 16, 24, 32, 40, 48, 56, 64 }; enum RRCCyclicPrefix { - RRC_CP_NORMAL = 0, - RRC_CP_EXTENDED = 1 + CTRL_CP_NORMAL = 0, + CTRL_CP_EXTENDED = 1 }; class RRC : public cSimpleModule, public INotifiable { @@ -51,6 +51,7 @@ protected: unsigned char dlBandwithSel; unsigned char cyclicPrefix; unsigned short phyCellId; + unsigned char nrOfAntennas; PHICHConfig phichCfg; RACHConfigCommon rachCfg; diff --git a/src/linklayer/lte/rrc/RRCenb.cc b/src/linklayer/lte/rrc/RRCenb.cc index ceca5351bc3c1df44ffc08b9e24eedc69d4fdd97..c02c246e508cc02a1dda7da883656aa1ad54cec8 100644 --- a/src/linklayer/lte/rrc/RRCenb.cc +++ b/src/linklayer/lte/rrc/RRCenb.cc @@ -40,7 +40,7 @@ void RRCenb::initialize(int stage) { nb->subscribe(this, CONFIGResponse); nb->subscribe(this, SUBFRAMEIndication); - cyclicPrefix = RRC_CP_NORMAL; + cyclicPrefix = CTRL_CP_NORMAL; dlBandwithSel = 1; phyCellId = uniform(0, 503); @@ -91,6 +91,8 @@ void RRCenb::initialize(int stage) { siCfg.setSiMsgList(0, siMsgEl); cellCfg->setSiConfig(siCfg); cellCfg->setDlBandwith(dlBandwiths[dlBandwithSel]); + cellCfg->setDlCyclPrefLen(cyclicPrefix); + cellCfg->setAntennaPortsCount(nrOfAntennas); nb->fireChangeNotification(CSCHED_CELL_CONFIG_REQ, cellCfg); } @@ -281,11 +283,12 @@ void RRCenb::receiveChangeNotification(int category, const cPolymorphic *details PhyCommandTlv phySt = paramResp->getTlvs(0); if (phySt.getValue() == IDLE) { ConfigRequest *cfgReq = new ConfigRequest(); - cfgReq->setTlvsArraySize(4); + cfgReq->setTlvsArraySize(5); cfgReq->setTlvs(0, createPhyCommandTlv(SfnSf, 1, sfn * 10 + sf)); cfgReq->setTlvs(1, createPhyCommandTlv(DlCyclicPrefixType, 1, cyclicPrefix)); cfgReq->setTlvs(2, createPhyCommandTlv(DlChannelBandwith, 1, dlBandwiths[dlBandwithSel])); - cfgReq->setTlvs(3, createPhyCommandTlv(PhysicalCellId, 1, phyCellId)); + cfgReq->setTlvs(3, createPhyCommandTlv(TxAntennaPorts, 1, 1)); + cfgReq->setTlvs(4, createPhyCommandTlv(PhysicalCellId, 1, phyCellId)); nb->fireChangeNotification(CONFIGRequest, cfgReq); } } else if (category == CONFIGResponse) {