229 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			229 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								#include <cstdio>
							 | 
						||
| 
								 | 
							
								#include <cstdlib>
							 | 
						||
| 
								 | 
							
								#include <ctime>
							 | 
						||
| 
								 | 
							
								#include <cstring>
							 | 
						||
| 
								 | 
							
								#include <iostream>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  char tx[6][10];
							 | 
						||
| 
								 | 
							
								  int tx_table_2hr_slot=-1, tx_table_pctx=0;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int tx_band_sum(char bsum[10])
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int i,j;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    for (j=0; j<10; j++) {
							 | 
						||
| 
								 | 
							
								        bsum[j]=0;
							 | 
						||
| 
								 | 
							
								        for (i=0; i<6; i++) {
							 | 
						||
| 
								 | 
							
								            bsum[j]=bsum[j]+tx[i][j];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int tx_add_to_band(int band)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // add tx cycle to a band without regard to ntxlim
							 | 
						||
| 
								 | 
							
								    int i,islot;
							 | 
						||
| 
								 | 
							
								    for ( i=0; i<10; i++) {
							 | 
						||
| 
								 | 
							
								        islot=rand()%6;
							 | 
						||
| 
								 | 
							
								        if( tx[islot][band] != 1 ) {
							 | 
						||
| 
								 | 
							
								            tx[islot][band]=1;
							 | 
						||
| 
								 | 
							
								            return 1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int tx_sum()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int i,j,sum=0;
							 | 
						||
| 
								 | 
							
								    for (i=0; i<6; i++) {
							 | 
						||
| 
								 | 
							
								        for (j=0; j<10; j++) {
							 | 
						||
| 
								 | 
							
								            sum=sum+tx[i][j];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return sum;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int tx_add_one(char* tx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int i, j, txflag, ngap;
							 | 
						||
| 
								 | 
							
								    // adds one tx slot to an existing array without
							 | 
						||
| 
								 | 
							
								    // creating successive tx slots. 
							 | 
						||
| 
								 | 
							
								    // try to fill largest gaps first  
							 | 
						||
| 
								 | 
							
								    // try gap sizes of 13, 11, 9, 7, 5, and finally 3
							 | 
						||
| 
								 | 
							
								    for (ngap=13; ngap>=3; ngap=ngap-2) {
							 | 
						||
| 
								 | 
							
								        for (i=0; i< 60-ngap; i++) {
							 | 
						||
| 
								 | 
							
								            txflag=0;
							 | 
						||
| 
								 | 
							
								            for (j=0; j<ngap; j++) {
							 | 
						||
| 
								 | 
							
								              if( tx[i+j]==1 ) 
							 | 
						||
| 
								 | 
							
								                  txflag=1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if( txflag == 0 ) { // found a gap of size ngap
							 | 
						||
| 
								 | 
							
								                tx[i+ngap/2]=1;
							 | 
						||
| 
								 | 
							
								                return 1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // last resort - see if we can set the last slot to 1
							 | 
						||
| 
								 | 
							
								    if( tx[58]==0 && tx[59]==0 ) {
							 | 
						||
| 
								 | 
							
								      tx[59]=1;
							 | 
						||
| 
								 | 
							
								      return 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int tx_trim(char* tx, int ntxlim)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* ntxlim is max number of successive transmissions 
							 | 
						||
| 
								 | 
							
								    * trim array so that ntxlim is not exceeded
							 | 
						||
| 
								 | 
							
								    * also make sure that first slot is never a tx slot
							 | 
						||
| 
								 | 
							
								    * this enures that we won't get a double tx because of the 
							 | 
						||
| 
								 | 
							
								    * last slot of one table and the first slot of the next table
							 | 
						||
| 
								 | 
							
								    * both being tx slots. 
							 | 
						||
| 
								 | 
							
								    */
							 | 
						||
| 
								 | 
							
								    int i,nrun,sum;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if( tx[0] == 1 ) tx[0] = 0;
							 | 
						||
| 
								 | 
							
								    nrun=0;
							 | 
						||
| 
								 | 
							
								    for (i=0; i<60; i++) {
							 | 
						||
| 
								 | 
							
								        if( tx[i]==1 ) {
							 | 
						||
| 
								 | 
							
								            nrun++;
							 | 
						||
| 
								 | 
							
								            if( nrun > ntxlim ) {
							 | 
						||
| 
								 | 
							
								                tx[i]=0;
							 | 
						||
| 
								 | 
							
								                nrun=0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            nrun=0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    sum=0;
							 | 
						||
| 
								 | 
							
								    for (i=0; i<60; i++) {
							 | 
						||
| 
								 | 
							
								        sum=sum+tx[i];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return sum;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void tx_print()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int i,j;
							 | 
						||
| 
								 | 
							
								    for (i=0; i<6; i++) {
							 | 
						||
| 
								 | 
							
								        for (j=0; j<10; j++) {
							 | 
						||
| 
								 | 
							
								            if( (i*10+j)%10 == 0 && i>=0 ) printf("\n");
							 | 
						||
| 
								 | 
							
								            printf("%d ",tx[i][j]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    printf("\n");
							 | 
						||
| 
								 | 
							
								    fflush(stdout);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int create_tx_schedule(int pctx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    char bsum[10];
							 | 
						||
| 
								 | 
							
								    int i, j, k, sum, ntxlim, ntxbandmin, needed;
							 | 
						||
| 
								 | 
							
								    int iflag, nrx;
							 | 
						||
| 
								 | 
							
								    float rxavg,x;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    needed=60*(pctx/100.0)+0.5;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    memset(tx,0,sizeof(char)*60);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    if( pctx == 0 ) return 0;
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								    if( pctx <= 25 ) { // Use K1JT's algorithm in this regime
							 | 
						||
| 
								 | 
							
								        rxavg=100.0/pctx-1.0;
							 | 
						||
| 
								 | 
							
								        i=0; 
							 | 
						||
| 
								 | 
							
								        while(1) {
							 | 
						||
| 
								 | 
							
								            x=(rand()%100)/100.0;
							 | 
						||
| 
								 | 
							
								            nrx=(rxavg+3.0*x-1.0); //2-5 for 25%
							 | 
						||
| 
								 | 
							
								            i=i+nrx+1; 
							 | 
						||
| 
								 | 
							
								            if( i < 60 ) {
							 | 
						||
| 
								 | 
							
								                tx[i/10][i%10]=1;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								    } else if( pctx > 25 && pctx < 33 ) {
							 | 
						||
| 
								 | 
							
								        ntxlim=1;
							 | 
						||
| 
								 | 
							
								        ntxbandmin=1;
							 | 
						||
| 
								 | 
							
								    } else if( pctx >= 33 && pctx < 50 ) {
							 | 
						||
| 
								 | 
							
								        ntxlim=1;
							 | 
						||
| 
								 | 
							
								        ntxbandmin=2;
							 | 
						||
| 
								 | 
							
								    } else if( pctx >= 50 && pctx < 60 ) {
							 | 
						||
| 
								 | 
							
								        ntxlim=2;
							 | 
						||
| 
								 | 
							
								        ntxbandmin=3;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        ntxlim=3;
							 | 
						||
| 
								 | 
							
								        ntxbandmin=4;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    // when txpct>25% create a table that guarantees that all
							 | 
						||
| 
								 | 
							
								    // bands will be visited 1, 2, or 3 times, as appropriate. 
							 | 
						||
| 
								 | 
							
								    //
							 | 
						||
| 
								 | 
							
								    // start by filling each band slot with ntxbandmin tx's
							 | 
						||
| 
								 | 
							
								    for (i=0; i<ntxbandmin; i++) {
							 | 
						||
| 
								 | 
							
								        for (j=0; j<10; j++) {
							 | 
						||
| 
								 | 
							
								            tx_add_to_band(j);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // trim so that no more than ntxlim successive transmissions
							 | 
						||
| 
								 | 
							
								    sum=tx_trim(*tx,ntxlim);
							 | 
						||
| 
								 | 
							
								    j=0;
							 | 
						||
| 
								 | 
							
								    iflag=0;
							 | 
						||
| 
								 | 
							
								    while (j<100 && iflag==0) {
							 | 
						||
| 
								 | 
							
								        // now backfill columns that got trimmed
							 | 
						||
| 
								 | 
							
								        tx_band_sum(bsum);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        iflag=1;
							 | 
						||
| 
								 | 
							
								        for (i=0; i<10; i++) {
							 | 
						||
| 
								 | 
							
								            if( bsum[i] < ntxbandmin ) {
							 | 
						||
| 
								 | 
							
								                iflag=0;
							 | 
						||
| 
								 | 
							
								                for (k=0; k<ntxbandmin-bsum[i]; k++) {
							 | 
						||
| 
								 | 
							
								                    tx_add_to_band(i);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        sum=tx_trim(*tx,ntxlim);
							 | 
						||
| 
								 | 
							
								        j++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    for(j=0; j < (needed-sum); j++ ) {
							 | 
						||
| 
								 | 
							
								        tx_add_one(*tx); 
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int next_tx_state(int pctx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  time_t now=time(0)+30;
							 | 
						||
| 
								 | 
							
								  tm *ltm = gmtime(&now);
							 | 
						||
| 
								 | 
							
								  int hour  = ltm->tm_hour;
							 | 
						||
| 
								 | 
							
								  int minute = ltm->tm_min;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  int tx_2hr_slot = hour/2; 
							 | 
						||
| 
								 | 
							
								  int tx_20min_slot = (hour-tx_2hr_slot*2)*3 + minute/20;
							 | 
						||
| 
								 | 
							
								  int tx_2min_slot = (minute%20)/2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if( (tx_2hr_slot != tx_table_2hr_slot) || (tx_table_pctx != pctx) ) {
							 | 
						||
| 
								 | 
							
								    create_tx_schedule(pctx);
							 | 
						||
| 
								 | 
							
								    tx_table_2hr_slot = tx_2hr_slot;
							 | 
						||
| 
								 | 
							
								    tx_table_pctx = pctx;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								//  tx_print();
							 | 
						||
| 
								 | 
							
								  return tx[tx_20min_slot][tx_2min_slot];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int next_hopping_band()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  time_t now=time(0)+30;
							 | 
						||
| 
								 | 
							
								  tm *ltm = gmtime(&now);
							 | 
						||
| 
								 | 
							
								  int minute = ltm->tm_min;
							 | 
						||
| 
								 | 
							
								  int tx_2min_slot = (minute%20)/2;
							 | 
						||
| 
								 | 
							
								  return tx_2min_slot;
							 | 
						||
| 
								 | 
							
								} 
							 |