📄 ofdm_c.txt
字号:
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <sys/ioctl.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <sys/socket.h>
11 #include <linux/if.h>
12 #include <linux/if_tun.h>
13 #include <errno.h>
14 #include <zlib.h>
15 #include <sys/time.h>
16 #include <time.h>
17 #include <assert.h>
18 #include <fftw3.h>
19 #include <math.h>
20 #include "ieee80211a.h"
21 #include "nalla.h"
22
23 char *
24 read_input(char *filename, int nbytes)
25 {
26 FILE *file;
27 unsigned char *msg = (unsigned char *)malloc(nbytes);
28
29 if (filename == 0)
30 file = stdin;
31 else
32 file = fopen(filename, "r");
33
34 fread(msg, 1, nbytes, file);
35 return msg;
36 }
37
38 void
39 print_bytes(unsigned char *bytes, int nbytes)
40 {
41 int i;
42 for (i=0; i<nbytes; i++)
43 printf("%.2x ", bytes[i]);
44 printf("\n");
45 }
46
47 void
48 print_bits(unsigned char *in, int nbits)
49 {
50 int i, bit;
51 for (i = 0; i < nbits; i++) {
52 bit = (in[i/8] >> (i % 8)) & 1;
53 bit = in[i];
54 //printf("%d %d\n", i, bit);
55 printf("%d", bit);
56 if (i%4 == 3)
57 printf("\n");
58 if (i%16 == 15)
59 printf("\n");
60 }
61 printf("\n");
62 }
63
64 void
65 fwrite_bits(char *filename, unsigned char *in, int nbits)
66 {
67 int i, j, bit;
68 unsigned char byte;
69 FILE *f;
70
71 f = fopen(filename, "w");
72 if (!f) {
73 perror("fwrite_bits");
74 return;
75 }
76
77 for (i = 0; i < nbits;) {
78 byte = 0;
79 for (j=0; (i<nbits) && (j<8); i++, j++) {
80 byte = byte | ((in[i] & 1) << j);
81 }
82 fwrite(&byte, 1, 1, f);
83 }
84
85 fclose(f);
86 }
87
88 void
89 print_hw_data(unsigned char *in, int n, int offset)
90 {
91 int i;
92 for (i=0; i<n; i++) {
93 printf("%d:\t%d\t%x\n", i, in[i+offset], in[i+offset]);
94 }
95 }
96
97 int
98 init_tap(void)
99 {
100 int tap;
101 struct ifreq ifr;
102
103 tap = open("/dev/net/tun", O_RDWR);
104 if (tap < 0) {
105 perror("open tap");
106 exit(1);
107 }
108
109 memset(&ifr, 0, sizeof(ifr));
110 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
111 if (ioctl(tap, TUNSETIFF, (void *) &ifr) < 0) {
112 perror("ioctl tap");
113 exit(1);
114 }
115
116 if(fcntl(tap, F_SETFL, O_NONBLOCK) < 0 )
117 perror("fcntl");
118
119 return tap;
120 }
121
122 #define OFDM_DATA_ID 0x1
123 #define OFDM_NCARRIERS_ID 0x2
124 #define OFDM_GUARD_ID 0x3
125 #define OFDM_MOD_ID 0x4
126
127 static fftw_complex table_modulation[4][64];
128 static fftw_complex *ifft_in;
129 static fftw_complex *ifft_out;
130 static fftw_plan ifft_plan;
131 static fftw_complex *fft_in;
132 static fftw_complex *fft_out;
133 static fftw_plan fft_plan;
134
135 void
136 ofdm_init_modulation(void)
137 {
138 const int fft_size = 256;
139 int i;
140 double d0, d1;
141
142 memset(table_modulation, 0, 4*64*sizeof(fftw_complex));
143
144 // BPSK
145 d0 = 1.0 / sqrt(13.0/6.0);
146 table_modulation[BPSK][0][0] = -1.0*d0;
147 table_modulation[BPSK][0][1] = 0.0;
148 table_modulation[BPSK][1][0] = 1.0*d0;
149 table_modulation[BPSK][1][1] = 0.0;
150
151 // BPSK for short preamble
152 table_modulation[BPSK][2][0] = -1.0;
153 table_modulation[BPSK][2][1] = -1.0;
154 table_modulation[BPSK][3][0] = 1.0;
155 table_modulation[BPSK][3][1] = 1.0;
156
157 // QPSK
158 d1 = 1.0 / sqrt(2.0);
159 d1 = d0 * d1;
160 double qpsk[] = {-1.0, 1.0};
161 for(i=0; i<4; i++) {
162 table_modulation[QPSK][i][0] = d1 * qpsk[i & 1]; /* I */
163 table_modulation[QPSK][i][1] = d1 * qpsk[i >> 1]; /* Q */
164 }
165
166 // 16-QAM
167 d1 = 1.0 / sqrt(10.0);
168 d1 = d0 * d1;
169 double qam16[] = {-3.0, 3.0, -1.0, 1.0};
170 for(i=0; i<16; i++) {
171 table_modulation[QAM16][i][0] = d1 * qam16[i & 0x3]; /* I */
172 table_modulation[QAM16][i][1] = d1 * qam16[i >> 2]; /* Q */
173 }
174
175 // 64-QAM
176 d1 = 1.0 / sqrt(42.0);
177 d1 = d0 * d1;
178 double qam64[] = {-7.0, 7.0, -1.0, 1.0, -5.0, 5.0, -3.0, 3.0};
179 for(i=0; i<64; i++) {
180 table_modulation[QAM64][i][0] = d1 * qam64[i & 0x7]; /* I */
181 table_modulation[QAM64][i][1] = d1 * qam64[i >> 3]; /* Q */
182 }
183
184 ifft_in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft_size);
185 ifft_out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft_size);
186 ifft_plan = fftw_plan_dft_1d(fft_size, ifft_in, ifft_out, FFTW_BACKWARD, FFTW_MEASURE);
187
188 fft_in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft_size);
189 fft_out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * fft_size);
190 fft_plan = fftw_plan_dft_1d(fft_size, fft_in, fft_out, FFTW_FORWARD, FFTW_MEASURE);
191 }
192
193 // data sink emulating the modulation hardware
194 // assumes the data came from prepare_data() and we're doing 256 pt ifft
195 void
196 ofdm_modulate_ieee80211a(unsigned char *in, fftw_complex *out, int nin, int *nout)
197 {
198 // temporaries
199 int j, k, n, mod, enable;
200 unsigned char addr, data;
201 fftw_complex *sample;
202 fftw_complex zero;
203 zero[0] = 0.0;
204 zero[1] = 0.0;
205
206 // state
207 const int fft_size = 256;
208 int i;
209 int mod_table[fft_size];
210 int guard = 0;
211 int ncarriers = 0;
212
213 memset(mod_table, 0, fft_size*sizeof(int));
214 *nout = 0;
215
216 i=0;
217 while (i<nin) {
218 data = in[i++];
219 switch (data) {
220 // symbols
221 case OFDM_DATA_ID:
222 n = in[i++];
223 for (k=0; k<n/ncarriers; k++) {
224
225 for (j=0; j<fft_size; j++) {
226 mod = mod_table[j];
227 if (mod) {
228 data = in[i++];
229 } else {
230 data = 0;
231 }
232 enable = (data & 0x80) && (mod & 0x08);
233 if (enable) {
234 data &= 0x7f;
235 mod &= 0x3;
236 memcpy(&ifft_in[j], &table_modulation[mod][data], sizeof(fftw_complex));
237 } else {
238 memcpy(&ifft_in[j], &zero, sizeof(fftw_complex));
239 }
240 }
241
242 fftw_execute(ifft_plan);
243 memcpy(out, ifft_out+(fft_size-guard), guard*sizeof(fftw_complex));
244 out += guard;
245 *nout += guard;
246 memcpy(out, ifft_out, fft_size*sizeof(fftw_complex));
247 out += fft_size;
248 *nout += fft_size;
249 }
250 break;
251 case OFDM_MOD_ID:
252 n = in[i++];
253 for (j=0; j<n; j++) {
254 addr = in[i+0];
255 data = in[i+1];
256 mod_table[addr+0] = data & 0xf;
257 mod_table[addr+1] = data >> 4;
258 i+=2;
259 }
260 break;
261 case OFDM_NCARRIERS_ID:
262 ncarriers = in[i++];
263 break;
264 case OFDM_GUARD_ID:
265 guard = in[i++];
266 break;
267 default:
268 break;
269 }
270 }
271 }
272
273 unsigned char *
274 ofdm_demodulate_ieee80211a(fftw_complex *complex_samples, int n)
275 {
276 int nbytes;
277 char *data = malloc(5000);
278
279 // skip preamble
280 fftw_complex *c = complex_samples + (4 * 320);
281
282 // demodulate SIGNAL symbol
283 unsigned char *mod_ctl = malloc(100);
284 ofdm_mod_80211a(mod_ctl, BPSK);
285 ofdm_demodulate_symbols(c, 1, data, mod_ctl, 64);
286 c += 320;
287
288 // decode PLCP
289 int rate, nsyms;
290 int p = ieee80211a_decode_signal_symbol(data, &rate, &nbytes, &nsyms);
291 if (p) {
292 fprintf(stderr, "PLCP decode failed\n");
293 goto out;
294 } else {
295 printf("receiving %d symbols, %d bytes, %s\n", nsyms, nbytes, rate_to_char[rate]);
296 }
297
298 // demodulate DATA symbols
299 ofdm_mod_80211a(mod_ctl, rate);
300 ofdm_demodulate_symbols(c, nsyms, data, mod_ctl, 64);
301
302 // decode DATA symbols
303 data = ieee80211a_decode_data_symbols(data, nsyms, &n, rate);
304
305 out:
306 //free(data);
307 free(mod_ctl);
308 return data;
309 }
310
311 #define REAL(c) c[0][0]
312 #define IMAG(c) c[0][1]
313
314 static unsigned char
315 ofdm_demodulate_subcarriers_bpsk(fftw_complex *c)
316 {
317 unsigned char b0;
318 //printf("c %f\n", c[0][0]);
319 b0 = c[0][0] > 0.0;
320 return b0;
321 }
322
323 static unsigned char
324 ofdm_demodulate_subcarriers_qpsk(fftw_complex *c)
325 {
326 unsigned char b0, b1;
327 b0 = REAL(c) > 0;
328 b1 = IMAG(c) > 0;
329 return (b1 << 1) | b0;
330 }
331
332 static unsigned char
333 ofdm_demodulate_subcarriers_qam16(fftw_complex *c)
334 {
335 unsigned char b0, b1, b2, b3;
336 double d = sqrt(10.0) * sqrt(13.0/6.0);
337 double i = fabs((REAL(c) * d) / 256);
338 double q = fabs((IMAG(c) * d) / 256);
339
340 b0 = REAL(c) > 0;
341 b1 = i < 2;
342 b2 = IMAG(c) > 0;
343 b3 = q < 2;
344 return (b3 << 3) | (b2 << 2) | (b1 << 1) | b0;
345 }
346
347 static unsigned char
348 ofdm_demodulate_subcarriers_qam64(fftw_complex *c)
349 {
350 unsigned char b0, b1, b2;
351 unsigned char b3, b4, b5;
352 double d = sqrt(42.0) * sqrt(13.0/6.0);
353 double i = fabs((REAL(c) * d) / 256);
354 double q = fabs((IMAG(c) * d) / 256);
355
356 b0 = REAL(c) > 0;
357 b1 = i < 4;
358 b2 = (i > 2) && (i < 6);
359
360 b3 = IMAG(c) > 0;
361 b4 = q < 4;
362 b5 = (q > 2) && (q < 6);
363
364 return (b5 << 5) | (b4 << 4) | (b3 << 3) | (b2 << 2) | (b1 << 1) | b0;
365 }
366
367 #undef REAL
368 #undef IMAG
369
370 static unsigned char (*ofdm_demodulate_subcarriers[4])(fftw_complex *) = {
371 &ofdm_demodulate_subcarriers_qam64,
372 &ofdm_demodulate_subcarriers_qam16,
373 &ofdm_demodulate_subcarriers_qpsk,
374 &ofdm_demodulate_subcarriers_bpsk
375 };
376
377 int
378 ofdm_demodulate_symbols(fftw_complex *in, int nofdm, unsigned char *out, unsigned char *ctl, int guard)
379 {
380 int i, j, k, n, mod;
381 unsigned char decision;
382 fftw_complex *inp = in;
383 int *mod_table = calloc(256, sizeof(int));
384
385 // expect a MOD block
386 i = j = k = 0;
387 if (ctl[i++] == OFDM_MOD_ID) {
388 n = ctl[i++];
389 for (j=0; j<n; j++) {
390 int addr = ctl[i+0];
391 int data = ctl[i+1];
392 mod_table[addr+0] = data & 0xf;
393 mod_table[addr+1] = data >> 4;
394 i+=2;
395 }
396 } else
397 goto out;
398
399 // for each symbol
400 for (i=0; i<nofdm; i++) {
401
402 // skip cyclic extention
403 inp += guard;
404
405 // compute the fft
406 memcpy(fft_in, inp, 256*sizeof(fftw_complex));
407 fftw_execute(fft_plan);
408
409
410 // for each subcarrier, demodulate
411 for (j=0; j<256; j++) {
412 mod = mod_table[j];
413 if (mod) {
414 out[k++] = (*ofdm_demodulate_subcarriers[mod & 0x3])(&fft_out[j]);
415 }
416 }
417
418 inp += 256;
419 }
420
421 out:
422 free(mod_table);
423 return k;
424 }
425
426 int
427 ofdm_map_to_ifft(unsigned char *in, unsigned char *out, int nsyms,
428 int ncarriers, int carrier_offset, int ifft_size)
429 {
430 int i,j,c,d;
431
432 for (i=0; i<nsyms; i++) {
433
434 // c = the leftmost carrier
435 c = carrier_offset - (ncarriers/2);
436
437 for (j=0; j<ncarriers; j++) {
438 d = (c + ifft_size) % ifft_size;
439 out[d] = in[j];
440 c++;
441 }
442 in += ncarriers;
443 out += ifft_size;
444 }
445 return ifft_size*nsyms;
446 }
447
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -