root/experimental/components/Packetizer/trunk/Packetizer-metadata/src/PacketizerDSP.cpp @ 5283

Revision 5283, 10.0 KB (checked in by jgaeddert, 6 years ago)

fixing bug; flags/counters not set properly. Packetizer/depacketizer now works properly for situations with bit inversions

  • Property svn:eol-style set to native
Line 
1/****************************************************************************
2
3Copyright 2007 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Packetizer.
6
7OSSIE Packetizer is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12OSSIE Packetizer is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OSSIE Packetizer; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21****************************************************************************/
22
23
24#include <iostream>
25#include "PacketizerDSP.h"
26#include <math.h>
27
28// Default constructor
29PacketizerDSP::PacketizerDSP()
30{
31    // Initialize P/N synchronization code block
32    pnSyncCode = pn_code_63;
33
34    // Initialize P/N synchronization shift register
35    pn_sync_code = binary_sequence_create();
36    binary_sequence_initialize(pn_sync_code, PN_SYNC_CODE_LENGTH);
37    for (unsigned int i=0; i<PN_SYNC_CODE_LENGTH; i++)
38        binary_sequence_push(pn_sync_code, pnSyncCode[i] & 0x01);
39
40    // Initialize P/N synchronization code block
41    pnControlCode = pn_code_7;
42
43    // Initialize P/N control code shift register
44    pn_control_code = binary_sequence_create();
45    binary_sequence_initialize(pn_control_code, PN_CONTROL_CODE_LENGTH);
46    for (unsigned int i=0; i<PN_CONTROL_CODE_LENGTH; i++)
47        binary_sequence_push(pn_control_code, pnControlCode[i] & 0x01);
48
49    // Initialize control block pointers
50    controlBlock = new char*[NUM_CONTROL_CODES];
51
52    // Default control block codes to be all positive
53    for (unsigned int i=0; i<NUM_CONTROL_CODES; i++)
54        controlBlock[i] = pnControlCode;
55
56    // Initialize shift registers for receiver
57    pn_sync_buffer    = binary_sequence_create();
58    pn_control_buffer = binary_sequence_create();
59    pn_eom_buffer     = binary_sequence_create();
60    binary_sequence_initialize( pn_sync_buffer,    PN_SYNC_CODE_LENGTH );
61    binary_sequence_initialize( pn_control_buffer, PN_CONTROL_CODE_LENGTH );
62    binary_sequence_initialize( pn_eom_buffer,     PN_SYNC_CODE_LENGTH );
63
64}
65
66// Destructor
67PacketizerDSP::~PacketizerDSP()
68{
69    delete [] controlBlock;
70    binary_sequence_destroy(pn_sync_code);
71
72    binary_sequence_destroy( pn_sync_buffer );
73    binary_sequence_destroy( pn_control_buffer );
74    binary_sequence_destroy( pn_eom_buffer );
75}
76
77// Returns the necessary buffer size for processing given the current
78// packet configuration
79unsigned int PacketizerDSP::RequiredBufferSize(unsigned int input_length)
80{
81    switch (packet_type) {
82    case PACKET_RAW_400:
83        return 512;
84    default:
85        ///\todo calculate buffer size based on coding rate, etc.
86        std::cerr << "ERROR! PacketizerDSP::RequiredBufferSize() "
87                  << "Unsupported packet type: " << packet_type << std::endl;
88        throw 0;
89    }
90
91    // should never get to this point, but include the return statement
92    // to keep the compiler happy
93    return 0;
94}
95
96//
97void PacketizerDSP::ConfigurePacketType( PacketType type )
98{
99    switch (type) {
100    case PACKET_RAW_400:
101        ConfigureControl( 0x00 );
102        dynamic_packet_size = false;
103        packet_subheader_length = 21;
104        packet_data_length = 400;
105        break;
106    default:
107        std::cerr << "ERROR! PacketizerDSP::ConfigurePacketType() "
108                  << "Unsupported packet type: " << type << std::endl;
109        throw 0;
110    }
111
112    packet_type = type;
113}
114
115
116// Sets pointers in controlBlock to appropriate control codes
117void PacketizerDSP::ConfigureControl( unsigned char id )
118{
119    for (unsigned int i=NUM_CONTROL_CODES; i>0; i--) {
120        controlBlock[i-1] = ( id & 0x01 ) ? pn_code_7 : pn_code_7_inv;
121        id >>= 1;
122    }
123}
124
125// Assemble packet and store in output buffer
126void PacketizerDSP::AssemblePacket(
127    char* input,
128    unsigned int input_length,
129    char* output,
130    unsigned int &output_length,
131    PacketType type)
132{
133    unsigned int i;
134    output_index = 0;
135
136    ConfigurePacketType( type );
137
138    // check output size
139    unsigned int output_length_req = RequiredBufferSize(input_length);
140
141    // ensure output buffer is sufficiently long
142    if ( output_length_req > output_length ) {
143        std::cerr << "ERROR! PacketizerDSP::AssemblePacket():" << std::endl
144                  << "  => required output length (" << output_length_req
145                  << ") exceeds buffer size (" << output_length << ")" << std::endl;
146        throw 0;
147    }
148   
149    // ensure output packet does not exceed the maximum allowable
150    if ( output_length_req > MAX_PACKET_SIZE ) {
151        std::cerr << "ERROR! PacketizerDSP::AssemblePacket():" << std::endl
152                  << "  => required output length (" << output_length_req
153                  << ") exceeds maximum size (" << MAX_PACKET_SIZE << ")" << std::endl;
154        throw 0;
155    }
156
157    // write P/N sync code
158    memcpy(output+output_index, pnSyncCode, PN_SYNC_CODE_LENGTH);
159    output_index += PN_SYNC_CODE_LENGTH;
160
161    // write control codes
162    for (i=0; i<NUM_CONTROL_CODES; i++) {
163        memcpy(output+output_index, controlBlock[i], PN_CONTROL_CODE_LENGTH);
164        output_index += PN_CONTROL_CODE_LENGTH;
165    }
166
167    switch (type) {
168    case PACKET_RAW_400:
169
170        // configure sub-header here
171        for (i=0; i<3; i++) {
172            memcpy( output+output_index, pn_code_7_inv, PN_CONTROL_CODE_LENGTH);
173            output_index += PN_CONTROL_CODE_LENGTH;
174        }
175        // output_index should be at this point 112;
176
177        // no error correction coding; copy data to output buffer
178        memcpy( output+output_index, input, 400 );
179        output_index += 400;
180
181        output_length = output_index;
182
183        break;
184    default:
185        std::cerr << "ERROR! PacketizerDSP::AssemblePacket(): unsupported packet type" << std::endl;
186        throw 0;
187    }
188}
189
190bool PacketizerDSP::ExtractPacketHeader(
191    char * input,
192    unsigned int input_length,
193    unsigned int &num_bits_read)
194{
195    rxy = 0;
196    int correlator_threshold(60);
197    unsigned int i(0);
198   
199    for (i=0; i<input_length; i++) {
200        // push bit into shift register
201        binary_sequence_push( pn_sync_buffer, input[i] & 0x01 );
202
203        // correlate with P/N sync code
204        rxy = binary_sequence_correlate( pn_sync_buffer, pn_sync_code );
205
206        //printf("rxy(%d) = %d;\n", i, rxy);
207        if ( abs(rxy) > correlator_threshold ) {
208            //printf("\nPN sync code found!!\n\n");
209            invert_bits = ( rxy < 0 ) ? true : false;
210            num_bits_read = i+1;
211            num_control_codes_extracted = 0;
212            num_control_bits_read = 0;
213            new_packet_type = 0;
214            return true;
215        }
216    }
217
218    num_bits_read = input_length;
219    return false;
220
221}
222
223
224bool PacketizerDSP::ExtractPacketType(
225    char * input,
226    unsigned int input_length,
227    unsigned int &num_bits_read)
228{
229    unsigned int i;
230
231    // Extract control codes to describe packet type.
232    // At this point the P/N sync code header has been found.
233    for (i=0; i<input_length; i++) {
234        // push bit into shift register
235        binary_sequence_push( pn_control_buffer, input[i] & 0x01 );
236        num_control_bits_read++;
237
238        if ( num_control_bits_read==PN_CONTROL_CODE_LENGTH ) {
239            // correlate with control code
240            rxy = binary_sequence_correlate( pn_control_buffer, pn_control_code );
241
242            // store result in new packet type variable
243            new_packet_type <<= 1;
244            if (invert_bits)
245                new_packet_type |= ( rxy > 0 ) ? 0x00 : 0x01;
246            else
247                new_packet_type |= ( rxy > 0 ) ? 0x01 : 0x00;
248
249            num_control_bits_read = 0;
250            num_control_codes_extracted++;
251
252            if ( num_control_codes_extracted == NUM_CONTROL_CODES ) {
253                // try to configure the new packet type
254                ConfigurePacketType( (PacketType) new_packet_type );
255                num_bits_read = i+1;
256                num_subheader_bits_read = 0;
257                return true;
258            }
259        }
260    }
261   
262    num_bits_read = input_length;
263    return false;
264}
265
266
267bool PacketizerDSP::ExtractPacketSubheader(
268    char * input,
269    unsigned int input_length,
270    unsigned int &num_bits_read)
271{
272    unsigned int i;
273
274    for (i=0; i<input_length; i++) {
275        ///\todo do something with the subheader bits here
276        num_subheader_bits_read++;
277
278        if ( num_subheader_bits_read == packet_subheader_length ) {
279            num_packet_bits_read = 0;
280            num_bits_read = i+1;
281            return true;
282        }
283    }
284
285    return false;
286}
287
288bool PacketizerDSP::ExtractPacketData(
289    char * input,
290    unsigned int input_length,
291    char * output,
292    unsigned int &output_length)
293{
294    bool packet_extracted;
295
296    if (dynamic_packet_size) {
297        packet_extracted =
298            ExtractPacketDataDynamicLength(input, input_length, output, output_length);
299    } else {
300        packet_extracted =
301            ExtractPacketDataFixedLength(input, input_length, output, output_length);
302    }
303
304    return packet_extracted;
305}
306
307bool PacketizerDSP::ExtractPacketDataDynamicLength(
308    char * input,
309    unsigned int input_length,
310    char * output,
311    unsigned int &output_length)
312{
313    ///\todo look for eom code
314
315    return false;
316}
317
318
319bool PacketizerDSP::ExtractPacketDataFixedLength(
320    char * input,
321    unsigned int input_length,
322    char * output,
323    unsigned int &output_length)
324{
325    unsigned int i;
326
327    for (i=0; i<input_length; i++) {
328        output[i] = invert_bits ? (~input[i]) & 0x01 : input[i];
329        num_packet_bits_read++;
330
331        if (num_packet_bits_read == packet_data_length) {
332            // packet data have been extracted
333            output_length = i+1;
334            return true;
335        }
336    }
337   
338    return false;
339}
340
341
Note: See TracBrowser for help on using the browser.