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

Revision 5492, 30.7 KB (checked in by jgaeddert, 6 years ago)

fixing PACKET_RS_512 encoder/decoder for main data block

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