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

Revision 5504, 31.1 KB (checked in by jgaeddert, 6 years ago)

moving from char to unsigned char

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