📄 phy-umts.cc
字号:
} if (wait_ == 1) { // already in other RACH procedure. prach_temp_->enque(p); } else { wait_ = 1; rach_recv_ = p->copy(); if (lh->lltype() == LL_SETUP){ // switch on procedure or handover if (verbose_==1) printf("UE %d at %f PHY: Cell search procedure starts. Listen to SCH\n", ip_ue_, NOW); listen_sch_ = 1; pCell_.start(20*slot_time_); // start timer for cell search procedure } else { tx_preamble(); // send preamble for RACH procedure } Packet::free(p); p = NULL; } break; case DCH: // if (verbose_==1) //printf("UE %d at %f PHY: DCH with flow %d arrived at PHY with uid:%d\n", ip_ue_, NOW, ih->flowid(), ch->uid()); ul_mux(p); // to uplink multiplexing chain break; default: if (verbose_==1) printf("UE %d at %f PHY: Pkt of flow %d arrived at PHY with uid:%d and direction%d:\n",ip_ue_, NOW, ih->flowid(), ch->uid(), ch->direction()); pkttoTx_->enque(p); break; } }return;}// looking for an available Scrambling Codeint PhyUmts::scrambling_allot(){ int index_c_, i = 0; // begin in an aleatory place index_c_ = Random::integer(MAX_NUM_SCRAM-1); while (i < MAX_NUM_SCRAM) { if (w_control.free_res_[0][index_c_] == 0) return (index_c_); // index_c is an available scrambling code i++; index_c_++; if (index_c_ == MAX_NUM_SCRAM) index_c_ = 0; } return (-1); // no free resources}// For Setup and Handover Procedurevoid PhyUmts::cell_selection(Packet* p){ hdr_phy *ph = HDR_PHY_UMTS(p); if (verbose_==1) printf("UE %d at %f PHY: analizing SCH power: %e from NodeB with phyaddr %d.....\n\n", ip_ue_,NOW, ph->rx_power(), ph->p_scrambling_c()); if (ph->rx_power() > power_sch_){ // higher power than the one that we have stored, store the new one selected_sc_ = ph->p_scrambling_c(); // new node B primary scrambling code selected_p_ = ph->sa(); // new node B physical address power_sch_ = ph->rx_power(); if (verbose_==1) printf("UE %d at %f PHY: Nodeb with higher power and scram: %d\n", ip_ue_,NOW, ph->p_scrambling_c()); } Packet::free(p); p = NULL; return;}// for transmitting the RACH preamblevoid PhyUmts::tx_preamble(){ int i, j, index_c_, index_s_; // looking for an available RACH i = 0; j = Random::integer(MAX_NUM_RACH-1); while (i < MAX_NUM_RACH) { if (w_control.free_rach_[j] == 0) // j is an available RACH break; i++; j++; if (j == MAX_NUM_RACH) j = 0; } // check if there is an available RACH if (i == MAX_NUM_RACH) { // there is not any available RACH // arbitly limited the backoff timer from 4 to 12 slots.- pPreamble_.stop(); pPreamble_.start(); //start Preamble timer return; } else { // j is the available RACH to use // 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 // arbitly limited the backoff timer from 4 to 12 slots.- pPreamble_.stop(); pPreamble_.start(); //start Preamble timer return; } else { // index_c_ is the available Scrambling Code // looking for an available Signature i = 0; index_s_ = Random::integer(MAX_NUM_SIG-1)+1; while (i < MAX_NUM_SIG) { if (w_control.free_res_[index_s_][index_c_] == 0) // available Signature break; i++; index_s_++; if (index_s_ == MAX_NUM_SIG + 1) index_s_ = 1; } // check if there is an available Signature if (i == MAX_NUM_SIG) { // there is not any available Signature // arbitly limited the backoff timer from 4 to 12 slots.- pPreamble_.stop(); pPreamble_.start(); //start Preamble timer return; } else { // Preamble with parameters: j, index_c_, index_s_ if (verbose_==1) printf("UE %d at %f PHY: PREAMBLE with rach: %d, sc: %d, sign: %d\n", ip_ue_,NOW,j, index_c_, index_s_); // storing preamble characteristics w_control.signature_ = index_s_; w_control.rach_tx_ = j; w_control.scram_tx_ = index_c_; // building the preamble message Packet* sp = Packet::alloc(); struct hdr_cmn *chsp = HDR_CMN(sp); hdr_phy *phsp = HDR_PHY_UMTS(sp); hdr_ip *ihsp = HDR_IP(sp); hdr_ll *lhrach_recv = HDR_LL(rach_recv_); hdr_ip *ihrach_recv = HDR_IP(rach_recv_); if (lhrach_recv->lltype() == LL_SETUP){ // for setup and handover procedures phsp->first_access_ = 1; phsp->da_ = selected_p_; // destination address } else { // for resource allocation phsp->first_access_ = 0; phsp->da_ = nodeb_address_; // destination address } phsp->sa_ = ue_address_; // source address phsp->scrambling_c_ = index_c_; // scrambling code phsp->signature_ = w_control.signature_; // signature phsp->used_rach_ = w_control.rach_tx_; // RACH phsp->sf_ = 16; // spreading factor phsp->k_ = w_control.signature_; // k for the channelisation code chsp->direction_ = hdr_cmn::DOWN; chsp->ptype() = PT_PREAMBLE; // calculating message size chsp->size_=(int)(UMTS_TBLength / (phsp->sf_ * 8)); // bits = 2560/SF if ((UMTS_TBLength % (phsp->sf_ * 8)) != 0){ chsp->size_++; } chsp->error()= 0; chsp->channel_t()=PRACH; // channel allocation chsp->next_hop() = ip_nodeb_; chsp->prev_hop_ = ip_ue_; ihsp->saddr() = ihrach_recv->saddr(); ihsp->daddr() = ihrach_recv->daddr(); rachtoTx_->enque(sp); // store preamble in the RACH transmission queue // arbitly limited the backoff timer from 4 to 12 slots.- pPreamble_.stop(); pPreamble_.start(); //start Preamble timer num_preambles_++; } } } return;}// for channel codingvoid PhyUmts::c_coding(Packet* p){ hdr_cmn *chp = HDR_CMN(p); hdr_phy *php = HDR_PHY_UMTS(p); switch (php->c_coding()) { case TURBO: // turbo coding chp->size() = 3*chp->size(); break; case CONV_HALF: // convolutional half chp->size() = 2*chp->size(); break; case CONV_THIRD: // convolutional third chp->size() = 3*chp->size(); break; default: break; } return;}// for channel decodingvoid PhyUmts::c_decoding(Packet* p){ hdr_cmn *chp = HDR_CMN(p); hdr_phy *php = HDR_PHY_UMTS(p); switch (php->c_coding()) { case TURBO: // turbo coding chp->size() = (int)(chp->size()/3); break; case CONV_HALF: // convolutional half chp->size() = (int)(chp->size()/2); break; case CONV_THIRD: // convolutional third chp->size() = (int)(chp->size()/3); break; default: break; } return;}// uplink multiplexing chainvoid PhyUmts::ul_mux(Packet* p){ int i; hdr_cmn *chp = HDR_CMN(p); hdr_phy *php = HDR_PHY_UMTS(p); c_coding(p); // for Channel Coding php->size() = chp->size_; // store size php->sa_ = ue_address_; // source address php->da_ = nodeb_address_; // destination address data_temp_->enque(p); // store packet for sending it over the air interface return;}// decoding packets with direction UPvoid PhyUmts::decode(){ int i, j; Packet* p; hdr_cmn *chp; hdr_ip *ihp; hdr_phy *php; hdr_phy *phrecv; // demux DPDCH and extract packets for (i=0; i<d_control.n_dpdch_; i++) { phrecv = HDR_PHY_UMTS(rx_dpdch[i]); // go through the array extracting packets while (phrecv->dpdch_control_->length() > 0) { p = phrecv->dpdch_control_->deque(); chp = HDR_CMN(p); ihp = HDR_IP(p); php = HDR_PHY_UMTS(p); hdr_rlc_umts *rhp = HDR_RLC_UMTS(p); if (php->sa() == nodeb_address_) { if (in_seq_ == -1) { // Previusly packets arrived not in sequence if (php->seqno_ == 0) { // first physical fragment of a packet if (php->eofsec_ == 1) { // last physical fragment of a packet chp->channel_t() = DCH; // ch mapping dl_demux(p->copy()); // send it to demux chain if (verbose_==1) printf("UE %d at %f PHY: decode: sending end of sequence of flow %d uid %d and size %d from NodeB %d\n", ip_ue_,NOW, ihp->flowid(),chp->uid(),chp->size(),php->sa()); in_seq_ = 0; // waiting for fragment 0 } else { // is not the last fragment, drop it if (verbose_==1) printf("UE %d at %f PHY: a decode: pkt in seq: %d ue %d flow %d uid %d and size %d from NodeB %d\n", ip_ue_,NOW, php->seqno_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa()); in_seq_ = 1; // waiting fragment number 1 Packet::free(p); } } else { // is not the first fragment, drop the packet if (verbose_==1) printf("UE %d at %f PHY: decode: not seq: Drop pkt from NodeB %d\n",ip_ue_,NOW, php->sa()); Packet::free(p); } } else if (php->seqno_ == in_seq_) { // Previous packets arrived in sequence // is the fragment that we expected if (php->eofsec_ == 1) { // is the last physical fragment, send it to MAC chp->channel_t() = DCH; // ch mapping dl_demux(p->copy()); // send it to demux chain in_seq_ = 0; // waiting fragment number 0 if (verbose_==1) printf("UE %d at %f PHY: decode: sending end of sequence of flow %d uid %d and size %d from NodeB %d dpdch con size %f\n", ip_ue_,NOW, ihp->flowid(),chp->uid(),chp->size(),php->sa(),phrecv->size()); } else { // is not the last fragment, drop the packet if (verbose_==1) printf("UE %d at %f PHY: decode: pkt in seq: %d ue %d flow %d uid %d and size %d from NodeB %d dpdch con size %f\n", ip_ue_, NOW, php->seqno_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa(),phrecv->size()); in_seq_++; Packet::free(p); } } else { // Previous packets arrived in sequence // Previous packets arrived in sequence if (verbose_==1) printf("UE %d at %f PHY: decode: pkt not in seq: %d waiting %d ue %d flow %d uid %d and size %d from NodeB %d\n", ip_ue_,NOW, php->seqno_, in_seq_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa()); in_seq_ = -1; // not in sequence Packet::free(p); } // used during Handover Procedure } else if (php->sa() == hnodeb_) { if (hin_seq_ == -1) { // Previusly packets arrived in not sequence if (php->seqno_ == 0) { // first physical fragment of a packet if (php->eofsec_ == 1) { // last physical fragment of a packet chp->channel_t() = DCH; // ch mapping dl_demux(p->copy()); // send it to demux chain if (verbose_==1) printf("UE %d at %f PHY: decode: pkt UP of flow %d uid %d and size %d from NodeB %d\n", ip_ue_,NOW, ihp->flowid(),chp->uid(),chp->size(),php->sa()); hin_seq_ = 0; // waiting fragment number 0 } else { // is not the last fragment, drop the packet if (verbose_==1) printf("UE %d at %f PHY: decode: pkt in seq: %d ue %d flow %d uid %d and size %d from NodeB %d\n", ip_ue_, NOW, php->seqno_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa()); hin_seq_ = 1; // waiting for fragment number 1 Packet::free(p); } } else { // is not the first fragment, drop the packet if (verbose_==1) printf("UE %d at %f PHY: decode: not seq: Drop pkt from NodeB %d\n",ip_ue_,NOW,php->sa()); Packet::free(p); } } else if (php->seqno_ == hin_seq_) { // Previusly packets arrived in sequence // is the fragment number that we expected if (php->eofsec_ == 1) { // last physical fragment of a packet chp->channel_t() = DCH; // ch mapping dl_demux(p->copy()); // send it to demux chain hin_seq_ = 0; // waiting fragment number 0 if (verbose_==1) printf("UE %d at %f PHY: decode: pkt UP of flow %d uid %d and size %d from NodeB %d\n", ip_ue_,NOW, ihp->flowid(),chp->uid(),chp->size(),php->sa()); } else { // is not the last fragment, drop the packet if (verbose_==1) printf("UE %d at %f PHY: decode: pkt in seq: %d ue %d flow %d uid %d and size %d from NodeB %d\n", ip_ue_,NOW, php->seqno_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa()); hin_seq_++; Packet::free(p); } } else { // Previous packets arrived in sequence // is not the fragment number that we expected if (verbose_==1) printf("UE %d at %f PHY: decode: pkt not in seq: %d waiting %d ue %d flow %d uid %d and size %d from NodeB %d\n", ip_ue_,NOW, php->seqno_, hin_seq_, php->sa(), ihp->flowid(),chp->uid(),chp->size(),php->sa()); hin_seq_ = -1; Packet::free(p); } } } Packet::free(rx_dpdch[i]); // remove resources rx_dpdch[i] = NULL; } return;}// downlink demultiplexing channelvoid PhyUmts::dl_demux(Packet* p){ int i; hdr_cmn *chp = HDR_CMN(p); hdr_phy *php = HDR_PHY_UMTS(p); chp->direction_ = hdr_cmn::UP; //if (verbose_==1) //printf("UE %d at %f PHY: phy --->> mac pkt con uid: %d y size: %d, direccion: %d\n", ip_ue_, NOW,chp->uid(), chp->size(), chp->direction()); c_decoding(p); // channel decoding uptarget_->recv(p, this); // send the packet to MAC layer return;}// Building dedicated channels depending on the given bytes per slotvoid PhyUmts::mk_dpxch(void){ // Rate matching int i, j, sf_, k_, n_dpdch; double index, temp, sum, mod, tbytes, total_size; hdr_cmn * chp; hdr_phy * php; hdr_rlc_umts * rh; tbytes = 0.0; sum = 0.0; total_size = bytes_slot; // maximum physical bytes that is possible sending in one slot if (data_temp_->length() > 0) { // no flows to tx Packet* p; // looking for an available Scrambling Code if (up_slot_ == 0) { d_sc_ = scrambling_allot(); } // d_sc_ is the available Scrambling Code if (total_size > MAX_NUM_BYTES_PER_SLOT){ // is necesary 2 or more DPDCH, with SF=4 // building DPDCH packets n_dpdch = (int)(total_size / MAX_NUM_BYTES_PER_SLOT); mod = (int)(total_size) % (MAX_NUM_BYTES_PER_SLOT); if (mod > 0) n_dpdch++; if (n_dpdch > MAX_NUM_DPDCH) n_dpdch = MAX_NUM_DPDCH; // n_dpdch is the number of necessary DPDCH for that application for (i=0; i<n_dpdch; i++){ 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_ = i+1; sum = 0.0; // extracting packets from the buffer to transmit while (data_temp_->length() > 0){ p = data_temp_->deque(); php = HDR_PHY_UMTS(p); rh = HDR_RLC_UMTS(p); sum += php->size(); // check if there is enough space in that DPDCH if (sum <= MAX_NUM_BYTES_PER_SLOT) { // there is enough space for the whole packet php->seqno_ = count; php->eofsec_ = 1; phsp->dpdch_control_->enque(p->copy()); phsp->size() += php->size(); count = 0; Packet::free(p); if (sum == MAX_NUM_BYTES_PER_SLOT) break; } else { // no space to allocate all the packet in the current DPDCH sum -= php->size(); temp = php->size(); php->size() = MAX_NUM_BYTES_PER_SLOT - sum; php->seqno_ = count; php->eofsec_ = 0; // sending a part of the message phsp->dpdch_control_->enque(p->copy()); phsp->size() = phsp->size() + MAX_NUM_BYTES_PER_SLOT - sum; php->size() = temp - (MAX_NUM_BYTES_PER_SLOT - sum); count++; // storing the rest of the packet in the buffer data_temp_->enqueHead(p); break; } } sf_ = 4; // spreading factor // calculate k_ if (i==0 || i==1) k_ = 1; if (i==2 || i==3) k_ = 3; if (i==4 || i==5) k_ = 2; chsp->channel_t()=DPDCH; // ch mapping
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -