1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
#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;
}
|