⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ofdm_c.txt

📁 用c语言实现OFDM 的调制 相当有用的程序
💻 TXT
📖 第 1 页 / 共 3 页
字号:
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 + -