📄 phy-umts.cc
字号:
send_msg(sp->copy(), d_sc_, sf_, k_); // sending DPDCH Packet::free(sp); sp = NULL; } } else { // only 1 DPDCH is needed // building DPDCH packet n_dpdch = 1; // calculate the necessary spreading factor for that application index = total_size; index = (320 / total_size); index = (int)(log(index)/log(2)); sf_ = 2; for (i=0; i<((int)index - 1); i++) { sf_ *= 2; } // sf_ is the spreading factor chosen Packet* sp = Packet::alloc(); hdr_cmn *chsp = HDR_CMN(sp); hdr_phy *phsp = HDR_PHY_UMTS(sp); phsp->dpdch_control_ = new PacketQueue(); phsp->size() = 0; phsp->n_dpdch_ = 1; n_dpdch = 1; // extract packets from the buffer to transmit while ((tbytes < total_size) && (data_temp_->length() > 0)){ p = data_temp_->deque(); php = HDR_PHY_UMTS(p); rh = HDR_RLC_UMTS(p); tbytes += php->size(); if (tbytes <= total_size) { // checks if is possible to send the whole packet php->seqno_ = count; php->eofsec_ = 1; phsp->dpdch_control_->enque(p->copy()); phsp->size() += php->size(); count = 0; Packet::free(p); } else { // no space to allocate all the packet in the current DPDCH tbytes -= php->size(); temp = php->size(); php->size() = total_size - tbytes; php->seqno_ = count; php->eofsec_ = 0; // sending a part of the message phsp->dpdch_control_->enque(p->copy()); phsp->size() = phsp->size() + total_size - tbytes; php->size() = temp - total_size; count++; // storing the rest of the packet in the buffer data_temp_->enqueHead(p); break; } } k_ = sf_/4; // calculates k_ chsp->channel_t()=DPDCH; // ch mapping send_msg(sp->copy(), d_sc_, sf_, k_); // send packet over the air interface Packet::free(sp); sp = NULL; } // building DPCCH Packet* sp = Packet::alloc(); hdr_cmn *chsp = HDR_CMN(sp); hdr_phy *phsp = HDR_PHY_UMTS(sp); // calculate de physical rate transmitted phsp->dpcch_control().dpdch_rate_ = (2560 / (UMTS_SlotTime * sf_)) * n_dpdch; chsp->channel_t()=DPCCH; // ch mapping phsp->size() = 1.25; phsp->dpcch_control().n_dpdch_ = n_dpdch; // number of DPDCH multiplexed with the DPCCH if (verbose_==1) printf("UE %d at %f PHY: DPCCH/%dDPDCH with SF=%d sent to NodeB %d in upslot %d\n", ip_ue_, NOW,phsp->dpcch_control_.n_dpdch_, sf_, ip_nodeb_, up_slot_); send_msg(sp->copy(), d_sc_, 256, 0); // send DPCCH message Packet::free(sp); sp = NULL; return; } return;}// send DPDCHs and DPCCH over the air interface to Node Bvoid PhyUmts::send_msg(Packet* p, int scram_c, int sf, int k){ int i; hdr_cmn *chp = HDR_CMN(p); hdr_phy *php = HDR_PHY_UMTS(p); php->sa_ = ue_address_; // source address php->da_ = nodeb_address_; // destination address php->scrambling_c_ = scram_c; // scrambling code php->sf_ = sf; // spreading factor php->k_ = k; // k for the channelisation code php->freq() = ulfreq; // uplink frequence chp->error()= 0; // size in bytes depending on the spreading factor chosen chp->size_=(int)(UMTS_TBLength / (php->sf_ * 8)); if ((UMTS_TBLength % (php->sf_ * 8)) != 0){ chp->size_++; } chp->next_hop() = ip_nodeb_;// if (verbose_==1)// printf("UE %d at %f PHY: send_msg: long: %d\n", ip_ue_, NOW,chp->size()); pkttoTx_->enque(p); // prepare pkt to tx onto air interface return;}// rach without preamblevoid PhyUmts::mk_msg_rach(Packet* p){ int i, j, index_c_; hdr_cmn *chsp = HDR_CMN(p); hdr_ll *lhsp = HDR_LL(p); hdr_phy *phsp = HDR_PHY_UMTS(p); // looking for an available Scrambling Code index_c_ = scrambling_allot(); if (index_c_ == -1) { // there is not any available Scrambling Code chsp->ptype() = PT_RRC_FAILURE; wait_ = 0; num_preambles_ = 0; send_to_rrc(p); // directive to RRC return; } else { // index_c_ is the available Scrambling Code phsp->scrambling_c_ = index_c_; // scrambling code phsp->used_rach_ = w_control.rach_tx_; // RACH // choose a random spreading factor i = Random::integer(3)+5; phsp->sf_ = 2; for (j=0; j<i-1; j++) phsp->sf_ *= 2; phsp->k_ = 0; // k for the channelisation code// if (verbose_==1)// printf("UE %d at %f PHY: prach built for ACK with sf %d, k %d towards %d\n", ip_ue_,NOW, phsp->sf_, phsp->k_, phsp->da()); phsp->bofsec_ = 1; // begin of RACH tx phsp->eofsec_ = 1; // end of RACH tx // size in bytes depending on the spreading factor chosen chsp->size_=(int)(UMTS_TBLength / (phsp->sf_ * 8)); if ((UMTS_TBLength % (phsp->sf_ * 8)) != 0){ chsp->size_++; } if (chsp->ptype() != PT_ACK){ // is not an RLC ACK chsp->next_hop() = ip_nodeb_; } chsp->channel_t()=PRACH; // ch mapping rachtoTx_->enqueHead(p->copy()); // store PRACH message in the RACH transmission queue } Packet::free(p); p = NULL; return;}// send RACH with preamblevoid PhyUmts::mk_msg_rach(){ int i, j, index_c_; Packet* csp = Packet::alloc(); hdr_cmn *chsp = HDR_CMN(rach_recv_); hdr_ll *lhsp = HDR_LL(rach_recv_); hdr_phy *phsp = HDR_PHY_UMTS(rach_recv_); // looking for an available Scrambling Code index_c_ = scrambling_allot(); // check if there is an available Scrambling Code if (index_c_ == -1) { // there is not any available Scrambling Code chsp->ptype() = PT_RRC_FAILURE; wait_ = 0; num_preambles_ = 0; send_to_rrc(rach_recv_); // directive to RRC Packet::free(csp); return; } else { // index_c_ is the available Scrambling Code phsp->scrambling_c_ = index_c_; // scrambling code phsp->used_rach_ = w_control.rach_tx_; // RACH phsp->sa() = ue_address_; if (lhsp->lltype() == LL_SETUP){ phsp->da() = selected_p_; chsp->next_hop() = BROADCAST; }else{ chsp->next_hop() = ip_nodeb_; phsp->da() = nodeb_address_; } // choose a random spreading factor i = Random::integer(3)+5; phsp->sf_ = 2; for (j=0; j<i-1; j++) phsp->sf_ *= 2; phsp->k_ = phsp->sf_ * w_control.signature_ / 16; // k for the channelisation code phsp->eofsec_ = 0; // size in bytes depending on the spreading factor chosen chsp->size_=(int)(UMTS_TBLength / (phsp->sf_ * 8)); if ((UMTS_TBLength % (phsp->sf_ * 8)) != 0){ chsp->size_++; } chsp->channel_t()=PRACH; // ch mapping if (verbose_==1) printf("UE %d at %f PHY: prach built with sf %d, k %d towards %d\n", ip_ue_,NOW, phsp->sf_, phsp->k_, phsp->da()); // control part csp = rach_recv_->copy(); hdr_phy *phcsp = HDR_PHY_UMTS(csp); hdr_cmn *chcsp = HDR_CMN(csp); phcsp->sf_ = 256; // spreading factor phcsp->k_ = 16 * w_control.signature_ + 15; // k for the channelisation code // size in bytes depending on the spreading factor chosen chcsp->size_=(int)(UMTS_TBLength / (phcsp->sf_ * 8)); // bytes if ((UMTS_TBLength % (phcsp->sf_ * 8)) != 0){ chcsp->size_++; } // length of a RACH message part is a frame (8 slots) for (i=0; i<8; i++){ if (i == 0){ phsp->bofsec_ = 1; // begin of RACH tx phcsp->bofsec_ = 1; } else { phsp->bofsec_ = 0; phcsp->bofsec_ = 0; } if (i == 7){ phsp->eofsec_ = 1; // end of RACH tx phcsp->eofsec_ = 1; } rachtoTx_->enque(rach_recv_->copy()); // store PRACH data part in the RACH transmission queue rachtoTx_->enque(csp->copy()); // store PRACH control part in the RACH transmission queue } } Packet::free(rach_recv_); rach_recv_ = NULL; Packet::free(csp); csp = NULL; return;}// send directives directly to RRCvoid PhyUmts::send_to_rrc(Packet* p)// method for communicating with the RRC layer. Possible types of messages are:// - PT_RRC_FAILURE Failure when trying to tx RACH// - LL_HANDOVER For handover decission// - LL_PAGING Check the paging destination broadcasted in S-CCPCH{ hdr_cmn *chp = HDR_CMN(p); chp->direction_ = hdr_cmn::UP; // put direction UP chp->channel_t() = TO_RRC; // ch mapping ll_->recv(p, this);}// Turn on / off the radiovoid PhyUmts::radioSwitch(int i){ radio_active_ = i; EnergyModel *em = netif_->node()->energy_model(); if (i == ON) { // turn the radio ON if (em && em->sleep()){ em->set_node_sleep(0); } } if (i == OFF) { // turn the radio OFF if (em && !em->sleep()) { em->set_node_sleep(1); }; }}// calculate the transmission timedouble PhyUmts::TX_Time(Packet *p) { double len=(HDR_CMN(p))->size(); double t = (double)(len*8)/tx_rate; return t;}// transmit packets to Node Bvoid PhyUmts::tx_to_nodeb(Packet *p){ double stime; double temp; hdr_cmn* ch = HDR_CMN(p); hdr_phy* ph = HDR_PHY_UMTS(p); ph->rx_power() = 0; stime = TX_Time(p); // calculate the transmission time// if (verbose_==1)// printf("UE %d at %f PHY: txing pkt, sendtime=%f, size=%d\n", ip_ue_, NOW, stime, ch->size()); pTxPkt_.start(p->copy(), stime); // start the transmission timer hdr_ll* lh = HDR_LL(p); hdr_ip* ih = HDR_IP(p); downtarget_->recv(p->copy(), this); // send the packet to Node B}/************************** HANDLERS **********************/// Called during Handover and Setup procedures when CellTimer expires.void PhyUmts::cellHandler(){ listen_sch_ = 0; if (selected_sc_ < 0) { // We don't received higher power than my NodeB's power of any cell. //Stops the handover procedure if (verbose_==1) printf("UE %d at %f PHY: No NodeB with higher power than mine. Stop HANDOVER PROCEDURE...\n", ip_ue_, NOW); handover_ = 0; wait_ = 0; Packet::free(rach_recv_); return; } // we have found a Node B nearest than the other one if (verbose_==1) printf("UE %d at %f PHY: selecting Nodeb with scram code: %d\n", ip_ue_,NOW, selected_sc_); tx_preamble(); // transmit RACH preamble return;}// Called when PreambleTimer expires.// We have not received the waited AICH as a response of the PREAMBLE sentvoid PhyUmts::PreambleHandler(){ if (num_preambles_ < MAX_NUM_PREAMBLE) { // we can continue transmitting preambles if (verbose_==1) printf("UE %d at %f PHY: other preamble -----------------------------------------%d\n", ip_ue_,NOW, num_preambles_); tx_preamble(); // transmit RACH preamble } else { // we have transmit the maximum number of preambles hdr_cmn *ch = HDR_CMN(rach_recv_); ch->ptype() = PT_RRC_FAILURE; wait_ = 0; num_preambles_ = 0; send_to_rrc(rach_recv_); // directive to RRC }}// Called when BlerTimer expires.// Timer for calculating the Interferencevoid PhyUmts::blerHandler(Event *e){ double Eb_No, bler, I=0; // Restart timer for next time. pBler_.start((Packet *)e, 5*UMTS_FrameTime); if ((lastRate > 0) && (noIoth > 0)) { // if there has been any interference I = Ioth / noIoth; Eb_No = (CHIP_RATE * Prx) / (lastRate * (I + Pn)); } else { // no interference at all Eb_No = 1e38; } Ioth = 0; noIoth = 0; bler = BTable->getbler(Eb_No); // consult table (Eb_No) dl_ErrorRate = (int)(1/bler) + 1; if (verbose_) printf("UE %d at %f PHY: blerHandler,,, {lastRate Ioth noIoth I Prx EbNo bler dl_ErrorRate}\n[%f %e %d %e %e %e %e %lu]\n", ip_ue_,NOW, lastRate, Ioth ,noIoth, I, Prx, Eb_No, bler, dl_ErrorRate); mac_->dl_interference(dl_ErrorRate); // send the results to MAC return;}// Called after the transmission of a packet when TxPktUmtsTimer expires.// Frees the pkt. Turns off the radio.void PhyUmts::sendHandler(Event *e){ Packet::free((Packet *)e); e = NULL; radioSwitch(OFF); return;}// Called after the reception of a packet when RxPktUmtsTimer expires.// Turns the radio off and call recv_from_phyvoid PhyUmts::recvHandler(Event *e){ Packet * p = (Packet * )e; radioSwitch(OFF); // turn the radio OFF recv_from_phy(p, this); // send the packet to analize in method recv_from_phy() return;}// Called when UpSlotUmtsTimer expires.void PhyUmts::upslotHandler(Event *e){ int i,len; // Restart timer for next slot. pUpSlot_.start((Packet *)e, slot_time_); mk_dpxch(); // DPDCH Multiplexing and DPCCH creation while (pkttoTx_->length() > 0) { //start transmission radioSwitch(ON); // turn the radio ON tx_to_nodeb(pkttoTx_->deque()); // transmit to Node B } // program the next slot up_slot_ ++; if (up_slot_ == SLOTS_PER_FRAME) { up_slot_ = 0; } return;}// Called when RachUpSlotUmtsTimer expires.void PhyUmts::rachupslotHandler(Event *e){ int i,len; // Restart timer for next slot. pRachUpSlot_.start((Packet *)e, rach_slot_time_);AGAIN: // check if there is any packet in the buffer if (rachtoTx_->length() > 0) { Packet * prov = rachtoTx_->deque(); struct hdr_phy *phprov = HDR_PHY_UMTS(prov); struct hdr_cmn *chprov = HDR_CMN(prov); struct hdr_ll *lhprov = HDR_LL(prov); //start transmission radioSwitch(ON); // turn the radio ON if ((chprov->ptype() == PT_ACK) || (lhprov->lltype() == LL_RELEASE_REQ)){ // RLC ACK or Release Request tx_to_nodeb(prov); // transmit to Node B goto AGAIN; // send more packets } tx_to_nodeb(prov); // preamble modulated in BPSK but RACH message part in QPSK if (chprov->ptype() != PT_PREAMBLE) tx_to_nodeb(rachtoTx_->deque()); // send the next packet // end of transmision of RACH message if (phprov->eofsec_ == 1) wait_ = 0; } // check if there is other rach waiting to be transmited if ((wait_ == 0) && (prach_temp_->length() > 0)){ // begin RACH procedure rach_recv_ = prach_temp_->deque(); wait_ = 1; num_preambles_ = 0; tx_preamble(); // transmit preamble if (verbose_==1) printf("UE %d at %f PHY: other rach to tx?????\n", ip_ue_,NOW ); } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -