3 * Copyright 2007 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
27 #include <gr_ofdm_frame_sink.h>
28 #include <gr_io_signature.h>
35 gr_ofdm_frame_sink::enter_search()
38 fprintf(stderr, "@ enter_search\n");
40 d_state = STATE_SYNC_SEARCH;
45 gr_ofdm_frame_sink::enter_have_sync()
48 fprintf(stderr, "@ enter_have_sync\n");
50 d_state = STATE_HAVE_SYNC;
52 // clear state of demapper
57 d_headerbytelen_cnt = 0;
61 gr_ofdm_frame_sink::enter_have_header()
63 d_state = STATE_HAVE_HEADER;
65 // header consists of two 16-bit shorts in network byte order
66 // payload length is lower 12 bits
67 // whitener offset is upper 4 bits
68 d_packetlen = (d_header >> 16) & 0x0fff;
69 d_packet_whitener_offset = (d_header >> 28) & 0x000f;
73 fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n",
74 d_packetlen, d_packet_whitener_offset);
77 unsigned char gr_ofdm_frame_sink::bpsk_slicer(gr_complex x)
79 return (unsigned char)(x.real() > 0 ? 1 : 0);
82 unsigned int gr_ofdm_frame_sink::bpsk_demapper(const gr_complex *in,
85 unsigned int i=0, bytes_produced=0;
87 while(i < d_occupied_carriers) {
89 while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
90 //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag());
91 d_partial_byte |= bpsk_slicer(in[i++]) << (d_byte_offset++);
94 if(d_byte_offset == 8) {
95 out[bytes_produced++] = d_partial_byte;
101 return bytes_produced;
106 gr_ofdm_frame_sink_sptr
107 gr_make_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
109 return gr_ofdm_frame_sink_sptr(new gr_ofdm_frame_sink(target_queue, occupied_carriers));
113 gr_ofdm_frame_sink::gr_ofdm_frame_sink(gr_msg_queue_sptr target_queue, unsigned int occupied_carriers)
114 : gr_sync_block ("ofdm_frame_sink",
115 gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)),
116 gr_make_io_signature (0, 0, 0)),
117 d_target_queue(target_queue), d_occupied_carriers(occupied_carriers),
118 d_byte_offset(0), d_partial_byte(0)
120 d_bytes_out = new unsigned char[(int)ceil(d_occupied_carriers/8.0)];
125 gr_ofdm_frame_sink::~gr_ofdm_frame_sink ()
127 delete [] d_bytes_out;
131 gr_ofdm_frame_sink::work (int noutput_items,
132 gr_vector_const_void_star &input_items,
133 gr_vector_void_star &output_items)
135 const gr_complex *in = (const gr_complex *) input_items[0];
136 const char *sig = (const char *) input_items[1];
137 int count_tones=0, count_items=0;
139 unsigned int bytes=0;
142 fprintf(stderr,">>> Entering state machine\n");
144 bytes = bpsk_demapper(&in[0], d_bytes_out);
148 case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt
150 fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items);
152 if (sig[0]) { // Found it, set up for header decode
157 case STATE_HAVE_SYNC:
159 printf("ERROR -- Found SYNC in HAVE_SYNC\n");
161 fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
162 d_headerbytelen_cnt, d_header);
166 d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF);
169 if (++d_headerbytelen_cnt == HEADERBYTELEN) {
172 fprintf(stderr, "got header: 0x%08x\n", d_header);
174 // we have a full header, check to see if it has been received properly
177 printf("\nPacket Length: %d\n", d_packetlen);
178 //for(int k=0; k < d_packetlen; k++)
179 // printf("%02x", d_packet[k]);
182 while((j < bytes) && (d_packetlen_cnt < d_packetlen)) {
183 d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
186 if(d_packetlen_cnt == d_packetlen) {
187 gr_message_sptr msg =
188 gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen);
189 memcpy(msg->msg(), d_packet, d_packetlen_cnt);
190 d_target_queue->insert_tail(msg); // send it
191 msg.reset(); // free it up
197 enter_search(); // bad header
203 case STATE_HAVE_HEADER:
205 printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen);
207 fprintf(stderr,"Packet Build\n");
211 d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
213 if (d_packetlen_cnt == d_packetlen){ // packet is filled
215 // NOTE: passing header field as arg1 is not scalable
216 gr_message_sptr msg =
217 gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt);
218 memcpy(msg->msg(), d_packet, d_packetlen_cnt);
220 d_target_queue->insert_tail(msg); // send it
221 msg.reset(); // free it up