| 
									
										
										
										
											2015-06-05 19:48:53 +00:00
										 |  |  | #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; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-07-12 01:06:24 +00:00
										 |  |  |     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; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-07-12 14:12:31 +00:00
										 |  |  |     // last resort - see if we can set the last slot to 1
 | 
					
						
							|  |  |  |     if( tx[58]==0 && tx[59]==0 ) { | 
					
						
							|  |  |  |       tx[59]=1; | 
					
						
							|  |  |  |       return 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int tx_trim(char* tx, int ntxlim) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-07-12 01:06:24 +00:00
										 |  |  |     /* 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.  | 
					
						
							|  |  |  |     */ | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |     int i,nrun,sum; | 
					
						
							| 
									
										
										
										
											2015-07-12 01:06:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if( tx[0] == 1 ) tx[0] = 0; | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |     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"); | 
					
						
							| 
									
										
										
										
											2015-06-06 00:06:46 +00:00
										 |  |  |     fflush(stdout); | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-04 22:25:27 +00:00
										 |  |  | int create_tx_schedule(int pctx) | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     char bsum[10]; | 
					
						
							|  |  |  |     int i, j, k, sum, ntxlim, ntxbandmin, needed; | 
					
						
							| 
									
										
										
										
											2015-07-12 01:06:24 +00:00
										 |  |  |     int iflag, nrx; | 
					
						
							|  |  |  |     float rxavg,x; | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |      | 
					
						
							|  |  |  |     needed=60*(pctx/100.0)+0.5; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     memset(tx,0,sizeof(char)*60); | 
					
						
							| 
									
										
										
										
											2015-07-13 01:12:28 +00:00
										 |  |  |     | 
					
						
							|  |  |  |     if( pctx == 0 ) return 0; | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2015-07-12 01:06:24 +00:00
										 |  |  |     if( pctx <= 25 ) { // Use K1JT's algorithm in this regime
 | 
					
						
							|  |  |  |         rxavg=100.0/pctx-1.0; | 
					
						
							|  |  |  |         i=0;  | 
					
						
							| 
									
										
										
										
											2015-07-13 01:12:28 +00:00
										 |  |  |         while(1) { | 
					
						
							| 
									
										
										
										
											2015-07-12 01:06:24 +00:00
										 |  |  |             x=(rand()%100)/100.0; | 
					
						
							|  |  |  |             nrx=(rxavg+3.0*x-1.0); //2-5 for 25%
 | 
					
						
							|  |  |  |             i=i+nrx+1;  | 
					
						
							| 
									
										
										
										
											2015-07-13 01:12:28 +00:00
										 |  |  |             if( i < 60 ) { | 
					
						
							|  |  |  |                 tx[i/10][i%10]=1; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-07-13 01:12:28 +00:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2015-07-12 01:06:24 +00:00
										 |  |  |     } else if( pctx > 25 && pctx < 33 ) { | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |         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; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-07-12 01:06:24 +00:00
										 |  |  |     | 
					
						
							|  |  |  |     // when txpct>25% create a table that guarantees that all
 | 
					
						
							|  |  |  |     // bands will be visited 1, 2, or 3 times, as appropriate. 
 | 
					
						
							|  |  |  |     //
 | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |     // 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++ ) { | 
					
						
							| 
									
										
										
										
											2015-07-12 01:06:24 +00:00
										 |  |  |         tx_add_one(*tx);  | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-04 22:25:27 +00:00
										 |  |  | int next_tx_state(int pctx) | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   time_t now=time(0)+30; | 
					
						
							| 
									
										
										
										
											2015-11-20 13:19:05 +00:00
										 |  |  |   tm *ltm = gmtime(&now); | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |   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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-05 00:41:12 +00:00
										 |  |  |   if( (tx_2hr_slot != tx_table_2hr_slot) || (tx_table_pctx != pctx) ) { | 
					
						
							| 
									
										
										
										
											2015-06-04 22:25:27 +00:00
										 |  |  |     create_tx_schedule(pctx); | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |     tx_table_2hr_slot = tx_2hr_slot; | 
					
						
							| 
									
										
										
										
											2015-06-05 00:41:12 +00:00
										 |  |  |     tx_table_pctx = pctx; | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2015-06-05 23:03:32 +00:00
										 |  |  | //  tx_print();
 | 
					
						
							| 
									
										
										
										
											2015-06-04 21:07:45 +00:00
										 |  |  |   return tx[tx_20min_slot][tx_2min_slot]; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-05 23:03:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int next_hopping_band() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   time_t now=time(0)+30; | 
					
						
							| 
									
										
										
										
											2015-11-20 13:19:05 +00:00
										 |  |  |   tm *ltm = gmtime(&now); | 
					
						
							| 
									
										
										
										
											2015-06-05 23:03:32 +00:00
										 |  |  |   int minute = ltm->tm_min; | 
					
						
							|  |  |  |   int tx_2min_slot = (minute%20)/2; | 
					
						
							|  |  |  |   return tx_2min_slot; | 
					
						
							|  |  |  | }  |