예제 #1
0
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 */
                }
        }
  }
}
예제 #2
0
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 */
        }
  }
}
예제 #3
0
void protocol6(void)
{
  seq_nr ack_expected;	/* lower edge of sender's window */
  seq_nr next_frame_to_send;	/* upper edge of sender's window + 1 */
  seq_nr frame_expected;	/* lower edge of receiver's window */
  seq_nr too_far;	/* upper edge of receiver's window + 1 */
  int i;	/* index into buffer pool */
  frame r;	/* scratch variable */
  packet out_buf[NR_BUFS];	/* buffers for the outbound stream */
  packet in_buf[NR_BUFS];	/* buffers for the inbound stream */
  boolean arrived[NR_BUFS];	/* inbound bit map */
  seq_nr nbuffered;	/* how many output buffers currently used */
  event_type event;

  enable_network_layer();	/* initialize */
  ack_expected = 0;	/* next ack expected on the inbound stream */
  next_frame_to_send = 0;	/* number of next outgoing frame */
  frame_expected = 0;	/* frame number expected */
  too_far = NR_BUFS;	/* receiver's upper window + 1 */
  nbuffered = 0;	/* initially no packets are buffered */

  for (i = 0; i < NR_BUFS; i++) arrived[i] = false;
  while (true) {
     wait_for_event(&event);	/* five possibilities: see event_type above */
     switch(event) { 
        case network_layer_ready:	/* accept, save, and transmit a new frame */
                nbuffered = nbuffered + 1;	/* expand the window */
                from_network_layer(&out_buf[next_frame_to_send % NR_BUFS]); /* fetch new packet */
                send_frame(data, next_frame_to_send, frame_expected, out_buf);	/* transmit the frame */
                inc(next_frame_to_send);	/* advance upper window edge */
                break;

        case frame_arrival:	/* a data or control frame has arrived */
                from_physical_layer(&r);	/* fetch incoming frame from physical layer */
                if (r.kind == data) {
                        /* An undamaged frame has arrived. */
                        if ((r.seq != frame_expected) && no_nak)
                            send_frame(nak, 0, frame_expected, out_buf); else start_ack_timer();
                        if (between(frame_expected, r.seq, too_far) && (arrived[r.seq%NR_BUFS] == false)) {
                                /* Frames may be accepted in any order. */
                                arrived[r.seq % NR_BUFS] = true;	/* mark buffer as full */
                                in_buf[r.seq % NR_BUFS] = r.info;	/* insert data into buffer */
                                while (arrived[frame_expected % NR_BUFS]) {
                                        /* Pass frames and advance window. */
                                        to_network_layer(&in_buf[frame_expected % NR_BUFS]);
                                        no_nak = true;
                                        arrived[frame_expected % NR_BUFS] = false;
                                        inc(frame_expected);	/* advance lower edge of receiver's window */
                                        inc(too_far);	/* advance upper edge of receiver's window */
                                        start_ack_timer();	/* to see if (a separate ack is needed */
                                }
                        }
                }
                if((r.kind==nak) && between(ack_expected,(r.ack+1)%(MAX_SEQ+1),next_frame_to_send))
                        send_frame(data, (r.ack+1) % (MAX_SEQ + 1), frame_expected, out_buf);

                while (between(ack_expected, r.ack, next_frame_to_send)) {
                        nbuffered = nbuffered - 1;	/* handle piggybacked ack */
                        stop_timer(ack_expected % NR_BUFS);	/* frame arrived intact */
                        inc(ack_expected);	/* advance lower edge of sender's window */
                }
                break;

        case cksum_err: if (no_nak) send_frame(nak, 0, frame_expected, out_buf); break;	/* damaged frame */
        case timeout: send_frame(data, get_timedout_seqnr(), frame_expected, out_buf); break;	/* we timed out */
        case ack_timeout: send_frame(ack,0,frame_expected, out_buf);	/* ack timer expired; send ack */
     }

     if (nbuffered < NR_BUFS) enable_network_layer(); else disable_network_layer();
  }
}
예제 #4
0
  /*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

}