00001 #include "standard.h"
00002 #include "channel.h"
00003 #include "clock.h"
00004 #include "input.h"
00005
00006 #define MAX_RAND 2147483647
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 extern int debug;
00017
00018 #define BUFSIZE 65536
00019
00020
00021 void apply_errors(byte *data, channel *chan)
00022 {
00023 int i, j, count=0, num_bits;
00024 float r;
00025 float ber;
00026 byte b=*data;
00027
00028 chan->bit_count += 8;
00029
00030 if (chan->error==NoErrors)
00031 return;
00032
00033 if (chan->error == Random) {
00034 if (chan->bit_error_rate == 0.0)
00035 return;
00036
00037 if ((chan->bit_count/8) >= chan->error_offset) {
00038 for (j=0; j<8; j++) {
00039 r = (float) random() / MAX_RAND;
00040 if (r < chan->bit_error_rate) {
00041 b ^= (1 << j);
00042 count++;
00043 chan->error_count++;
00044 if (debug >= 2)
00045 printf("apply_errors() r=%e, bit %d flipped. \n", r, j);
00046 }
00047 }
00048 }
00049 else
00050 if (debug>=4) printf("apply_errors() - not applying errors yet\n");
00051 }
00052
00053 else if (chan->error == File) {
00054 if (chan->filename==NULL) {
00055 warn("apply_errors","channel's error file name is NULL");
00056 return;
00057 }
00058 if ((chan->bit_count/8) > chan->error_offset) {
00059 if (!chan->file_open) {
00060 chan->error_file = fopen(chan->filename,"r");
00061 if (chan->error_file == NULL) {
00062 error("apply_errors","Can't open error file");
00063 }
00064 chan->file_open = 1;
00065 }
00066
00067 for (j=0; j<8; j++) {
00068 if (feof(chan->error_file))
00069 fseek(chan->error_file, 0, 0);
00070 if (fgetc(chan->error_file)=='1') {
00071 b ^= (1 << j);
00072 count++;
00073 chan->error_count++;
00074 if (debug >= 4)
00075 printf("apply_errors() bit %d flipped\n", j);
00076 }
00077 }
00078 }
00079 else
00080 if (debug>=4) printf("apply_errors() - not applying errors yet\n");
00081 }
00082 if (debug >= 4) {
00083 printf("apply_errors() [%s] Applied %d errors to byte\n",
00084 chan->label, count);
00085 }
00086 if (debug >= 1) {
00087 printf("apply_errors() [%s] Errors %d / %d bits (BER %e)\n",
00088 chan->label,
00089 chan->error_count, chan->bit_count,
00090 (float) chan->error_count / chan->bit_count);
00091 }
00092
00093
00094
00095
00096 *data = b;
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 return;
00107 }
00108
00109
00110 int channel_write_indication(channel *one)
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 {
00121
00122 long int allowed = (one->transmission_speed * get_clock()) / 8000;
00123
00124 return (one->write_count < allowed);
00125 }
00126
00127
00128 int channel_write(channel *one, byte m)
00129
00130
00131
00132
00133
00134 {
00135 bwrite(one->pdus, &m);
00136 one->write_count++;
00137 }
00138
00139
00140 int channel_read_indication(channel *one)
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 {
00151
00152 long int allowed = ((get_clock() - one->transmission_delay) * one->transmission_speed) / 8000;
00153
00154 if (blevel(one->pdus) > 0)
00155 return (one->read_count < allowed);
00156 else
00157 return 0;
00158 }
00159
00160
00161 byte channel_read(channel *one)
00162
00163
00164
00165 {
00166 static byte b;
00167
00168 bread(one->pdus, &b);
00169
00170 apply_errors(&b, one);
00171
00172 one->read_count++;
00173
00174 return(b);
00175 }
00176
00177
00178 channel *new_channel(char *name)
00179 {
00180 char s[256];
00181 int x;
00182
00183 channel *one = malloc(sizeof(channel));
00184 if (one != NULL) {
00185 strcpy(one->label, name);
00186 one->transmission_speed = DEF_CHANNEL_SPEED;
00187 one->transmission_delay = DEF_CHANNEL_DELAY;
00188 one->error = DEF_CHANNEL_ERROR;
00189 one->bit_error_rate = DEF_CHANNEL_BER;
00190 strcpy(one->filename, DEF_CHANNEL_FILE);
00191 one->pdus = mkbuffer(BUFSIZE, sizeof(byte));
00192 one->error_count = 0;
00193 one->bit_count = 0;
00194 one->write_count=0;
00195 one->read_count=0;
00196 one->error_offset=0;
00197 one->file_open=0;
00198 one->error_file=NULL;
00199 }
00200 else
00201 error("new_channel","Can't malloc new channel");
00202 return (one);
00203 }
00204
00205 void close_channel(channel *c)
00206 {
00207 if (debug) {
00208 fprintf(stdout,"Channel %s:\n",c->label);
00209 fprintf(stdout,"Number of errors: %d\nNumber of bits: %d\n",c->error_count,
00210 c->bit_count);
00211 fprintf(stdout,"BER: %f\n", (float) c->error_count/c->bit_count);
00212 }
00213 if (c->error_file!=NULL)
00214 fclose(c->error_file);
00215 closebuffer(c->pdus);
00216 free(c);
00217 }
00218