MACenb.cc 9.5 KB
Newer Older
C
x  
calincerchez 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.
// 

#include "MACenb.h"
C
calin cerchez 已提交
17
#include "LTEControlInfo.h"
C
x  
calincerchez 已提交
18 19 20 21 22 23
#include "MACUtils.h"

Define_Module(MACenb);

MACenb::MACenb() {
    // TODO Auto-generated constructor stub
C
calin cerchez 已提交
24
	msgIds = 0;
C
x  
calincerchez 已提交
25 26 27 28 29 30 31
}

MACenb::~MACenb() {
    // TODO Auto-generated destructor stub
}

void MACenb::initialize(int stage) {
C
calin cerchez 已提交
32
	MAC::initialize(stage);
C
x  
calincerchez 已提交
33

C
calin cerchez 已提交
34
    if (stage == 4) {
C
x  
calincerchez 已提交
35
        nb->subscribe(this, SUBFRAMEIndication);
C
calin cerchez 已提交
36
        nb->subscribe(this, RACHIndication);
C
x  
calincerchez 已提交
37 38 39 40 41 42 43 44 45 46
        nb->subscribe(this, SCHED_DL_CONFIG_IND);
    }
}

void MACenb::handleLowerMessage(cMessage *msg) {

}

void MACenb::handleUpperMessage(cMessage *msg) {
    LTEControlInfo *ctrl = check_and_cast<LTEControlInfo*>(msg->removeControlInfo());
C
calin cerchez 已提交
47
    EV << "LTE-MACenb: Receiving message on " << ctrl->getChannelName() << " from upper layer.\n";
C
x  
calincerchez 已提交
48

C
calin cerchez 已提交
49
    MACServiceDataUnit *sdu = new MACServiceDataUnit(msg->getName());
C
x  
calincerchez 已提交
50 51 52 53
    sdu->encapsulate(PK(msg));
    sdu->setKind(msg->getKind());

    if (ctrl->getChannel() == BCCH0) {
C
calin cerchez 已提交
54 55
    	MACProtocolDataUnit *pdu = MACUtils().createTransparentPDU(BCH, sdu);
        EV << "LTE-MACenb: Sending message with id = " << pdu->getKind() << " on BCH to lower layer.\n";
C
x  
calincerchez 已提交
56 57
        this->send(pdu, gate("lowerLayerOut"));
    } else if (ctrl->getChannel() == BCCH1) {
C
calin cerchez 已提交
58
        EV << "LTE-MACenb: Buffering received message.\n";
C
x  
calincerchez 已提交
59 60 61
        buffer[sdu->getKind()] = sdu;

        MACProtocolDataUnit *pdu = MACUtils().createTransparentPDU(DLSCH0, sdu->dup());
C
calin cerchez 已提交
62
        EV << "LTE-MACenb: Sending message with id = " << pdu->getKind() << " on DLSCH0 to lower layer.\n";
C
x  
calincerchez 已提交
63 64 65 66 67 68 69 70 71
        this->send(pdu, gate("lowerLayerOut"));
    }
}

