void enframe(packet p,int seq){ frame s; int i; s.checksum = (char)NULL; s.seq = 0; s.eop = 0; for (i = 0; i<=23;i++){ s.data.load[i] = (char)NULL; } s.type=data; s.seq=seq; s.data=p; s.eop=p.eop; s.checksum=XOR(s); enqueued(s); enqueuef(s); if(seven==6){ s = error(s); seven=0; }else{ seven++; } to_physical_layer(s); }
void sender3(void) { seq_nr next_frame_to_send; /* seq number of next outgoing frame */ frame s; /* scratch variable */ packet buffer; /* buffer for an outbound packet */ event_type event; next_frame_to_send = 0; /* initialize outbound sequence numbers */ from_network_layer(&buffer); /* fetch first packet */ while (true) { init_frame(&s); s.info = buffer; /* construct a frame for transmission */ s.seq = next_frame_to_send; /* insert sequence number in frame */ to_physical_layer(&s); /* send it on its way */ start_timer(s.seq); /* if answer takes too long, time out */ wait_for_event(&event); /* frame_arrival, cksum_err, timeout */ if (event == frame_arrival) { from_physical_layer(&s); /* get the acknowledgement */ if (s.ack == next_frame_to_send) { from_network_layer(&buffer); /* get the next one to send */ inc(next_frame_to_send); /* invert next_frame_to_send */ } } } }
/* ------------------------------------------------------------ * sig_trama * ------------------------------------------------------------ */ int sig_trama ( TEntity * inEntity, TState inFromState, TEvent inEvent, Argumentos * argu ) { int rc = AUTOMAT_OK; int n_carac; packet *paquete; packet paq; printf(" ===> Enviamos trama. \n"); //para la trama con datos memset(argu->trama_e->data,'\0',sizeof(argu->trama_e->data)); argu->trama_e->control='T';//0x09; argu->trama_e->address = argu->sec_actual; /***********************************/ camb_intro(argu->paquete->data); //void formato_trama(frame *tra,packet paq,int n_carac) //paquete = argu->paquete; // paq= *argu->paquete; //paq = *paquete; formato_trama(argu->trama_e, *argu->paquete/*paq*/, argu->paquete->n); printf(" *************cuatro. \n"); //enviamos trama de datos to_physical_layer(argu->trama_e,argu->fde); // printf("adress , control \n %c %c: \n",argu->trama_e->address, argu->trama_e->control); // printf("% i, %i",0x00,0x08); /* ********************** */ print_estado(argu->active_en); //usleep(argu->retardo); return rc; }
static void send_frame(frame_kind fk, seq_nr frame_nr, seq_nr frame_expected, packet buffer[]) { /* Construct and send a data, ack, or nak frame. */ frame s; /* scratch variable */ s.kind = fk; /* kind == data, ack, or nak */ if (fk == data) s.info = buffer[frame_nr % NR_BUFS]; s.seq = frame_nr; /* only meaningful for data frames */ s.ack = (frame_expected + MAX_SEQ) % (MAX_SEQ + 1); if (fk == nak) no_nak = false; /* one nak per frame, please */ to_physical_layer(&s); /* transmit the frame */ if (fk == data) start_timer(frame_nr % NR_BUFS); stop_ack_timer(); /* no need for separate ack frame */ }
/* ------------------------------------------------------------ * reenviar_trama * ------------------------------------------------------------ */ int reenviar_trama( TEntity * inEntity, TState inFromState, TEvent inEvent, Argumentos * argu ) { int rc = AUTOMAT_OK; printf(" ===> Reenviamos trama de datos. \n"); //enviamos trama de datos to_physical_layer(argu->trama_e,argu->fde); argu->tra_retx ++; /* printf("adress , control %i %i: \n",argu->trama_e->address, argu->trama_e->control); printf("% i, %i \n",0x00 );*/ /* ********************** */ print_estado(argu->active_en); // semaphore_timeout_set(argu->tempo,argu,automata); //usleep(argu->retardo); return rc; }
void receiver3(void) { seq_nr frame_expected; frame r, s; event_type event; frame_expected = 0; while (true) { wait_for_event(&event); /* possibilities: frame_arrival, cksum_err */ if (event == frame_arrival) { /* A valid frame has arrived. */ from_physical_layer(&r); /* go get the newly arrived frame */ if (r.seq == frame_expected) { /* This is what we have been waiting for. */ to_network_layer(&r.info); /* pass the data to the network layer */ inc(frame_expected); /* next time expect the other sequence nr */ } init_frame(&s); s.ack = 1 - frame_expected; /* tell which frame is being acked */ to_physical_layer(&s); /* only the ack field is use */ } } }
int from_physical_layer(int expected){ int flag=0; frame r; char u; unsigned char checkvalue; if(recv(sock,message,sizeof(frame),0)<0){ perror("recv"); }else{ r=message[0]; /*server checks ack*/ if((int)message[0].type==1){ if(expected == message[0].seq ){ fprintf(fileserv,"ACKrecv:%d\n",message[0].seq); if(message[0].seq==here){ here=0; flag1=0; tail-=1; printf("frame sent:%d\n",frame_sent); } dequeuef(); expected++; } return expected; /*client receives frames*/ }else if((int)message[0].type==0){ checkvalue = XOR(message[0]); if ((int)checkvalue==(int)r.checksum){ }else{ fprintf(filecl,"Problem!! checkvalue %d\n",(int)checkvalue); fprintf(filecl,"checksum %d\n",(int)r.checksum); } if((r.seq==expected)&&((int)checkvalue==(int)r.checksum)){ fprintf(filecl,"recvframe:%d\n",message[0].seq); frame a; a=ackframe(r); /*send ACK*/ to_physical_layer(a); expected++; packet pc; pc=enp(r); to_datalink_layerc(pc); return expected; }else{ perror("Error occured upon receiving, cannot send to datalink layer!"); } }else{ perror("Error occured upon receiving!"); } } }
/*frame *trama_e, int fde,TEntity *active_en, TAutomat *automata */ void recibe_ACK(Argumentos * argu, TAutomat *automata, int fin_f) { int tam_trama,conretx; frame trama_recb; long t_ini,t_actual; char aux; struct timeval tiempo; STOP=FALSE; conretx=0; /* //Empieza el temporizador */ semaphore_timeout_set(argu->tempo,argu,automata); gettimeofday(&tiempo,NULL); t_ini= tiempo.tv_sec+(long)argu->tempo+1; while (STOP==FALSE) { gettimeofday(&tiempo,NULL); /* printf("t_ini = %i\n", t_ini); printf("t actual = %i \n", tiempo.tv_sec); */ if ( (t_ini+(long)argu->tempo) <= tiempo.tv_sec ){ t_ini =tiempo.tv_sec; printf("Reenviamos trama desde temporizador \n"); automat_transit(argu->active_en, automata, TIME_O, argu); argu->tr_perdidas ++; } printf("."); printf("bucle - espero ACK\n"); usleep(100000); /*tras recibir SIGIO, wait_flag = FALSE, la entrada esta disponible y puede ser leida */ // printf("En el recibe_ack el wait_flag vale :%i \n", wait_flag); if (wait_flag==FALSE) { //Al recibir datos en el canal cancelo el temporizador semaphore_timeout_cancel( ); //tam_trama = from_physical_layer(argu->trama_e, argu->fde); //printf("control : %c \n", argu->trama_e->control); //if ( c=='A'/*128 ACK*/){ tam_trama = from_physical_layer(&trama_recb, argu->fde); printf("control : %c \n", trama_recb.control); if ( trama_recb.control=='A'/*128 ACK*/){ //Si el ACK no lleva la secuencia para la siguiente trama if (argu->sec_siguiente != trama_recb.address) { //transito automa con ese evento automat_transit(argu->active_en, automata, ACK_N_SIG, argu); } else //else1-> Si el ACK lleva la secuencia para la siguiente trama { argu->sec_actual= argu->sec_siguiente; //Se desdignan la secuencia actual y la secuencia esperada switch (argu->sec_actual) { case 'A': { printf("Estoy en A espero un B \n" ); argu->sec_siguiente = 'B'; break; } case 'B': { printf("Estoy en B espero un A \n" ); argu->sec_siguiente = 'A'; break; } default : { printf("Es un estado no designado \n"); break; } } /*copiamos los datos de la trama al paquete*/ printf(" Recibimos el ACK \n"); STOP=TRUE; /* para el bucle si solo entra un CR */ printf(" \n Para, y enviamos la siguiente trama \n"); //Para enviar la trama vacia if (fin_f ==0){ /* entidad , automata, evento, argumentos de evento */ automat_transit(argu->active_en, automata, ACK_SIG, argu); } else{ printf(" \n Se ha enviado la ultima trama \n"); argu->trama_e->data[0]='\0'; argu->trama_e->control='T';//0x09; printf("Se envia la trama vacia %s: ,tam : %d \n",argu->trama_e->data,strlen(argu->trama_e->data)); to_physical_layer(argu->trama_e,argu->fde); automat_transit(argu->active_en,automata,ACK_0, argu); } /*Se puede borrar ya que paramos*/ wait_flag = TRUE; /* espera una nueva entrada */ }//else 1 }//if else//else2 { //Si el NACK lleva la secuencia de la trama actual if (argu->sec_actual == trama_recb.address) { /*Como sria un Nack se puede hacer una comprobafcion de la secuencia*/ if (conretx == argu->n_rtx) { automat_transit(argu->active_en, automata, N_NACK_MAX, argu); printf("Se ha superado el numero de retransmisiones por trama \n"); printf("ERROR en el canal \n"); exit(-1); } conretx++; printf("El limite de retrasnmisiones es %i veces\n", argu->n_rtx); printf("Se ha retransmitido %i veces\n", conretx); printf("Recibido Recibo Nack\n"); automat_transit(argu->active_en, automata, NACK_ACT, argu); /* //Empieza otra vez el temporizador por el reenvio temporizador*/ semaphore_timeout_set(argu->tempo,argu,automata); gettimeofday(&tiempo,NULL); t_ini= tiempo.tv_sec+(long)argu->tempo+1; printf("Se ha reenviado la trama\n"); wait_flag = TRUE; /* espera una nueva entrada */ } else //else23-> Si el NACK no lleva la secuencia de la trama actual { //transito automa con ese evento automat_transit(argu->active_en, automata, NACK_N_ACT, argu); } }//else2 }//if }//while }