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 <omnetpp.h> 00012 #include <vector> 00013 #include <time.h> 00014 #include <string.h> 00015 #include "BS_rx_tx.h" 00016 #include "BS_table.h" 00017 #include "BS_queue.h" 00018 #include "BS_mac.h" 00019 #include "LSA_m.h" 00020 #include "DATA_m.h" 00021 /* 00022 * MODULO BS_rx_tx: 00023 * Recibe los mensajes procedentes de modulos externos (usuarios/BSs) para enviarlos al 00024 * submodulo BS_queue correspondiente, asi como envia hacia el modulo externo pertinente 00025 * los mensajes de los submodulos BS_queue. 00026 */ 00027 Define_Module(BS_rx_tx); 00028 00030 //FUNCION INITIALIZE()--> ESTA FUNCION SE INVOCA DESPUES DE QUE OMNET++ HA PUESTO EN MARCHA LA RED, EN LA CUAL SE LEEN LOS // 00031 // PARIMETROS DEL MODULO Y SE INICIALIZAN TODAS DAS LAS VARIABLES DECLARADAS PARA ESTE MODULO SIMPLE, SE // 00032 // ASIGNAN ESTRUCTURAS DE DATOS DINIMICOS Y SE ASIGNAN E INICIALIZAN LOS AUTOMENSAJES SI SON NECESARIOS // 00033 // PARA EL FUNCIONAMIENTO DE ESTE MODULO. // 00035 void BS_rx_tx::initialize() 00036 { 00037 // INICIALIZACION DE LAS VARIABLES: 00038 indice_esta_bs = (int)this->getParentModule()->par("indice"); 00039 //indice_esta_bs = (int)this->getParentModule()->getIndex(); /////// CAMBIO_RED /////// 00040 retardo_mensaje = 0; // Retardo con el que llega cada paquete a este modulo 00041 umbral_retardo = 0.025; // En el paper de DARA, se fija el retardo maximo de un paquete en 25ms. 00042 paquetes_borrados_dara = 0; // Acumula el numero de paquetes borrados por superar el umbral de retardo al implementar DARA 00043 aux_counter = 0; // Variable auxiliar para seguir la llegada de 100000 paquetes a cada BS 00044 full_bs_queues = 0; // Acumula el numero de BSs que ya han recibido 100000 paquetes (util para parar la simulacion cuando han llegado 100000 paquetes a todas las BSs, o a las BSs pasarela) 00045 paquetes_recibidos = 0; // Acumula el total de paquetes recibidos por esta BS 00046 bytes_recibidos = 0; // Acumula el total de bytes recibidos por esta BS 00047 tx_rate = (double) this->getParentModule()->par("tasabinaria"); // Tasa de transmision de la BS 00048 BSs = (int) par("numBS"); // Numero de BSs de la red 00049 pasarelas = (int) par("numGW"); // Numero de BSs-pasarela 00050 prioridades = (int) this->getParentModule()->par("numcolas"); // Numero de prioridades en el trafico inalambrico 00051 control = check_and_cast<BS_mac *>(getParentModule()->getSubmodule("bs_mac")); // Acceso remoto al modulo BS_mac de esta BS 00052 mean_link_load = 0.0; // Media de la carga de recpecion de paquetes de cada enlace (normalizada a la capacidad de enlace) 00053 mean_alt_link_load = 0.0; // Media de la carga de recepcion de paquetes de enlace (normalizada a la tasa binaria) 00054 mean_node_load = 0.0; // Media de la carga de transmision de paquetes de cada enlace (normalizada a la capacidad de enlace) 00055 mean_alt_node_load = 0.0; // Media de la carga de transmision de paquetes de cada enlace (normalizada a la tasa binaria) 00056 00058 // Se incluyen en la topologia los nodos que contienen el parametro 'aux' (Users, BSs y ONUs): 00059 top.extractByParameter("aux"); 00060 // Si esta bien, debe ser: t.getNumNodes() = numBS+numOnu 00061 // Se define como nodo del grafo la BS a la que pertenece esta cola: 00062 nodeOut = top.getNodeFor(getParentModule()); 00063 if(strcmp(nodeOut->getLinkOut(1)->getRemoteNode()->getModule()->getName(),"onu")==0) 00064 { 00065 esPasarela=1; 00066 } 00067 else 00068 { 00069 esPasarela=0; 00070 } 00071 links = (int)nodeOut->getNumOutLinks(); // Total de enlaces salientes de esta BS 00072 bs_links = links-1; 00073 if(esPasarela == 1) 00074 { 00075 // Si esta BS es una pasarela, al numero conexiones con otras BSs hay que restarle el numero de conexiones con la ONU pasarela 00076 // (tantas como prioridades) para que represente realmente el numero de BSs con las que conecta la pasarela 00077 bs_links = bs_links-prioridades; 00078 // Si esta es una BS pasarela, la tasa de transmision de paquetes hacia la ONU pasarela es la de un enlace optico: 00079 tx_rate = (double) this->getParentModule()->par("txrate"); 00080 tx_rate = tx_rate/10; // 100 Mbps, como las ONUs 00081 } 00082 00083 // Impresion por pantalla de las conexiones salientes de esta BS: 00084 //ev << " Numero de enlaces salientes de este nodo: "<< links << endl; 00085 //ev << " De los cuales conectan con otras BSs: "<< bs_links << endl; 00086 /*for(int a=0; a<links; a++) 00087 { 00088 ev << " Enlace: " << a 00089 << " --> Puerta interna: " << nodeOut->getLinkOut(a)->getLocalGate()->getOwnerModule()->gate(nodeOut->getLinkOut(a)->getLocalGate()->getName(),nodeOut->getLinkOut(a)->getLocalGate()->getIndex())->getPreviousGate()->getFullName() 00090 << " --> Puerta externa: " << nodeOut->getLinkOut(a)->getLocalGate()->getFullName() 00091 << " --> Puerta remota externa: " << nodeOut->getLinkOut(a)->getRemoteGate()->getFullName() 00092 << " --> Nodo: " << nodeOut->getLinkOut(a)->getRemoteNode()->getModule()->getFullName() << endl; 00093 }*/ 00094 total_enlaces = 0; // Numero total de enlaces entre BSs de la red (el valor autentico de esta variable es e lque se obtiene al inicializar la ultima BS, por eso al hacer finish se da ese valor obtenido por la ultima BS a todas las demas) 00095 for(int i=0; i<BSs; i++) 00096 { 00097 total_enlaces = total_enlaces + check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[i])->getSubmodule("bs_rx_tx"))->bs_links; 00098 //total_enlaces = total_enlaces + check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule("bs",i)->getSubmodule("bs_rx_tx"))->bs_links; /////// CAMBIO_RED /////// 00099 } 00101 00102 /* 00103 //ev << " Numero de nodos de la topologia: " << top.getNumNodes() << endl; 00104 for(int b=0; b<(int)top.getNumNodes(); b++) 00105 { 00106 //ev << " Nodo de indice " << b << " en la topologia: " << top.getNode(b)->getModule()->getFullName() << endl; 00107 } 00108 */ 00109 // REDIMENSIONAMIENTO DE LOS VECTORES: 00110 retardo_medio.resize(links); // Retardo medio de cada enlace de esta BS 00111 arrived_packets.resize(links, 0); // Paquetes recibidos por cada enlace de esta BS (se resetea en cada periodo LSA para recalcular la tasa de llegadas en cada periodo) 00112 arrived_bytes.resize(links, 0); // Bytes recibidos por cada enlace de esta BS (sirve para calcular la carga de los enlaces al hacer finish) 00113 sent_packets.resize(links, 0); // Paquetes enviados por cada enlace de esta BS 00114 sent_bytes.resize(links, 0); // Bytes enviados por cada enlace de esta BS (sirve para calcular la carga de los enlaces al hacer finish) 00115 link_load.resize(links, 0); // Carga de rx de paquetes de cada enlace de esta BS, normalizada a la capacidad de enlace 00116 alt_link_load.resize(links, 0); // Carga de rx de paquetes de cada enlace de esta BS, normalizada a la tasa de transmision 00117 node_load.resize(links, 0); // Carga de rx de paquetes de cada enlace de esta BS, normalizada a la capacidad de enlace 00118 alt_node_load.resize(links, 0); // Carga de rx de paquetes de cada enlace de esta BS, normalizada a la tasa de transmision 00119 int long_paq = (int) this->getParentModule()->par("longitud_media_paquete"); 00120 int bits_paquete = 8*long_paq; 00121 service_rate = (double) 1/bits_paquete; // Tasa de servicio de los nodos 00122 effective_capacity = (double)tx_rate/bs_links; // Capacidad efectiva (capacidad de canal entre enlaces salientes a otras BSs) 00125 00126 // SEGUN EL CRITERIO DE ENCAMINAMIENTO ELEGIDO EN OMNETPP.INI... 00127 int criterio = (int)this->getParentModule()->par("criterio"); 00128 if(criterio == 1) // SI SE CONSIDERA CAMINO OPTIMO EL DE MENOR RETARDO (DARA): 00129 { 00130 packet_intensity.resize(links, 0); 00131 previous_estimated_lambda.resize(links, 0); 00132 aux_samples.resize(links,0); 00133 //gateway_arrival_rate.resize(pasarelas,0); 00134 estimated_lambda = 0; 00135 00136 // Envio de automensaje para crear el primer LSA: 00137 LSA_period = (simtime_t) 7.5; // Periodos entre LSAs recogidos en el paper: 7.5s, 15s, 30s, 60s. 00138 ev << " Periodo entre envios de LSAs: " << SIMTIME_DBL(LSA_period) << endl; 00139 cMessage *msg = new cMessage ("Creacion LSA",3); 00140 scheduleAt(LSA_period,msg); 00141 contador_LSAs = 0; 00142 prev_LSAs = 0; 00143 } 00144 } 00145 00147 //FUNCION HANDLEMESSAGE(CMESSAGE *MSG)--> ESTA FUNCION SE INVOCA CON EL MENSAJE COMO PARAMETRO CADA VEZ QUE EL MODULO RECIBE UN // 00148 // UN MENSAJE O PAQUETE. SE RECORRE EL CODIGO IMPLEMENTADO PARA DEVOLVER UN VALOR O // 00149 // EJECUTAR UNA FUNCION DENTRO DEL MODULO SIMPLE. EL TIEMPO DE SIMULACION NO TRANSCURRE // 00150 // DENTRO DE LA LLAMADA DE LA FUNCION HANDLEMESSAGE(CMESSAGE *MSG) MIENTRAS RECORRE EL // 00151 // CODIGO IMPLEMENTADO. // // 00153 void BS_rx_tx::handleMessage(cMessage *msg) 00154 { 00155 int type = msg->getKind(); 00156 switch(type) 00157 { 00158 case 3: 00159 // LLEGA UN AUTOMENSAJE QUE INDICA UN NUEVO ENVIO DE LSA, CON IDENTIFICADOR = 3 00160 if(type==3) 00161 { 00162 // PASOS A SEGUIR: 00163 // 1. Se calculan los parametros a meter en el LSA (con la funcion 'calculate_weight_params()'). 00164 // 2. Se crea el LSA y se insertan los datos. 00165 // 3. Se envía el LSA por todas las puertas conectadas con BSs. 00166 //ev << " Total mensajes LSA recibidos en el periodo anterior: " << prev_LSAs << endl; 00167 // 1: 00168 int first_link_index = links - bs_links; 00169 for(int i=first_link_index; i<links; i++) // Se descuentan los enlaces que no son entre BSs. 00170 { 00171 if(strpbrk(nodeOut->getLinkOut(i)->getRemoteNode()->getModule()->getFullName(),"b")!=NULL) 00172 { 00173 calculate_weight_params(i); 00174 } 00175 } 00176 /* 00177 // Si esta BS es una pasarela, calculo lambda_j (tasa de llegadas de paquetes a la pasarela j): 00178 // NOTA: Enlace pasarela -> 1 (el primero es para el usuario asociado) 00179 if(strcmp(nodeOut->getLinkOut(1)->getRemoteNode()->getModule()->getName(),"onu")==0) 00180 { 00181 gateway_arrival_rate[indice_esta_bs] = packet_intensity[1]; 00182 } 00183 // NOTA: En el paper de DARA, lambda_j es la tasa de llegadas a la ONU pasarela (downstream) 00184 */ 00185 // 2: 00186 LSA *advertisement = new LSA("Link_State_Advertisement",9); 00187 advertisement->setSrcAddress(indice_esta_bs); 00188 advertisement->setSrcName(this->getParentModule()->getFullName()); 00189 advertisement->setNum_links(links); 00190 advertisement->setRemote_gatesArraySize(links); 00191 advertisement->setRemote_nodesArraySize(links); 00192 advertisement->setArrival_rateArraySize(links); 00193 advertisement->setRcvd_pcktsArraySize(links); 00194 advertisement->setLink_loadArraySize(links); 00195 advertisement->setEffective_link_capacity((double)control->eff_cap); // eff_cap; // 00196 advertisement->setService_rate((double)service_rate); 00197 advertisement->setTimestamp(simTime()); 00198 for(int i=0; i<links; i++) 00199 { 00200 advertisement->setRemote_nodes(i,nodeOut->getLinkOut(i)->getRemoteNode()->getModule()->getFullName()); 00201 advertisement->setRemote_gates(i,(int)nodeOut->getLinkOut(i)->getRemoteGate()->getIndex()); 00202 // NOTA: Si el extremo remoto es un usuario, la puerta es unica, y el indice que devuelve es 0. 00203 advertisement->setArrival_rate(i,(double)packet_intensity[i]); 00204 advertisement->setLink_load(i,(double)link_load[i]); 00205 advertisement->setRcvd_pckts(i,arrived_packets[i]); 00206 } 00207 // VACIAMOS LOS VECTORES CADA PERIODO LSA: 00208 packet_intensity.clear(); 00209 link_load.clear(); 00210 arrived_packets.clear(); 00211 00212 // 3: 00213 for(int i=first_link_index; i<links; i++) 00214 { 00215 //if(strpbrk(advertisement->getRemote_nodes(i),"b")!=NULL){ 00216 //ev << " Envio LSA al nodo " << advertisement->getRemote_nodes(i) << endl; //ev-comentar 00218 LSA *nuevo = check_and_cast<LSA *>(advertisement->dup()); 00219 send(nuevo,nodeOut->getLinkOut(i)->getLocalGate()->getOwnerModule()->gate(nodeOut->getLinkOut(i)->getLocalGate()->getName(),nodeOut->getLinkOut(i)->getLocalGate()->getIndex())->getPreviousGate()); 00220 //} 00221 } 00222 scheduleAt(simTime()+LSA_period, msg); 00223 delete advertisement; 00224 } 00225 break; 00226 00227 case 9: 00228 // LLEGA UN LSA DE OTRO NODO, CON IDENTIFICADOR = 9 00229 if(type==9) 00230 { 00231 if(esPasarela == 0) 00232 { 00233 contador_LSAs++; 00234 //ev << " Mensajes LSA recibidos hasta el momento en este periodo: " << contador_LSAs << endl; 00235 // PASOS A SEGUIR: 00236 // 1. Se extraen los parametros del enlace por el que ha entrado el LSA (únicamente). 00237 // 2. Se calcula el peso de ese enlace. 00238 // 3. Se actualiza el retardo del canal asociado a ese enlace, con el peso. 00239 // 4. Se actualiza la tabla de retardos de cada ruta y el vector de retardos totales. 00240 // 5. Se actualiza la tabla de rutas optimas para cada usuario. 00241 00242 // 1: 00243 LSA *anuncio = check_and_cast<LSA*>(msg); 00244 //ev << " Longitud del mensaje LSA: " << anuncio->getByteLength() << " Bytes." << endl; 00245 // Busqueda del indice del enlace en el sentido Emisor_LSA-->Receptor_LSA: 00246 int indice=-1; 00247 for(int i=1; i<(int)anuncio->getNum_links(); i++) 00248 { 00250 if(strcmp(anuncio->getRemote_nodes(i),this->getParentModule()->getFullName())==0) 00251 { 00252 indice = i; 00253 } 00254 } 00255 // Busqueda del indice del enlace en el sentido Receptor_LSA-->Emisor_LSA: 00256 int index=-1; 00257 for(int i=1; i<links; i++) 00258 { 00259 char* name = (char*) nodeOut->getLinkOut(i)->getRemoteNode()->getModule()->getFullName(); 00261 if(strcmp(name,anuncio->getSrcName())==0) 00262 { 00263 index = i; 00264 } 00265 } 00266 // 2-3: 00267 if(indice!=-1) 00268 { 00269 calculate_delay_weight(indice, index, anuncio); 00270 } 00271 // ¡OJO! Como los dos siguientes pasos pueden suponer mucha carga computacional, 00272 // realizarlos solo cuando llega el ultimo LSA esperado. 00273 if(contador_LSAs==bs_links) 00274 { 00275 check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule("bs0")->getSubmodule("bs_mac"))->nodos_actualizados++; 00276 //check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule("bs",0)->getSubmodule("bs_mac"))->nodos_actualizados++; /////// CAMBIO_RED /////// 00277 int nodos = BSs - pasarelas; 00278 BS_mac *control_aux; 00279 if(check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule("bs0")->getSubmodule("bs_mac"))->nodos_actualizados == nodos) 00280 //if(check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule("bs",0)->getSubmodule("bs_mac"))->nodos_actualizados == nodos) /////// CAMBIO_RED /////// 00281 { 00282 for(int n=0; n<BSs; n++) 00283 { 00284 control_aux = check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[n])->getSubmodule("bs_mac")); 00285 //control_aux = check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule("bs",n)->getSubmodule("bs_mac")); /////// CAMBIO_RED /////// 00286 // 4: 00287 control_aux->relleno_arrays_retardos(); 00288 for(int i=0; i<(int)par("numUser"); i++) 00289 { 00290 // 5: 00291 control_aux->recalculo_ruta_delay_aware(i); 00292 } 00293 } 00294 check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule("bs0")->getSubmodule("bs_mac"))->nodos_actualizados = 0; 00295 //check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule("bs",0)->getSubmodule("bs_mac"))->nodos_actualizados = 0; /////// CAMBIO_RED /////// 00296 } 00297 prev_LSAs = contador_LSAs; 00298 contador_LSAs = 0; 00299 } 00300 } 00301 // Si es pasarela, como no necesita enviar trafico a otras BSs, lo del encaminamiento wireless le da un poco igual, 00302 // asi que borra los LSAs que recibe (pero es importante que los reciba, y que los envie) 00303 else if(esPasarela == 1) 00304 { 00305 delete msg; 00306 } 00307 } 00308 break; 00309 00310 case 12: 00311 // LLEGA UN PAQUETE 'DATA' CON IDENTIFICADOR = 12 00312 if(type==12) 00313 { 00314 DATA *msjdatos = check_and_cast<DATA*>(msg); 00315 cModule *destino; 00316 if(simTime() >= 200) // SI LLEVAMOS 200s DE SIMULACION... 00317 { 00318 endSimulation(); // LLAMAMOS A LA FUNCION TERMINAR SIMULACION 00319 callFinish(); // LLAMAMOS A LA FUNCION FINALIZAR 00320 } 00321 // Si esta BS que recibe el paquete es una pasarela, este se borra (o se envia a la ONU pasarela, segun se configure la red), 00322 // previo calculo y almacenamiento de informacion referente al nuevo paquete: 00323 if(esPasarela == 1) 00324 { 00325 // Si el mensaje viene de uno de los modulos BS_queue[] de esta BS, hacia el exterior: 00326 if(strcmp(msjdatos->getOrigen(),this->getParentModule()->getFullName())==0) 00327 { 00328 msjdatos->setTime_exit_bs(simTime()); 00329 //ev << " Envio de paquete inalambrico, de prioridad P" << msjdatos->getPriority() << " e Id." << msjdatos->getId() << endl; 00330 //ev << " Longitud del mensaje: " << msjdatos->getByteLength() << "B" << endl; 00331 00332 simtime_t retardo = simTime() - msjdatos->getTimestamp(); 00333 retardo_mensaje = SIMTIME_DBL(retardo); 00334 //ev << " Retardo del mensaje destinado al nodo " << msjdatos->getDestino() << ": " << retardo_mensaje << "s" << endl; 00335 simtime_t d_queue = simTime() - msjdatos->getTime_enter_queue(); 00336 //ev << " Retardo de encolamiento: " << d_queue << "s" << endl; 00337 00338 double hops = (double) msjdatos->getSaltos(); 00339 saltos.analyze(hops); 00340 double meters = (double) msjdatos->getMetros(); 00341 longitud.analyze(meters); 00342 00343 //int link = get_index_link(1); 00344 int link = 1; 00345 sent_packets[link]++; 00347 sent_bytes[link] = sent_bytes[link] + msjdatos->getByteLength(); 00348 // Conexion directa con la ONU: 00349 destino = (cModule*) nodeOut->getLinkOut(1)->getRemoteNode()->getModule(); 00350 //delete msjdatos; // BORRADO DEL PAQUETE 00351 00352 // Envio del paquete al modulo rx/tx,considerando el retardo de transmision: 00353 double datarate = (double) msjdatos->getByteLength()*8/tx_rate; // CALCULAMOS EL PARAMETRO datarate QUE INDICA LA TASA DE TRANSMISION DEL PAQUETE INALAMBRICO 00354 simtime_t tasa = (simtime_t)datarate; 00355 control->timepacket = control->timepacket + tasa; 00356 //ev << " Retardo de transmision: " << control->timepacket << "s" << endl; 00357 int puerta = 1 + msjdatos->getPriority(); // IMPORTANTISIMO SI numcolas > 1 00358 sendDelayed(msjdatos, control->timepacket, "bsRxTx$o", puerta); 00359 // NOTA: Tal como esta configurada la red en el fichero *.ned, el enlace de indice 1 00360 // de toda BS pasarela conecta con la cola de prioridad P0 de la ONU pasarela asociada. 00361 // Ahora bien, si el numero de clases de servicio en la parte inalambrica es mayor que 1, 00362 // hay que asegurarse de que el trafico se envia a la cola adecuada de la ONU: 00363 // Si msjdatos tiene prioridad Pn, la BS pasarela ha de enviarlo al modulo ON_SISTqueue[n], 00364 // con el que coencta por la puerta 1+n. 00365 00366 /* 00367 double tiempo_slot = (double) check_and_cast<BS_queue *>(msjdatos->getSenderGate()->getOwnerModule())->t_slot; 00368 int ind_cola = (int) check_and_cast<BS_queue *>(msjdatos->getSenderGate()->getOwnerModule())->used_index; 00369 double offset = (double) tiempo_slot*ind_cola; 00370 offset_time = (simtime_t) offset; 00371 //ev << " Retardo de slot: " << offset_time << "s" << endl; 00372 control->slot_tx_delay[ind_cola] = control->slot_tx_delay[ind_cola] + tasa; 00373 //ev << " Retardo de transmision: " << control->slot_tx_delay[ind_cola] << "s" << endl; 00374 sendDelayed(msjdatos, offset_time + control->slot_tx_delay[ind_cola], "bsRxTx$o", 1); 00375 */ 00376 } 00377 // Si el mensaje viene de fuera, hacia alguno de los modulos BS_queue[] de esta BS: 00378 else if(strcmp(msjdatos->getOrigen(),this->getParentModule()->getFullName())!=0) 00379 { 00380 paquetes_recibidos++; 00381 bytes_recibidos = bytes_recibidos + msjdatos->getByteLength(); 00382 //ev << " Paquetes recibidos en esta BS: " << paquetes_recibidos << endl; 00383 /* 00384 // PARA PARAR LA SIMULACION CUANDO LLEGAN 100000 PAQUETES A CADA UNA DE LAS BSs PASARELA: 00385 if(paquetes_recibidos>=100000 && aux_counter==0) 00386 { 00387 aux_counter = 1; 00388 full_bs_queues = 1; 00389 } 00390 double total_paquetes = 0; 00391 for(int i=0; i<(int)control->indices_pasarelas.size(); i++) 00392 { 00393 total_paquetes = total_paquetes + check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[control->indices_pasarelas[i]])->getSubmodule("bs_rx_tx"))->full_bs_queues; 00394 } 00395 if(total_paquetes == (int)control->indices_pasarelas.size()) 00396 { 00397 endSimulation(); // LLAMAMOS A LA FUNCION TERMINAR SIMULACION 00398 callFinish(); // LLAMAMOS A LA FUNCION FINALIZAR 00399 } 00400 */ 00401 /* 00402 // PARA PARAR LA SIMULACION CUANDO LLEGAN 100000 PAQUETES A LA BS PASARELA 'bs7' 00403 // (CUANDO SOLO SE GENERAN PAQUETES ENTRE bs0 Y bs7, ruta de mayor retardo): 00404 if(indice_esta_bs==5 && paquetes_recibidos>=100000) 00405 { 00406 endSimulation(); // LLAMAMOS A LA FUNCION TERMINAR SIMULACION 00407 callFinish(); // LLAMAMOS A LA FUNCION FINALIZAR 00408 } 00409 */ 00410 /* 00411 // PARA PARAR LA SIMULACION CUANDO LLEGAN 100000 PAQUETES A CADA UNA DE LAS BSs DE LA RED: 00412 if(paquetes_recibidos >=100000 && aux_counter==0) 00413 { 00414 aux_counter=1; 00415 full_bs_queues = 1; 00416 } 00417 double total_paquetes = 0; 00418 for(int i=0; i<BSs; i++) 00419 { 00420 total_paquetes = total_paquetes + check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[i])->getSubmodule("bs_rx_tx"))->full_bs_queues; 00421 } 00422 if(total_paquetes == BSs) 00423 { 00424 endSimulation(); // LLAMAMOS A LA FUNCION TERMINAR SIMULACION 00425 callFinish(); // LLAMAMOS A LA FUNCION FINALIZAR 00426 }*/ 00427 /* 00428 // PARA PARAR LA SIMULACION CUANDO LLEGAN 100000 PAQUETES EN TOTAL A LAS BSs PASARELA: 00429 double total_paquetes = 0; 00430 for(int i=0; i<(int)control->indices_pasarelas.size(); i++) 00431 { 00432 total_paquetes = total_paquetes + check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[control->indices_pasarelas[i]])->getSubmodule("bs_rx_tx"))->paquetes_recibidos; 00433 } 00434 */ 00435 //ev << " Recepcion de un paquete inalambrico, de prioridad P" << msjdatos->getPriority() << endl; 00436 simtime_t retardo = simTime() - msjdatos->getTimestamp(); 00437 retardo_mensaje = SIMTIME_DBL(retardo); 00438 //ev << " Retardo total del mensaje procedente del nodo " << msjdatos->getOrigen() << ": " << retardo_mensaje << "s" << endl; 00439 retardo_pasarela.analyze(retardo_mensaje); 00440 (check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule("bs0")->getSubmodule("bs_mac")))->retardo.analyze(retardo_mensaje); 00441 //(check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule("bs",0)->getSubmodule("bs_mac")))->retardo.analyze(retardo_mensaje); /////// CAMBIO_RED /////// 00442 00443 //double tasa_aux = (double) this->getParentModule()->par("tasabinaria"); 00444 double tasa_aux = (double) check_and_cast<BS_mac *>(msjdatos->getSenderModule()->getParentModule()->getSubmodule("bs_mac"))->txrate; 00445 carga = (double) (bytes_recibidos * 8 / (SIMTIME_DBL(simTime()) * tasa_aux)); 00446 media_carga.analyze((double)carga); 00447 //ev << " Carga de este nodo pasarela: " << carga << endl; 00448 00449 double hops = (double) msjdatos->getSaltos(); 00450 //ev << " Nodos intermedios (BSs) por los que ha pasado el paquete: " << hops << endl; 00451 00452 double meters = (double) msjdatos->getMetros(); 00453 //ev << " Distancia (metros) recorrida por el paquete: " << meters << endl; 00454 00455 saltos.analyze(hops); 00456 longitud.analyze(meters); 00457 /* 00458 if(total_paquetes >= 100000) 00459 { 00460 endSimulation(); // LLAMAMOS A LA FUNCION TERMINAR SIMULACION 00461 callFinish(); // LLAMAMOS A LA FUNCION FINALIZAR 00462 } 00463 */ 00465 // Indice, en el grafo, del enlace por el que ha llegado el paquete: 00466 //int link = get_index_link(msjdatos->getArrivalGate()->getIndex()); 00467 int link = msjdatos->getArrivalGate()->getIndex(); 00469 00470 // Se cambia almacena el retardo del ultimo paquete para calcular el retardo medio del enlace por el que vino: 00471 retardo_medio[link].analyze(retardo_mensaje); 00472 arrived_packets[link]++; 00473 arrived_bytes[link] = arrived_bytes[link] + msjdatos->getByteLength(); 00474 //delete msjdatos; // BORRADO DEL PAQUETE 00475 send(msjdatos,"queueRxTx$o",0); // ALMACENAMIENTO DEL PAQUETE EN LA COLA CORRESPONDIENTE, PARA SU POSTERIOR ENVIO A LA ONU PASARELA 00476 } 00477 } 00478 // Si esta BS que recibe el paquete no es una pasarela... 00479 else if(esPasarela == 0) 00480 { 00481 char* nombre_origen = (char*) msjdatos->getOrigen(); 00482 char* nombre_destino = (char*) msjdatos->getDestino(); 00483 // Si el mensaje viene de un modulo BS_queue[] de esta BS, hacia otra BS: 00484 if(strcmp(nombre_origen,this->getParentModule()->getFullName())==0) 00485 { 00486 msjdatos->setTime_exit_bs(simTime()); 00487 //ev << " Envio de paquete inalambrico, de prioridad P" << msjdatos->getPriority() << " e Id." << msjdatos->getId() << endl; 00488 simtime_t retardo = simTime() - msjdatos->getTimestamp(); 00489 retardo_mensaje = SIMTIME_DBL(retardo); 00490 //ev << " Retardo del mensaje destinado al nodo " << msjdatos->getDestino() << ": " << retardo_mensaje << "s" << endl; 00491 simtime_t d_queue = simTime() - msjdatos->getTime_enter_queue(); 00492 //ev << " Retardo de encolamiento: " << d_queue << "s" << endl; 00493 00494 destino = this->getParentModule()->getParentModule()->getSubmodule(nombre_destino); 00495 //destino = this->getParentModule()->getParentModule()->getSubmodule("bs", msjdatos->getDestAddress()); /////// CAMBIO_RED /////// 00496 00497 // INICIO BUSQUEDA INDICE PUERTA DE SALIDA: 00498 int gate_size = (int) this->gateSize("bsRxTx"); 00499 int i=0; 00500 encontrado = -1; 00501 while(i<gate_size && encontrado<0) 00502 { 00503 if(this->gate("bsRxTx$o",i)->getNextGate()->isConnected()) 00504 { 00505 cModule *nodo; 00506 nodo = (cModule*) this->gate("bsRxTx$o",i)->getNextGate()->getNextGate()->getOwnerModule(); 00507 if(strcmp(destino->getFullName(),nodo->getFullName())==0) 00508 { 00509 encontrado = i; 00510 } 00511 } 00512 i++; 00513 } 00514 // FIN BUSQUEDA INDICE PUERTA DE SALIDA. 00515 00516 //ev << " Longitud del mensaje: " << msjdatos->getByteLength() << "B" << endl; 00517 //int link = get_index_link(encontrado); 00518 int link = encontrado; 00519 sent_packets[link]++; 00521 sent_bytes[link] = sent_bytes[link] + msjdatos->getByteLength(); 00522 00523 // Envio del paquete al modulo rx/tx,considerando el retardo de transmision: 00524 double datarate = (double) msjdatos->getByteLength()*8/control->txrate; // CALCULAMOS EL PARAMETRO datarate QUE INDICA LA TASA DE TRANSMISION DEL PAQUETE INALAMBRICO 00525 simtime_t tasa = (simtime_t)datarate; 00526 /* 00527 double tiempo_slot = (double) check_and_cast<BS_queue *>(msjdatos->getSenderGate()->getOwnerModule())->t_slot; 00528 int ind_cola = (int) check_and_cast<BS_queue *>(msjdatos->getSenderGate()->getOwnerModule())->used_index; 00529 double offset = (double) tiempo_slot*ind_cola; 00530 offset_time = (simtime_t) offset; 00531 //ev << " Retardo de slot: " << offset_time << "s" << endl; 00532 control->slot_tx_delay[ind_cola] = control->slot_tx_delay[ind_cola] + tasa; 00533 //ev << " Retardo de transmision: " << control->slot_tx_delay[ind_cola] << "s" << endl; 00534 */ 00535 control->timepacket = control->timepacket + tasa; 00536 //ev << " Retardo de transmision: " << control->timepacket << "s" << endl; 00537 insert_Packet(msjdatos); // Envio del paquete al siguiente nodo, pero comprobando antes que cabe en la cola del modulo BS_queue[] en el que se tiene que almacenar (distincion entre los metodos de insercion centralizado y de prioridad de colas) 00538 //sendDelayed(msjdatos, offset_time + control->slot_tx_delay[ind_cola], "bsRxTx$o", encontrado); 00539 } 00540 // Si el mensaje viene de fuera, hacia alguno de los modulos BS_queue[] de esta BS: 00541 else if(strcmp(nombre_origen,this->getParentModule()->getFullName())!=0) 00542 { 00543 /* Control de admision segun el retardo estimado en el algoritmo DARA */ 00544 int criterio = (int)this->getParentModule()->par("criterio"); 00545 // SI SE USA EL ALGORITMO DARA: 00546 if(criterio == 1) 00547 { 00548 // Suma de los bits presentes en las colas "activas" de esta BS: 00549 long longitud_cola = 0; 00550 for(int i=0; i<control->used_queues; i++) 00551 { 00552 longitud_cola = longitud_cola + (long) check_and_cast<BS_queue *>(this->gate("queueRxTx$o",control->index_used_queues[i])->getNextGate()->getOwnerModule())->tamqueue[msjdatos->getPriority()]; 00553 } 00554 double siguiente_ciclo = (double) fmod(SIMTIME_DBL(simTime()),control->t_frame); 00555 //ev << " Tiempo que falta hasta que llegue el siguiente ciclo de transmision: " << siguiente_ciclo << endl; 00556 double bits_previos = (double) 8*longitud_cola; 00557 //ev << " Bits presentes en las colas de esta BS: " << bits_previos << endl; 00558 bits_previos = bits_previos + (double) msjdatos->getBitLength(); 00559 double bits_ciclo = (double) tx_rate*control->t_frame; 00561 double ciclos_previos = (double) floor(bits_previos/bits_ciclo); 00563 double resto_ciclo = (double) fmod(bits_previos,bits_ciclo); 00565 double tiempo_previo = (double) ciclos_previos*control->t_frame + (double) resto_ciclo/tx_rate; 00566 //ev << " Tiempo que tardaria este paquete en llegar al siguiente nodo: " << tiempo_previo << endl; 00567 double retardo_paquete = SIMTIME_DBL(simTime() - msjdatos->getTimestamp()); 00568 //ev << " Retardo actual del paquete: " << retardo_paquete << endl; 00569 double retardo_estimado = siguiente_ciclo + tiempo_previo; //+ retardo_paquete; 00570 //ev << " Retardo de transferencia estimado para este paquete: " << retardo_estimado << endl; 00571 00572 /* Hasta aqui se ha calculado el retardo de enlace estimado para este paquete hasta el siguiente nodo 00573 * Si se quiere estimar el retardo end-to-end, se hace lo siguiente: 00574 * ¡OJO! Ahora si que se sumaria el retardo real previo del paquete */ 00575 int aux_length_route = (int) msjdatos->getRutaArraySize(); 00576 int intermediateBSs = aux_length_route - 2; // Los dos ultimos nodos son la BS pasarela y la ONU pasarela, que no cuentan en el encaminamiento por la red mesh. 00577 int aux_ind = 0; 00578 // Si en la ruta pasa por mas BSs intermedias aparte de esta misma, se calcula el retardo de enlace para cada una 00579 // (salvo ara esta, que ya se ha calculado ahora) y al final se suman todos los retardos de los enlaces para tener el end-to-end 00580 // (sumarle el retardo previo del paquete para que sea end-to-end de verdad). 00581 if(intermediateBSs > 1) 00582 { 00583 for(int i=0; i<intermediateBSs; i++) 00584 { 00585 if(strcmp((char*)msjdatos->getRuta(i),(char*)this->getParentModule()->getFullName())==0) 00586 { 00587 aux_ind = i+1; 00588 } 00589 } 00590 for(int i=aux_ind; i<intermediateBSs; i++) 00591 { 00592 BS_mac *aux_mac; 00593 aux_mac = check_and_cast<BS_mac *>(this->getParentModule()->getParentModule()->getSubmodule(msjdatos->getRuta(i))->getSubmodule("bs_mac")); 00594 longitud_cola = 0; 00595 siguiente_ciclo = 0; 00596 bits_previos = 0; 00597 bits_ciclo = 0; 00598 ciclos_previos = 0; 00599 resto_ciclo = 0; 00600 tiempo_previo = 0; 00601 for(int j=0; j<(int)aux_mac->used_queues; j++) 00602 { 00603 longitud_cola = longitud_cola + (long) check_and_cast<BS_queue *>(aux_mac->gate("bsmacInOut$o",aux_mac->index_used_queues[j])->getNextGate()->getOwnerModule())->tamqueue[msjdatos->getPriority()]; 00604 } 00605 // Tiempo que faltara para el proximo ciclo de tx cuando este paquete llegue a este nodo: 00606 siguiente_ciclo = (double) fmod(SIMTIME_DBL(simTime())+retardo_estimado,aux_mac->t_frame); 00607 // Se estima que los paquetes que habra en las colas de esta BS seran los mismos que ahora, 00608 // entre los que se envien y se reciban en este tiempo: 00609 bits_previos = (double) 8*longitud_cola; 00610 //ev << " Bits presentes en las colas de esta BS: " << bits_previos << endl; 00611 bits_previos = bits_previos + (double) msjdatos->getBitLength(); 00612 bits_ciclo = (double) tx_rate*aux_mac->t_frame; 00613 ciclos_previos = (double) floor(bits_previos/bits_ciclo); 00614 resto_ciclo = (double) fmod(bits_previos,bits_ciclo); 00615 tiempo_previo = (double) ciclos_previos*aux_mac->t_frame + (double) resto_ciclo/tx_rate; 00616 //ev << " Tiempo que tardaria este paquete en llegar al siguiente nodo: " << tiempo_previo << endl; 00617 retardo_estimado = siguiente_ciclo + tiempo_previo; 00618 } 00619 } 00620 // Una vez se ha estimado el retardo para todos los enlaces intermedios, se sume el retardo previo: 00621 retardo_estimado = retardo_estimado + retardo_paquete; 00622 //ev << " Retardo end-to-end estimado para este paquete:" << retardo_estimado << endl; 00623 // SI SE SUPERA EL UMBRAL DE RETARDO: 00624 if(retardo_estimado >= umbral_retardo) 00625 { 00626 //ev << " Mayor de 25 ms --> BORRADO!" << endl; 00627 paquetes_borrados_dara++; 00628 delete msjdatos; 00629 } 00630 // SI NO SE SUPERA EL UMBRAL DE RETARDO: 00631 else 00632 { 00633 //ev << " Menor de 25 ms --> SE INSERTA" << endl; 00635 paquetes_recibidos++; 00636 bytes_recibidos = bytes_recibidos + msjdatos->getByteLength(); 00637 //ev << " Paquetes recibidos en esta BS: " << paquetes_recibidos << endl; 00638 /* 00639 // PARA PARAR LA SIMULACION CUANDO LLEGAN 100000 PAQUETES A CADA UNA DE LAS BSs DE LA RED: 00640 if(paquetes_recibidos >=100000 & aux_counter==0) 00641 { 00642 aux_counter=1; 00643 full_bs_queues = 1; 00644 } 00645 double total_paquetes = 0; 00646 for(int i=0; i<BSs; i++) 00647 { 00648 total_paquetes = total_paquetes + check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[i])->getSubmodule("bs_rx_tx"))->full_bs_queues; 00649 } 00650 if(total_paquetes == BSs) 00651 { 00652 endSimulation(); // LLAMAMOS A LA FUNCION TERMINAR SIMULACION 00653 callFinish(); // LLAMAMOS A LA FUNCION FINALIZAR 00654 } 00655 */ 00656 //ev << " Recepcion de un paquete inalambrico, de prioridad P" << msjdatos->getPriority() << endl; 00657 simtime_t retardo = simTime() - msjdatos->getTimestamp(); 00658 retardo_mensaje = SIMTIME_DBL(retardo); 00659 //ev << " Retardo total del mensaje procedente del nodo " << msjdatos->getOrigen() << ": " << retardo_mensaje << "s" << endl; 00660 //ev << " Mensaje recibido por la puerta " << msjdatos->getArrivalGate()->getFullPath() << endl; 00661 // Indice, en el grafo, del enlace por el que ha llegado el paquete: 00662 //int link = get_index_link(msjdatos->getArrivalGate()->getIndex()); 00663 int link = msjdatos->getArrivalGate()->getIndex(); 00664 //ev << " Correspondiente al enlace " << link << " del grafo" << endl; 00665 // Se cambia almacena el retardo del ultimo paquete para calcular el retardo medio del enlace por el que vino: 00666 retardo_medio[link].analyze(retardo_mensaje); 00667 arrived_packets[link]++; 00669 arrived_bytes[link] = arrived_bytes[link] + msjdatos->getByteLength(); 00670 00671 // INICIO BUSQUEDA INDICE BS_QUEUE[]: 00672 // Vamos a ver la ruta en el mensaje: 00673 int h=0, siguiente = -1; 00674 while(h<(int)msjdatos->getRutaArraySize() && siguiente<0) 00675 { 00676 char* nodo_ruta = (char*) msjdatos->getRuta(h); 00677 if(strcmp(msjdatos->getDestino(),nodo_ruta)==0) 00678 { 00679 siguiente = h+1; 00680 } 00681 h++; 00682 } 00683 char* nodo_siguiente = (char*) msjdatos->getRuta(siguiente); 00684 // Si el 'target' de la cola coincide con el nombre del nodo destino, ahi va: 00685 int long_puerta = (int) this->gateSize("queueRxTx"); // Tantas como modulos BS_queue 00686 int j=0, found = -1; 00687 while(j<long_puerta && found<0) 00688 { 00689 cola_bs = check_and_cast<BS_queue *>(this->gate("queueRxTx$o",j)->getNextGate()->getOwnerModule()); // ENTRAMOS Y CHEQUEAMOS EL MODULO BS_QUEUE 00690 if(strcmp(nodo_siguiente,cola_bs->getTarget())==0) 00691 { 00692 found = j; 00693 } 00694 j++; 00695 } 00696 // FIN BUSQUEDA INDICE BS_QUEUE[] 00697 00698 // --> Envio del paquete al modulo BS_queue[] que toca: 00699 send(msjdatos,"queueRxTx$o",found); 00700 //ev << " Mensaje entregado a la cola " << cola_bs->getFullName() << ", para luego enviarlo al nodo " << cola_bs->getTarget() << endl; 00701 } 00703 } 00704 // SI NO SE USA EL ALGORITMO DARA: 00705 else 00706 { 00707 paquetes_recibidos++; 00708 bytes_recibidos = bytes_recibidos + msjdatos->getByteLength(); 00709 //ev << " Paquetes recibidos en esta BS: " << paquetes_recibidos << endl; 00710 /* 00711 // PARA PARAR LA SIMULACION CUANDO LLEGAN 100000 PAQUETES A CADA UNA DE LAS BSs DE LA RED: 00712 if(paquetes_recibidos >=100000 & aux_counter==0) 00713 { 00714 aux_counter=1; 00715 full_bs_queues = 1; 00716 } 00717 double total_paquetes = 0; 00718 for(int i=0; i<BSs; i++) 00719 { 00720 total_paquetes = total_paquetes + check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[i])->getSubmodule("bs_rx_tx"))->full_bs_queues; 00721 } 00722 if(total_paquetes == BSs) 00723 { 00724 endSimulation(); // LLAMAMOS A LA FUNCION TERMINAR SIMULACION 00725 callFinish(); // LLAMAMOS A LA FUNCION FINALIZAR 00726 } 00727 */ 00728 //ev << " Recepcion de un paquete inalambrico, de prioridad P" << msjdatos->getPriority() << endl; 00729 simtime_t retardo = simTime() - msjdatos->getTimestamp(); 00730 retardo_mensaje = SIMTIME_DBL(retardo); 00731 //ev << " Retardo total del mensaje procedente del nodo " << msjdatos->getOrigen() << ": " << retardo_mensaje << "s" << endl; 00732 //ev << " Mensaje recibido por la puerta " << msjdatos->getArrivalGate()->getFullPath() << endl; 00733 // Indice, en el grafo, del enlace por el que ha llegado el paquete: 00734 //int link = get_index_link(msjdatos->getArrivalGate()->getIndex()); 00735 int link = msjdatos->getArrivalGate()->getIndex(); 00736 //ev << " Correspondiente al enlace " << link << " del grafo" << endl; 00737 // Se cambia almacena el retardo del ultimo paquete para calcular el retardo medio del enlace por el que vino: 00738 retardo_medio[link].analyze(retardo_mensaje); 00739 arrived_packets[link]++; 00741 arrived_bytes[link] = arrived_bytes[link] + msjdatos->getByteLength(); 00742 00743 // INICIO BUSQUEDA INDICE BS_QUEUE: 00744 // Vamos a ver la ruta en el mensaje: 00745 int h=0, siguiente = -1; 00746 while(h<(int)msjdatos->getRutaArraySize() && siguiente<0) 00747 { 00748 char* nodo_ruta = (char*) msjdatos->getRuta(h); 00749 if(strcmp(msjdatos->getDestino(),nodo_ruta)==0) 00750 { 00751 siguiente = h+1; 00752 } 00753 h++; 00754 } 00755 char* nodo_siguiente = (char*) msjdatos->getRuta(siguiente); 00756 // Si el 'target' de la cola coincide con el nombre del nodo destino, ahi va: 00757 int long_puerta = (int) this->gateSize("queueRxTx"); // Tantas como modulos BS_queue 00758 int j=0, found = -1; 00759 while(j<long_puerta && found<0) 00760 { 00761 cola_bs = check_and_cast<BS_queue *>(this->gate("queueRxTx$o",j)->getNextGate()->getOwnerModule()); // ENTRAMOS Y CHEQUEAMOS EL MODULO BS_QUEUE 00762 if(strcmp(nodo_siguiente,cola_bs->getTarget())==0) 00763 { 00764 found = j; 00765 } 00766 j++; 00767 } 00768 // FIN BUSQUEDA INDICE BS_QUEUE[] 00769 00770 // --> Envio del paquete al modulo BS_queue[] que toca: 00771 send(msjdatos,"queueRxTx$o",found); 00772 //ev << " Mensaje entregado a la cola " << cola_bs->getFullName() << ", para luego enviarlo al nodo " << cola_bs->getTarget() << endl; 00773 } 00774 } 00775 } 00776 } 00777 break; 00778 default: 00779 delete msg; 00780 break; 00781 } 00782 } 00783 00785 //FUNCION FINISH()--> ESTA FUNCION SE INVOCA CUANDO LA SIMULACION HA TERMINADO CON EXITO SIN QUE SE PRODUZCA NINGUN ERROR. // 00786 // LO USAMOS PARA LA RECOGIDA DE ESTADASTICAS Y VISUALIZACION POR PANTALLA O MEDIANTE UN ARCHIVO. // 00788 void BS_rx_tx::finish() 00789 { 00790 // Asignacion a la variable total_enlaces de su valor real (el que se ha calculado en la ultima BS en la inicializacion) 00791 total_enlaces = check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[BSs - 1])->getSubmodule("bs_rx_tx"))->total_enlaces; 00792 //total_enlaces = check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule("bs",BSs - 1)->getSubmodule("bs_rx_tx"))->total_enlaces; /////// CAMBIO_RED /////// 00793 00794 ev << " Total enlaces entre nodos de la red mallada: " << total_enlaces << endl; 00795 double total_average_delay = calculate_average_transfer_delay(); 00796 00797 // 'RETARDO_NODOS_WIRELESS': FICHERO CON EL RETARDO MEDIO EN CADA ENLACE SALIENTE DE CADA BS DE LA SUBRED WIRELESS. 00798 retardo_intermedio=fopen("results/retardo_nodos_wireless.txt", "a+"); 00799 if(esPasarela==1) 00800 { 00801 fprintf(retardo_intermedio,"BS[%i] (pasarela)\n", indice_esta_bs); 00802 } 00803 else 00804 { 00805 fprintf(retardo_intermedio,"BS[%i] (NO pasarela)\n", indice_esta_bs); 00806 } 00807 for (int i=0; i<links; i++) 00808 { 00809 fprintf(retardo_intermedio, "\t Retardo del enlace wireless %i: %g\n", i, (double)retardo_medio[i].average()); 00810 } 00811 if(indice_esta_bs == BSs-1) 00812 { 00813 fprintf(retardo_intermedio, " TOTAL RETARDO MEDIO DE TRANSFERENCIA EN LOS ENLACES INTERMEDIOS DE LA SUBRED WIRELESS: %g\n", total_average_delay); 00814 } 00815 fclose(retardo_intermedio); 00816 00817 // 'PAQUETES_RECIBIDOS_BS': FICHERO CON EL NUMERO TOTAL DE PAQUETES Y BYTES RECIBIDOS EN CADA BS. 00818 paquetes_por_bs = fopen("results/paquetes_recibidos_bs.txt", "a+"); 00819 if(esPasarela==1) 00820 { 00821 fprintf(paquetes_por_bs,"BS[%i] (pasarela)\n", indice_esta_bs); 00822 } 00823 else 00824 { 00825 fprintf(paquetes_por_bs,"BS[%i] (NO pasarela)\n", indice_esta_bs); 00826 } 00827 int paqs = check_and_cast<BS_table *>(this->getParentModule()->getSubmodule("bs_table"))->paquetes_borrados; 00828 fprintf(paquetes_por_bs,"\t Total Paquetes:\t%g \t\t Total Bytes:\t%g \t\t Paquetes Borrados:\t%i\n",(double) paquetes_recibidos, (double) bytes_recibidos, paqs); 00829 fclose(paquetes_por_bs); 00830 00831 // Llamada a la funcion que calcula la carga de cada enlace: 00832 calculate_link_load(); 00833 // 'WIRELESS_LINK_LOAD': FICHERO CON EL VALOR MEDIO DE LA CARGA DE CADA ENLACE ENTRANTE Y SALIENTE EN CADA MODULO BS. 00834 wireless_link_loads=fopen("results/wireless_link_load.txt", "a+"); 00835 if(esPasarela==1) 00836 { 00837 fprintf(wireless_link_loads,"BS[%i] (pasarela)\n", indice_esta_bs); 00838 } 00839 else 00840 { 00841 fprintf(wireless_link_loads,"BS[%i] (NO pasarela)\n", indice_esta_bs); 00842 } 00843 int aux_number_links = links - bs_links; 00844 for (int i=aux_number_links-1; i<links; i++) 00845 { 00846 fprintf(wireless_link_loads, "\t Enlace %i:\n",i); 00847 fprintf(wireless_link_loads, "\t\t Paquetes recibidos: %g\n",(double)arrived_packets[i]); 00848 fprintf(wireless_link_loads, "\t\t\t Carga normalizada a la capacidad efectiva: %g\n",(double)link_load[i]); 00849 fprintf(wireless_link_loads, "\t\t\t Carga normalizada a la tasa de transmision: %g\n",(double)alt_link_load[i]); 00850 fprintf(wireless_link_loads, "\t\t Paquetes enviados: %g\n",(double)sent_packets[i]); 00851 fprintf(wireless_link_loads, "\t\t\t Carga normalizada a la capacidad efectiva: %g\n",(double)node_load[i]); 00852 fprintf(wireless_link_loads, "\t\t\t Carga normalizada a la tasa de transmision: %g\n",(double)alt_node_load[i]); 00853 } 00854 if(indice_esta_bs == BSs-1) 00855 { 00856 fprintf(wireless_link_loads, " MEDIA CARGA RX ENLACES NORMALIZADA A CAP_EFF: %g\n", (double)mean_link_load); 00857 fprintf(wireless_link_loads, " MEDIA CARGA RX ENLACES NORMALIZADA A RX_RATE: %g\n", (double)mean_alt_link_load); 00858 fprintf(wireless_link_loads, " MEDIA CARGA TX ENLACES NORMALIZADA A CAP_EFF: %g\n", (double)mean_node_load); 00859 fprintf(wireless_link_loads, " MEDIA CARGA TX ENLACES NORMALIZADA A TX_RATE: %g\n", (double)mean_alt_node_load); 00860 } 00861 fclose(wireless_link_loads); 00862 00863 if(esPasarela==1) 00864 { 00865 // 'CARGA_PASARELAS': FICHERO CON LA CARGA DE ENTRADA A CADA BS PASARELA. 00866 carga_pasarela = fopen("results/carga_pasarelas.txt", "a+"); 00867 fprintf(carga_pasarela,"BS [%i] (pasarela)\n", indice_esta_bs); 00868 fprintf(carga_pasarela,"Carga total de llegadas: %g \n", (double)media_carga.average()); 00869 fclose(carga_pasarela); 00870 00871 // 'DATOS_RECIBIDOS_PASARELAS': FICHEROS CON EL TOTAL DE PAQUETES Y BYTES RECIBIDOS EN CADA BS PASARELA. 00872 datos_recibidos = fopen("results/datos_recibidos_pasarela.txt", "a+"); 00873 fprintf(datos_recibidos,"BS[%i] (pasarela)\n", indice_esta_bs); 00874 fprintf(datos_recibidos,"\t Paquetes recibidos en total: %g\n",(double) paquetes_recibidos); 00875 fprintf(datos_recibidos,"\t Bytes recibidos en total: %g\n",(double) bytes_recibidos); 00876 fclose(datos_recibidos); 00877 00878 // 'RETARDO_WIRELESS': RETARDO MEDIO DE TODOS LOS PAQUETES RECIBIDOS EN CADA BS PASARELA, MAS EL RETARDO MEDIO DE TODOS LOS PAQUETES 00879 // QUE HAN LLEGADO EN TOTAL A TODAS LAS BSs PASARELA (DATO INSERTADO DESDE EL MODULO bs0.BS_MAC). 00880 retardo_wireless_pasarelas=fopen("results/retardo_wireless.txt", "a+"); 00881 fprintf(retardo_wireless_pasarelas, "\tRetardo wireless BS[%i]: %g\n", indice_esta_bs, (double)retardo_pasarela.average()); 00882 fclose(retardo_wireless_pasarelas); 00883 00884 // 'SALTOS_METROS_BS_PASARELAS': FICHERO CON EL NUMERO MEDIO DE SALTOS Y DE LONGITUD RECORRIDOS POR CADA PAQUETE 00885 // WIRELESS RECIBIDO EN CADA BS PASARELA. 00886 saltos_metros = fopen("results/saltos_metros_bs_pasarelas.txt", "a+"); 00887 fprintf(saltos_metros,"BS [%i]\n", indice_esta_bs); 00888 fprintf(saltos_metros,"\t Media saltos paquetes wireless: %g\n",(double) saltos.average()); 00889 fprintf(saltos_metros,"\t Media longitud recorrida: %g\n",(double) longitud.average()); 00890 fclose(saltos_metros); 00891 } 00892 00893 } 00894 00896 //FUNCION INSERT_PACKET(CMESSAGE *MSG)--> INSERCION DE UN MENSAJE EN LA COLA DEL MODULO BS_QUEUE DE LA SIGUIENTE BS POR LA QUE HA DE PASAR / 00897 // EL PAQUETE, SEGUN EL METODO ELEGIDO EN EL ARCHIVO DE CONFIGURACION (COLAS SEPARADAS O CON PRIORIDAD) / 00899 void BS_rx_tx::insert_Packet(cMessage *msg) 00900 { 00901 DATA *msjdatos = check_and_cast<DATA*>(msg); 00902 int h=0, sig = -1; 00903 while(h<(int)msjdatos->getRutaArraySize() && sig<0) 00904 { 00905 char* nodo_ruta = (char*) msjdatos->getRuta(h); 00906 if(strcmp(msjdatos->getDestino(),nodo_ruta)==0){ sig = h+1; } 00907 h++; 00908 } 00909 char* nodo_siguiente = (char*) msjdatos->getRuta(sig); 00910 int longitud_puerta = (int) this->gateSize("queueRxTx"); // Tantas como modulos BS_queue 00911 // Si el 'target' de la cola coincide con el nombre del nodo destino, ahi va: 00912 int j=0, found = -1; 00913 while(j<longitud_puerta && found<0) 00914 { 00915 cola_bs = check_and_cast<BS_queue *>(this->getParentModule()->getParentModule()->getSubmodule(msjdatos->getDestino())->getSubmodule("bs_queue",j)); 00916 //cola_bs = check_and_cast<BS_queue *>(this->getParentModule()->getParentModule()->getSubmodule("bs",msjdatos->getDestAddress())->getSubmodule("bs_queue",j)); /////// CAMBIO_RED /////// 00917 if(strcmp(nodo_siguiente,cola_bs->getTarget())==0) 00918 { 00919 found = j; 00920 } 00921 j++; 00922 } 00923 double buffer = (double) this->getParentModule()->par("buffer_size"); // Longitud total del buffer (Bytes) 00925 //buffer = buffer/cola_bs->colas_salida;/////// 00927 00928 long suma_total_user = 0; 00929 long tamsumqueue_user = 0; 00930 int metodo = (int) this->getParentModule()->par("user_insercionmethod_separatequeue0_priorityqueue1"); 00931 switch(metodo) 00932 { 00933 case 0: // Metodo de insercion de paquetes en colas separadas 00934 // Comprobacion de si hay espacio suficiente o no en el buffer de esta cola: 00935 // Si hay espacio: 00936 if(buffer/prioridades >= (cola_bs->tamqueue[msjdatos->getPriority()] + msjdatos->getByteLength())) 00937 { 00938 // Envio del paquete "msjdatos" a la siguiente BS: 00939 sendDelayed(msjdatos, control->timepacket, "bsRxTx$o", encontrado); 00940 //int ind_cola = (int) check_and_cast<BS_queue *>(msjdatos->getSenderGate()->getOwnerModule())->used_index; 00941 //sendDelayed(msjdatos, offset_time + control->slot_tx_delay[ind_cola], "bsRxTx$o", encontrado); 00942 } 00943 // Si no hay espacio: 00944 else if(buffer/prioridades < (cola_bs->tamqueue[msjdatos->getPriority()] + msjdatos->getByteLength())) 00945 { 00946 // Borrado del mensaje "msjdatos" al no poderlo insertar en su cola por estar llena: 00947 //ev << " MENSAJE 'DATA' (Id." << msjdatos->getId() << ") BORRADO" << endl; 00948 delete msjdatos; 00949 // INCREMENTO DE LA VARIABLE PARA CONTROLAR EL BORRADO DE PAQUETES EN LA PARTE INALAMBRICA: 00950 check_and_cast<BS_table *>(this->getParentModule()->getSubmodule("bs_table"))->paquetes_borrados++; 00951 } 00952 break; 00953 case 1: // Metodo de insercion de paquetes en colas por prioridades 00954 // Suma de todas las subcolas del modulo BS_QUEUE correspondiente: 00955 for(int i=0; i<prioridades; i++) 00956 { 00957 // Los bytes en todas las cQueue (tantas como prioridades) se almacenan en 'suma_total_user': 00958 suma_total_user = suma_total_user + cola_bs->tamqueue[i]; 00959 } 00960 // La variable 'tamsumqueue_user' almacena la suma total de los bytes de todos los paquetes de la bs_queue 00961 // y la longitud del paquete a enviar: 00962 tamsumqueue_user = suma_total_user + msjdatos->getByteLength(); 00963 // Comprobacion de si hay espacio suficiente en el buffer total (todas las colas): 00964 // Si los bytes de todas las colas no superan la longitud del buffer total: 00965 if(buffer >= tamsumqueue_user) 00966 { 00967 // Envio del paquete "msjdatos" a la siguiente BS: 00968 //ev << "Mensaje enviado." << endl; 00969 sendDelayed(msjdatos, control->timepacket, "bsRxTx$o", encontrado); 00970 //int ind_cola = (int) check_and_cast<BS_queue *>(msjdatos->getSenderGate()->getOwnerModule())->used_index; 00971 //sendDelayed(msjdatos, offset_time + control->slot_tx_delay[ind_cola], "bsRxTx$o", encontrado); 00972 } 00973 // Si la suma de los bytes de todas las colas supera la longitud del buffer total: 00974 else if(buffer < tamsumqueue_user) 00975 { 00976 // Recorremos todas las colas, de menor a mayor prioridad, para borrar alguno de sus paquetes previos 00977 // y dejar sitio asi al nuevo paquete: 00978 int i = prioridades-1, fuera = -1; 00979 while(i>=0 && fuera < 0) 00980 { 00981 // Si el nuevo paquete es de la misma prioridad que la de la cola que se esta checkeando (en principio, la mas baja), se borra directamente: 00982 if(msjdatos->getPriority() == i) 00983 { 00984 //ev << " MENSAJE 'DATA' (Id." << msjdatos->getId() << ") BORRADO" << endl; 00985 // Resta de los bytes del paquete borrado a la suma total de todas las colas: 00986 tamsumqueue_user = tamsumqueue_user - msjdatos->getByteLength(); 00987 delete msjdatos; // BORRADO DEL PAQUETE 'msjdatos' 00988 // INCREMENTO DE LA VARIABLE PARA CONTROLAR EL BORRADO DE PAQUETES EN LA PARTE INALAMBRICA: 00989 check_and_cast<BS_table *>(this->getParentModule()->getSubmodule("bs_table"))->paquetes_borrados++; 00990 // Salida del bucle que recorre las colas 00991 fuera = 1; 00992 } 00993 // Si el nuevo paquete es de mayor prioridad que la de la cola que se esta checkeando 00994 // Y esta cola NO esta vacia, se borran paquetes suyos hasta poder meter el nuevo: 00995 else if(msjdatos->getPriority() < i && cola_bs->queue[i].getLength()>0) 00996 { 00997 int salir = -1; 00998 // Recorremos todos los paquetes de esta cola, desde el mas antiguo: 00999 while (cola_bs->queue[i].getLength()>0 && salir < 0) 01000 { 01001 // Llamada a la funcion del modulo 'bs_queue' para borrar el primer paquete de la cola: 01002 cola_bs->deleteElement(msjdatos,i); 01003 // INCREMENTO DE LA VARIABLE PARA CONTROLAR EL BORRADO DE PAQUETES EN LA PARTE INALAMBRICA: 01004 check_and_cast<BS_table *>(this->getParentModule()->getSubmodule("bs_table"))->paquetes_borrados++; 01005 01006 // Resta de los bytes del paquete extraido a la variable 'tamsumqueue_user': 01007 tamsumqueue_user = tamsumqueue_user - cola_bs->user_tamqueuepop[i]; 01008 // Si hay espacio suficiente en cola para insertar el nuevo paquete... 01009 if(buffer >= tamsumqueue_user) 01010 { 01011 // Envio del mensaje a la siguiente BS: 01012 //ev << "Mensaje enviado." << endl; 01013 sendDelayed(msjdatos, control->timepacket, "bsRxTx$o", encontrado); 01014 //int ind_cola = (int) check_and_cast<BS_queue *>(msjdatos->getSenderGate()->getOwnerModule())->used_index; 01015 //sendDelayed(msjdatos, offset_time + control->slot_tx_delay[ind_cola], "bsRxTx$o", encontrado); 01016 01017 // Salida del bucle que recorre los paquetes de esta cola 01018 salir = 1; 01019 fuera = 1; 01020 } 01021 // Si NO hay espacio suficiente en cola para insertar el nuevo paquete... 01022 else if(buffer < tamsumqueue_user) 01023 { 01025 // << " bytes) --> LIBERACION DE MAS ESPACIO EN LAS COLAS" << endl; 01026 } 01027 // Pasamos a la siguiente iteracion 01028 } 01029 if(buffer > tamsumqueue_user) 01030 { 01031 // Salida del bucle que recorre todas las colas 01032 fuera = 1; 01033 } 01034 } 01035 else if(msjdatos->getPriority() < i && cola_bs->queue[i].getLength()==0) 01036 { 01038 } 01039 i--; 01040 } 01041 } 01042 break; 01043 default: 01044 delete msjdatos; 01045 break; 01046 } 01047 } 01048 01050 //FUNCION DELAY_WEIGHT(INT INDICE1, INT INDICE2, CMESSAGE *MSG)--> CALCULA EL PESO DEL ENLACE 'INDICE' A PARTIR DE LOS PARAMETROS / 01051 // ADJUNTADOS EN EL MENSAJE 'MSG' (LINK STATE ANNOUNCEMENT), Y / 01052 // ACTUALIZA EL RETARDO DEL CANAL ASOCIADO A ESTE ENLACE CON EL PESO. / 01054 void BS_rx_tx::calculate_delay_weight(int indice1, int indice2, cMessage *msg) 01055 { 01056 // Para cada enlace i-->j, el peso se calcula con la siguiente formula: 01057 // Wi = 1/(mhu*Ci) + 1/(2*mhu*Ci) + rho_i/(mhu*Ci - lambda_est_i) 01058 // mhu = service_rate 01059 // Ci = Capacidad efectiva del enlace i (Capacidad_total/num_enlaces_activos) 01060 // lambda_i = anuncio->getArrival_rate(j) 01061 // rho_i = anuncio->getLink_load(j) = lambda_i/(mhu*Ci) 01062 // Estimated_Lambda_i(Tn) = [3*alpha/(3*alpha+1)]*[Lambda_i(Tn)+Estimated_Lambda(Tn-1)]*S^(1-alpha/1+alpha) 01063 // Carga < 0.3 -> alpha = 1 -> Estimated_Lambda_i(Tn) = (3/4)*[Lambda_i(Tn)+Estimated_Lambda(Tn-1)] 01064 // Carga >= 0.3 -> alpha->inf -> Estimated_Lambda_i(Tn) = [Lambda_i(Tn)+Estimated_Lambda(Tn-1)]*1/S 01065 // NOTA: En el paper del algoritmo DARA pone que "S" es el numero de muestras usadas para las predicciones, pero no dice NADA MAS. 01066 // Tras buscar info de la Media Movil Ponderada (WMA, Weighted Moving Average), que es lo que dice dicho informe que hace este algoritmo, 01067 // he acabado poniendo en la formula de la WMA: 01068 // S = Tiempo_simulacion_total/Periodo_entre_envios_LSAs = Numero de veces que se actualizan los pesoso de los enlaces a lo largo de toda la simulacion. 01069 // Y además, para que tenga mas peso la Lambda del ultimo periodo LSA, multiplico la ultima Lambda por el numero de veces que se ha entrado en este metodo, hasta el momento. 01070 01071 01072 LSA *anuncio = check_and_cast<LSA*>(msg); 01073 // indice1 --> Indice del enlace en el array del nodo remoto 01074 // indice2 --> Indice del enlace en el array de este nodo 01075 01076 //cTopology::Node *rem_node = top.getNodeFor(this->getParentModule()->getParentModule()->getSubmodule(anuncio->getSrcName())); 01077 //cTopology::Node *rem_node = top.getNodeFor(this->getParentModule()->getParentModule()->getSubmodule("bs",anuncio->getSrcAddress())); /////// CAMBIO_RED /////// 01078 01079 //ev << " CALCULO DEL PESO DEL ENLACE DE " << this->getParentModule()->getFullName() << " A " << anuncio->getSrcName() << " + ACTUALIZACION DEL RETARDO DEL CANAL" << endl; 01081 double paquetes = anuncio->getRcvd_pckts(indice1); 01082 //ev << " -> Paquetes enviados desde este nodo al nodo " << anuncio->getSrcName() << ": " << paquetes << endl; //ev-comentar 01083 double lambda = anuncio->getArrival_rate(indice1); 01084 //ev << " -> Tasa de llegadas a " << anuncio->getSrcName() << ": " << lambda << "pqt/s" << endl; //ev-comentar 01085 //ev << " --> Tasa de llegadas estimada en el periodo anterior: " << previous_estimated_lambda[indice2] << "pqt/s" << endl; //ev-comentar 01086 double diferencia = lambda - previous_estimated_lambda[indice2]; 01087 //ev << " --> Diferencia con la tasa de llegadas estimada previamente: " << diferencia << endl; //ev-comentar 01088 double rho = anuncio->getLink_load(indice1); // rho = lambda/(service_rate*capacity); 01089 //ev << " -> Carga: " << rho << endl; //ev-comentar 01090 //double capacity = anuncio->getEffective_link_capacity(); 01091 double capacity = control->eff_cap; // eff_cap; // 01092 //ev << " -> Capacidad efectiva: " << capacity << "bps" << endl; 01093 double tx_delay, slot_sync_delay, queueing_delay, weight; 01094 // Suma de la Lambda reportada en el LSA del nodo vecino y la Lambda estimada para este enlace en el periodo anterior 01095 // (se pondera lambda*aux_samples[indice2] para que pese mas el valor real obtenido en el ultimo LSA): 01096 aux_samples[indice2]++; 01097 //double sum_real_lambda_and_prev_estim_lambda = aux_samples[indice2]*lambda + previous_estimated_lambda[indice2]; 01098 double sum_real_lambda_and_prev_estim_lambda = lambda + previous_estimated_lambda[indice2]; 01099 01100 /* 01101 double aux_sum = 0; 01102 for(int i=1; i<=aux_samples[indice2]; i++) 01103 { 01104 aux_sum += i; 01105 } 01106 //ev << " Numero de veces que se ha ejecutado el algoritmo DARA: " << aux_samples[indice2] << endl; 01107 //ev << " Sumatorio: " << aux_sum << endl; 01108 */ 01109 double carga_nodo = (double) this->getParentModule()->par("carga_nodo"); 01110 if(carga_nodo < 0.6) // Para cargas bajas-moderadas (se puede poner 0.5)... 01111 { 01112 double three_quarters = (double) 3/4; 01113 estimated_lambda = (double)three_quarters*sum_real_lambda_and_prev_estim_lambda; 01114 } 01115 else // Para el resto... 01116 { 01117 double T = 200; 01118 //double inv_paquetes = (double) 1/aux_samples[indice2]; 01119 //estimated_lambda = (double)inv_paquetes*sum_real_lambda_and_prev_estim_lambda; 01120 //estimated_lambda = (double)sum_real_lambda_and_prev_estim_lambda*aux_samples[indice2]/aux_sum; 01121 estimated_lambda = (double)sum_real_lambda_and_prev_estim_lambda*SIMTIME_DBL(LSA_period)/T; 01122 } 01123 //ev << " --> Tasa de llegadas estimada para el siguiente periodo: " << estimated_lambda << "pqt/s" << endl; //ev-comentar 01124 tx_delay = (double) 1/(service_rate*capacity); 01125 //ev << " --> Retardo de transmision: " << tx_delay << "s" << endl; //ev-comentar 01126 slot_sync_delay = (double) tx_delay/2; 01127 //ev << " --> Retardo de sincronizacion de slot: " << slot_sync_delay << "s" << endl; //ev-comentar 01128 queueing_delay = (double) rho/(service_rate*capacity - estimated_lambda); 01129 //queueing_delay = (double) rho/(service_rate*capacity - lambda); // SIN LA WMA 01130 //ev << " --> Retardo de encolamiento: " << queueing_delay << "s" << endl; //ev-comentar 01131 double prev_peso = (check_and_cast<cDelayChannel*>(nodeOut->getLinkOut(indice2)->getLocalGate()->getChannel()))->par(3); 01132 //ev << " * Antiguo peso del canal: " << prev_peso << endl; //ev-comentar 01133 // CALCULO DEL NUEVO PESO DEL ENLACE: 01134 weight = (double) (tx_delay + slot_sync_delay + queueing_delay); 01135 weight = (double) fabs(weight); 01136 // NOTA: Si se quiere tener en cuenta tambien el retardo de propagacion (que, aunque sea pequeño, es lo que 01137 // diferencia a los enlaces no usados, pues mhu y Ci es comun a todos los del mismo nodo), se haria 01138 // lo siguiente: 01139 //double length = (check_and_cast<cDelayChannel*>(rem_node->getLinkOut(indice1)->getLocalGate()->getChannel()))->par(2); 01141 //double propagation_delay = (double) (check_and_cast<cDelayChannel*>(nodeOut->getLinkOut(indice2)->getLocalGate()->getChannel()))->par(4); 01143 //weight = (double)(weight + propagation_delay); 01144 01145 // ACTUALIZACION DEL RETARDO DEL CANAL EN EL SENTIDO BS_rx_LSA --> BS_tx_LSA: 01146 // NOTA: Enlace BS_rx_LSA --> BS_tx_LSA <==> Enlace BS_tx_paquetes --> BS_rx_paquetes 01147 (check_and_cast<cDelayChannel*>(nodeOut->getLinkOut(indice2)->getLocalGate()->getChannel()))->par(3) = (double)weight; 01148 // ¡OJO! El enlace puede tener pesos asimetricos (distinto peso en un sentido que en otro), luego 01149 // ¡no se cambia en el sentido BS_tx_LSA --> BS_rx_LSA! 01150 //(check_and_cast<cDelayChannel*>(rem_node->getLinkOut(indice1)->getLocalGate()->getChannel()))->par(3) = (double)weight; 01151 01152 double retardo = (check_and_cast<cDelayChannel*>(nodeOut->getLinkOut(indice2)->getLocalGate()->getChannel()))->par(3); 01153 //ev << " * Nuevo peso del canal: " << retardo << endl; //ev-comentar 01154 01155 //double retardo_2 = (check_and_cast<cDelayChannel*>(rem_node->getLinkOut(indice1)->getLocalGate()->getChannel()))->par(3); 01156 //ev << " --> Peso del canal en el otro sentido: " << retardo_2 << endl; 01157 01158 previous_estimated_lambda[indice2] = estimated_lambda; 01159 delete anuncio; 01160 } 01161 01163 //FUNCION GET_INDEX_LINK(INT INDEX)--> ACTUALIZA EL RETARDO DE CADA ENLACE DE LA RED, SEGUN EL VALOR PROMEDIO / 01164 // DEL MISMO ENTRE TODOS LOS PAQUETES QUE LLEGAN POR EL (PESO). / 01165 // DEVUELVE EL INDICE DEL ENLACE EN EL GRAFO DE LA CLASE cTopology. / 01167 int BS_rx_tx::get_index_link(int index) 01168 { 01169 int indice=-1; 01170 // Se habilitan como enlaces los asociados a puertas de salida de la BS que estan conectadas: 01171 for(int i=0; i<links; i++) 01172 { 01173 //ev << " Indice enlace: " << nodeOut->getLinkOut(i)->getLocalGate()->getIndex() << endl; 01174 //ev << " Indice puerta: " << this->gate("bsRxTx$o",i)->getIndex() << endl; 01175 if(nodeOut->getLinkOut(i)->getLocalGate()->getIndex()==index) 01176 { 01177 indice = i; 01178 } 01179 } 01180 return indice; 01181 } 01182 01184 //FUNCION CALCULATE_WEIGHT_PARAMS(INT IND)--> CALCULA LOS PARAMETROS QUE SE ENVIAN EN EL LSA, NECESARIOS PARA CALCULAR / 01185 // EL RETARDO DE TRANSMISION (PESO DEL ENLACE). / 01187 void BS_rx_tx::calculate_weight_params(int ind) 01188 { 01190 // packet_intensity -> Tasa de llegadas de paquetes (lambda) -> [paquetes/segundos] 01191 // service_rate -> Tasa de servicio del enlace (mhu) -> [1/bits] 01192 // link_load -> Carga del enlace (rho) -> [u.n.] 01193 // effective_capacity -> Capacidad efectiva del enlace (Capacidad/num_enlaces) -> [bits/segundo] 01194 // En "User_traffic": 01195 // --> lambda = tx_rate/(packetSize_user*8); --> Paquetes/segundo (teorico) 01196 // --> total_load_user = (double) (suma_total_bytes * 8/(simTime()*tx_rate)) --> Adimensional (practico) 01197 01198 // Calculo lambda_i (tasa de llegadas del enlace i): 01199 01200 packet_intensity[ind] = arrived_packets[ind]/SIMTIME_DBL(LSA_period); //ACTUAL 01201 //packet_intensity[ind] = arrived_packets[ind]/SIMTIME_DBL(simTime()); 01202 //ev << " -> Tasa de llegadas de paquetes del enlace " << ind << ": " << packet_intensity[ind] << " paq/seg" << endl; 01204 01205 double aux_eff_cap = check_and_cast<BS_mac *>(nodeOut->getLinkOut(ind)->getRemoteNode()->getModule()->getSubmodule("bs_mac"))->eff_cap; // eff_cap; // 01206 01207 // Calculo rho_i (carga o utilizacion del enlace i): 01208 link_load[ind] = packet_intensity[ind]/(service_rate*aux_eff_cap); // rho_i 01209 //link_load[ind] = packet_intensity[ind]/(service_rate*effective_capacity); // rho_i 01210 //ev << " -> Uso del enlace " << ind << ": " << link_load[ind] << endl; 01211 //double prueba = arrived_bytes[ind]*8/(SIMTIME_DBL(simTime())*effective_capacity); 01212 //double prueba = arrived_bytes[ind]*8/(SIMTIME_DBL(simTime())*tx_rate); 01214 // NOTA: He comprobado que "prueba = packet_intensity[ind]", pero es que son la misma fórmula. 01215 } 01216 01218 //FUNCION CALCULATE_LINK_LOAD()--> CALCULA LA CARGA DE ENVIO/RECEPCION DE PAQUETES DE CADA ENLACE, NORMALIZADAS TANTO / 01219 // A LA CAPACIDAD EFECTIVA DEL CANAL COMO A LA CAPACIDAD TOTAL DE LA RED. / 01221 void BS_rx_tx::calculate_link_load() 01222 { 01223 int aux_number_links = links - bs_links; 01224 for(int i=aux_number_links; i<links; i++) 01225 { 01226 // C_i = Tasa de transmision de radio entre el numero total de enlaces salientes de cada nodo, conectando con otras BSs 01227 // txrate = Tasa de transmision de radio (suele coincidir con eff_cap, que la divide entre el numero de enlaces salientes activos) 01228 double aux_eff_cap = check_and_cast<BS_mac *>(nodeOut->getLinkOut(i)->getRemoteNode()->getModule()->getSubmodule("bs_mac"))->C_i; 01229 double aux_txrate = check_and_cast<BS_mac *>(nodeOut->getLinkOut(i)->getRemoteNode()->getModule()->getSubmodule("bs_mac"))->txrate; 01230 link_load[i] = (double) (arrived_bytes[i]*8)/(SIMTIME_DBL(simTime())*aux_eff_cap); 01231 alt_link_load[i] = (double) (arrived_bytes[i]*8)/(SIMTIME_DBL(simTime())*aux_txrate); 01232 node_load[i] = (double) (sent_bytes[i]*8)/(SIMTIME_DBL(simTime())*control->C_i); 01233 alt_node_load[i] = (double) (sent_bytes[i]*8)/(SIMTIME_DBL(simTime())*control->txrate); 01234 } 01235 for(int j=aux_number_links; j<links; j++) 01236 { 01237 mean_link_load = mean_link_load + link_load[j]; 01238 mean_alt_link_load = mean_alt_link_load + alt_link_load[j]; 01239 mean_node_load = mean_node_load + node_load[j]; 01240 mean_alt_node_load = mean_alt_node_load + alt_node_load[j]; 01241 } 01242 mean_link_load = (double)(mean_link_load/total_enlaces); 01243 mean_alt_link_load = (double)(mean_alt_link_load/total_enlaces); 01244 mean_node_load = (double)(mean_node_load/total_enlaces); 01245 mean_alt_node_load = (double)(mean_alt_node_load/total_enlaces); 01246 } 01247 01249 //FUNCION CALCULATE_AVERAGE_TRANSFER_DELAY()--> CALCULA EL RETARDO MEDIO DE TRANSFERENCIA EN LOS ENLACES ENTRE BSs DE TODA LA PARTE / 01250 // INALAMBRICA Y DEVUELVE ESTE VALOR PARA REGISTRARLO EN EL ARCHIVO "RETARDO_NODOS_WIRELESS". / 01252 double BS_rx_tx::calculate_average_transfer_delay() 01253 { 01254 double total_retardo = 0, media = 0; 01255 int total_enlaces_bs = 0; 01256 for(int i=0; i<BSs; i++) 01257 { 01258 cTopology::Node *aux_nodo = top.getNodeFor(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[i])); 01259 total_enlaces_bs = check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[i])->getSubmodule("bs_rx_tx"))->links; 01260 //cTopology::Node *aux_nodo = top.getNodeFor(this->getParentModule()->getParentModule()->getSubmodule("bs",i)); /////// CAMBIO_RED /////// 01261 //total_enlaces_bs = check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule("bs",i)->getSubmodule("bs_rx_tx"))->links; /////// CAMBIO_RED /////// 01262 01263 for(int j=0; j<total_enlaces_bs; j++) 01264 { 01265 if (strpbrk(aux_nodo->getLinkOut(j)->getRemoteNode()->getModule()->getFullName(),"b") != NULL) 01266 { 01267 double retardo_auxiliar = (double)check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule(control->nombres_bs[i])->getSubmodule("bs_rx_tx"))->retardo_medio[j].average(); 01268 // retardo_auxiliar = (double)check_and_cast<BS_rx_tx *>(this->getParentModule()->getParentModule()->getSubmodule("bs",i)->getSubmodule("bs_rx_tx"))->retardo_medio[j].average(); /////// CAMBIO_RED /////// 01269 total_retardo = total_retardo + retardo_auxiliar; 01271 if(retardo_auxiliar == 0.0) 01272 { 01273 total_enlaces = total_enlaces - 1; 01274 } 01276 } 01277 } 01278 } 01279 ev << " Total enlaces activos entre BSs de la red: " << total_enlaces << endl; 01280 media = (double) (total_retardo/total_enlaces); 01284 return media; 01285 }