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

Revision 5520, 30.4 KB (checked in by jgaeddert, 6 years ago)

creating RS objects to be members of the base class; move to more efficient processing

  • 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
29PacketizerBase::PacketizerBase()
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    packet_header_length = NUM_CONTROL_CODES*PN_CONTROL_CODE_LENGTH;
50
51    // initialize buffers
52    buf1 = new unsigned char[MAX_PACKET_SIZE];
53    buf2 = new unsigned char[MAX_PACKET_SIZE];
54    buf3 = new unsigned char[MAX_PACKET_SIZE];
55    buf_len = MAX_PACKET_SIZE;
56
57    // 4-bit RS (15,11) code for 12 blocks
58    //    132 4-bit symbols (uncoded)
59    // -> 180 4-bit symbols (coded)
60    // symsize = 4;
61    // nn = (1<<symsize)-1 = 15
62    // nroots = 4;
63    // kk = nn-nroots = 11
64    rs_4_15_11 = init_rs_char(4,0x13,1,1,4,0);
65
66    // 6-bit RS (63,55) punctured to (35,27)
67    //    27 symbols (uncoded)
68    // -> 35 symbols (coded)
69    // symsize = 6;
70    // npad = 28;
71    // nn = (1<<symsize)-1-npad = 63-28 = 35
72    // nroots = 8;
73    // kk = nn-nroots = 35-8 = 27
74    rs_6_35_27 = init_rs_char(6,0x43,1,1,8,28);
75
76    src_id = 0;
77    dst_id = 0;
78    port_id = 0;
79    app_id = 0;
80    packet_id = 0;
81}
82
83// Destructor
84PacketizerBase::~PacketizerBase()
85{
86    binary_sequence_destroy(pn_sync_code);
87    free_rs_char(rs_4_15_11);
88    free_rs_char(rs_6_35_27);
89
90    delete [] buf1;
91    delete [] buf2;
92    delete [] buf3;
93}
94
95PacketEncoder::PacketEncoder()
96{
97    // Initialize control block pointers
98    controlBlock = new char*[NUM_CONTROL_CODES];
99
100    // Default control block codes to be all positive
101    for (unsigned int i=0; i<NUM_CONTROL_CODES; i++)
102        controlBlock[i] = pnControlCode;
103}
104
105PacketDecoder::PacketDecoder()
106{
107    // Initialize shift registers for receiver
108    pn_sync_buffer    = binary_sequence_create();
109    pn_control_buffer = binary_sequence_create();
110    pn_eom_buffer     = binary_sequence_create();
111    binary_sequence_initialize( pn_sync_buffer,    PN_SYNC_CODE_LENGTH );
112    binary_sequence_initialize( pn_control_buffer, PN_CONTROL_CODE_LENGTH );
113    binary_sequence_initialize( pn_eom_buffer,     PN_SYNC_CODE_LENGTH );
114
115    op_mode = FIND_HEADER;
116}
117
118// Destructor
119PacketEncoder::~PacketEncoder()
120{
121    delete [] controlBlock;
122}
123
124// Destructor
125PacketDecoder::~PacketDecoder()
126{
127    binary_sequence_destroy( pn_sync_buffer );
128    binary_sequence_destroy( pn_control_buffer );
129    binary_sequence_destroy( pn_eom_buffer );
130}
131
132void PacketizerBase::SetBuffer(unsigned char *_b1, unsigned char *_b2, unsigned int _len)
133{
134    buf1 = _b1;
135    buf2 = _b2;
136    buf_len = _len;
137}
138
139// Returns the necessary buffer size for processing given the current
140// packet configuration
141unsigned int PacketizerBase::RequiredBufferSize(unsigned int input_length)
142{
143    switch (packet_type) {
144    case PACKET_RAW_400:
145        return 512;
146    case PACKET_RS_512:
147        return 1024;
148    default:
149        ///\todo calculate buffer size based on coding rate, etc.
150        std::cerr << "ERROR! PacketizerBase::RequiredBufferSize() "
151                  << "Unsupported packet type: " << packet_type << std::endl;
152        throw 0;
153    }
154
155    // should never get to this point, but include the return statement
156    // to keep the compiler happy
157    return 0;
158}
159
160//
161void PacketizerBase::CheckBuffers(unsigned int input_length)
162{
163    if (buf1 == NULL || buf2 == NULL) {
164        std::cerr << "ERROR! PacketizerBase:" << std::endl
165                  << "  => buffers not yet initialized!" << std::endl;
166        throw 0;
167    }
168
169    // ensure buffer size is sufficient
170    unsigned int output_length_req = RequiredBufferSize(input_length);
171
172    // ensure output buffer is sufficiently long
173    if ( output_length_req > buf_len ) {
174        std::cerr << "ERROR! PacketizerBase:" << std::endl
175                  << "  => required output length (" << output_length_req
176                  << ") exceeds available buffer size (" << buf_len << ")" << std::endl;
177        throw 0;
178    }
179}
180
181
182//
183void PacketEncoder::ConfigurePacketType( PacketType type )
184{
185    switch (type) {
186    case PACKET_RAW_400:
187        ConfigureControl( 0x00 );
188        dynamic_packet_size = false;
189        packet_subheader_length = 21;
190        packet_data_length = 400;
191        packet_data_length_encoded = 400;
192        break;
193    case PACKET_RS_512:
194        ConfigureControl( 0x01 );
195        dynamic_packet_size = false;
196        packet_subheader_length = 213;
197        packet_data_length = 512;
198        packet_data_length_encoded = 720;
199        fec_inner = RS_4_15_11;
200        fec_outer = FEC_NONE;
201        crc = CRC_CHECKSUM_16;
202        break;
203    default:
204        std::cerr << "ERROR! PacketEncoder::ConfigurePacketType() "
205                  << "Unsupported packet type: " << type << std::endl;
206        //throw 0;
207        ConfigurePacketType(PACKET_RAW_400);
208        return;
209    }
210
211    packet_type = type;
212}
213
214
215//
216void PacketizerBase::ConfigurePacketType( PacketType type )
217{
218    switch (type) {
219    case PACKET_RAW_400:
220        dynamic_packet_size = false;
221        packet_subheader_length = 21;
222        packet_data_length = 400;
223        packet_data_length_encoded = 400;
224        break;
225    case PACKET_RS_512:
226        dynamic_packet_size = false;
227        packet_subheader_length = 213;
228        packet_data_length = 512;
229        packet_data_length_encoded = 720;
230        fec_inner = RS_4_15_11;
231        fec_outer = FEC_NONE;
232        crc = CRC_CHECKSUM_16;
233        break;
234    default:
235        std::cerr << "ERROR! PacketizerBase::ConfigurePacketType() "
236                  << "Unsupported packet type: " << type << std::endl;
237        //throw 0;
238        ConfigurePacketType(PACKET_RAW_400);
239        return;
240    }
241
242    packet_type = type;
243}
244
245
246// Completely constructs and encodes a packet from raw data bits
247bool PacketEncoder::CreatePacket(
248    unsigned char* input,
249    unsigned int input_length,
250    unsigned int &num_read,
251    unsigned char* output,
252    unsigned int output_length,
253    unsigned int &num_written)
254{
255    unsigned int encoded_packet_length;
256    unsigned int nr;
257    EncodePacketData(
258        input,
259        input_length,
260        num_read,
261        buf3,
262        buf_len,
263        encoded_packet_length);
264
265    AssemblePacket(
266        buf3,
267        encoded_packet_length,
268        nr,
269        output,
270        output_length,
271        num_written);
272
273    return true;
274}
275
276
277// Completely finds and decodes a packet from raw data
278bool PacketDecoder::ExtractPacket(
279    unsigned char* input,
280    unsigned int input_length,
281    unsigned int &num_read,
282    unsigned char* output,
283    unsigned int output_length,
284    unsigned int &num_written)
285{
286    unsigned int nr(0); // samples read from input buffer on each function
287    unsigned int nw(0); // samples written to output buffer on each function
288    bool success;
289
290    // reset counter return values
291    num_read = 0;
292    num_written = 0;
293
294    //
295    switch (op_mode) {
296    case FIND_HEADER:
297        //
298        DEBUG_PRINTF(2, "MODE 0: EXTRACT_HEADER\n");
299        success = FindHeader(input, input_length, nr);
300        num_read += nr;
301
302        if ( success ) {
303            DEBUG_PRINTF(2, "  :: header found!\n");
304            op_mode = EXTRACT_HEADER;
305        } else {
306            return false;
307        }
308    case EXTRACT_HEADER:
309        //
310
311        DEBUG_PRINTF(2, "MODE 1: EXTRACT_HEADER\n");
312
313        success = ExtractHeader(
314                    input + num_read,
315                    input_length - num_read,
316                    nr,
317                    buf1 + num_header_bits_read,
318                    buf_len - num_header_bits_read,
319                    nw);
320        num_read += nr;
321
322        if ( success ) {
323            DEBUG_PRINTF(2, "  :: header extracted!\n");
324            op_mode = DECODE_HEADER;
325        } else {
326            return false;
327        }
328
329    case DECODE_HEADER:
330        //
331
332        DEBUG_PRINTF(2, "MODE 2: DECODE_HEADER\n");
333
334        success = DecodeHeader(buf1, buf_len);
335
336        if ( success ) {
337            DEBUG_PRINTF(2, "  :: header decoded!\n");
338            op_mode = EXTRACT_SUBHEADER;
339        } else {
340            return false;
341        }
342    case EXTRACT_SUBHEADER:
343        //
344
345        DEBUG_PRINTF(2, "MODE 3: EXTRACT_SUBHEADER\n");
346
347        // try to extract subheader and put into external buffer 1
348        success = ExtractSubheader(
349                    input + num_read,
350                    input_length - num_read,
351                    nr,
352                    buf1 + num_subheader_bits_read,
353                    buf_len - num_subheader_bits_read,
354                    nw);
355        num_read += nr;
356
357        if ( success ) {
358            DEBUG_PRINTF(2, "  :: subheader extracted!\n");
359            op_mode = DECODE_SUBHEADER;
360        } else {
361            return false;
362        }
363    case DECODE_SUBHEADER:
364        //
365
366        DEBUG_PRINTF(2, "MODE 4: DECODE_SUBHEADER\n");
367
368        success = DecodeSubheader(buf1, buf_len);
369
370        if ( success ) {
371            DEBUG_PRINTF(2, "  :: subheader decoded!\n");
372            op_mode = EXTRACT_PACKET_DATA;
373        } else {
374            DEBUG_PRINTF(2, "  COULD NOT DECODE SUBHEADER!\n");
375            op_mode = EXTRACT_HEADER;
376            return false;
377        }
378
379    case EXTRACT_PACKET_DATA:
380        //
381
382        DEBUG_PRINTF(2, "MODE 5: EXTRACT_PACKET_DATA\n");
383
384        // try to extract subheader and put into external buffer 1
385        success = ExtractPacketData(
386                    input + num_read,
387                    input_length - num_read,
388                    nr,
389                    buf1 + num_packet_bits_read,
390                    buf_len - num_packet_bits_read,
391                    nw);
392        num_read += nr;
393
394        if ( success ) {
395
396            DEBUG_PRINTF(2, "  :: packet data extracted!\n");
397
398            op_mode = DECODE_PACKET_DATA;
399        } else {
400            return false;
401        }
402    case DECODE_PACKET_DATA:
403        //
404
405        DEBUG_PRINTF(2, "MODE 6: DECODE_PACKET_DATA\n");
406
407        success = DecodePacketData(
408                buf1,
409                packet_data_length_encoded,
410                nr,
411                output,
412                output_length,
413                num_written);
414       
415        op_mode = FIND_HEADER;
416
417        if ( success ) {
418
419            DEBUG_PRINTF(2, "  :: packet data decoded!\n");
420
421            return true;
422        } else {
423            DEBUG_PRINTF(2, "  COULD NOT DECODE PACKET DATA!\n");
424            return false;
425        }
426    default:;
427    }
428
429    return false;
430}
431
432
433
434// Sets pointers in controlBlock to appropriate control codes
435void PacketEncoder::ConfigureControl( unsigned char id )
436{
437    for (unsigned int i=NUM_CONTROL_CODES; i>0; i--) {
438        controlBlock[i-1] = ( id & 0x01 ) ? pn_code_7 : pn_code_7_inv;
439        id >>= 1;
440    }
441}
442
443// Assemble packet and store in output buffer
444bool PacketEncoder::AssemblePacket(
445    unsigned char* input,
446    unsigned int input_length,
447    unsigned int &num_read,
448    unsigned char* output,
449    unsigned int output_length,
450    unsigned int &num_written)
451{
452    unsigned int i;
453    unsigned int output_index(0);
454
455    // check output size
456    unsigned int output_length_req = RequiredBufferSize(input_length);
457
458    // ensure output buffer is sufficiently long
459    if ( output_length_req > output_length ) {
460        std::cerr << "ERROR! PacketEncoder::AssemblePacket():" << std::endl
461                  << "  => required output length (" << output_length_req
462                  << ") exceeds buffer size (" << output_length << ")" << std::endl;
463        throw 0;
464    }
465   
466    // ensure output packet does not exceed the maximum allowable
467    if ( output_length_req > MAX_PACKET_SIZE ) {
468        std::cerr << "ERROR! PacketEncoder::AssemblePacket():" << std::endl
469                  << "  => required output length (" << output_length_req
470                  << ") exceeds maximum size (" << MAX_PACKET_SIZE << ")" << std::endl;
471        throw 0;
472    }
473
474    // write P/N sync code
475    memcpy(output+output_index, pnSyncCode, PN_SYNC_CODE_LENGTH);
476    output_index += PN_SYNC_CODE_LENGTH;
477
478    // write control codes
479    for (i=0; i<NUM_CONTROL_CODES; i++) {
480        memcpy(output+output_index, controlBlock[i], PN_CONTROL_CODE_LENGTH);
481        output_index += PN_CONTROL_CODE_LENGTH;
482    }
483
484    //unsigned int nr;
485    unsigned int nw;
486
487    EncodeSubheader(output+output_index, output_length-output_index, nw);
488    output_index += nw;
489    memmove(&output[output_index], input, input_length*sizeof(unsigned char));
490    //EncodePacketData(input, input_length, nr, output+output_index, output_length-output_index, nw);
491    output_index += input_length;
492
493    num_written = output_index;
494    num_read = packet_data_length; ///\todo num_read = input_length ???
495
496    return true;
497}
498
499// Encode subheader
500bool PacketEncoder::EncodeSubheader(
501    unsigned char* output,
502    unsigned int output_length,
503    unsigned int &num_written)
504{
505    ///\todo use function pointer for this
506
507    switch (packet_type) {
508    case PACKET_RAW_400:
509        return EncodeSubheader_PACKET_RAW_400(output, output_length, num_written);
510    case PACKET_RS_512:
511        return EncodeSubheader_PACKET_RS_512(output, output_length, num_written);
512    default:
513        std::cerr << "ERROR! PacketEncoder::EncodeSubheader(): unsupported packet type" << std::endl;
514        throw 0;
515    }
516
517}
518
519// Encode subheader for PACKET_RAW_400
520bool PacketEncoder::EncodeSubheader_PACKET_RAW_400(
521    unsigned char* output,
522    unsigned int output_length,
523    unsigned int &num_written)
524{
525    unsigned int i;
526    unsigned int N(0);
527
528    ///\todo use reed-solomon codec to encode subheader data
529    // configure sub-header here
530    if ( packet_id > 7 )
531        printf("WARNING! PacketEncoder::EncodeSubheader_PACKET_RAW_400() cannot encode packet_id > 7\n");
532
533    for (i=0; i<3; i++) {
534        if ( (packet_id >> (2-i)) & 0x01 )
535            memcpy( output+N, pn_code_7, PN_CONTROL_CODE_LENGTH);
536        else
537            memcpy( output+N, pn_code_7_inv, PN_CONTROL_CODE_LENGTH);
538
539        N += PN_CONTROL_CODE_LENGTH;
540    }
541    num_written = N;
542    return true;
543}
544
545// Encode subheader for PACKET_RS_512
546bool PacketEncoder::EncodeSubheader_PACKET_RS_512(
547    unsigned char* output,
548    unsigned int output_length,
549    unsigned int &num_written)
550{
551    unsigned int nw;    // num samples written from each function
552
553    // 1. push 16 8-bit symbols into buf1
554    // variable     num bits
555    // ----         ----
556    // packet_id    32
557    // src_id        8
558    // dst_id        8
559    // app_id        8
560    // port_id       8
561    // packet_len   16
562    // expansion    48
563    buf1[0] = (packet_id >> 0)  & 0xFF;
564    buf1[1] = (packet_id >> 8)  & 0xFF;
565    buf1[2] = (packet_id >> 16) & 0xFF;
566    buf1[3] = (packet_id >> 24) & 0xFF;
567
568    buf1[4] = (src_id >> 0 ) & 0xFF;
569
570    buf1[5] = (dst_id >> 0 ) & 0xFF;
571
572    buf1[6] = (app_id >> 0 ) & 0xFF;
573
574    buf1[7] = (port_id >> 0 ) & 0xFF;
575
576    buf1[8] = (packet_data_length >> 0 ) & 0xFF;
577    buf1[9] = (packet_data_length >> 8 ) & 0xFF;
578
579    buf1[10] = 7;
580    buf1[11] = 7;
581    buf1[12] = 7;
582    buf1[13] = 7;
583    buf1[14] = 7;
584    buf1[15] = 7;
585
586    // 2. compute CRC and append to end of message
587    FastCrc crc(0x04c11db7);
588    for (unsigned int i=0; i<16; i++)
589        crc.PutByte(buf1[i]);
590    UINT32 crc_code = crc.Done();
591
592    buf1[16] = (crc_code >> 0 )  & 0xFF;
593    buf1[17] = (crc_code >> 8 )  & 0xFF;
594    buf1[18] = (crc_code >> 16 ) & 0xFF;
595    buf1[19] = (crc_code >> 24 ) & 0xFF;
596
597    // 3. repack 20 8-bit symbols (+2 bits) into 27 6-bit symbols
598    SigProc::repack_bytes(buf1, 8, 20, buf2, 2, buf_len, &nw);
599    buf2[640] = 0;
600    SigProc::repack_bytes(buf2, 2, 641, buf1, 6, buf_len, &nw);
601   
602    // 4. use 6-bit RS (63,55) punctured to (35,27)
603    //    27 symbols (uncoded)
604    // -> 35 symbols (coded)
605    int symsize = 6;
606    int npad = 28;
607    int nn = (1<<symsize)-1-npad;    // 63-28 = 35
608    int nroots = 8;
609    int kk = nn-nroots;             // 35-8 = 27
610    encode_rs_char(rs_6_35_27, buf1, &buf1[kk]);
611
612    // 5. unpack to output buffer
613    SigProc::repack_bytes(buf1, 6, 35, output, 1, output_length, &num_written);
614    num_written += 3; // pad to 213
615    return true;
616}
617
618bool PacketDecoder::FindHeader(
619    unsigned char* input,
620    unsigned int input_length,
621    unsigned int &num_bits_read)
622{
623    rxy = 0;
624    int correlator_threshold(60);
625    unsigned int i(0);
626   
627    for (i=0; i<input_length; i++) {
628        // push bit into shift register
629        binary_sequence_push( pn_sync_buffer, input[i] & 0x01 );
630
631        // correlate with P/N sync code
632        rxy = binary_sequence_correlate( pn_sync_buffer, pn_sync_code );
633
634        if ( abs(rxy) > correlator_threshold ) {
635            DEBUG_PRINTF(4, "\nPN sync code found!!\n\n");
636            invert_bits = ( rxy < 0 ) ? true : false;
637            num_bits_read = i+1;
638            num_header_bits_read = 0;
639            return true;
640        }
641    }
642
643    num_bits_read = input_length;
644    return false;
645
646}
647
648
649bool PacketDecoder::ExtractHeader(
650    unsigned char* input,
651    unsigned int input_length,
652    unsigned int &num_read,
653    unsigned char* output,
654    unsigned int output_length,
655    unsigned int &num_written)
656{
657    unsigned int i;
658    num_written = 0;
659    num_read = 0;
660
661    for (i=0; i<input_length; i++) {
662        output[i] = invert_bits ? (~input[i]) & 0x01 : input[i];
663        num_header_bits_read++;
664        num_written++;
665        num_read++;
666
667        if ( num_header_bits_read == packet_header_length ) {
668            // header data have been extracted
669            num_subheader_bits_read = 0;
670            return true;
671        }
672    }
673
674    return false;
675}
676
677// decode control codes to describe packet type
678bool PacketDecoder::DecodeHeader(
679    unsigned char* input,
680    unsigned int input_length)
681{
682    // At this point the P/N sync code header has been found and
683    // the data should be completely stored in the input buffer
684
685    unsigned int new_packet_type(0);
686    for (unsigned int i=0; i<NUM_CONTROL_CODES; i++) {
687        for (unsigned int j=0; j<PN_CONTROL_CODE_LENGTH; j++) {
688            binary_sequence_push( pn_control_buffer, input[j+i*PN_CONTROL_CODE_LENGTH] & 0x01 );
689        }
690
691        rxy = binary_sequence_correlate( pn_control_buffer, pn_control_code );
692
693        new_packet_type <<= 1;
694        new_packet_type |= ( rxy > 0 ) ? 0x01 : 0x00;
695    }
696
697    ConfigurePacketType( (PacketType) new_packet_type );
698    num_subheader_bits_read = 0;
699    return true;
700}
701
702
703bool PacketDecoder::ExtractSubheader(
704    unsigned char* input,
705    unsigned int input_length,
706    unsigned int &num_read,
707    unsigned char* output,
708    unsigned int output_length,
709    unsigned int &num_written)
710{
711    unsigned int i;
712    num_written = 0;
713    num_read = 0;
714
715    for (i=0; i<input_length; i++) {
716        output[i] = invert_bits ? (~input[i]) & 0x01 : input[i];
717        num_subheader_bits_read++;
718        num_written++;
719        num_read++;
720
721        if ( num_subheader_bits_read == packet_subheader_length ) {
722            // subheader data have been extracted
723            num_packet_bits_read = 0;
724            return true;
725        }
726    }
727
728    return false;
729}
730
731//
732bool PacketDecoder::DecodeSubheader(
733    unsigned char* input,
734    unsigned int input_length)
735{
736    ///\todo use function pointer instead of switch statement
737
738    switch (packet_type) {
739    case PACKET_RAW_400:
740        return PacketDecoder::DecodeSubheader_PACKET_RAW_400(input, input_length);
741    case PACKET_RS_512:
742        return PacketDecoder::DecodeSubheader_PACKET_RS_512(input, input_length);
743    default:;
744    }
745
746    return true;
747}
748
749//
750bool PacketDecoder::DecodeSubheader_PACKET_RAW_400(
751    unsigned char* input,
752    unsigned int input_length)
753{
754    ///\todo use reed-solomon codec to decode subheader data
755    packet_id = 0;
756    for (unsigned int i=0; i<3; i++) {
757        // shift 7 bits into buffer
758        for (unsigned int j=0; j<PN_CONTROL_CODE_LENGTH; j++) {
759            binary_sequence_push( pn_control_buffer, input[j+i*PN_CONTROL_CODE_LENGTH] & 0x01 );
760        }
761
762        rxy = binary_sequence_correlate( pn_control_buffer, pn_control_code );
763
764        packet_id <<= 1;
765        packet_id |= ( rxy > 0 ) ? 0x01 : 0x00;
766    }
767    return true;
768}
769
770bool PacketDecoder::DecodeSubheader_PACKET_RS_512(
771    unsigned char* input,
772    unsigned int input_length)
773{
774    unsigned int nw;    // num samples written from each function
775   
776    // 1. pack 210 bits into 35 6-bit symbols to buf2
777    SigProc::repack_bytes(input, 1, 210, buf2, 6, buf_len, &nw);
778
779    // 2. use RS 6-bit (63,55) code, punctured to (35,27)
780    int symsize = 6;
781    int npad = 28;
782    //int nn = (1<<symsize)-1-npad;   // 63-28 = 35
783    int nroots = 8;
784    //int kk = nn-nroots;             // 35-8 = 27
785    int nerrors(0);
786    nerrors = decode_rs_char(rs_6_35_27, buf2, 0, 0);
787
788    // 3. repack 27 6-bit symbols (-2 bits) to 20 8-bit symbols
789    SigProc::repack_bytes(buf2, 6, 27, buf1, 2, buf_len, &nw);
790    SigProc::repack_bytes(buf1, 2, 80, buf2, 8, buf_len, &nw);
791   
792    // 4. decode and compare CRC
793    FastCrc crc(0x04c11db7);
794    for (unsigned int i=0; i<16; i++)
795        crc.PutByte( buf2[i] );
796    UINT32 crc_code = crc.Done();
797    UINT32 crc_rx(0);
798    for (unsigned int i=0; i<4; i++) {
799        crc_rx <<= 8;
800        crc_rx |= 0xFF & (UINT32) (buf2[20-i-1]);
801    }
802    crc_rx = 0;
803    crc_rx |= (buf2[16] << 0);
804    crc_rx |= (buf2[17] << 8);
805    crc_rx |= (buf2[18] << 16);
806    crc_rx |= (buf2[19] << 24);
807    if (crc_rx != crc_code) {
808        printf("ERROR! PACKET_RS_512 subheader did not pass cyclic redundancy check\n");
809        //return false;
810    } else {
811    }
812
813    // 5. decode 16 8-bit symbols...
814    // variable     num bits
815    // ----         ----
816    // packet_id    32
817    // src_id        8
818    // dst_id        8
819    // app_id        8
820    // port_id       8
821    // packet_len   16
822    // expansion    48
823    packet_id = 0;
824    packet_id = 0;
825    packet_id |= (buf2[0] << 0);
826    packet_id |= (buf2[1] << 8);
827    packet_id |= (buf2[2] << 16);
828    packet_id |= (buf2[3] << 24);
829
830    src_id = 0;
831    src_id |= buf2[4];
832
833    dst_id = 0;
834    dst_id |= buf2[5];
835
836    app_id = 0;
837    app_id |= buf2[6];
838
839    port_id = 0;
840    port_id |= buf2[7];
841
842    packet_data_length = 0;
843    packet_data_length |= buf2[8];
844    packet_data_length |= buf2[9];
845
846    return true;
847}
848
849bool PacketDecoder::ExtractPacketData(
850    unsigned char* input,
851    unsigned int input_length,
852    unsigned int &num_read,
853    unsigned char* output,
854    unsigned int output_length,
855    unsigned int &num_written)
856{
857    bool packet_extracted;
858
859    if (dynamic_packet_size) {
860        packet_extracted =
861            ExtractPacketDataDynamicLength(input, input_length, num_read, output, output_length, num_written);
862    } else {
863        packet_extracted =
864            ExtractPacketDataFixedLength(input, input_length, num_read, output, output_length, num_written);
865    }
866
867    return packet_extracted;
868}
869
870bool PacketDecoder::ExtractPacketDataDynamicLength(
871    unsigned char* input,
872    unsigned int input_length,
873    unsigned int &num_read,
874    unsigned char* output,
875    unsigned int output_length,
876    unsigned int &num_written)
877{
878    ///\todo look for eom code
879
880    num_written = 0;
881    num_read = input_length;
882    return false;
883}
884
885
886bool PacketDecoder::ExtractPacketDataFixedLength(
887    unsigned char* input,
888    unsigned int input_length,
889    unsigned int &num_read,
890    unsigned char* output,
891    unsigned int output_length,
892    unsigned int &num_written)
893{
894    unsigned int i;
895    num_read = 0;
896    num_written = 0;
897
898    for (i=0; i<input_length; i++) {
899        output[i] = invert_bits ? (~input[i]) & 0x01 : input[i];
900        num_packet_bits_read++;
901        num_read++;
902        num_written++;
903
904        if (num_packet_bits_read == packet_data_length_encoded) {
905            // packet data have been extracted
906            num_packet_bits_read = 0;
907            return true;
908        }
909    }
910   
911    return false;
912}
913
914
915//
916bool PacketEncoder::EncodePacketData(
917    unsigned char* input,
918    unsigned int input_length,
919    unsigned int &num_read,
920    unsigned char* output,
921    unsigned int output_length,
922    unsigned int &num_written)
923{
924    bool success;
925
926    // CheckBuffers();
927
928    switch (packet_type) {
929    case PACKET_RAW_400:
930        success = EncodePacketData_PACKET_RAW_400(
931            input, input_length, num_read, output, output_length, num_written);
932        return success;
933    case PACKET_RS_512:
934        success = EncodePacketData_PACKET_RS_512(
935            input, input_length, num_read, output, output_length, num_written);
936        return success;
937    default:;
938        std::cerr << "ERROR! PacketEncoder::EncodePacketData() " << std::endl
939                  << "  => Unsupported packet type: " << packet_type << std::endl;
940        throw 0;
941    }
942   
943    return false;
944}
945
946
947bool PacketEncoder::EncodePacketData_PACKET_RAW_400(
948    unsigned char* input,
949    unsigned int input_length,
950    unsigned int &num_read,
951    unsigned char* output,
952    unsigned int output_length,
953    unsigned int &num_written)
954{
955    // nothing to do; just copy data
956    memcpy( output, input, packet_data_length );
957    num_read = packet_data_length;
958    num_written = packet_data_length_encoded;
959    return true;
960}
961
962
963bool PacketEncoder::EncodePacketData_PACKET_RS_512(
964    unsigned char* input,
965    unsigned int input_length,
966    unsigned int &num_read,
967    unsigned char* output,
968    unsigned int output_length,
969    unsigned int &num_written)
970{
971    unsigned int nr;
972    unsigned int nw;
973
974    // 1. pack data into symbols
975    // 512 1-bit symbols -> 128 4-bit symbols
976    SigProc::repack_bytes(input, 1, 512, buf2, 4, buf_len, &nw);
977
978    // 2. add crc/checksum: 16-bit checksum
979    unsigned int ones(0);
980    for (unsigned int i=0; i<128; i++)
981        ones += c_ones[(unsigned int) (buf2[i])];
982    ones = ones % 65536;    // 2^16
983    buf2[128] = ones & 0x0F;
984    buf2[129] = (ones >> 4) & 0x0F;
985    buf2[130] = (ones >> 8) & 0x0F;
986    buf2[131] = (ones >> 12) & 0x0F;
987
988    // 3. apply RS 4-bit (15,11) code for 12 blocks
989    //    132 4-bit symbols (uncoded)
990    // -> 180 4-bit symbols (coded)
991    int symsize = 4;
992    int nn = (1<<symsize)-1;    // 15
993    int nroots = 4;
994    int kk = nn-nroots;         // 11
995    nw = 0;
996    nr = 0;
997    for (unsigned int i=0; i<12; i++) {
998        // copy data from buf2 to buf1
999        memmove(&buf1[nw], &buf2[nr], kk);
1000
1001        // apply encoder
1002        encode_rs_char(rs_4_15_11, &buf1[nw], &buf1[nw+kk]);
1003        nr += kk;
1004        nw += nn;
1005    }
1006   
1007    // 4. unpack data: move 4-bit symbols from buf1 to 1-bit symbols in output
1008    SigProc::repack_bytes(buf1, 4, nw, output, 1, output_length, &num_written);
1009    num_read = 512;
1010
1011    return true;
1012}
1013
1014//
1015bool PacketDecoder::DecodePacketData(
1016    unsigned char* input,
1017    unsigned int input_length,
1018    unsigned int &num_read,
1019    unsigned char* output,
1020    unsigned int output_length,
1021    unsigned int &num_written)
1022{
1023    bool success;
1024
1025    switch (packet_type) {
1026    case PACKET_RAW_400:
1027        success = DecodePacketData_PACKET_RAW_400(
1028            input, input_length, num_read, output, output_length, num_written);
1029        return success;
1030    case PACKET_RS_512:
1031        success = DecodePacketData_PACKET_RS_512(
1032            input, input_length, num_read, output, output_length, num_written);
1033        return success;
1034    default:;
1035        std::cerr << "ERROR! PacketDecoder::DecodePacketData() " << std::endl
1036                  << "  => Unsupported packet type: " << packet_type << std::endl;
1037        throw 0;
1038    }
1039
1040    return false;
1041}
1042
1043bool PacketDecoder::DecodePacketData_PACKET_RAW_400(
1044    unsigned char* input,
1045    unsigned int input_length,
1046    unsigned int &num_read,
1047    unsigned char* output,
1048    unsigned int output_length,
1049    unsigned int &num_written)
1050{
1051    // nothing to do; just copy data
1052    memcpy( output, input, packet_data_length );
1053    num_read = packet_data_length_encoded;
1054    num_written = packet_data_length;
1055    return true;
1056}
1057
1058bool PacketDecoder::DecodePacketData_PACKET_RS_512(
1059    unsigned char* input,
1060    unsigned int input_length,
1061    unsigned int &num_read,
1062    unsigned char* output,
1063    unsigned int output_length,
1064    unsigned int &num_written)
1065{
1066    unsigned int nr;
1067    unsigned int nw;
1068
1069    // 1. Pack data into 4-bit symbols, put into buf2
1070    SigProc::repack_bytes(input, 1, 720, buf2, 4, buf_len, &nw);
1071   
1072    // 2. Decode using RS 4-bit (15,11) code on 12 blocks
1073    //    180 4-bit symbols (coded)
1074    // -> 132 4-bit symbols (uncoded)
1075    int symsize = 4;
1076    int nn = (1<<symsize)-1;    // 15
1077    int nroots = 4;
1078    int kk = nn-nroots;         // 11
1079    nw = 0;
1080    nr = 0;
1081    int nerrors(0);
1082    int nerrors_total(0);
1083    for (unsigned int i=0; i<12; i++) {
1084        // apply decoder (no erasure knowledge)
1085        nerrors = decode_rs_char(rs_4_15_11, &buf2[nr], 0, 0);
1086        nerrors_total = nerrors_total + nerrors;
1087
1088        // copy data from buf2 to buf1
1089        memmove(&buf1[nw], &buf2[nr], kk);
1090
1091        nr += nn;
1092        nw += kk;
1093    }
1094
1095    // 3. calculate and compare crc/checksum (16-bit)
1096    unsigned int checksum(0);
1097    // read four 4-bit symbols from end of buffer
1098    for (unsigned int i=0; i<4; i++) {
1099        checksum <<= 4;
1100        checksum |= buf1[nw-i-1];
1101    }
1102    unsigned int ones(0);
1103    for (unsigned int i=0; i<128; i++)
1104        ones += c_ones[(unsigned int) (buf1[i])];
1105    //printf("checksum: %d, ones: %d\n", checksum, ones);
1106
1107    // 4. unpack data: move 4-bit symbols from buf1 to 1-bit symbols in output
1108    SigProc::repack_bytes(buf1, 4, nw-4, output, 1, output_length, &num_written);
1109    num_read = 720;
1110
1111    if (checksum != ones) {
1112        //printf("ERROR! did not pass checksum!\n");
1113        return false;
1114    } else {
1115        return true;
1116    }
1117}
1118
Note: See TracBrowser for help on using the browser.