/*    

                    Selective Repeat ARQ Simülasyonu


Görselliğini http://media.pearsoncmg.com/aw/aw_kurose_network_3/applets/SelectRepeat/SR.html adresindeki simülasyondan,
algoritmasını ise Communication Networks kitabının ilgili konusundan referans alarak yazdığım ufak bir simülasyon.
                                                                                    
5 Mayıs 2009
                                                                                 
                                                                                 
                                                                                   
                                                                                 Ahmet Kamil Keleş


*/

#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>

 short int s_last=0,r_son=0,s_recent=0;
 short int w_s=5;
bool gonder[26],al[26],islem[26]; 

void wait ( int seconds )
{
 //Simülasyon içerisindeki beklemeyi sağlayan fonksiyon.
 // Kaynak: http://www.dreamincode.net/forums/showtopic10512.htm    
     
  clock_t endwait;
  endwait = clock () + seconds * CLOCKS_PER_SEC ;
  while (clock() < endwait) {}
}



void yazdir() {
 //Bu fonksiyonun amacı, simülasyonun görselliğini sağlamak. Selective Repeat ARQ algoritmasıyla ilgisi yok.    
     
     int i;
      if (system("cls")) system("clear");  
for(i=0;i<s_recent;i++) printf("   ");
printf("%c",218);

for(i=0;i<14;i++) printf("%c",196);
printf("%c\n ",191);

for(i=0;i<26;i++) {
 if(i<10)printf("0");
 printf("%d ",i);                 
                  
                  }
                  
                  printf("\n");
  for(i=0;i<26;i++) {
                    if(gonder[i] && !islem[i]) printf(" %c ",2); 
                    if(!gonder[i] && !islem[i] ) printf(" %c ",1);
                    if(islem[i]) printf(" ? ");
                    }
  
  printf("\n\n\n\n\n\n\n\n\n\n\n\n");
    for(i=0;i<26;i++) if(al[i]) printf(" %c ",2); else printf(" %c ",1);
    printf("\n ");
for(i=0;i<26;i++) {
 if(i<10)printf("0");
 printf("%d ",i);                
 }
     
 printf("\n\n\n\n\t%c:G%cnderilen/Al%cnan",2,148,141);    
 printf("\n\t%c:G%cnderilmemi%c/Al%cnmam%c%c",1,148,159,141,141,159); 
     }




int main() {
    
    
printf("G%crselli%cini\n\n http://media.pearsoncmg.com/aw/aw_kurose_network_3/applets/SelectRepeat/SR.html\nadresindeki sim%clasyondan, ",148,167,129);
printf("algoritmas%cn%c ise Communication Networks kitab%cn%cn \nilgili konusundan referans alarak yazd%c%c%cm ufak bir sim%clasyon.",141,141,141,141,141,167,141,129);
printf("\n\n\n\t\t\t\t\t5 May%cs 2009,",141);
printf("\n\t\t\t\t\tAhmet Kamil Kele%c\n",159);
getch(); 
 if (system("cls")) system("clear");  
 int i,r_next=0;
 
  int hatapayi=80;
 //Bu simülasyonda, veri iletişimindeki bozulmaların yüksek ihtimalle görüldüğü bir ortam için SR ARQ'nun
 //ne kadar etkili olabildiğini göstermek adına hatalı veri ihtimali payını %80 gibi yüksek bir sayı tuttum.

 bool hazir;

   srand(time(NULL));
 
   
 for(i=0;i<26;i++) {gonder[i]=false; al[i]=false; islem[i]=false; }

 islem[s_last]=true; 
 
 
 
 
 while(r_next<26) {
     
yazdir();

//Kitapta anlatılan algoritmayı basitleştirerek uyguladım.

 if(s_last<s_recent+w_s-1) hazir=false;

if(hazir) 
{
   if(al[r_next]) {
   //Eğer r_next'in gösterdiği veri başarılı bir şekilde aktarılmışsa ve gönderme penceresindeki veriler de
   //gönderilmişse o zaman gönderme aralığını sağa doğru kaydırabiliriz.               
                  
                  
                  islem[r_next]=false;
                         r_next++;
s_recent=r_next;  
printf("%c",7);

}

else{
     //r_next için NAK gönderilmişse o veriyi yeniden yollamaya çalışırız
     
      if(rand()%100>hatapayi) {
     islem[r_next]=true;
     gonder[r_next]=true;
      al[r_next]=true;
      
      yazdir();
     wait(1);
}
     
     }



} 

while(!hazir) {   
//Blocking state. Eğer gönderme aralığındaki tüm veriler henüz yollanmadıysa onları teker teker yollamaya başlarız
 
 if(s_last<s_recent+w_s-1)  islem[s_last+1]=true; 
  gonder[s_last]=true;
  

  yazdir();
  wait(1);
  islem[s_last]=false;
  if(rand()%100>hatapayi) al[s_last]=true;
 
  yazdir();
  if(s_last==s_recent+w_s-1) hazir=true;//Blocking state'den ready state'e geçiş.
  else s_last++;

  
}
  
}
}

