7d2b309ffc8490a29a2243fc07763e7752a5fe66
[debian/gnuradio] / gr-pager / src / pager_flex_parse.cc
1 /*
2  * Copyright 2004,2006 Free Software Foundation, Inc.
3  * 
4  * This file is part of GNU Radio
5  * 
6  * GNU Radio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  * 
11  * GNU Radio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with GNU Radio; see the file COPYING.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <pager_flex_parse.h>
27 #include <pageri_bch3221.h>
28 #include <gr_io_signature.h>
29
30 pager_flex_parse_sptr pager_make_flex_parse()
31 {
32     return pager_flex_parse_sptr(new pager_flex_parse());
33 }
34
35 pager_flex_parse::pager_flex_parse() :
36     gr_sync_block("flex_parse",
37     gr_make_io_signature(1, 1, sizeof(gr_int32)),
38     gr_make_io_signature(0, 0, 0))
39 {
40     d_count = 0;
41 }
42
43 int pager_flex_parse::work(int noutput_items,
44     gr_vector_const_void_star &input_items,
45     gr_vector_void_star &output_items)
46 {
47     const gr_int32 *in = (const gr_int32 *)input_items[0];
48     
49     int i = 0;
50     while (i < noutput_items) {
51         // Accumulate one whole frame's worth of data words (88 of them)
52         d_datawords[d_count] = *in++; i++;
53         if (++d_count == 88) {
54             parse_data();
55             d_count = 0;
56         }
57     }
58
59     return i;
60 }
61
62 /* FLEX data frames (that is, 88 data words per phase recovered after sync,
63    symbol decoding, dephasing, deinterleaving, error correction, and conversion
64    from codewords to data words) start with a block information word containing
65    indices of the page address field and page vector fields.
66 */
67
68 void pager_flex_parse::parse_capcode(gr_int32 aw1, gr_int32 aw2)
69 {
70     d_laddr = (aw1 < 0x008001L) ||
71               (aw1 > 0x1E0000L) ||
72               (aw1 > 0x1E7FFEL);        
73     
74     if (d_laddr)
75         d_capcode = aw1+((aw2^0x001FFFFF)<<15)+0x1F9000;  // Don't ask
76     else
77         d_capcode = aw1-0x8000;
78 }
79
80 void pager_flex_parse::parse_data()
81 {
82     // Block information word is the first data word in frame
83     gr_int32 biw = d_datawords[0];
84
85     // Nothing to see here, please move along
86     if (biw == 0 || biw == 0x001FFFFF)
87         return;
88
89     // Vector start index is bits 15-10
90     // Address start address is bits 9-8, plus one for offset
91     int voffset = (biw >> 10) & 0x3f;
92     int aoffset = ((biw >> 8) & 0x03) + 1;
93     
94 //  printf("BIW=%08X A=%i V=%i\n", biw, aoffset, voffset);
95
96     // Iterate through pages and dispatch to appropriate handler
97     for (int i = aoffset; i < voffset; i++) {
98         int j = voffset+i-aoffset;              // Start of vector field for address @ i
99
100         if (d_datawords[i] == 0x00000000 ||
101             d_datawords[i] == 0x001FFFFF)
102             continue;                           // Idle codewords, invalid address
103
104         parse_capcode(d_datawords[i], d_datawords[i+1]);
105         if (d_laddr)
106            i++;
107                            
108         if (d_capcode < 0)                      // Invalid address, skip
109           continue;        
110
111         // Parse vector information word for address @ offset 'i'
112         gr_int32 viw = d_datawords[j];
113         d_type = (page_type_t)((viw >> 4) & 0x00000007);
114         int mw1 = (viw >> 7) & 0x00000007F;
115         int len = (viw >> 14) & 0x0000007F;
116
117         if (is_numeric_page(d_type))
118             len &= 0x07;
119         int mw2 = mw1+len;
120             
121         if (mw1 == 0 && mw2 == 0)
122             continue;                           // Invalid VIW
123
124         if (is_tone_page(d_type))
125             mw1 = mw2 = 0;
126
127         if (mw1 > 87 || mw2 > 87)
128             continue;                           // Invalid offsets
129
130         printf("%09i: ", d_capcode);
131
132         if (is_alphanumeric_page(d_type))
133             parse_alphanumeric(mw1, mw2-1);
134         else if (is_numeric_page(d_type))
135             parse_numeric(mw1, mw2);
136         else if (is_tone_page(d_type))
137             parse_tone_only();
138         else
139             parse_unknown(mw1, mw2);
140
141         printf("\n");
142     }
143 }
144
145 void pager_flex_parse::parse_alphanumeric(int mw1, int mw2)
146 {
147     printf("ALPHA");
148
149     for (int i = mw1; i < mw2; i++) {
150         
151     }
152 }
153
154 void pager_flex_parse::parse_numeric(int mw1, int mw2)
155 {
156     printf("NUMERIC");
157 }
158
159 void pager_flex_parse::parse_tone_only()
160 {
161     printf("TONE");
162 }
163
164 void pager_flex_parse::parse_unknown(int mw1, int mw2)
165 {
166     printf("UNKNOWN");
167 }