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

Revision 5373, 11.4 KB (checked in by jgaeddert, 6 years ago)

modifying subheader extraction methods; initialization of external buffer pointers

  • 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    buf1(NULL),
31    buf2(NULL),
32    buf_len(0)
33{
34    // Initialize P/N synchronization code block
35    pnSyncCode = pn_code_63;
36
37    // Initialize P/N synchronization shift register
38    pn_sync_code = binary_sequence_create();
39    binary_sequence_initialize(pn_sync_code, PN_SYNC_CODE_LENGTH);
40    for (unsigned int i=0; i<PN_SYNC_CODE_LENGTH; i++)
41        binary_sequence_push(pn_sync_code, pnSyncCode[i] & 0x01);
42
43    // Initialize P/N synchronization code block
44    pnControlCode = pn_code_7;
45
46    // Initialize P/N control code shift register
47    pn_control_code = binary_sequence_create();
48    binary_sequence_initialize(pn_control_code, PN_CONTROL_CODE_LENGTH);
49    for (unsigned int i=0; i<PN_CONTROL_CODE_LENGTH; i++)
50        binary_sequence_push(pn_control_code, pnControlCode[i] & 0x01);
51
52    // Initialize control block pointers
53    controlBlock = new char*[NUM_CONTROL_CODES];
54
55    // Default control block codes to be all positive
56    for (unsigned int i=0; i<NUM_CONTROL_CODES; i++)
57        controlBlock[i] = pnControlCode;
58
59    // Initialize shift registers for receiver
60    pn_sync_buffer    = binary_sequence_create();
61    pn_control_buffer = binary_sequence_create();
62    pn_eom_buffer     = binary_sequence_create();
63    binary_sequence_initialize( pn_sync_buffer,    PN_SYNC_CODE_LENGTH );
64    binary_sequence_initialize( pn_control_buffer, PN_CONTROL_CODE_LENGTH );
65    binary_sequence_initialize( pn_eom_buffer,     PN_SYNC_CODE_LENGTH );
66
67}
68
69// Destructor
70PacketizerDSP::~PacketizerDSP()
71{
72    delete [] controlBlock;
73    binary_sequence_destroy(pn_sync_code);
74
75    binary_sequence_destroy( pn_sync_buffer );
76    binary_sequence_destroy( pn_control_buffer );
77    binary_sequence_destroy( pn_eom_buffer );
78}
79
80void PacketizerDSP::SetBuffer(char *_b1, char *_b2, unsigned int _len)
81{
82    buf1 = _b1;
83    buf2 = _b2;
84    buf_len = _len;
85}
86
87// Returns the necessary buffer size for processing given the current
88// packet configuration
89unsigned int PacketizerDSP::RequiredBufferSize(unsigned int input_length)
90{
91    switch (packet_type) {
92    case PACKET_RAW_400:
93        return 512;
94    default:
95        ///\todo calculate buffer size based on coding rate, etc.
96        std::cerr << "ERROR! PacketizerDSP::RequiredBufferSize() "
97                  << "Unsupported packet type: " << packet_type << std::endl;
98        throw 0;
99    }
100
101    // should never get to this point, but include the return statement
102    // to keep the compiler happy
103    return 0;
104}
105
106//
107void PacketizerDSP::ConfigurePacketType( PacketType type )
108{
109    switch (type) {
110    case PACKET_RAW_400:
111        ConfigureControl( 0x00 );
112        dynamic_packet_size = false;
113        packet_subheader_length = 21;
114        packet_data_length = 400;
115        break;
116    default:
117        std::cerr << "ERROR! PacketizerDSP::ConfigurePacketType() "
118                  << "Unsupported packet type: " << type << std::endl;
119        throw 0;
120    }
121
122    packet_type = type;
123}
124
125
126// Sets pointers in controlBlock to appropriate control codes
127void PacketizerDSP::ConfigureControl( unsigned char id )
128{
129    for (unsigned int i=NUM_CONTROL_CODES; i>0; i--) {
130        controlBlock[i-1] = ( id & 0x01 ) ? pn_code_7 : pn_code_7_inv;
131        id >>= 1;
132    }
133}
134
135// Assemble packet and store in output buffer
136void PacketizerDSP::AssemblePacket(
137    char* input,
138    unsigned int input_length,
139    char* output,
140    unsigned int &output_length,
141    PacketType type)
142{
143    unsigned int i;
144    output_index = 0;
145
146    ConfigurePacketType( type );
147
148    // check output size
149    unsigned int output_length_req = RequiredBufferSize(input_length);
150
151    // ensure output buffer is sufficiently long
152    if ( output_length_req > output_length ) {
153        std::cerr << "ERROR! PacketizerDSP::AssemblePacket():" << std::endl
154                  << "  => required output length (" << output_length_req
155                  << ") exceeds buffer size (" << output_length << ")" << std::endl;
156        throw 0;
157    }
158   
159    // ensure output packet does not exceed the maximum allowable
160    if ( output_length_req > MAX_PACKET_SIZE ) {
161        std::cerr << "ERROR! PacketizerDSP::AssemblePacket():" << std::endl
162                  << "  => required output length (" << output_length_req
163                  << ") exceeds maximum size (" << MAX_PACKET_SIZE << ")" << std::endl;
164        throw 0;
165    }
166
167    // write P/N sync code
168    memcpy(output+output_index, pnSyncCode, PN_SYNC_CODE_LENGTH);
169    output_index += PN_SYNC_CODE_LENGTH;
170
171    // write control codes
172    for (i=0; i<NUM_CONTROL_CODES; i++) {
173        memcpy(output+output_index, controlBlock[i], PN_CONTROL_CODE_LENGTH);
174        output_index += PN_CONTROL_CODE_LENGTH;
175    }
176
177    switch (type) {
178    case PACKET_RAW_400:
179
180        // configure sub-header here
181        for (i=0; i<3; i++) {
182            memcpy( output+output_index, pn_code_7_inv, PN_CONTROL_CODE_LENGTH);
183            output_index += PN_CONTROL_CODE_LENGTH;
184        }
185        // output_index should be at this point 112;
186
187        // no error correction coding; copy data to output buffer
188        memcpy( output+output_index, input, 400 );
189        output_index += 400;
190
191        output_length = output_index;
192
193        break;
194    default:
195        std::cerr << "ERROR! PacketizerDSP::AssemblePacket(): unsupported packet type" << std::endl;
196        throw 0;
197    }
198}
199
200bool PacketizerDSP::ExtractPacketHeader(
201    char * input,
202    unsigned int input_length,
203    unsigned int &num_bits_read)
204{
205    rxy = 0;
206    int correlator_threshold(60);
207    unsigned int i(0);
208   
209    for (i=0; i<input_length; i++) {
210        // push bit into shift register
211        binary_sequence_push( pn_sync_buffer, input[i] & 0x01 );
212
213        // correlate with P/N sync code
214        rxy = binary_sequence_correlate( pn_sync_buffer, pn_sync_code );
215
216        //printf("rxy(%d) = %d;\n", i, rxy);
217        if ( abs(rxy) > correlator_threshold ) {
218            //printf("\nPN sync code found!!\n\n");
219            invert_bits = ( rxy < 0 ) ? true : false;
220            num_bits_read = i+1;
221            num_control_codes_extracted = 0;
222            num_control_bits_read = 0;
223            new_packet_type = 0;
224            return true;
225        }
226    }
227
228    num_bits_read = input_length;
229    return false;
230
231}
232
233
234bool PacketizerDSP::ExtractPacketType(
235    char * input,
236    unsigned int input_length,
237    unsigned int &num_bits_read)
238{
239    unsigned int i;
240
241    // Extract control codes to describe packet type.
242    // At this point the P/N sync code header has been found.
243    for (i=0; i<input_length; i++) {
244        // push bit into shift register
245        binary_sequence_push( pn_control_buffer, input[i] & 0x01 );
246        num_control_bits_read++;
247
248        if ( num_control_bits_read==PN_CONTROL_CODE_LENGTH ) {
249            // correlate with control code
250            rxy = binary_sequence_correlate( pn_control_buffer, pn_control_code );
251
252            // store result in new packet type variable
253            new_packet_type <<= 1;
254            if (invert_bits)
255                new_packet_type |= ( rxy > 0 ) ? 0x00 : 0x01;
256            else
257                new_packet_type |= ( rxy > 0 ) ? 0x01 : 0x00;
258
259            num_control_bits_read = 0;
260            num_control_codes_extracted++;
261
262            if ( num_control_codes_extracted == NUM_CONTROL_CODES ) {
263                // try to configure the new packet type
264                ConfigurePacketType( (PacketType) new_packet_type );
265                num_bits_read = i+1;
266                num_subheader_bits_read = 0;
267                return true;
268            }
269        }
270    }
271   
272    num_bits_read = input_length;
273    return false;
274}
275
276
277bool PacketizerDSP::ExtractPacketSubheader(
278    char * input,
279    unsigned int input_length,
280    char * output,
281    unsigned int &output_length)
282{
283    unsigned int i;
284
285    for (i=0; i<input_length; i++) {
286        output[i] = invert_bits ? (~input[i]) & 0x01 : input[i];
287        num_subheader_bits_read++;
288
289        if ( num_subheader_bits_read == packet_subheader_length ) {
290            // subheader data have been extracted
291            num_packet_bits_read = 0;
292            output_length = i+1;
293            return true;
294        }
295    }
296
297    return false;
298}
299
300bool PacketizerDSP::ExtractPacketData(
301    char * input,
302    unsigned int input_length,
303    char * output,
304    unsigned int &output_length)
305{
306    bool packet_extracted;
307
308    if (dynamic_packet_size) {
309        packet_extracted =
310            ExtractPacketDataDynamicLength(input, input_length, output, output_length);
311    } else {
312        packet_extracted =
313            ExtractPacketDataFixedLength(input, input_length, output, output_length);
314    }
315
316    return packet_extracted;
317}
318
319bool PacketizerDSP::ExtractPacketDataDynamicLength(
320    char * input,
321    unsigned int input_length,
322    char * output,
323    unsigned int &output_length)
324{
325    ///\todo look for eom code
326
327    return false;
328}
329
330
331bool PacketizerDSP::ExtractPacketDataFixedLength(
332    char * input,
333    unsigned int input_length,
334    char * output,
335    unsigned int &output_length)
336{
337    unsigned int i;
338
339    for (i=0; i<input_length; i++) {
340        output[i] = invert_bits ? (~input[i]) & 0x01 : input[i];
341        num_packet_bits_read++;
342
343        if (num_packet_bits_read == packet_data_length) {
344            // packet data have been extracted
345            output_length = i+1;
346            return true;
347        }
348    }
349   
350    return false;
351}
352
353
354///
355void PacketizerDSP::EncodePacketData(
356    char * input,
357    unsigned int input_length,
358    char * output,
359    unsigned int &output_length)
360{
361    if (buf1 == NULL || buf2 == NULL) {
362        std::cerr << "ERROR! PacketizerDSP::EncodePacketData() " << std::endl
363                  << "  => buffers not yet initialized!" << std::endl;
364        throw 0;
365    }
366
367    // ensure buffer size is sufficient
368    unsigned int output_length_req = RequiredBufferSize(input_length);
369
370    // ensure output buffer is sufficiently long
371    if ( output_length_req > buf_len ) {
372        std::cerr << "ERROR! PacketizerDSP::EncodePacketData():" << std::endl
373                  << "  => required output length (" << output_length_req
374                  << ") exceeds available buffer size (" << buf_len << ")" << std::endl;
375        throw 0;
376    }
377   
378    switch (packet_type) {
379    case PACKET_RAW_400:
380        // nothing to do; just copy data
381        memcpy( output, input, packet_data_length );
382        output_length = input_length;
383        return;
384    default:;
385        std::cerr << "ERROR! PacketizerDSP::EncodePacketData() " << std::endl
386                  << "  => Unsupported packet type: " << packet_type << std::endl;
387        throw 0;
388    }
389}
390
391
Note: See TracBrowser for help on using the browser.