void MACenb::receiveChangeNotification(int category, const cPolymorphic *details) {
    Enter_Method_Silent();

    if (category == SUBFRAMEIndication) {
        SubframeIndication *sfInd = check_and_cast<SubframeIndication*>(details);
C
calincerchez 已提交
72 73 74
        unsigned char sf = sfInd->getSf();
        unsigned short sfn = sfInd->getSfn();

C
calincerchez 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
        // downlink scheduling
        SchedDlTriggerReq *triggReq = new SchedDlTriggerReq();
        triggReq->setSf(sf);
        triggReq->setSfn(sfn);
        // TODO harq proc information
        nb->fireChangeNotification(SCHED_DL_TRIGGER_REQ, triggReq);
//
    } else if (category == SCHED_DL_CONFIG_IND) {
        SchedDlConfigInd *cfgInd = check_and_cast<SchedDlConfigInd*>(details);
        unsigned char sf = cfgInd->getSf();
        unsigned short sfn = cfgInd->getSfn();

        // prepare downlink config request for physical layer
        unsigned pduIndex = 0;
        DlConfigRequest *dlReq = new DlConfigRequest();
        dlReq->setTti(tti);

        // prepare tx request for physical layer (sent only if tx is scheduled)
        TxRequest *txReq = new TxRequest();
        txReq->setTti(tti);

C
calincerchez 已提交
96 97
        // BCH scheduling
        if (sfn % 4 == 0 && sf == 0) {
C
calincerchez 已提交
98
        	EV << "LTE-MACenb: Sending RLC_TX_OPPORTUNITY for message with rnti = 0.\n";
C
calincerchez 已提交
99 100 101
            RlcTxOpportunity *txOpp = new RlcTxOpportunity();
            txOpp->setRnti(0);
            nb->fireChangeNotification(RLC_TX_OPPORTUNITY, txOpp);
C
calincerchez 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115

            // add pdu information to downlink request notification
            DlConfigRequestBchPdu *dlReqBCHpdu = new DlConfigRequestBchPdu();
            dlReqBCHpdu->setPduIndex(pduIndex);
            dlReq->pushPdu(dlReqBCHpdu);

            // add tx pdu information to tx request notification
            TxRequestPdu txReqPdu = TxRequestPdu();
            txReqPdu.setPduIndex(pduIndex++);
            txReqPdu.setMsgKindsArraySize(1);
            txReqPdu.setMsgKinds(0, MIB);

            txReq->setPdusArraySize(pduIndex);
            txReq->setPdus(pduIndex - 1, txReqPdu);
C
x  
calincerchez 已提交
116
        }
C
calincerchez 已提交
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
//
//        // check broadcast messages
//        for (unsigned i = 0; i < cfgInd->getBldBcastListArraySize(); i++) {
//            BuildBcastListElement bcastEl = cfgInd->getBldBcastList(i);
//            DlDciListElement dciEl = bcastEl.getDci();
//
//            // notify RLC layer of transmission opportunity
//            if (dciEl.getRv() == 0) {
//                EV << "LTE-MACenb: Sending RLC_TX_OPPORTUNITY for message with rnti = " << dciEl.getRnti() << ".\n";
//                RlcTxOpportunity *txOpp = new RlcTxOpportunity();
//                txOpp->setRnti(dciEl.getRnti());
//                nb->fireChangeNotification(RLC_TX_OPPORTUNITY, txOpp);
//            } else { // check for packet in buffer that should be retransmitted
//                MACBuffer::iterator i = buffer.find(bcastEl.getIndex());
//                if (i != buffer.end()) {
//                    MACServiceDataUnit *sdu = i->second;
//
//                    MACProtocolDataUnit *pdu = MACUtils().createTransparentPDU(DLSCH0, sdu->dup());
//                    EV << "LTE-MACenb: Sending buffered message with id = " << pdu->getKind() << " on DLSCH0 to lower layer.\n";
//                    this->send(pdu, gate("lowerLayerOut"));
//                }
//            }
//
//            // add pdu information to downlink request notification
//            if (bcastEl.getIndex() == MIB) {
C
calincerchez 已提交
142

C
calincerchez 已提交
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
//            } else {
//                DlConfigRequestDciDlPdu *dlReqDCIpdu = new DlConfigRequestDciDlPdu();
//                dlReqDCIpdu->setRnti(dciEl.getRnti());
////                dlReqDCIpdu->setRntiType(SiRnti);
//                dlReq->pushPdu(dlReqDCIpdu);
//
//                DlConfigRequestDlschPdu *dlReqDLSCHpdu = new DlConfigRequestDlschPdu();
//                dlReqDLSCHpdu->setPduIndex(pduIndex);
//                dlReqDLSCHpdu->setRnti(dciEl.getRnti());
//                dlReq->pushPdu(dlReqDLSCHpdu);
//            }
//
//            // add tx pdu information to tx request notification
//            TxRequestPdu txReqPdu = TxRequestPdu();
//            txReqPdu.setPduIndex(pduIndex++);
//            txReqPdu.setMsgKindsArraySize(1);
//            txReqPdu.setMsgKinds(0, bcastEl.getIndex());
//
//            txReq->setPdusArraySize(pduIndex);
//            txReq->setPdus(pduIndex - 1, txReqPdu);
//        }
//
////        // check random access response message
//        for (unsigned i = 0; i < cfgInd->getBldRarListArraySize(); i++) {
//        	BuildRarListElement rarEl = cfgInd->getBldRarList(i);
//        	Subscriber *sub = subT->findSubscriberForRnti(TempCRnti, rarEl.getRnti());
//
//        	if (sub) {
//        		// create MAC RAR PDU
//        		MACRandomAccessResponse *rarSdu = MACUtils().createRAR(0, rarEl.getGrant(), sub->getRnti());
//        		MACProtocolDataUnit *pdu = MACUtils().createRandomAccessPDU(true, sub->getRapid(), rarSdu);
//
//                // add pdu information to downlink request notification
//                DlConfigRequestDciDlPdu *dlReqDCIpdu = new DlConfigRequestDciDlPdu();
//                dlReqDCIpdu->setRnti(sub->getRaRtni());
//                dlReqDCIpdu->setRntiType(RaRnti);
//                dlReq->pushPdu(dlReqDCIpdu);
//
//                DlConfigRequestDlschPdu *dlReqDLSCHpdu = new DlConfigRequestDlschPdu();
//                dlReqDLSCHpdu->setPduIndex(pduIndex);
//                dlReqDLSCHpdu->setRnti(sub->getRaRtni());
//                dlReq->pushPdu(dlReqDLSCHpdu);
//
//                // add tx pdu information to tx request notification
//                TxRequestPdu txReqPdu = TxRequestPdu();
//                txReqPdu.setPduIndex(pduIndex++);
//                txReqPdu.setMsgKindsArraySize(1);
//                txReqPdu.setMsgKinds(0, rarEl.getRnti());	// tempCRnti will also identify the message in phy layer
//
//                txReq->setPdusArraySize(pduIndex);
//                txReq->setPdus(pduIndex - 1, txReqPdu);
//
//                EV << "LTE-MACenb: Sending message with id = " << pdu->getKind() << " on DLSCH1 to lower layer.\n";
//                this->send(pdu, gate("lowerLayerOut"));
//        	}
//        }
//
C
calincerchez 已提交
200 201 202 203
        nb->fireChangeNotification(DLCONFIGRequest, dlReq);

        if (pduIndex > 0)
            nb->fireChangeNotification(TXRequest, txReq);
C
calin cerchez 已提交
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230

    } else if (category == RACHIndication) {
    	// TODO check RACH type

    	RachIndication *rachInd = check_and_cast<RachIndication*>(details);
    	for (unsigned i = 0; i < rachInd->getPreamblesArraySize(); i++) {	// normally it should be only one preamble
    		RachPreamble preamble = rachInd->getPreambles(i);
    		unsigned short tempCRnti = uniform(0, 65523);
    		EV << "LTE-MACenb: Received RACHIndication for preamble with id = " << (unsigned)preamble.getPreamble() << " and RA-RNTI = " << preamble.getRnti() << ". Creating new subscriber.\n";

    		// subscriber creation
    		Subscriber *sub = new Subscriber();
    		sub->setRaRnti(preamble.getRnti());
    		sub->setRapid(preamble.getPreamble());
    		sub->setRntiType(TempCRnti);
    		sub->setRnti(tempCRnti);
    		subT->push_back(sub);

    		// scheduler configuration
    		SchedDlRachInfoReq *rachReq = new SchedDlRachInfoReq();
    		rachReq->setTti(rachInd->getTti());
    		rachReq->setRachListArraySize(1);
    		RachListElement rachEl = RachListElement();
    		rachEl.setRnti(tempCRnti);
    		rachReq->setRachList(0, rachEl);
    		nb->fireChangeNotification(SCHED_DL_RACH_INFO_REQ, rachReq);
    	}
C
x  
calincerchez 已提交
231 232
    }
}