00001 00002 // PROYECTO FIN DE CARRERA // 00003 // TITULO: Disenyo de nuevas arquitecturas y algoritmos de gestión de recursos en // 00004 // redes de acceso FiWi // 00005 // AUTOR: Ana Emma Lopez Mato // 00006 // TUTOR: Noemi Merayo Alvarez // 00007 // INGENIERIA TECNICA DE TELECOMUNICACIONES, SISTEMAS DE TELECOMUNICACION // 00008 // UNIVERSIDAD DE VALLADOLID // 00010 00011 #include "ONU_SISTqueue.h" 00012 #include "MAC_OLT.h" 00013 #include "MAC_ONU.h" 00014 #include "GATE_m.h" 00015 #include "REPORT_m.h" 00016 #include "ETHERNET_m.h" 00017 #include "DATA_m.h" 00018 #include "analysis.h" 00019 #include <string.h> 00020 #include <stdio.h> 00021 #include <vector> 00022 #include <math.h> 00023 /* 00024 * MODULO ONU_SISTqueue: 00025 */ 00026 Define_Module(ONU_SISTqueue); 00027 00029 //FUNCION INITIALIZE()--> ESTA FUNCION SE INVOCA DESPUES DE QUE OMNET++ HA PUESTO EN MARCHA LA RED, EN LA CUAL SE LEEN LOS // 00030 // PARAMETROS DEL MODULO Y SE INICIALIZAN TODAS DAS LAS VARIABLES DECLARADAS PARA ESTE MODULO SIMPLE, SE // 00031 // ASIGNAN ESTRUCTURAS DE DATOS DINAMICOS Y SE ASIGNAN E INICIALIZAN LOS AUTOMENSAJES SI SON NECESARIOS // 00032 // PARA EL FUNCIONAMIENTO DE ESTE MODULO. // 00034 void ONU_SISTqueue::initialize() 00035 { 00036 //max_control_admision.resize((int)this->getParentModule()->getParentModule()->getParentModule()->par("numSLA")); 00037 max_control_admision.resize(3); // UNO POR SLA 00038 max_control_admision[0] = 0.015; 00039 max_control_admision[1] = 0.06; 00040 max_control_admision[2] = 0.18; 00041 volcado = 0; 00042 contador = 0; 00043 paquetes_recibidos = 0; 00044 bytes_recibidos = 0; 00045 isGateway = 0; 00046 num_colas = (int) par("numqueue"); 00047 carga_cola = 0.0; 00048 queue.setName("queue"); // DEFINIMOS EL NOMBRE DE LA COLA 00049 // INICIALIZAMOS LAS VARIABLES AL VALOR 0 00050 tamqueuepop = 0; // VARIABLE DEL TAMANYO DE LOS PAQUETES QUE BORRAMOS DE LAS COLAS 00051 tamqueueextract = 0; // VARIABLE DEL TAMANYO DE LOS PAQUETES QUE CHEQUEAMOS ANTES DE SACARLOS DE LAS COLAS 00052 00053 // RESERVAMOS TAMANYO PARA LA VARIABLE tamqueue Y LA INICIALIZAMOS AL VALOR 0 00054 tamqueue.resize(num_colas,0); // VARIABLE DEL TAMANYO DE LOS PAQUETES QUE EXTRAEMOS DE LAS COLAS 00055 total_bytes = 0; 00056 if(this->getParentModule()->getParentModule()->gate("gatewirelessInOut$o",0)->isConnected()) 00057 { 00058 isGateway = 1; 00059 } 00060 int aux_cont = 0; 00061 for(int i=0; i<(int)this->getParentModule()->getParentModule()->par("numOnu"); i++) 00062 { 00063 if(check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getParentModule()->getParentModule()->getSubmodule("onu",i)->getSubmodule("onu_squeue")->getSubmodule("onu_sistqueue",0))->isGateway == 1) 00064 { 00065 aux_cont++; 00066 } 00067 } 00068 indices_gw_onu.resize(aux_cont); 00069 int aux=0; 00070 for(int j=0; j<(int)this->getParentModule()->getParentModule()->par("numOnu"); j++) 00071 { 00072 if(check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getParentModule()->getParentModule()->getSubmodule("onu",j)->getSubmodule("onu_squeue")->getSubmodule("onu_sistqueue",0))->isGateway == 1) 00073 { 00074 indices_gw_onu[aux] = j; 00075 aux++; 00076 } 00077 } 00078 //ev <<" Indices de las ONUs pasarela: "; 00079 for(int a=0; a<(int)indices_gw_onu.size(); a++) 00080 { 00081 //ev <<indices_gw_onu[a] << " "; 00082 } 00083 //ev <<endl; 00084 aux_counter = 0; 00085 full_onus_gw = 0; 00086 //double buffer = (double) this->getParentModule()->getParentModule()->par("tambuffer"); 00088 } 00089 00091 //FUNCION HANDLEMESSAGE(CMESSAGE *MSG)--> ESTA FUNCION SE INVOCA CON EL MENSAJE COMO PARAMETRO CADA VEZ QUE EL MODULO RECIBE UN // 00092 // UN MENSAJE O PAQUETE. SE RECORRE EL CODIGO IMPLEMENTADO PARA DEVOLVER UN VALOR O // 00093 // EJECUTAR UNA FUNCION DENTRO DEL MODULO SIMPLE. EL TIEMPO DE SIMULACION NO TRANSCURRE // 00094 // DENTRO DE LA LLAMADA DE LA FUNCION HANDLEMESSAGE(CMESSAGE *MSG) MIENTRAS RECORRE EL // 00095 // CODIGO IMPLEMENTADO. // 00097 void ONU_SISTqueue::handleMessage(cMessage *msg) 00098 { 00099 // VARIABLES 00100 int type = msg->getKind(); // VARIABLE TYPE PARA IDENTIFICAR LOS MENSAJES DE LA RED 00101 int admision = 0; // Variable para el control de admision en el caso de DaSPID 00102 double tx_rate, bit_rate, time_creation, hops, meters; 00103 // ESTRUCTURA CONDICIONAL SWITCH QUE NOS DIFERENCIA LOS MENSAJES QUE LLEGUEN A ESTE MODULO 00104 switch(type) 00105 { 00106 case 1: 00107 // LLEGA UN PAQUETE ETHERNET CON IDENTIFICADOR = 1 00108 if(type==1) 00109 { 00110 ETHERNETmsg *ethernetmsg = check_and_cast<ETHERNETmsg*>(msg); // CHEQUEAMOS EL PAQUETE ETHERNET 00111 int olt_method = (int) this->getParentModule()->getParentModule()->getParentModule()->par("oltmethod_Centralized0_Polling1_wdm2_PollingPID3_DaSPID4"); 00113 if(olt_method == 4 && ethernetmsg->getPriority() == 1) 00114 { 00115 // Acceso remoto a la cola P0 de esta misma ONU para obtener el numero de Bytes que almacena: 00116 ONU_SISTqueue *cola_onu; 00117 cola_onu = check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getSubmodule("onu_sistqueue",0)); 00118 // Suma de los bits presentes en las colas P0 y P1 de esta ONU para saber cuantos bits tiene por delante 00119 // el paquete recibido y estimar lo que le va a tocar esperar hasta ser transmitido: 00120 double bits_antes = (double) 8*cola_onu->tamqueue[0] + (double) 8*tamqueue[1]; 00121 //ev <<" Bits previstos para enviar antes que este nuevo paquete: " << bits_antes << endl; 00122 // Acceso remoto a la capa MAC de esta ONU para obtener el B_alloc que le fue asignado en el ultimo ciclo y 00123 // el intervalo de tiempo entre las dos ultimas transmisiones de esta ONU: 00124 MAC_ONU *onu_mac; 00125 onu_mac = check_and_cast<MAC_ONU *>(this->getParentModule()->getParentModule()->getSubmodule("onu_mac")); 00126 double B_alloc_ultimo = (double) onu_mac->B_alloc_prev; 00127 //ev <<" BW asignado en el ultimo ciclo a esta ONU: " << B_alloc_ultimo << endl; 00128 double T_ciclo_ultimo = (double) onu_mac->T_cycle_prev; 00129 //ev <<" Duracion del ultimo ciclo de transmision de esta ONU: " << T_ciclo_ultimo << endl; 00130 double delay_estimado = (double) T_ciclo_ultimo*(bits_antes/B_alloc_ultimo); 00131 //ev <<" Retardo estimado para este paquete de clase P1: " << delay_estimado << endl; 00132 00133 //ev << " ONU[" << this->getParentModule()->getParentModule()->getIndex() << "] --> SLA" << onu_mac->numsla_onu[this->getParentModule()->getParentModule()->getIndex()] << endl; 00134 MAC_OLT *olt_mac; 00135 olt_mac = check_and_cast<MAC_OLT *>(this->getParentModule()->getParentModule()->getParentModule()->getSubmodule("olt")->getSubmodule("olt_mac")); 00136 olt_mac->paquetes_recibidos_P1[onu_mac->numsla_onu[this->getParentModule()->getParentModule()->getIndex()]]++; 00137 if(delay_estimado < max_control_admision[onu_mac->numsla_onu[this->getParentModule()->getParentModule()->getIndex()]]) 00138 { 00139 admision = 0; // Bloqueo += 0.0; 00140 } 00141 else 00142 { 00143 admision = 1; // Bloqueo += 1.0; 00144 olt_mac->paquetes_borrados_P1[onu_mac->numsla_onu[this->getParentModule()->getParentModule()->getIndex()]]++; 00145 } 00146 //ev <<" ONU[" << this->getParentModule()->getParentModule()->getIndex() << "] asociada al SLA"<< onu_mac->numsla_onu[this->getParentModule()->getParentModule()->getIndex()] << ", cuyo limite de retardo es " << max_control_admision[onu_mac->numsla_onu[this->getParentModule()->getParentModule()->getIndex()]] << endl; 00147 if(admision == 0) 00148 { 00149 //ev<<" Envio del paquete 'Ethernet' a la cola P1. "<< endl; 00150 paquetes_recibidos++; 00151 bytes_recibidos = bytes_recibidos + (double) ethernetmsg->getByteLength(); 00152 tx_rate = (double) this->par("txrate"); 00153 bit_rate = tx_rate/10; 00154 time_creation = (double) SIMTIME_DBL(simTime()); 00155 carga_cola = (double) (bytes_recibidos * 8 / (time_creation * bit_rate)); 00156 carga.analyze(carga_cola); 00157 // SUMAMOS EL TAMANYO DE LOS PAQUETES QUE INSERTAMOS EN LAS COLAS 00158 tamqueue[ethernetmsg->getPriority()] = tamqueue[ethernetmsg->getPriority()] + ethernetmsg->getByteLength(); 00159 // VEMOS EL TIEMPO EN EL QUE EL PAQUETE ETHERNET SE INSERTA EN LA COLA PARA DESPU�S CALCULAR EL RETARDO 00160 // INTRODUCIMOS EN EL PAQUETE ETHERNET EL TIEMPO EN EL QUE EL PAQUETE SE INSERTA EN LA COLA 00161 ethernetmsg->setTime_enter_queue(simTime()); 00162 //ev<<" Tiempo de insercion del paquete Ethernet en cola: "<<ethernetmsg->getTime_enter_queue()<<endl; 00163 queue.insert(ethernetmsg); // INSERTAMOS EL PAQUETE EN LA COLA QUE NOS INDIQUE LA PRIORIDAD DEL PAQUETE ETHERNET 00164 } 00165 else if(admision == 1) 00166 { 00167 delete ethernetmsg; 00168 //ev <<" Borrado del paquete 'Ethernet' de clase P1 por superar las expectativas de retardo maximo." << endl; 00169 } 00170 } 00171 else 00172 { 00174 paquetes_recibidos++; 00175 bytes_recibidos = bytes_recibidos + (double) ethernetmsg->getByteLength(); 00176 tx_rate = (double) this->par("txrate"); 00177 bit_rate = tx_rate/10; 00178 time_creation = (double) SIMTIME_DBL(simTime()); 00179 carga_cola = (double) (bytes_recibidos * 8 / (time_creation * bit_rate)); 00180 carga.analyze(carga_cola); 00181 // SUMAMOS EL TAMANYO DE LOS PAQUETES QUE INSERTAMOS EN LAS COLAS 00182 tamqueue[ethernetmsg->getPriority()] = tamqueue[ethernetmsg->getPriority()] + ethernetmsg->getByteLength(); 00183 // VEMOS EL TIEMPO EN EL QUE EL PAQUETE ETHERNET SE INSERTA EN LA COLA PARA DESPU�S CALCULAR EL RETARDO 00184 // INTRODUCIMOS EN EL PAQUETE ETHERNET EL TIEMPO EN EL QUE EL PAQUETE SE INSERTA EN LA COLA 00185 ethernetmsg->setTime_enter_queue(simTime()); 00186 //ev<<" Tiempo de insercion del paquete Ethernet en cola: "<<ethernetmsg->getTime_enter_queue()<<endl; 00187 queue.insert(ethernetmsg); // INSERTAMOS EL PAQUETE EN LA COLA QUE NOS INDIQUE LA PRIORIDAD DEL PAQUETE ETHERNET 00188 } 00189 } 00190 break; 00191 00192 case 2: 00193 // LLEGA UN PAQUETE REPORT CON IDENTIFICADOR = 2 00194 if(type==2) 00195 { 00196 REPORTmsg *reportmsg=check_and_cast<REPORTmsg*>(msg); // CHEQUEAMOS EL PAQUETE REPORT 00197 // ENVIAMOS EL PAQUETE REPORT HACIA EL MODULO ONU_WDMSPLITTER Y VISUALIZAMOS POR PANTALLA CUANDO LO MANDAMOS 00198 //send(reportmsg, "onuqueuewdmOut", reportmsg->getPriority()); 00199 send(reportmsg, "onuqueuewdmOut"); 00201 } 00202 break; 00203 00204 case 12: 00205 if(type==12) 00206 { 00207 // Conversion del mensaje de tipo inalambrico a optico: 00208 ETHERNETmsg *msgethernet = check_and_cast<ETHERNETmsg*>(WirelessToOptical(msg)); 00209 paquetes_recibidos++; 00210 // Variable con el total de paquetes llegados a todas las ONUs pasarela: 00211 check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getParentModule()->getParentModule()->getSubmodule("onu",15)->getSubmodule("onu_squeue")->getSubmodule("onu_sistqueue",0))->paquetes_recibidos++; 00212 //long total_paquetes = (long)check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getParentModule()->getParentModule()->getSubmodule("onu",15)->getSubmodule("onu_squeue")->getSubmodule("onu_sistqueue",0))->paquetes_recibidos; 00213 bytes_recibidos = bytes_recibidos + (double) msgethernet->getByteLength(); 00214 delay_packets = simTime() - msgethernet->getTimestamp(); 00215 //ev <<" Retardo paquete wireless: " << delay_packets << endl; 00216 retardo.analyze(SIMTIME_DBL(delay_packets)); 00217 check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getParentModule()->getParentModule()->getSubmodule("onu",15)->getSubmodule("onu_squeue")->getSubmodule("onu_sistqueue",0))->retardo.analyze(SIMTIME_DBL(delay_packets)); 00218 /* 00219 tx_rate = (double) this->par("txrate"); 00220 //tx_rate = (double) this->par("tasabinaria"); 00221 bit_rate = tx_rate/10; 00222 time_creation = (double) SIMTIME_DBL(msgethernet->getTimestamp()); 00223 carga_cola = (double) (bytes_recibidos * 8 / (time_creation * bit_rate)); 00224 carga.analyze(carga_cola); 00225 */ 00226 hops = (double) msgethernet->getRelleno(); 00227 //ev <<" Nodos intermedios (BSs) por los que ha pasado el paquete: " << hops << endl; 00228 meters = (double) msgethernet->getLength(); 00229 //ev <<" Distancia (metros) recorrida por el paquete: " << meters << endl; 00230 saltos.analyze(hops); 00231 longitud.analyze(meters); 00232 insertPacket(msgethernet); 00233 //delete msgethernet; 00234 //ev <<" ******* " << endl; 00235 //ev <<" Total paquetes recibidos: " << paquetes_recibidos << endl; 00236 /* 00237 // PARA PARAR LA SIMULACION CUANDO LLEGAN 100000 PAQUETES EN TOTAL A LAS ONUs PASARELA: 00238 if(total_paquetes >= 100000) // Si han llegado 100000 paquetes en total a todas las ONUs pasarela... 00239 { 00240 endSimulation(); // LLAMAMOS A LA FUNCION TERMINAR SIMULACION 00241 callFinish(); // LLAMAMOS A LA FUNCION FINALIZAR 00242 } 00243 */ 00244 /* 00245 // PARA PARAR LA SIMULACION CUANDO LLEGAN 100000 PAQUETES A CADA ONU PASARELA DE LA RED: 00246 if(paquetes_recibidos>=100000 && aux_counter==0) 00247 { 00248 aux_counter = 1; 00249 check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getParentModule()->getParentModule()->getSubmodule("onu",15)->getSubmodule("onu_squeue")->getSubmodule("onu_sistqueue",0))->full_onus_gw++; 00250 } 00251 if(check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getParentModule()->getParentModule()->getSubmodule("onu",15)->getSubmodule("onu_squeue")->getSubmodule("onu_sistqueue",0))->full_onus_gw == (int)indices_gw_onu.size()) // Si han llegado 100000 paquetes en total a todas las ONUs pasarela... 00252 { 00253 endSimulation(); // LLAMAMOS A LA FUNCION TERMINAR SIMULACION 00254 callFinish(); // LLAMAMOS A LA FUNCION FINALIZAR 00255 } 00256 */ 00257 /* 00258 if (simTime()>=10*contador && volcado == 0) 00259 { 00260 contador++; 00261 //volcadoFicheros(); 00262 // SE PONE LA RUTA DONDE SE VAN A CREAR LOS ARCHIVOS 00263 carga_colas = fopen("results/carga_colas.txt", "a+"); // ABRIMOS EL ARCHIVO EN EL QUE GUARDAREMOS LOS RESULTADOS 00264 if(getIndex() == 0) // En la primera cola de cada ONU, se imprime esta cabecera: 00265 { 00266 if(isGateway == 1) 00267 { 00268 fprintf(carga_colas,"ONU [%i] (pasarela)\n", this->getParentModule()->getParentModule()->getIndex()); 00269 } 00270 else if(isGateway == 0) 00271 { 00272 fprintf(carga_colas,"ONU [%i] (NO pasarela)\n", this->getParentModule()->getParentModule()->getIndex()); 00273 } 00274 } 00275 if(getIndex() != num_colas) // La ultima cola es para los REPORT, no cuenta 00276 { 00277 fprintf(carga_colas,"Carga total de la cola P%i: %g \n", getIndex(), (double)carga.average()); 00278 } 00279 fclose(carga_colas); // CERRAMOS EL ARCHIVO EN EL QUE GUARDAMOS LOS DATOS 00280 } 00281 */ 00282 } 00283 break; 00284 00285 default: 00286 delete msg; 00287 //ev <<" MENSAJE BORRADO" << endl; 00288 break; 00289 } 00290 } 00291 00293 //FUNCION DELETEELEMENT(CMESSAGE *MSG)--> ESTA FUNCION SE INVOCA CON EL MENSAJE COMO PARAMETRO CADA VEZ QUE EL MODULO // 00294 // ONU_GENTraffic GENERA UN PAQUETE ETHERNET Y TIENE QUE INSERTARLO EN LA COLA Y NO HAY TANYANO SUFICIENTE PARA // 00295 // HACERLO Y TENEMOS QUE ELIMINAR MENSAJES ANTIGUOS PARA INSERTAR EL NUEVO PAQUETE CREADO. // 00296 // ESTA FUNCION EXTRAE UN PAQUETE QUE SE ENCONTRABA YA EN LA COLA Y LO ELIMINA, PERO ANTES OBTENEMOS EL // 00297 // TAMANYO DEL PAQUETE ETHERNET ELIMINADO PARA RESTARLO DEL TAMANYO TOTAL DE BYTES QUE TIENE ALMACENADO LA COLA // 00299 void ONU_SISTqueue::deleteelement(cMessage *msg) 00300 { 00301 // FUNCION PARA ELIMINAR LOS PAQUETES DEL PRINCIPIO DE LAS COLAS 00302 00303 ETHERNETmsg *ethernetmsg=check_and_cast<ETHERNETmsg*>(msg); // CHEQUEAMOS EL PAQUETE ETHERNET 00304 00305 ethernetmsg = (ETHERNETmsg *)queue.pop(); // EXTRAEMOS EL PAQUETE ETHERNET 00306 tamqueuepop = ethernetmsg->getByteLength(); // TAMANYO DEL PAQUETE ETHERNET EXTRAIDO DE LA COLA 00307 00308 // RESTAMOS AL TAMANYO DE LA COLAS EL TAMANYO DEL PAQUETE QUE SE BORRA PARA PODER INSERTAR UN PAQUETE MAS ACTUAL 00309 tamqueue[ethernetmsg->getPriority()] = tamqueue[ethernetmsg->getPriority()] - tamqueuepop; 00310 delete ethernetmsg; // BORRAMOS EL PAQUETE ETHERNET 00312 } 00313 00315 //FUNCION CHECKPACKET()--> ESTA FUNCION SE INVOCA CADA VEZ QUE EL MODULO ONU_Rx_Report RECIBE UN PAQUETE REPORT. DE ESTA MANERA // 00316 // PODEMOS AVERIGUAR EL TAMANYO DEL PRIMER PAQUETE DE LA COLA SIN NECESIDAD DE EXTRAER EL PAQUETE ENCOLADO. // 00317 // PARA OBTENER ESTA INFROMACION, ENTRAMOS EN LA COLA Y MEDIANTE LA FUNCION front() OBTENEMOS EL TAMANYO DEL // 00318 // PAQUETE QUE SE ENCUENTRA AL PRINCIPIO DE LA COLA Y LO INTRODUCIMOS EN UNA VARIABLE. // 00320 void ONU_SISTqueue::checkpacket() 00321 { 00322 // FUNCION PARA CHUEQUEAR LOS PAQUETES DEL PRINCIPIO DE LA COLA PARA SABER SU TAMANYO EN BYTES 00323 00324 ETHERNETmsg *ethernetmsg; // DEFINIMOS LA VARIABLE PARA EL PAQUETE ETHERNET 00325 ethernetmsg = (ETHERNETmsg *)queue.front(); // OBTENEMOS INFORMACION DEL PRIMER PAQUETE ETHERNET DE LA COLA SIN EXTRAERLO 00326 tamqueueextract = ethernetmsg->getByteLength(); // TAMANYO DEL PRIMER PAQUETE ETHERNET DE LA COLA SIN EXTRAERLO 00327 } 00328 00330 //FUNCION EXTRACTIONELEMENT(int priority)--> ESTA FUNCION SE INVOCA CON LA PRIORIDAD DEL PAQUETE COMO PARAMETRO CADA VEZ QUE EL // 00331 // MODULO ONU_Rx_Report RECIBE UN PAQUETE REPORT. DE ESTA MANERA PODEMOS EXTRAER EL PRIMER PAQUETE DE LA COLA Y// 00332 // ENVIARLE HACIA EL OLT. // 00333 // PRIMERAMENTE EXTRAEMOS EL PRIMER PAQUETE DE LA COLA CON LA FUNCION pop() Y METEMOS SU TAMANYO EN UNA VARIABLE// 00334 // PARA POSTERIORMENTE ACTUALIZAR EL TAMANYO DE LA COLA UNA VEZ SACADOS LOS PAQUETES PERTINENTES. DESPU�S LOS // 00335 // ENVIAMOS HACIA EL OLT POR LA SALIDA DEL MODULO ONU_Rx_Report CORRESPONDIENTE. // 00337 void ONU_SISTqueue::extractionelement(int priority) 00338 { 00339 // FUNCION PARA EXTRAER LOS PAQUETES DEL PRINCIPIO DE LAS COLAS 00340 00341 ETHERNETmsg *ethernetmsg; // DEFINIMOS LA VARIABLE PARA EL PAQUETE ETHERNET 00342 take(ethernetmsg = (ETHERNETmsg *)queue.pop()); // EXTRAEMOS EL PRIMER PAQUETE QUE SE ENCUENTRA EN EL INICIO DE LA COLA 00343 tamextract = ethernetmsg->getByteLength(); // TAMANYO DEL PRIMER PAQUETE QUE SE ENCUENTRA EN EL INICIO DE LA COLA 00344 00345 // RESTAMOS EL TAMANYO DEL PAQUETE QUE OBTUVIMOS EN LA FUNCION DE CHEQUEAR LOS PAQUETES AL TAMANYO DE LA COLA EN LA QUE EXTRAIGAMOS EL PAQUETE ETHERNET 00346 tamqueue[priority] = tamqueue[priority] - tamqueueextract; 00347 00348 if(ethernetmsg->getIsWireless()==1) 00349 { 00350 //<<" Envio de paquete Ethernet de origen inalambrico al modulo 'ONU_WDMSplitter'"<<endl; 00351 } 00352 // ENVIAMOS EL PAQUETE ETHERNET HACIA EL MODULO ONU_WDMSPLITTER 00353 send(ethernetmsg, "onuqueuewdmOut"); 00354 } 00355 00357 //FUNCION WIRELESSTOOPTICAL(cMessage *msg)--> TRADUCE LA PDU (Packet Data User) DEL ESTANDAR IEEE 802.11b EN UNA PDU DEL ESTANDAR EPON. // 00359 ETHERNETmsg* ONU_SISTqueue::WirelessToOptical(cMessage *msg) 00360 { 00361 /* Conversion mensajes wireless en mensajes Ethernet */ 00362 DATA *msjdatos = check_and_cast<DATA*>(msg); 00363 00364 //ev <<" Mensaje recibido -> Ruta seguida: " << msjdatos->getUserOrigin() << " | "; 00365 for(int y = 0; y < (int)msjdatos->getRutaArraySize(); y++) 00366 { 00367 //ev <<msjdatos->getRuta(y) << " | "; 00368 } 00369 //ev <<endl; 00370 00371 ETHERNETmsg *msgethernet = new ETHERNETmsg("Ethernet",1); 00372 // Indice de esta ONU: 00373 msgethernet->setSrcAddress(msjdatos->getDestAddress()); 00374 // Destino --> El OLT (num. direccion 9): 00375 msgethernet->setDestAddress(9); 00376 // Longitud (en Bytes) del mensaje: 00377 msgethernet->setByteLength(msjdatos->getByteLength()); 00378 // Prioridad del mensaje: 00379 msgethernet->setPriority(msjdatos->getPriority()); 00380 // Id. de servicio del mensaje: 00381 msgethernet->setId_servicio(msjdatos->getPriority()); 00382 // Longitud de onda por la que van los mensajes en la red EPON: 00383 msgethernet->setLambdaethernet(0); 00384 // Longitud (en metros) recorrida por el mensaje en la parte wireless: 00385 msgethernet->setLength(msjdatos->getMetros()); 00386 // Numero de nodos intermedios wireless por los que ha pasado el mensaje: 00387 msgethernet->setRelleno(msjdatos->getSaltos()); 00388 // Sello temporal de la creacion del mensaje wireless: 00389 msgethernet->setTimestamp(msjdatos->getTimestamp()); 00390 // Nombre completo del usuario wireless generador del mensaje inicial: 00391 //msgethernet->setAnotherField(msjdatos->getUserOrigin()); 00392 // Es un mensaje de origen inalambrico (isWireless = 1): 00393 msgethernet->setIsWireless(1); 00394 // Nombre completo de la ONU que reenvia al OLT este mensaje: 00395 msgethernet->setOrigen(msjdatos->getDestino()); 00396 delete msjdatos; 00397 return msgethernet; 00398 } 00399 00401 //FUNCION INSERTPACKET(cMessage *msg)--> INSERTA EN LA COLA DE ESTE MODULO EL PAQUETE ETHERNET PROCEDENTE DE LA PARTE INALAMBRICA // 00402 // DE LA RED SI HAY ESPACIO DISPONIBLE. EN CASO CONTRARIO, LO ELIMINA. LA INSERCION SE REALIZA// 00403 // SEGUN EL CRITERIO ELEGIDO EN OMNETPP.INI (PRIORIDAD O SEPARADO). // 00405 void ONU_SISTqueue::insertPacket(cMessage *msg) 00406 { 00407 ETHERNETmsg *msgethernet=check_and_cast<ETHERNETmsg*>(msg); 00408 double buffer = (double) this->getParentModule()->getParentModule()->par("tambuffer"); 00409 int metodo_insercion = (int)this->getParentModule()->getParentModule()->par("insercionmethod_separatequeue0_priorityqueue1"); 00410 switch(metodo_insercion) 00411 { 00412 case 0: // Metodo de Insercion de Paquetes de Colas Separadas 00413 buffer = buffer/num_colas; 00414 // SUMAMOS LA LONGITUD (BYTES) DE LOS PAQUETES QUE INSERTAMOS EN LAS COLAS: 00415 tamqueue[msgethernet->getPriority()] = tamqueue[msgethernet->getPriority()] + msgethernet->getByteLength(); 00416 if (buffer >= tamqueue[msgethernet->getPriority()]) 00417 { 00418 // INTRODUCIMOS EN EL PAQUETE ETHERNET EL TIEMPO DE INSERCION EN COLA PARA DESPUES CALCULAR EL RETARDO: 00419 msgethernet->setTime_enter_queue(simTime()); 00420 //ev<<" Tiempo de insercion del paquete Ethernet en cola: "<<ethernetmsg->getTime_enter_queue()<<endl; 00421 queue.insert(msgethernet); // INSERTAMOS EL PAQUETE EN LA COLA 00422 //ev <<" Insercion en cola de la ONU pasarela el paquete Ethernet transformado" << endl; 00423 } 00424 else if (buffer < tamqueue[msgethernet->getPriority()]) 00425 { 00426 tamqueue[msgethernet->getPriority()] = tamqueue[msgethernet->getPriority()] - msgethernet->getByteLength(); 00427 delete msgethernet; 00428 //ev <<" Borrado del paquete Ethernet transformado porque no cabe en la cola de la ONU" << endl; 00429 } 00430 break; 00431 case 1: // Metodo de Insercion de Paquetes de Prioridad de Colas 00432 ONU_SISTqueue *cola_onu; 00433 double bloqueo; 00434 total_bytes = 0; 00435 for (int i=0; i<num_colas; i++) 00436 { 00437 if(this->getIndex()!=i) 00438 { 00439 cola_onu = check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getSubmodule("onu_sistqueue",i)); 00440 total_bytes = total_bytes + cola_onu->tamqueue[i]; 00441 } 00442 else 00443 { 00444 total_bytes = total_bytes + tamqueue[getIndex()]; 00445 } 00446 } 00447 total_bytes = total_bytes + msgethernet->getByteLength(); 00448 if (buffer >= total_bytes) 00449 { 00450 tamqueue[msgethernet->getPriority()] = tamqueue[msgethernet->getPriority()] + msgethernet->getByteLength(); 00451 // INTRODUCIMOS EN EL PAQUETE ETHERNET EL TIEMPO DE INSERCION EN COLA PARA DESPUES CALCULAR EL RETARDO: 00452 msgethernet->setTime_enter_queue(simTime()); 00453 //ev<<" Tiempo de insercion del paquete Ethernet en cola: "<<ethernetmsg->getTime_enter_queue()<<endl; 00454 queue.insert(msgethernet); // INSERTAMOS EL PAQUETE EN LA COLA 00455 //ev <<" Insercion en cola de la ONU pasarela el paquete Ethernet transformado" << endl; 00456 } 00457 else if (buffer < total_bytes) 00458 { 00459 // Recorremos todas las colas, de menor a mayor prioridad, para borrar alguno de sus paquetes previos y dejar sitio al nuevo: 00460 int i = num_colas-1, fuera = -1; 00461 while(i>=0 && fuera < 0) 00462 { 00463 if(this->getIndex()!=i) 00464 { 00465 cola_onu = check_and_cast<ONU_SISTqueue *>(this->getParentModule()->getSubmodule("onu_sistqueue",i)); 00466 } 00467 else 00468 { 00469 cola_onu = this; 00470 } 00471 // Si el nuevo paquete es de la misma prioridad que la de la cola que se esta checkeando 00472 // (en principio, la mas baja), se borra directamente: 00473 if(msgethernet->getPriority() == i) 00474 { 00475 //ev <<" MENSAJE BORRADO (Id." << msgethernet->getId() << ")" << endl; 00476 // Resta de los bytes del paquete borrado a la suma total de todas las colas: 00477 total_bytes = total_bytes - msgethernet->getByteLength(); 00478 bloqueo = 1.0; //BORRADO PAQUETE 00479 delete msgethernet; // BORRADO DEL PAQUETE 'msgethernet' 00480 // Salida del bucle que recorre las colas 00481 fuera = 1; 00482 } 00483 // Si el nuevo paquete es de mayor prioridad que la de la cola que se esta checkeando 00484 // Y esta cola NO esta vacia, se borran paquetes suyos hasta poder meter el nuevo: 00485 else if(msgethernet->getPriority()<i && cola_onu->queue.getLength()>0) 00486 { 00487 int salir = -1; 00488 // Recorremos todos los paquetes de esta cola, desde el mas antiguo: 00489 while (cola_onu->queue.getLength()>0 && salir < 0) 00490 { 00491 // Llamada a la funcion del modulo 'bs_queue' para borrar el primer paquete de la cola: 00492 cola_onu->deleteelement(msgethernet); 00493 // Resta de los bytes del paquete extraido a la variable 'tamqueuepop': 00494 total_bytes = total_bytes - cola_onu->tamqueuepop; 00495 // Si hay espacio suficiente en cola para insertar el nuevo paquete... 00496 if(buffer >= total_bytes) 00497 { 00498 tamqueue[msgethernet->getPriority()] = tamqueue[msgethernet->getPriority()] + msgethernet->getByteLength(); 00499 // INTRODUCIMOS EN EL PAQUETE ETHERNET EL TIEMPO DE INSERCION EN COLA PARA DESPUES CALCULAR EL RETARDO: 00500 msgethernet->setTime_enter_queue(simTime()); 00501 //ev<<" Tiempo de insercion del paquete Ethernet en cola: "<<ethernetmsg->getTime_enter_queue()<<endl; 00502 queue.insert(msgethernet); // INSERTAMOS EL PAQUETE EN LA COLA 00503 //ev <<" Insercion en cola de la ONU pasarela el paquete Ethernet transformado" << endl; 00504 salir = 1; 00505 fuera = 1; 00506 bloqueo=0.0; 00507 } 00508 // Si NO hay espacio suficiente en cola para insertar el nuevo paquete... 00509 else if(buffer < total_bytes){} // Pasamos a la siguiente iteracion 00510 } 00511 if(buffer > total_bytes) 00512 { 00513 // Salida del bucle que recorre todas las colas 00514 fuera = 1; 00515 } 00516 } 00517 else if(msgethernet->getPriority() < i && cola_onu->queue.getLength()==0) 00518 { 00520 } 00521 i--; 00522 } 00523 } 00524 break; 00525 } 00526 } 00527 00529 //FUNCION VOLCADOFICHEROS()--> ESCRIBE EN UNO O VARIOS FICHEROS DE TEXTO LOS DATOS DE MAYOR INTERES DE LA / 00530 // SIMULACION, PARA SU POSTERIOR ANALISIS. / 00532 void ONU_SISTqueue::volcadoFicheros() 00533 { 00534 //volcado = 1; 00535 /* 00536 carga_colas = fopen("results/carga_colas.txt", "a+"); 00537 if(getIndex() == 0) // En la primera cola de cada ONU, se imprime esta cabecera: 00538 { 00539 fprintf(carga_colas,"Carga de ONU [%i] (pasarela)\n", this->getParentModule()->getParentModule()->getIndex()); 00540 if(isGateway == 1) 00541 { 00542 fprintf(carga_colas,"ONU [%i] (pasarela)\n", this->getParentModule()->getParentModule()->getIndex()); 00543 } 00544 else if(isGateway == 0) 00545 { 00546 fprintf(carga_colas,"ONU [%i] (NO pasarela)\n", this->getParentModule()->getParentModule()->getIndex()); 00547 } 00548 } 00549 if(getIndex() != num_colas) // La ultima cola es para los REPORT, no cuenta 00550 { 00551 fprintf(carga_colas,"Carga total de la cola P%i: %g \n", getIndex(), (double)carga_cola); 00552 //fprintf(carga_colas,"Carga total de la cola P%i: %g \n", getIndex(), (double)carga.average()); 00553 } 00554 fclose(carga_colas); 00555 */ 00556 00557 int indiceOnu = this->getParentModule()->getParentModule()->getIndex(); 00558 00559 if(getIndex() != num_colas && isGateway == 1) 00560 { 00561 // 'BYTES_RECIBIDOS_ONU': FICHERO CON EL NUMERO DE PAQUETES Y DE BYTES RECIBIDOS EN CADA COLA DE CADA ONU PASARELA. 00562 bytes_recibidos_onu = fopen("results/bytes_recibidos_onu.txt", "a+"); 00563 fprintf(bytes_recibidos_onu,"ONU [%i] (pasarela)\n", this->getParentModule()->getParentModule()->getIndex()); 00564 fprintf(bytes_recibidos_onu,"\t Cola P%i - Paquetes recibidos en total: %g\n",(int)getIndex(),(double) paquetes_recibidos); 00565 fprintf(bytes_recibidos_onu,"\t Cola P%i - Bytes recibidos en total: %g\n",(int)getIndex(),(double) bytes_recibidos); 00566 fclose(bytes_recibidos_onu); 00567 00568 // 'RETARDO_RED_WIRELESS': FICHERO CON EL RETARDO DE LOS PAQUETES RECIBIDOS EN CADA COLA DE CADA ONU PASARELA, 00569 // MAS EL RETARDO MEDIO ENTRE TODOS LOS PAQUETES LLEGADOS A TODAS LAS ONUS PASARELA (DATO 00570 // INCLUIDO DESDE EL MODULO ONU[15].BS_QUEUE[0]). 00571 retardo_red_wireless = fopen("results/retardo_red_wireless.txt", "a+"); 00572 if(getIndex() == 0) // En la primera cola de cada ONU, se imprime esta cabecera: 00573 { 00574 fprintf(retardo_red_wireless,"ONU [%i] (pasarela)\n", indiceOnu); 00575 } 00576 fprintf(retardo_red_wireless, "\tRetardo wireless P%i: %g\n", getIndex(), (double)retardo.average()); 00577 fclose(retardo_red_wireless); 00578 00579 // 'MEDIA_LONGITUD_SALTOS_WIRELESS': FICHERO CON EL NUMERO MEDIO DE SALTOS Y DE LONGITUD RECORRIDOS POR CADA PAQUETE 00580 // WIRELESS RECIBIDO EN CADA COLA DE CADA ONU PASARELA. 00581 media_longitud_saltos_wireless = fopen("results/media_longitud_saltos_wireless.txt", "a+"); 00582 if(getIndex() == 0) // En la primera cola de cada ONU, se imprime esta cabecera: 00583 { 00584 fprintf(media_longitud_saltos_wireless,"ONU [%i]\n", this->getParentModule()->getParentModule()->getIndex()); 00585 } 00586 fprintf(media_longitud_saltos_wireless,"\t Cola P%i - Media saltos paquetes wireless: %g\n",(int)getIndex(),(double) saltos.average()); 00587 fprintf(media_longitud_saltos_wireless,"\t Cola P%i - Media longitud recorrida: %g\n",(int)getIndex(),(double) longitud.average()); 00588 fclose(media_longitud_saltos_wireless); 00589 } 00590 00591 if(indiceOnu == 15 && getIndex()==0) 00592 { 00593 retardo_red_wireless = fopen("results/retardo_red_wireless.txt", "a+"); 00594 fprintf(retardo_red_wireless, "\tTOTAL: %g\n", (double)retardo.average()); 00595 fclose(retardo_red_wireless); 00596 } 00597 } 00598 00600 //FUNCION FINISH()--> ESTA FUNCION SE INVOCA CUANDO LA SIMULACION HA TERMINADO CON EXITO SIN QUE SE PRODUZCA NINGUN ERROR. // 00601 // LO USAMOS PARA LA RECOGIDA DE ESTADASTICAS Y VISUALIZACION POR PANTALLA O MEDIANTE UN ARCHIVO. // 00603 void ONU_SISTqueue::finish() 00604 { 00605 ev <<" Total Paquetes Recibidos: " << paquetes_recibidos << endl; 00606 volcadoFicheros(); 00607 }