Statistics
| Branch: | Tag: | Revision:

root / gnuradio-core / src / lib / general / gr_framer_sink_1.cc @ c96ea672

History | View | Annotate | Download (4.8 kB)

1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2004,2006,2010 Free Software Foundation, Inc.
4
 * 
5
 * This file is part of GNU Radio
6
 * 
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 3, or (at your option)
10
 * any later version.
11
 * 
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.
16
 * 
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.
21
 */
22
23
#ifdef HAVE_CONFIG_H
24
#include "config.h"
25
#endif
26
27
#include <gr_framer_sink_1.h>
28
#include <gr_io_signature.h>
29
#include <cstdio>
30
#include <stdexcept>
31
#include <string.h>
32
33
#define VERBOSE 0
34
35
inline void
36
gr_framer_sink_1::enter_search()
37
{
38
  if (VERBOSE)
39
    fprintf(stderr, "@ enter_search\n");
40
41
  d_state = STATE_SYNC_SEARCH;
42
}
43
    
44
inline void
45
gr_framer_sink_1::enter_have_sync()
46
{
47
  if (VERBOSE)
48
    fprintf(stderr, "@ enter_have_sync\n");
49
50
  d_state = STATE_HAVE_SYNC;
51
  d_header = 0;
52
  d_headerbitlen_cnt = 0;
53
}
54
55
inline void
56
gr_framer_sink_1::enter_have_header(int payload_len, int whitener_offset)
57
{
58
  if (VERBOSE)
59
    fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", payload_len, whitener_offset);
60
61
  d_state = STATE_HAVE_HEADER;
62
  d_packetlen = payload_len;
63
  d_packet_whitener_offset = whitener_offset;
64
  d_packetlen_cnt = 0;
65
  d_packet_byte = 0;
66
  d_packet_byte_index = 0;
67
}
68
69
gr_framer_sink_1_sptr
70
gr_make_framer_sink_1(gr_msg_queue_sptr target_queue)
71
{
72
  return gnuradio::get_initial_sptr(new gr_framer_sink_1(target_queue));
73
}
74
75
76
gr_framer_sink_1::gr_framer_sink_1(gr_msg_queue_sptr target_queue)
77
  : gr_sync_block ("framer_sink_1",
78
                   gr_make_io_signature (1, 1, sizeof(unsigned char)),
79
                   gr_make_io_signature (0, 0, 0)),
80
    d_target_queue(target_queue)
81
{
82
  enter_search();
83
}
84
85
gr_framer_sink_1::~gr_framer_sink_1 ()
86
{
87
}
88
89
int
90
gr_framer_sink_1::work (int noutput_items,
91
                        gr_vector_const_void_star &input_items,
92
                        gr_vector_void_star &output_items)
93
{
94
  const unsigned char *in = (const unsigned char *) input_items[0];
95
  int count=0;
96
  
97
  if (VERBOSE)
98
    fprintf(stderr,">>> Entering state machine\n");
99
100
  while (count < noutput_items){
101
    switch(d_state) {
102
      
103
    case STATE_SYNC_SEARCH:    // Look for flag indicating beginning of pkt
104
      if (VERBOSE)
105
        fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items);
106
107
      while (count < noutput_items) {
108
        if (in[count] & 0x2){  // Found it, set up for header decode
109
          enter_have_sync();
110
          break;
111
        }
112
        count++;
113
      }
114
      break;
115
116
    case STATE_HAVE_SYNC:
117
      if (VERBOSE)
118
        fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
119
                d_headerbitlen_cnt, d_header);
120
121
      while (count < noutput_items) {        // Shift bits one at a time into header
122
        d_header = (d_header << 1) | (in[count++] & 0x1);
123
        if (++d_headerbitlen_cnt == HEADERBITLEN) {
124
125
          if (VERBOSE)
126
            fprintf(stderr, "got header: 0x%08x\n", d_header);
127
128
          // we have a full header, check to see if it has been received properly
129
          if (header_ok()){
130
            int payload_len;
131
            int whitener_offset;
132
            header_payload(&payload_len, &whitener_offset);
133
            enter_have_header(payload_len, whitener_offset);
134
135
            if (d_packetlen == 0){            // check for zero-length payload
136
              // build a zero-length message
137
              // NOTE: passing header field as arg1 is not scalable
138
              gr_message_sptr msg =
139
                gr_make_message(0, d_packet_whitener_offset, 0, 0);
140
              
141
              d_target_queue->insert_tail(msg);                // send it
142
              msg.reset();                                  // free it up
143
144
              enter_search();                                
145
            }
146
          }
147
          else
148
            enter_search();                                // bad header
149
          break;                                        // we're in a new state
150
        }
151
      }
152
      break;
153
      
154
    case STATE_HAVE_HEADER:
155
      if (VERBOSE)
156
        fprintf(stderr,"Packet Build\n");
157
158
      while (count < noutput_items) {   // shift bits into bytes of packet one at a time
159
        d_packet_byte = (d_packet_byte << 1) | (in[count++] & 0x1);
160
        if (d_packet_byte_index++ == 7) {                  // byte is full so move to next byte
161
          d_packet[d_packetlen_cnt++] = d_packet_byte;
162
          d_packet_byte_index = 0;
163
164
          if (d_packetlen_cnt == d_packetlen){                // packet is filled
165
166
            // build a message
167
            // NOTE: passing header field as arg1 is not scalable
168
            gr_message_sptr msg =
169
              gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt);
170
            memcpy(msg->msg(), d_packet, d_packetlen_cnt);
171
172
            d_target_queue->insert_tail(msg);                // send it
173
            msg.reset();                                  // free it up
174
175
            enter_search();
176
            break;
177
          }
178
        }
179
      }
180
      break;
181
182
    default:
183
      assert(0);
184
185
    } // switch
186
187
  }   // while
188
189
  return noutput_items;
190
}