phy2.c

00001 /*
00002  * Copyright (c) 2008 Regents of the SIGNET lab, University of Padova.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University of Padova (SIGNET lab) nor the 
00014  *    names of its contributors may be used to endorse or promote products 
00015  *    derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00018  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
00019  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00020  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00021  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00022  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00023  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00024  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00025  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00026  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00027  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 //
00031 // ANEMURAS
00032 //
00033 // file: phy2.c 
00034 //
00035 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <math.h>
00040 #include "../main/anemuras.h"
00041 #include "../main/event.h"
00042 #include "../main/packet.h"
00043 #include "../main/fileio.h"
00044 #include "../channel1/channel1.h"
00045 
00046 //#define debug 1
00047 //#define control 1
00048 
00049 // UMTS slot time (sec.)
00050 #define UMTS_SLOT_TIME 0.000666
00051 // time in second of Round Trip Time
00052 #define UMTS_RTT_VALUE 0.21
00053 // Handover threshold (dB)
00054 #define HANDOVER_TH_DB 1.2
00055 // Accept Power Threshold (max rx power accepted at a BS) [linear scale]
00056 // now used only  for congestion estimate
00057 #define ACCEPT_POW_TH 10e-3
00058 // number of BS active for each user
00059 //#define BS_ACTIVE_NUM 3       //(ATT: also defined in umts.c)
00060 // user handover is updated every N_UPDATE_HANDOVER
00061 #define N_UPDATE_HANDOVER 150
00062 // spreading factor init value
00063 #define SF_INIT_VALUE 16
00064 // max power in uplink (dBW)
00065 #define POWER_MAX_UP -16
00066 // min power in uplink (dBW)
00067 #define POWER_MIN_UP -96
00068 // max power in downlink (dBW)
00069 #define POWER_MAX_DOWN -5
00070 // power control step (dB)
00071 #define DELTA 0.5
00072 // power control delay (n° of slots, =1 ideal, >1 not ideal)
00073 #define POWER_CONTROL_DELAY 1
00074 // SIR target for all user (dB)
00075 #define SIR_TARGET_DB 4.5
00076 // margine temporale per cui il calcolo dellle potenze ricevute resta valido
00077 #define RX_POW_VALID_TIME 1e-6
00078 // paramter to compute Pe from SIR (see article)
00079 #define ZETA 2.72
00080 
00081 extern time clock;
00082 extern ANnode *globalPtr;
00083 extern char  OUT_FILE[STRING_MAX_LENGTH];
00084 extern const ANid NODES_NUM;
00085 extern const ANid AP_NODES_MAC1_NUM;
00086 extern const ANid AP_NODES_MAC2_NUM;
00087 extern const ANid AP_NODES_NUM;
00088 
00089 extern flag Mac2Available(ANid id);
00090 
00091 
00092 ANid AP_MAC2_TOT_NUM;                           // total n° of MAC2 AP (MAC2 + MAC12)
00093 unsigned int BS_ACTIVE_NUM;                     // n° of BS active for each node (for soft- handover)
00094 
00095 typedef struct ANidList{
00096         ANid id;
00097         struct ANidList *toNextPtr;
00098 }ANidList;
00099 ANidList *nodesWantSync;        // list of nodes that want sync in the next slot
00100 ANid *BSlist;                           // list of basestation
00101 double po0 = 49.0/225.0;                // ratio of used power when node is idle
00102 double f0 = 1;                          // ortogonality factor
00103 double No = 1e-32;              // thermal noise (-328 dB)
00104 
00105 
00106 // define the accurancy in symbol test, i.e. the number of symbols every which
00107 // have to made a test
00108 unsigned int PHY2_SYMBOL_TEST;          // 1 is default (heuristic, every single symbol)
00109 
00110 
00111 typedef enum{
00112         TX,
00113         RX,
00114         IDLE
00115 } PBState;
00116 
00117 typedef enum{
00118 // substate of TX
00119         WAIT_SYNC,
00120 // substate of RX
00121 // substate of IDLE
00122         PB_IDLE,
00123 } PBSubState;
00124 
00125 typedef struct{
00126         unsigned long int txNo;                         // total number of pkt tx
00127         unsigned long int txBits;                               // total number of bits tx
00128 } PBStats;
00129 
00130 typedef struct{
00131         unsigned long int rxNo;                         // total number of pkt rx
00132         unsigned long int rxBits;                       // total number of bits rx
00133 }BSStats;
00134 
00135 typedef struct{
00136         flag isInCell;
00137         flag pktInFlyNow;
00138         ANpacket* pktInFly;
00139         ANsize currentBlockSize;
00140         time endRxPkt;                                  // time that BS finish to receive pkt
00141         ANsize bitCount;
00142         int fadingErrorNum;
00143         flag contextTransferDuringRx;
00144         ANtx_power rxPowLin;                    // instant rx power in linear scale (mW)
00145         ANtx_power SIR;                         // linear
00146         ANposition distance;
00147         time propDelay;
00148 }PBArrayEl;
00149 
00150 typedef struct{
00151         PBArrayEl *PBarray;
00152         time lastRxPowUpdate;                   // time of the last calculation of rx power of BS from node
00153         BSStats stats;
00154 }BSStruct;
00155 
00156 typedef struct{
00157         ANpacket *TxPkt;
00158         ANid *BSlist;
00159         unsigned int sf;                        // current spreading factor
00160         ANtx_power *BSgain;     // [dB]
00161         PBState state;
00162         PBSubState subState;
00163         PBStats stats;
00164         ANtx_power txPower;             // current tx power (dB)
00165 }PBStruct;
00166 
00167 
00168 // FUNCTION     Phy2NextBlockSymbolTest
00169 // PURPOSE      calculate next block test symbol event and the size of the next block
00170 //                              if the last must be smaller
00171 time Phy2NextBlockSymbolTest(ANid id,ANpacket *pkt){
00172         BSStruct *BSptr;
00173         double nextTest;
00174                 
00175         BSptr = (BSStruct *)NODEPTR(id)->Phy2StructPtr;
00176         if ((BSptr->PBarray[pkt->txId].bitCount + PHY2_SYMBOL_TEST) > pkt->size){
00177                 // there isn't enough symbol to create a normal block -> reduced block size
00178                 BSptr->PBarray[pkt->txId].currentBlockSize = 
00179                                 pkt->size - BSptr->PBarray[pkt->txId].bitCount;
00180                 nextTest = BSptr->PBarray[pkt->txId].endRxPkt;
00181         }else
00182                 nextTest = clock + (PHY2_SYMBOL_TEST * (1/pkt->txRate));
00183 
00184         return(nextTest);       
00185 }
00186 
00187 
00188 // FUNCTION     Phy2UpdatePostMobility
00189 // PURPOSE      update after a mobility event the structures that maintain the ralation between
00190 //                      all nodes to BS indicate(distance, paropagation delay)
00191 void Phy2UpdatePostMobility(ANid id){
00192 ANid i;
00193 BSStruct *BSptr;
00194 ANid *BStemp;
00195 
00196         if (NODEPTR(id)->node_type==PAN_BAN){
00197                 BStemp = BSlist;
00198                 // update all the data relative to node id in all the BS
00199                 for(i=0; i<AP_MAC2_TOT_NUM; i++){
00200                         BSptr = (BSStruct *)NODEPTR(BStemp[i])->Phy2StructPtr;
00201                         BSptr->PBarray[id].distance = Distance(BStemp[i],id);
00202                         BSptr->PBarray[id].propDelay = Channel1PropDelay(BStemp[i],id);
00203                 }
00204                 BStemp = BSlist;
00205                 /* DEBUG OUTPUT
00206                 printf("UMTS Post Mobility Update:\n");
00207                 for(i=0; i<AP_MAC2_TOT_NUM; i++){
00208                         BSptr = (BSStruct *)NODEPTR(BStemp[i])->Phy2StructPtr;
00209                         printf("Node %d to AP %d: distance %3.3f propDelay %e\n",id,BStemp[i],BSptr->PBarray[id].distance,
00210                                         BSptr->PBarray[id].propDelay);
00211                 }
00212                 */ // END DEBUG OUTPUT
00213         }
00214 }
00215 
00216 
00217 // FUNCTION     sf2datarate
00218 // PURPOSE      returns the physical channel datarate [bps] from the spreading factor value
00219 double sf2datarate(unsigned int sf, linkType link)
00220 {
00221         if (link==DOWNLINK) {
00222                 switch (sf)
00223                 {
00224                         case 4:         return(1966080);        // [1920 Kbps]
00225                         case 8: return(983040); // [960 Kbps]
00226                         case 16:        return(491520); // [480 Kbps]
00227                         case 32:        return(245760); // [240 Kbps]
00228                         case 64:        return(122880); // [120 Kbps]
00229                         case 128:       return(61440);          // [60 Kbps]
00230                         case 256:       return(30720);  // [30 Kbps]
00231                         case 512:       return(15360);  // [15 Kbps]
00232                 }
00233         } else {                // UPLINK
00234                 switch (sf)
00235                 {
00236                         case 4:         return(983040); // [960 Kbps]
00237                         case 8: return(491520); // [480 Kbps]
00238                         case 16:        return(245760); // [240 Kbps]
00239                         case 32:        return(122880); // [120 Kbps]
00240                         case 64:        return(61440);          // [60 Kbps]
00241                         case 128:       return(30720);  // [30 Kbps]
00242                         case 256:       return(15360);  // [15 Kbps]
00243                 }
00244         }
00245 }
00246 
00247 
00248 
00249 // FUNCTION     Phy2RxPowUpdateUP
00250 // PURPOSE      calculate the rx power (linear) of BS from all nodes (0 stand for all the BS)
00251 void Phy2RxPowUpdateUP(ANid BS){
00252 BSStruct *BSptr;
00253 PBStruct *PBptr;
00254 int i;
00255 
00256         if (BS==0){
00257                 // update for all the BS
00258                 for(i=0;i<AP_MAC2_TOT_NUM; i++){
00259                         BSptr = (BSStruct *)NODEPTR(BSlist[i])->Phy2StructPtr;
00260                         if (BSptr->lastRxPowUpdate+RX_POW_VALID_TIME < clock){
00261                                 Phy2RxPowUpdateUP(BSlist[i]);
00262                         }
00263                 }
00264         }else{
00265 #ifdef control
00266                 if ((Mac2Avaiable(BS)==FALSE) && (NODEPTR(BS)->node_type!=ACCESS_PROVIDER)){
00267                         puts("Error Phy2RxPowUpdate, uncorrect BS");
00268                         exit(1);
00269                 }
00270 #endif
00271                 // il controllo sulla validità del calcolo delle potenze ricevute per la singola BS si suppone venga fatto a 
00272                 // monte, così da evitare ridondanti chiamate a funzioni.
00273                 BSptr = (BSStruct *)NODEPTR(BS)->Phy2StructPtr;
00274                 for(i=1; i<=NODES_NUM;i++){
00275                         if ((Mac2Available(i)==TRUE)&& (NODEPTR(i)->node_type==PAN_BAN)){
00276                                 PBptr = (PBStruct *)NODEPTR(i)->Phy2StructPtr;
00277                                 BSptr->PBarray[i].rxPowLin = FromDbToLinear(Channel1RxPower(i,BS,PBptr->txPower));
00278                                 //printf("Nodo %d txpower%f, rxpower(dB)%f rxpower (liN)%e\n",i,PBptr->txPower,
00279                                 //      Channel1RxPower(i,BS,PBptr->txPower),BSptr->PBarray[i].rxPowLin);
00280                         }
00281                 }
00282                 BSptr->lastRxPowUpdate = clock;
00283         }
00284 }
00285 
00286 
00287 // FUNCTION     Phy2ComputeSIR
00288 // PURPOSE      calculate the current value of SIR in BS for the PB node, if necessary recalculate the rx pow
00289 ANtx_power Phy2ComputeSIR(ANid BS, ANid PB){
00290 BSStruct *BSptr;
00291 PBStruct *PBptr;
00292 int i;
00293 ANtx_power util, interIntra, interExtra,rxPow,SIR;
00294 
00295 #ifdef control
00296         if ( (Mac2Available(BS)==FALSE) && (NODEPTR(BS)->node_type!=ACCESS_PROVIDER)){
00297                 puts("Error Phy2RxPowUpdate, uncorrect BS");
00298                 exit(1);
00299         }
00300         if ((Mac2Available==FALSE) && (NODEPTR(PB)->node_type!=PAN_BAN)){
00301                 puts("Error Phy2RxPowUpdate, uncorrect PB");
00302                 exit(1);
00303         }
00304 #endif
00305         BSptr = (BSStruct *)NODEPTR(BS)->Phy2StructPtr;
00306         PBptr = (PBStruct *)NODEPTR(PB)->Phy2StructPtr;
00307         // verify if necessary recalculate rx power
00308         if (BSptr->lastRxPowUpdate+RX_POW_VALID_TIME < clock)
00309                 Phy2RxPowUpdateUP(BS);
00310         // useful power utile (used only for data)
00311         util = BSptr->PBarray[PB].rxPowLin * (1./(1.+po0));
00312         interIntra = 0.0;
00313         interExtra = 0.0;
00314         for (i=1;i<NODES_NUM;i++){
00315                 if ((Mac2Available(i)==TRUE) && (NODEPTR(i)->node_type==PAN_BAN) && (i!=PB) ){
00316                         rxPow = BSptr->PBarray[i].rxPowLin;
00317                         if (BSptr->PBarray[i].pktInFlyNow==FALSE)
00318                                 // node is idle -> only a ratio of tx power is used
00319                                 rxPow *= (po0/(1.+po0));
00320                         if (BSptr->PBarray[i].isInCell==TRUE)
00321                                 // intra-cell interference
00322                                 interIntra += rxPow;
00323                         else
00324                                 // extra-cell interference
00325                                 interExtra += rxPow;
00326                 }
00327         }
00328         SIR = (PBptr->sf * util) / (f0*interIntra + interExtra + No);
00329         //printf("Calcolato BS%d PB %d SIR %2.2f util%e interIntra%e interExtra%e SF %d\n",
00330         //      BS, PB, SIR,util,interIntra,interExtra,PBptr->sf);
00331         return(SIR);
00332 }
00333 
00334 
00335 // FUNCTION     Phy2GetUmtsSync
00336 // PURPOSE      set level structure that the node indicate want receive the sync at the begin of next slot
00337 void Phy2GetUmtsSync(ANid id){
00338 ANidList *ptr;
00339 ANidList *temp;
00340 
00341         ptr = nodesWantSync;
00342         // insert in tail
00343         if (nodesWantSync==NULL){
00344                 // empty queue -> first element
00345                 ptr = (ANidList *)malloc(sizeof(ANidList));
00346                 if (ptr==NULL){
00347                         puts("Error Phy2GetUmtsSync, ptr malloc error");
00348                         exit(1);
00349                 }
00350                 ptr->id = id;
00351                 ptr->toNextPtr = NULL;
00352                 nodesWantSync = ptr;
00353         }else {
00354                 // go to the tail and than insert
00355                 while(ptr->toNextPtr!=NULL) ptr = ptr->toNextPtr;
00356                 temp = (ANidList *)malloc(sizeof(ANidList));
00357                 if (temp==NULL){
00358                         puts("Error Phy2GetUmtsSync, temp malloc error");
00359                         exit(1);
00360                 }
00361                 temp->id = id;
00362                 temp->toNextPtr = NULL;
00363                 ptr->toNextPtr = temp;
00364         }
00365         return;
00366 }
00367 
00368 
00369 // FUNCTION     Phy2Synchronization
00370 // PURPOSE      tell sync to nodes who want
00371 void Phy2Synchronization(ANid id){
00372 ANidList *ptr;
00373 ANidList *last;
00374 int counter=0;
00375 
00376         ptr = nodesWantSync;
00377         while(ptr!=NULL){
00378                 EventNew(ptr->id, PHY2, UMTS_SLOT_BEGIN, clock, (void *)NULL);
00379                 last = ptr;
00380                 ptr = ptr->toNextPtr;
00381                 free(last);
00382         }
00383         nodesWantSync = NULL;
00384         EventNew(id, PHY2, UMTS_SYNC,clock + UMTS_SLOT_TIME, (void *) NULL);
00385 }
00386 
00387 
00388 void PrintfList(ANid *BSlist, ANtx_power *gainlist){
00389 int i;
00390 
00391         for(i=0; i<AP_MAC2_TOT_NUM;i++)
00392                 printf("( %d, %2.1f)", BSlist[i],gainlist[i]);
00393         printf("\n");
00394 }
00395 
00396 // FUNCTION     Phy2UpdateBS
00397 // PURPOSE      find service BSs set of all user and tell to do contest transfer if necessary
00398 void Phy2HandoverUpdate(ANid id){
00399 PBStruct *PBptr;
00400 ANid *BStemp;
00401 BSStruct *BSptr;
00402 ANid idtemp;
00403 ANtx_power gaintemp;
00404 ANtx_power *BSgainTemp;
00405 double *vectValue;
00406 int i,j,k,dum,counter;
00407 HandoverStruct *HSptr;
00408 
00409 
00410         /* DEBUG OUTPUT (BS active nodes set)
00411         for(j=0;j<AP_MAC2_TOT_NUM;j++){
00412                 BSptr = (BSStruct *)NODEPTR(BSlist[j])->Phy2StructPtr;
00413                 printf("AP %d active set: ",BSlist[j]);
00414                 for(k=1;k<=NODES_NUM;k++)
00415                         if(BSptr->PBarray[k].isInCell==TRUE) printf(" %d",k);
00416                 printf("\n");
00417         }*/
00418         for(i=1; i<=NODES_NUM; i++){
00419                 PBptr = (PBStruct *)NODEPTR(i)->Phy2StructPtr;
00420                 if ((Mac2Available(i)==TRUE) && (NODEPTR(i)->node_type==PAN_BAN)){
00421                         vectValue = (double *)malloc(sizeof(double)*AP_MAC2_TOT_NUM);
00422                         if (vectValue==NULL){
00423                                 puts("Error Phy2UpdateBS, vaectValue malloc error");
00424                                 exit(1);
00425                         }
00426                         for(j=0; j<AP_MAC2_TOT_NUM; j++)
00427                                 vectValue[j] = Phy2ComputeSIR(BSlist[j],i);
00428                         //printf("Nodo %d Generata lista: ",i);
00429                         //PrintfList(BSlist, vectValue);
00430                         if (PBptr->BSlist==NULL){
00431                                 // init procedure -> only copy, not context transfer
00432                                 // ordinate gain vector
00433                                 for(j=0; j<AP_MAC2_TOT_NUM -1; j++)
00434                                         for(k=j; k<AP_MAC2_TOT_NUM; k++)
00435                                                 if (vectValue[j]<vectValue[k]){
00436                                                         gaintemp = vectValue[k];
00437                                                         idtemp = BSlist[k];
00438                                                         vectValue[k] = vectValue[j];
00439                                                         BSlist[k] = BSlist[j];
00440                                                         vectValue[j] = gaintemp;
00441                                                         BSlist[j] = idtemp;
00442                                                 }
00443                                 //printf("Prima volta, ordinata: ");
00444                                 //PrintfList(BSlist,vectValue);
00445                                 BStemp = (ANid *)malloc(sizeof(ANid)*AP_MAC2_TOT_NUM);
00446                                 BSgainTemp = (ANtx_power *)malloc(sizeof(ANtx_power)*AP_MAC2_TOT_NUM);
00447                                 if ((BStemp==NULL)||(BSgainTemp==NULL)){
00448                                         puts("Error Phy2UpdateBs, BStemp BSgainTemp malloc error");
00449                                         exit(1);
00450                                 }
00451                                 for(j=0; j<AP_MAC2_TOT_NUM; j++){
00452                                         BStemp[j] = BSlist[j];
00453                                         BSgainTemp[j] = vectValue[j];
00454                                 }
00455                                 PBptr->BSlist = BStemp;
00456                                 PBptr->BSgain = BSgainTemp;
00457                                 //printf("Nodo %d save BS list:",i);
00458                                 //PrintfList(PBptr->BSlist, PBptr->BSgain);
00459                                 // Update BS structure with node BS active set
00460                                 for(j=0;j<BS_ACTIVE_NUM;j++){
00461                                         BSptr = (BSStruct *)NODEPTR(PBptr->BSlist[j])->Phy2StructPtr;
00462                                         BSptr->PBarray[i].isInCell = TRUE;
00463                                 }
00464                         }else{
00465                                 // update BS list
00466                                 BStemp = (ANid *)malloc(sizeof(ANid)*AP_MAC2_TOT_NUM);
00467                                 if ((BStemp==NULL)||(BSgainTemp==NULL)){
00468                                         puts("Error Phy2UpdateBs, BStemp BSgainTemp malloc error");
00469                                         exit(1);
00470                                 }
00471                                 //printf("Nodo %d old BS list:",i);
00472                                 //PrintfList(PBptr->BSlist, PBptr->BSgain);
00473                                 //printf("Nodo %d new BS list:",i);
00474                                 //PrintfList(BSlist, vectValue);
00475                                 for(j=0;j<AP_MAC2_TOT_NUM;j++){
00476                                         dum = 0;
00477                                         for(k=0;k<AP_MAC2_TOT_NUM;k++)
00478                                                 if ((PBptr->BSlist[k]==BSlist[j])&&(k<BS_ACTIVE_NUM)) {
00479                                                         dum=1;
00480                                                         break;
00481                                                 }
00482                                         if (dum)
00483                                                 // this bs was previously in the bs active set -> add hysteresys threshold to gain
00484                                                 vectValue[j] = vectValue[j] + HANDOVER_TH_DB;
00485                                 }
00486                                 // ordinare il vettore dei guadagni
00487                                 for(j=0; j<AP_MAC2_TOT_NUM -1; j++)
00488                                         for(k=j; k<AP_MAC2_TOT_NUM; k++)
00489                                                 if (vectValue[j]<vectValue[k]){
00490                                                         gaintemp = vectValue[k];
00491                                                         idtemp = BSlist[k];
00492                                                         vectValue[k] = vectValue[j];
00493                                                         BSlist[k] = BSlist[j];
00494                                                         vectValue[j] = gaintemp;
00495                                                         BSlist[j] = idtemp;
00496                                                 }
00497                                 // verificare se necessario context transfert
00498                                 //printf("Nodo %d new BS list:",i);
00499                                 //PrintfList(BSlist, vectValue);
00500                                 counter = 0;
00501                                 for(j=0; j<BS_ACTIVE_NUM; j++){
00502                                         dum = 0;
00503                                         for(k=0; k<BS_ACTIVE_NUM;k++)
00504                                                 if (PBptr->BSlist[j]==BSlist[k]){
00505                                                         dum = 1;
00506                                                         break;
00507                                                 }
00508                                         if (!dum){
00509                                                 // memorizzo le BS uscite dall'active set
00510                                                 BStemp[counter] = PBptr->BSlist[j];
00511                                                 counter++;
00512                                         }
00513                                 }
00514                                 while(counter>0){
00515                                         for(j=0; j<BS_ACTIVE_NUM; j++){
00516                                                 dum = 0;
00517                                                 for(k=0; k<BS_ACTIVE_NUM;k++)
00518                                                         if(BSlist[j]==PBptr->BSlist[k]){
00519                                                                 dum = 1;
00520                                                                 break;
00521                                                         }
00522                                                 if (!dum){
00523                                                         //context transfer fra BStemp[counter-1] e BSlist[j]
00524                                                         HSptr = (HandoverStruct *)malloc(sizeof(HandoverStruct));
00525                                                         HSptr->oldBS = BStemp[counter-1];
00526                                                         HSptr->newBS = BSlist[j];
00527                                                         HSptr->node = i;
00528                                                         EventNew(BSlist[j], MAC2L, CONTEXT_TRANSFER, clock, (void *)HSptr);
00529                                                         //Phy2ContextTransfer(BStemp[counter - 1], BSlist[j], i);
00530 #ifdef debug
00531                                                         printf("Context Transfer nodo %d from AP %d to AP %d\n",i,
00532                                                                 BStemp[counter-1],BSlist[j]);
00533 #endif
00534                                                         // update Bs table after context transfer
00535                                                         BSptr = (BSStruct *)NODEPTR(BStemp[counter - 1])->Phy2StructPtr;
00536                                                         BSptr->PBarray[i].isInCell = FALSE;
00537                                                         BSptr = (BSStruct *)NODEPTR(BSlist[j])->Phy2StructPtr;
00538                                                         BSptr->PBarray[i].isInCell = TRUE;
00539                                                         counter--;
00540                                                 }
00541                                         }
00542                                 }//end while BS to context transfer
00543                                 free(BStemp);
00544                                 // save into node structure new BS list
00545                                 for(j=0; j<AP_MAC2_TOT_NUM; j++)
00546                                         PBptr->BSlist[j] = BSlist[j];
00547                         }// end if PBptr->BSlist==NULL (init or not)
00548                 }// end if node is mac2
00549         }// end for
00550         // generate next update handover event
00551         EventNew(id, PHY2, HANDOVER_UPDATE, clock + ((double)(N_UPDATE_HANDOVER*UMTS_SLOT_TIME)), 
00552                         (void *)NULL);
00553         /*
00554         // DEBUG OUTPUT (BS active nodes set)
00555         for(j=0;j<AP_MAC2_TOT_NUM;j++){
00556                 BSptr = (BSStruct *)NODEPTR(BSlist[j])->Phy2StructPtr;
00557                 printf("AP %d active set: ",BSlist[j]);
00558                 for(k=1;k<=NODES_NUM;k++)
00559                         if(BSptr->PBarray[k].isInCell==TRUE) printf(" %d",k);
00560                 printf("\n");
00561         }*/
00562         return;
00563 }
00564 
00565 // FUNCTION     Phy2Init
00566 // PURPOSE      initialize level paramters and structures
00567 void Phy2Init(){
00568 ANid i,j,k;
00569 BSStruct *BSptr;
00570 PBStruct *PBptr;
00571 PBArrayEl *array;
00572 ANid *AParray;
00573 int counter;
00574 
00575         // Read paramters
00576         if(ReadUInt("BS_ACTIVE_NUM",&(BS_ACTIVE_NUM))==FALSE) {
00577                 puts("UMTS_MacInit: BS_ACTIVE_NUM not defined in configuration file");
00578                 exit(1);
00579         }
00580         AP_MAC2_TOT_NUM = AP_NODES_NUM - AP_NODES_MAC1_NUM;
00581         if (BS_ACTIVE_NUM>AP_MAC2_TOT_NUM){
00582                 puts("Error Phy2Init, BS_ACTIVE_NUM>AP_MAC2_TOT_NUM");
00583                 exit(1);
00584         }
00585         if ((AP_MAC2_TOT_NUM>0)&&(BS_ACTIVE_NUM<=0)){
00586                 puts("Error Phy2Init, there's mac2 node but any BS");
00587                 exit(1);
00588         }
00589         if(ReadUInt("PHY2_SYMBOL_TEST",&(PHY2_SYMBOL_TEST))==FALSE)
00590                 PHY2_SYMBOL_TEST = 1;   // default value (heuristic, every single symbol)
00591         if (PHY2_SYMBOL_TEST < 1){
00592                 puts("Error Phy2Init, PHY2_SYMBOL_TEST must be an integer equal or greater than 1");
00593                 exit(1);
00594         }
00595         printf("PHY2_SYMBOL_TEST = %d\n",PHY2_SYMBOL_TEST);     
00596         nodesWantSync = NULL;
00597         // create an array that contain the id of Access Provider
00598         AParray = (ANid *)malloc(sizeof(ANid)*AP_MAC2_TOT_NUM);
00599         if (AParray==NULL){
00600                 puts("Error Phy2Init, AParray malloc error");
00601                 exit(1);
00602         }
00603         counter = 0;
00604         i = 1;
00605         while ((counter<AP_MAC2_TOT_NUM)&&(i<=NODES_NUM)){
00606                 if ((NODEPTR(i)->node_type==ACCESS_PROVIDER) && (Mac2Available(i)==TRUE) ){
00607                         AParray[counter] = i;
00608                         counter ++;
00609                 }
00610                 i++;
00611         }
00612         if (counter!=AP_MAC2_TOT_NUM){
00613                 puts("Error Phy2Init, doesn't find all the mac2 Access Provider");
00614                 exit(1);
00615         }
00616         BSlist = AParray;
00617 #ifdef debug
00618         printf("Generata lista AP:");
00619         for(i=0; i<AP_MAC2_TOT_NUM; i++)
00620                 printf(" %d",BSlist[i]);
00621         printf("\n");
00622 #endif
00623         // initialize phy2 level structurtes for all nodes
00624         for(i=1; i<=NODES_NUM; i++){
00625                 if (Mac2Available(i)==TRUE){
00626                         switch(NODEPTR(i)->node_type){
00627                         case PAN_BAN:
00628                                 PBptr = (PBStruct *)malloc(sizeof(PBStruct));
00629                                 if (PBptr==NULL){
00630                                         puts("Error Phy2Init, PBptr malloc error");
00631                                         exit(1);
00632                                 }
00633                                 PBptr->TxPkt = NULL;
00634                                 PBptr->state = IDLE;
00635                                 PBptr->subState = PB_IDLE;
00636                                 PBptr->BSlist = NULL;
00637                                 PBptr->BSgain = NULL;
00638                                 PBptr->txPower = POWER_MAX_UP;          // begin with max value
00639                                 PBptr->sf = SF_INIT_VALUE;
00640                                 PBptr->stats.txNo = 0;
00641                                 PBptr->stats.txBits = 0;
00642                                 NODEPTR(i)->Phy2StructPtr = (void *)PBptr;
00643                                 break;
00644                         case ACCESS_PROVIDER:
00645                                 BSptr = (BSStruct *)malloc(sizeof(BSStruct));
00646                                 if (BSptr==NULL){
00647                                         puts("Error Phy2Init, BSptr malloc error");
00648                                         exit(1);
00649                                 }
00650                                 // ne alloco uno in più per semplificare la gestione dell'array, visto che la numerazione
00651                                 // dei nodi va da 1 a NODES_NUM, la mantengo e lascio il primo elemento del vettore "vuoto"
00652                                 array = (PBArrayEl *)malloc(sizeof(PBArrayEl)*(NODES_NUM+1));
00653                                 if (array==NULL){
00654                                         puts("Phy2Init: array malloc error");
00655                                         exit(1);
00656                                 }
00657                                 for(j=1; j<=NODES_NUM;j++){
00658                                         array[j].isInCell = FALSE;
00659                                         array[j].pktInFlyNow = FALSE;
00660                                         array[j].pktInFly = NULL;
00661                                         array[j].bitCount = 0;
00662                                         array[j].currentBlockSize = PHY2_SYMBOL_TEST;
00663                                         array[j].endRxPkt = 0.0;
00664                                         array[j].rxPowLin = 0.0;
00665                                         array[j].contextTransferDuringRx = FALSE;
00666                                         array[j].SIR = 0.0;
00667                                         array[j].distance = Distance(i,j);
00668                                         array[j].propDelay = Channel1PropDelay(i,j);
00669                                 }
00670                                 BSptr->PBarray = array;
00671                                 // init to -1 value for forcing function "Phy2RxPowUpdateUP" in the
00672                                 // first calling (after in this function)
00673                                 BSptr->lastRxPowUpdate = -1.0;
00674                                 BSptr->stats.rxNo = 0;
00675                                 BSptr->stats.rxBits = 0;
00676                                 NODEPTR(i)->Phy2StructPtr = (void *)BSptr;
00677                                 break;
00678                         default:
00679                                 puts("Error Phy2Init, node type not recognized");
00680                                 exit(1);
00681                         }
00682                         
00683                 }
00684         }
00685         /*
00686         // DEBUG OUTPUT
00687         for(i=1; i<=NODES_NUM; i++){
00688                 if (NODEPTR(i)->Phy2StructPtr!=NULL){
00689                         printf("Nodo %d è mac2",i);
00690                         switch (NODEPTR(i)->node_type){
00691                         case PAN_BAN:
00692                                 printf(" PAN BAN\n");
00693                                 break;
00694                         case ACCESS_PROVIDER:
00695                                 printf("ACCESS_PROVIDER\n");
00696                                 BSptr = (BSStruct *)NODEPTR(i)->Phy2StructPtr;
00697                                 for(j=1; j<=NODES_NUM; j++){
00698                                         printf("Dest %d, distanza %f, propDelay %e, rxpowerlin %e ",j,
00699                                                 BSptr->PBarray[j].distance,
00700                                                 BSptr->PBarray[j].propDelay, BSptr->PBarray[j].rxPowLin);
00701                                         if (BSptr->PBarray[j].isInCell==TRUE) printf("IN_CELL\n");
00702                                         else printf("NOT_IN_CELL\n");
00703                                 }
00704                                 break;
00705                         }
00706                 }else printf("Nodo %d non è mac2\n",i);
00707         }
00708         // END DEBUG OUTPUT
00709         */
00710         // ATTENZIONE!!!
00711         // per effettuare l'operazione  UpdateInterNodesRelationship è necessario che 
00712         // il livello CHANNEL1 sia già stato inizializzato
00713         //Phy2UpdateInterNodesRelationship(0);
00714         // generate synchronization periodic event
00715         // eleggo una basestation come generatrice dei sync per tutti (comprese le altre bs),
00716         // come manager dell'handover e del power control
00717         if (AP_MAC2_TOT_NUM>0){
00718 #ifdef debug
00719                 printf("SYNC generato da AP %d\n",AParray[0]);
00720 #endif
00721                 EventNew(AParray[0], PHY2, UMTS_SYNC,clock + UMTS_SLOT_TIME, (void *) NULL);
00722                 EventNew(AParray[0], PHY2, HANDOVER_UPDATE, clock, (void *)NULL);
00723                 EventNew(AParray[0], PHY2, POWER_CONTROL, clock + 
00724                         ((double)(POWER_CONTROL_DELAY*UMTS_SLOT_TIME)), (void *)NULL);
00725         }
00726         return;
00727 }
00728 
00729 
00730 // FUNCTION     Phy2PowerControl
00731 // PURPOSE      manage the power control algorithm for all the user
00732 void Phy2PowerControl(ANid id){
00733 PBStruct *PBptr;
00734 ANid *qptr;
00735 int deltaSum,i,j;
00736 double SIR;
00737 static int count=0;
00738 FILE *fd;
00739 char filename[STRING_MAX_LENGTH];
00740 
00741         Phy2RxPowUpdateUP(0);
00742 #ifdef debug
00743         count++;
00744 #endif
00745         /*if (count==150){
00746                 strcpy(filename,OUT_FILE);
00747                 strcat(filename,"SIRtrace.out");
00748                 fd = fopen(filename,"a");
00749                 fprintf(fd,"%.3f\t",clock);
00750         }*/
00751         for(i=1;i<=NODES_NUM;i++){
00752                 if ((Mac2Available(i)==TRUE) &&(NODEPTR(i)->node_type==PAN_BAN)){
00753                         PBptr = (PBStruct *)NODEPTR(i)->Phy2StructPtr;
00754 #ifdef debug
00755                         if (count==500) printf("POW CONTROL PB %d ",i);
00756 #endif
00757                         deltaSum = 0;
00758                         for(j=0;j<BS_ACTIVE_NUM;j++){
00759                                 if ((SIR=Phy2ComputeSIR(PBptr->BSlist[j],i))>SIR_TARGET_DB)
00760                                         deltaSum--;
00761                                 else deltaSum++;
00762                                 //printf("BS %d SIR %2.2f deltaSum%d ",BSlist[j],SIR,deltaSum);
00763                         }
00764                         if (deltaSum>0){
00765                                 if (PBptr->txPower<POWER_MAX_UP) PBptr->txPower += DELTA;
00766                         }else 
00767                                 if (PBptr->txPower>POWER_MIN_UP) PBptr->txPower -= DELTA;
00768                         //if (deltaSum>0) printf(" (+)");
00769                         //else printf(" (-)");
00770                         //if (count==150) fprintf(fd,"(%4.2f,%4.2f,%3.1f)\t",SIR,Channel1RxPower(i,PBptr->BSlist[0],
00771                         //      PBptr->txPower),PBptr->txPower);
00772 #ifdef debug
00773                         if (count==500) printf(" txPow %2.2f\n",PBptr->txPower);
00774 #endif
00775                 }
00776         }
00777         /*
00778         if(count==150){
00779                 fprintf(fd,"\n");
00780                 fclose(fd);
00781                 count = 0;
00782         }*/
00783         EventNew(id, PHY2, POWER_CONTROL, clock + 
00784                         ((double)(POWER_CONTROL_DELAY*UMTS_SLOT_TIME)), (void *)NULL);
00785 #ifdef debug
00786         if (count==500) count=0;
00787 #endif
00788 }
00789 
00790 // FUNCTION     Phy2UmtsSlotBegin
00791 // PURPOSE      begin the tx of pkt
00792 void Phy2UmtsSlotBegin(ANid id){
00793 PBStruct *temp;
00794 ANid *AParray;
00795 ANpacket *pktDup;
00796 BSStruct *BSptr;
00797 double endTx;
00798 int i;
00799 
00800         temp = (PBStruct *)NODEPTR(id)->Phy2StructPtr;
00801 #ifdef control
00802         if ((temp->state!=TX)||(temp->subState!=WAIT_SYNC)){
00803                 puts("Error Phy2UmtsSlotBegin, uncorrect state");
00804                 exit(1);
00805         }
00806 #endif
00807         // send pkt to all bs
00808 #ifdef debug
00809                 printf("2- Node %d in sending umts pkt %d to all AP time %.10f\n",id, temp->TxPkt->UMTSpktId, clock);
00810 #endif
00811         for(i=0; i<AP_MAC2_TOT_NUM; i++){
00812                 pktDup = PacketDuplicate(temp->TxPkt);
00813                 pktDup->nextHop = temp->BSlist[i];
00814                 BSptr = (BSStruct *)NODEPTR(BSlist[i])->Phy2StructPtr;
00815                 EventNew(temp->BSlist[i], PHY2, BS_RX_UMTS_PKT, clock + 
00816                                 BSptr->PBarray[pktDup->txId].propDelay,(void *)pktDup);
00817         }
00818         endTx = ((double)(pktDup->size))/pktDup->txRate;
00819         EventNew(id, MAC2L, PACKET_TXED, clock + endTx, (void *)NULL);
00820         PacketFree(temp->TxPkt);
00821         temp->TxPkt = NULL;
00822 }
00823 
00824 
00825 // FUNCTION     Phy2PBSendPacket
00826 // PURPOSE      for debug mac 2 level: generate end tx event and randomly nack event
00827 void Phy2PBSendPacket(ANid id){
00828 ANpacket *pktPtr;
00829 PBStruct *temp;
00830 
00831         pktPtr = (ANpacket *)NODEPTR(id)->eventQPtr->extraStructPtr;
00832         temp = (PBStruct *)NODEPTR(id)->Phy2StructPtr;
00833         // set level paramters
00834         temp->state = TX;
00835         temp->subState = WAIT_SYNC;
00836         temp->TxPkt = pktPtr;
00837         // ask for sync
00838         Phy2GetUmtsSync(id);
00839         return;
00840 }
00841 
00842 
00843 // FUNCTION     Phy2SendPacketInfo
00844 // PURPOSE      send pkt info in error free channel (tell to BS that have receive corrupt packet info about these ones)
00845 void Phy2SendPacketInfo(ANid id){
00846 ANpacket *pktPtr;
00847 PBStruct *temp;
00848 ANpacket *pktDup;
00849 int i;
00850 
00851         pktPtr = (ANpacket *)NODEPTR(id)->eventQPtr->extraStructPtr;
00852         temp = (PBStruct *)NODEPTR(id)->Phy2StructPtr;
00853         for(i=0; i<BS_ACTIVE_NUM; i++){
00854                 pktDup = PacketDuplicate(pktPtr);
00855 #ifdef debug
00856                 printf("2- Node %d in sending info abuot umts pkt %d to AP %d, time %.10f\n",id, pktDup->UMTSpktId,
00857                         temp->BSlist[i], clock);
00858 #endif
00859                 pktDup->nextHop = temp->BSlist[i];
00860                 EventNew(temp->BSlist[i], MAC2L, RX_PACKET_INFO, clock ,(void *)pktDup);
00861         }
00862         PacketFree(pktPtr);
00863 }
00864 
00865 // FUNCTION     Phy2EndRxPacket
00866 // PURPOSE
00867 void Phy2EndRxPacket(ANid id){
00868 BSStruct *BSptr;
00869 ANid *sorgPtr;
00870 ANid sorg;
00871 ANpacket *pktRx;
00872 unsigned long int *pktIdptr;
00873 
00874         sorgPtr = (ANid *)NODEPTR(id)->eventQPtr->extraStructPtr;
00875         sorg = *sorgPtr;
00876         free(sorgPtr);
00877         BSptr = (BSStruct *)NODEPTR(id)->Phy2StructPtr;
00878         BSptr->PBarray[sorg].pktInFlyNow = FALSE;
00879         if (BSptr->PBarray[sorg].contextTransferDuringRx==TRUE){
00880                 pktRx = BSptr->PBarray[sorg].pktInFly;
00881                 if (pktRx==NULL)
00882                         printf("BS %d nothing to discared...\n",id);
00883                         // condizione che si verifica nel caso in cui il context transfer avvenga un instante prima
00884                         // della tx, così da trovare già aggiornata la lista delle BS attive
00885                 else {
00886                         printf("BS %d discared pkt %d.%d,%d for context transfer\n",id,pktRx->sourceId,
00887                                 pktRx->packetId,pktRx->UMTSpktId);
00888                         PacketFree(BSptr->PBarray[sorg].pktInFly);
00889                         BSptr->PBarray[sorg].pktInFly = NULL;
00890                 }
00891                 BSptr->PBarray[sorg].contextTransferDuringRx=FALSE;
00892                 return;
00893         }
00894         if (BSptr->PBarray[sorg].pktInFly!=NULL){
00895                 // this BS is receiving this pkt
00896                 pktRx = BSptr->PBarray[sorg].pktInFly;
00897                 pktRx->lastTech = MAC2;
00898                 if (pktRx->fadingErrorNum==0){
00899                         // rx correct
00900                         if (pktRx->nextHop!=id){
00901                                 // pkt not for this BS
00902                                 printf("BS %d rx pkt not for me from %d pkt (%d.%d)\n",id, pktRx->txId,
00903                                         pktRx->sourceId,pktRx->packetId);
00904                                 PacketFree(pktRx);
00905                                 return;
00906                         }
00907                         if (BSptr->PBarray[sorg].isInCell==FALSE){
00908                                 // rx pkt from a node out of BS cell
00909                                 printf("BS %d rx pkt from other cell from %d pkt (%d.%d)\n",id, pktRx->txId,
00910                                         pktRx->sourceId,pktRx->packetId);
00911                                 PacketFree(pktRx);
00912                                 return;
00913                         }
00914                         // pkt for this BS and from a node in its own cell -> update it
00915 #ifdef debug
00916                         printf("BS %d rx pkt pkt %d.%d(%d)\n",id, pktRx->sourceId,
00917                                          pktRx->packetId, pktRx->UMTSpktId);
00918 #endif
00919                         EventNew(id, MAC2L, RX_UMTS_PACKET, clock, (void *)pktRx);
00920                 }else {
00921                         // pkt corrupt
00922                         if ((pktRx->nextHop==id)&&(BSptr->PBarray[sorg].isInCell==TRUE)){
00923                                 // pkt is for this BS ->NACK
00924                                 pktIdptr = (unsigned long int *)malloc(sizeof(unsigned long int));
00925                                 *pktIdptr = pktRx->UMTSpktId;
00926                                 EventNew(pktRx->txId, MAC2L, NACK_ARRIVED, clock + UMTS_RTT_VALUE, (void *)pktIdptr);
00927 #ifdef debug
00928                                 printf("BS %d rx corrupt pkt %d.%d,%d at %.10f\n",id, pktRx->sourceId,
00929                                         pktRx->packetId, pktRx->UMTSpktId, clock);
00930 #endif
00931                         }
00932                         PacketFree(pktRx);
00933                 }
00934                 BSptr->PBarray[sorg].pktInFly = NULL;
00935         }
00936         return;
00937 }
00938 
00939 
00940 // FUNCTION     Phy2TestPktSymbol
00941 // PURPOSE      test current symbol txed from node indicate
00942 void Phy2TestPktSymbol(ANid id){
00943 BSStruct *BSptr;
00944 ANid *sorgPtr;
00945 ANid sorg;
00946 ANtx_power SIR;
00947 ANpacket *pkt;
00948 double random,Pe,PeBlock;
00949 unsigned int error=0;
00950 double endRx,nextTest;
00951  
00952         sorgPtr = (ANid *)NODEPTR(id)->eventQPtr->extraStructPtr;
00953         sorg = *sorgPtr;
00954         BSptr = (BSStruct *)NODEPTR(id)->Phy2StructPtr;
00955         BSptr->PBarray[sorg].bitCount += BSptr->PBarray[sorg].currentBlockSize;
00956         if (BSptr->lastRxPowUpdate+RX_POW_VALID_TIME < clock)
00957                                 Phy2RxPowUpdateUP(id);
00958         SIR = Phy2ComputeSIR(id,sorg);
00959         // Pe : single symbol error probability
00960         Pe = 0.5*erfc(sqrt(pow(SIR,ZETA)));
00961         random = ((float)rand())/((float)RAND_MAX);
00962         if (BSptr->PBarray[sorg].pktInFly==NULL){
00963                 printf("Error Phy2TestPktSymbol, doesn't find pkt to test in structure\n");
00964                 exit(1);
00965         }
00966         if (BSptr->PBarray[sorg].currentBlockSize==1)
00967                 // single symbol test
00968                 error = (random<Pe?1:0);
00969         else{
00970                 // block of symbol test
00971                 PeBlock = 1 - pow(1 - Pe,BSptr->PBarray[sorg].currentBlockSize);
00972                 error = (random<PeBlock?1:0);
00973         }
00974         if (error==1){
00975                 BSptr->PBarray[sorg].pktInFly->fadingErrorNum++;
00976                 endRx = clock + ( ((double)(BSptr->PBarray[sorg].pktInFly->size - BSptr->PBarray[sorg].bitCount)) * 
00977                                 (1/BSptr->PBarray[sorg].pktInFly->txRate) );
00978                 //pkt = BSptr->PBarray[sorg].pktInFly;
00979                 //printf("Node %d errore in pkt %d.%d,%d on bit %d -> now %.10f fine Rx %.10f\n",id,pkt->sourceId,
00980                 //      pkt->packetId,pkt->UMTSpktId,BSptr->PBarray[sorg].bitCount,clock,endRx);
00981                 EventNew(id, PHY2, END_RX_PACKET, endRx, (void *)sorgPtr);
00982                 return;
00983         }
00984         //DEBUG
00985         /*if (error==1)
00986                 printf("#2-BS %d rx pkt %d.%d,%d da %d, SIR %f Pe%f #bit_error %d\n", 
00987                         id,BSptr->PBarray[sorg].pktInFly->sourceId, BSptr->PBarray[sorg].pktInFly->packetId,
00988                         BSptr->PBarray[sorg].pktInFly->UMTSpktId,BSptr->PBarray[sorg].pktInFly->txId,SIR, Pe,
00989                         BSptr->PBarray[sorg].bitCount);
00990         */
00991         if (BSptr->PBarray[sorg].bitCount==BSptr->PBarray[sorg].pktInFly->size){
00992                 // end RX pkt
00993                 EventNew(id, PHY2, END_RX_PACKET, clock, (void *)sorgPtr);
00994                 //printf("BS %d clock %.10f EndRxPkt %.10f, diff %e BitCount %d\n",     id,clock, BSptr->PBarray[sorg].endRxPkt,
00995                 //              clock - BSptr->PBarray[sorg].endRxPkt, BSptr->PBarray[sorg].bitCount);
00996         }else{  // generate next test pkt symbol event
00997                 if (BSptr->PBarray[sorg].currentBlockSize==1)
00998                         // single symbol test mode
00999                         EventNew(id, PHY2, TEST_PKT_SYMBOL, clock + 
01000                                         (1/BSptr->PBarray[sorg].pktInFly->txRate), (void *)sorgPtr);
01001                 else {
01002                         nextTest = Phy2NextBlockSymbolTest(id,BSptr->PBarray[sorg].pktInFly);
01003                         EventNew(id, PHY2, TEST_PKT_SYMBOL, nextTest, (void *)sorgPtr);
01004                         //printf("BS %d clock %.10f next symbol %d at %.10f\n",id,clock,BSptr->PBarray[sorg].bitCount,
01005                         //      clock + (1/BSptr->PBarray[sorg].pktInFly->txRate));
01006                 }
01007         }
01008 }
01009 
01010 
01011 // FUNCTION     Phy2BSRxUmtsPkt
01012 // PURPOSE      begin rx session of BS
01013 void Phy2BSRxUmtsPkt(ANid id){
01014 BSStruct *BSptr;
01015 ANpacket *pktptr;
01016 ANid *sorgPtr;
01017 time endRx;
01018 double nextTest;
01019 
01020 #ifdef control
01021         if ((Mac2Available(i)==FALSE) || (NODEPTR(id)->node_type!=ACCESS_PROVIDER)){
01022                 puts("Error Phy2BSRxUmtsPkt, the node isn't a BS");
01023                 exit(1);
01024         }
01025 #endif
01026         BSptr = (BSStruct *)NODEPTR(id)->Phy2StructPtr;
01027         pktptr = (ANpacket *)NODEPTR(id)->eventQPtr->extraStructPtr;
01028 #ifdef control
01029         if (BSptr->PBarray[pktptr->txId].pktInFlyNow==TRUE){
01030                 puts("Error Phy2BSRxUmtsPkt, BS is receiving two pkt from the same PB");
01031                 exit(1);
01032         }
01033 #endif
01034         pktptr->fadingErrorNum = 0;
01035         if (BSptr->PBarray[pktptr->txId].isInCell==TRUE){
01036                 // the tx node is in BS cell -> have to receive the pkt
01037                 BSptr->PBarray[pktptr->txId].pktInFly = pktptr;
01038                 BSptr->PBarray[pktptr->txId].bitCount = 0;
01039                 BSptr->PBarray[pktptr->txId].currentBlockSize = PHY2_SYMBOL_TEST;
01040                 BSptr->PBarray[pktptr->txId].endRxPkt = clock + ((double)(pktptr->size))/pktptr->txRate;
01041                 // genrate event for testing symbol
01042                 sorgPtr = (ANid *)malloc(sizeof(ANid));
01043                 *sorgPtr = pktptr->txId;
01044                 if (PHY2_SYMBOL_TEST==1)
01045                         EventNew(id, PHY2, TEST_PKT_SYMBOL, clock + (1.0/pktptr->txRate),
01046                                                 (void *)sorgPtr);
01047                 else{
01048                         nextTest = Phy2NextBlockSymbolTest(id,
01049                                                                                         BSptr->PBarray[pktptr->txId].pktInFly);
01050                         EventNew(id, PHY2, TEST_PKT_SYMBOL, nextTest, (void *)sorgPtr);
01051                 }
01052         }else {
01053                 // generate event of end rx pkt
01054                 endRx = ((double)(pktptr->size))/pktptr->txRate;
01055                 sorgPtr = (ANid *)malloc(sizeof(ANid));
01056                 *sorgPtr = pktptr->txId;
01057                 EventNew(id, PHY2, END_RX_PACKET, clock + endRx, (void *)sorgPtr);
01058         }
01059         BSptr->PBarray[pktptr->txId].pktInFlyNow = TRUE;
01060 }
01061 
01062 // FUNCTION     Phy2ContextTransfer
01063 // PURPOSE      message from mac level that say this BS is rx pkt during context transfer 
01064 //                      so have to discared the pkt in rx becuase is the old BS
01065 void Phy2ContextTransfer(ANid id){
01066 BSStruct *BSptr;
01067 ANid *nodePtr;
01068 ANid node;
01069 
01070         BSptr = (BSStruct *)NODEPTR(id)->Phy2StructPtr;
01071         nodePtr = (ANid *)NODEPTR(id)->eventQPtr->extraStructPtr;
01072         node = *nodePtr;
01073         free(nodePtr);
01074         BSptr->PBarray[node].contextTransferDuringRx = TRUE;
01075 }
01076 
01077 
01078 // FUNCTION     Phy2SendSink
01079 // PURPOSE      send SINK pkt on control channel (error free)
01080 void Phy2SendSink(ANid id){
01081 ANpacket *pktPtr;
01082 BSStruct *temp;
01083 ANpacket *pktDup;
01084 int i;
01085 
01086 #ifdef control
01087         if ((Mac2Available(i)==FALSE) || (NODEPTR(id)->node_type!=ACCESS_PROVIDER)){
01088                 puts("Error Phy2SendSink, the node isn't a BS");
01089                 exit(1);
01090         }
01091 #endif
01092         pktPtr = (ANpacket *)NODEPTR(id)->eventQPtr->extraStructPtr;
01093         pktPtr->txId = id;
01094         pktPtr->lastTech = MAC2;
01095         temp = (BSStruct *)NODEPTR(id)->Phy2StructPtr;
01096         for(i=1; i<=NODES_NUM; i++){
01097                 // BS send sink to all terminal in its cell
01098                 if (temp->PBarray[i].isInCell==TRUE){
01099                         pktDup = PacketDuplicate(pktPtr);
01100 #ifdef debug
01101                         printf("2- BS %d in sending SINK pkt %d to PB %d, time %.10f\n",id, pktDup->UMTSpktId,
01102                                 i, clock);
01103 #endif
01104                         pktDup->nextHop = i;
01105                         // send into control channel (errror-free) -> directly to ROUTING
01106                         EventNew(i, ROUTING, NEW_SINK_FOR_ROUTING, clock ,(void *)pktDup);
01107                 }
01108         }
01109         PacketFree(pktPtr);
01110 }
01111 
01112 
01113 
01114 // FUNCTION     Phy2EventHandler
01115 // PURPOSE
01116 void Phy2EventHandler(ANid id) {
01117 // id = 0 for internal level event
01118 if (Mac2Available(id)==TRUE){
01119         switch(NODEPTR(id)->eventQPtr->eventType) {
01120         case PB_SEND_PACKET:
01121 #ifdef debug
01122                 printf("Nodo %d PHY2, event PB_SEND_PACKET time:%.10f\n", id, clock);
01123 #endif
01124                 Phy2PBSendPacket(id);
01125                 break;
01126         case UMTS_SYNC:
01127 #ifdef debug
01128                 //printf("Nodo %d PHY2, event UMTS_SYNC time:%.10f\n", id, clock);
01129 #endif
01130                 Phy2Synchronization(id);
01131                 break;
01132         case UMTS_SLOT_BEGIN:
01133 #ifdef debug
01134                 printf("Nodo %d PHY2, event UMTS_SLOT_BEGIN time:%.10f\n", id, clock);
01135 #endif
01136                 Phy2UmtsSlotBegin(id);
01137                 break;
01138         case BS_RX_UMTS_PKT:
01139 #ifdef debug
01140                 //printf("Nodo %d PHY2, event BS_RX_UMTS_PKT time:%.10f\n", id, clock);
01141 #endif
01142                 Phy2BSRxUmtsPkt(id);
01143                 break;
01144         case TEST_PKT_SYMBOL:
01145 #ifdef debug
01146                 //printf("Nodo %d PHY2, event TEST_PKT_SYMBOL time:%.10f\n", id, clock);
01147 #endif
01148                 Phy2TestPktSymbol(id);
01149                 break;
01150         case END_RX_PACKET:
01151 #ifdef debug
01152                 printf("Nodo %d PHY2, event END_RX_PACKET time:%.10f\n", id, clock);
01153 #endif
01154                 Phy2EndRxPacket(id);
01155                 break;
01156         case HANDOVER_UPDATE:
01157 #ifdef debug
01158                 printf("Nodo %d PHY2, event HANDOVER_UPDATE time:%.10f\n", id, clock);
01159 #endif
01160                 Phy2HandoverUpdate(id);
01161                 break;
01162         case UPDATE_POST_MOBILITY:
01163 #ifdef debug
01164                 //printf("Nodo %d PHY2, event UPDATE_POST_MOBILITY time:%.10f\n", id, clock);
01165 #endif
01166                 Phy2UpdatePostMobility(id);
01167                 break;
01168         case POWER_CONTROL:
01169 #ifdef debug
01170                 printf("Nodo %d PHY2, event POWER_CONTROL time:%.10f\n", id, clock);
01171 #endif
01172                 Phy2PowerControl(id);
01173                 break;
01174                 case SEND_PACKET_INFO:
01175 #ifdef debug
01176                 printf("Nodo %d PHY2, event SEND_PACKET_INFO:%.10f\n", id, clock);
01177 #endif
01178                 Phy2SendPacketInfo(id);
01179                 break;
01180         case CONTEXT_TRANSFER:
01181 #ifdef debug
01182                 printf("Nodo %d PHY2, event CONTEXT_TRANSFER:%.10f\n", id, clock);
01183 #endif
01184                 Phy2ContextTransfer(id);
01185                 break;
01186         case SEND_SINK:
01187 #ifdef debug
01188                 printf("Nodo %d PHY2, event SEND_SINK:%.10f\n", id, clock);
01189 #endif
01190                 Phy2SendSink(id);
01191                 break;
01192         default:
01193                 puts("Error Phy2EventHandler, unreocgnized type of event");
01194                 exit(1);
01195         }// end switch event
01196 }// end if mac_type
01197 }
01198 
01199 
01200 
01201 // FUNCTION     Phy2SARAReadParameters
01202 // PURPOSE      get congetsion state of this BS (ratio between tot rx power at BS, from all its user, 
01203 //                      and acception power threshold)
01204 double Phy2SARAReadParameters(ANid id){
01205 BSStruct *BSptr;
01206 double Beff,Pe,SIR;
01207 int i,howManyInCell;
01208 
01209         if (NODEPTR(id)->node_type!=ACCESS_PROVIDER){
01210                 puts("Error Phy2SARAReadParameters, request node isn't AP");
01211                 exit(1);
01212         }
01213         BSptr = (BSStruct *)NODEPTR(id)->Phy2StructPtr;
01214         // verify if necessary to calculate rx pow
01215         if (BSptr->lastRxPowUpdate+RX_POW_VALID_TIME < clock)
01216                 Phy2RxPowUpdateUP(id);
01217         Beff = 0.0;
01218         howManyInCell = 0;
01219         for (i=1;i<NODES_NUM;i++){
01220                 if ((Mac2Available(i)==TRUE) && (NODEPTR(i)->node_type==PAN_BAN) ){
01221                         if (BSptr->PBarray[i].isInCell==TRUE){
01222                                 howManyInCell++;
01223                                 SIR = Phy2ComputeSIR(id, i);
01224                                 Pe = 0.5*erfc(sqrt(pow(SIR,ZETA)));
01225                                 // datarate is calculate for speading factor init value (now it's the only value assumed)
01226                                 Beff += ((1-Pe)*sf2datarate(SF_INIT_VALUE,UPLINK));
01227                         }// end is in cell
01228                 }//end if mac PB
01229         }//end for
01230         // calculate Mean Effective Bandwidth
01231         Beff = floor(Beff/((double)howManyInCell));
01232         return(Beff);
01233 }
01234 
01235 // FUNCTION     Phy2ReadBs
01236 // PURPOSE              return best BS connetct to this umts node
01237 ANid Phy2ReadBestBs(ANid id){
01238 PBStruct *PBptr;
01239 
01240         PBptr = (PBStruct *)NODEPTR(id)->Phy2StructPtr;
01241         // first BS in list is the one eith the best SIR
01242         return(PBptr->BSlist[0]);
01243 }
01244 
01245 // FUNCTION     Phy2Finalize
01246 // PURPOSE
01247 //
01248 void Phy2Finalize() {
01249 PBStruct *PBptr;
01250 int i;
01251 
01252 #ifdef debug
01253         for(i=1;i<=NODES_NUM;i++){
01254                 if ((Mac2Available(i)==TRUE) && (NODEPTR(i)->node_type==PAN_BAN)){
01255                         PBptr = (PBStruct *)NODEPTR(i)->Phy2StructPtr;
01256                         printf("PB %d has tx power %f\n",i,PBptr->txPower);
01257                 }
01258         }
01259 #endif
01260 }

Generated on Wed Nov 26 15:47:29 2008 for NS-MIRACLE library by  doxygen 1.5.2