root/ossiedev/branches/jgaeddert/0.8.0/components/src/PacketEncoder.cpp @ 10677

Revision 10677, 8.3 KB (checked in by jgaeddert, 2 years ago)

PacketEncoder?: adding forward error-corrections, CRC to properties

Line 
1/****************************************************************************
2
3Copyright 2010 by your_name_or_organization, all rights reserved.
4
5****************************************************************************/
6
7
8#include <cstdio>
9#include <string>
10#include <iostream>
11
12#include "config.h"
13#include "PacketEncoder.h"
14
15// include main.cpp (must define COMPONENT_OBJECT)
16#define  COMPONENT_OBJECT PacketEncoder_i
17#include "main.cpp"
18
19PacketEncoder_i::PacketEncoder_i(const char *uuid, omni_condition *condition) :
20    Resource_impl(uuid), component_running(condition)
21{
22    portUncodedDataIn = new standardInterfaces_i::realChar_p("UncodedDataIn");
23    portCodedDataOut = new standardInterfaces_i::realChar_u("CodedDataOut");
24
25    // create DSP packetizer object
26    check     = LIQUID_CRC_16;
27    fec_inner = LIQUID_FEC_NONE;
28    fec_outer = LIQUID_FEC_HAMMING128;
29    dec_msg_len = 0;
30    enc_msg_len = packetizer_compute_enc_msg_len(dec_msg_len,check,fec_inner,fec_outer);
31    p = packetizer_create(dec_msg_len,check,fec_inner,fec_outer);
32}
33
34PacketEncoder_i::~PacketEncoder_i(void)
35{
36    delete portUncodedDataIn;
37    delete portCodedDataOut;
38
39    // destroy DSP packetizer object
40    packetizer_destroy(p);
41}
42
43// Static function for omni thread
44void PacketEncoder_i::Run( void * data )
45{
46    ((PacketEncoder_i*)data)->ProcessData();
47}
48
49CORBA::Object_ptr PacketEncoder_i::getPort( const char* portName ) throw (
50    CORBA::SystemException, CF::PortSupplier::UnknownPort)
51{
52    DEBUG(3, PacketEncoder, "getPort() invoked with " << portName)
53
54    CORBA::Object_var p;
55
56    p = portUncodedDataIn->getPort(portName);
57
58    if (!CORBA::is_nil(p))
59        return p._retn();
60
61    p = portCodedDataOut->getPort(portName);
62
63    if (!CORBA::is_nil(p))
64        return p._retn();
65
66    /*exception*/
67    throw CF::PortSupplier::UnknownPort();
68}
69
70void PacketEncoder_i::start() throw (CORBA::SystemException,
71    CF::Resource::StartError)
72{
73    DEBUG(3, PacketEncoder, "start() invoked")
74    omni_mutex_lock  l(processing_mutex);
75    if( false == thread_started )
76    {
77        thread_started = true;
78        // Create the thread for the writer's processing function
79        processing_thread = new omni_thread(Run, (void *) this);
80
81        // Start the thread containing the writer's processing function
82        processing_thread->start();
83    }
84}
85
86void PacketEncoder_i::stop() throw (CORBA::SystemException, CF::Resource::StopError)
87{
88    DEBUG(3, PacketEncoder, "stop() invoked")
89    omni_mutex_lock l(processing_mutex);
90    thread_started = false;
91}
92
93void PacketEncoder_i::releaseObject() throw (CORBA::SystemException,
94    CF::LifeCycle::ReleaseError)
95{
96    DEBUG(3, PacketEncoder, "releaseObject() invoked")
97
98    component_running->signal();
99}
100
101void PacketEncoder_i::initialize() throw (CF::LifeCycle::InitializeError,
102    CORBA::SystemException)
103{
104    DEBUG(3, PacketEncoder, "initialize() invoked")
105}
106
107void PacketEncoder_i::query( CF::Properties & configProperties ) throw (CORBA::SystemException, CF::UnknownProperties)
108{
109    if( configProperties.length() == 0 )
110    {
111        configProperties.length( propertySet.length() );
112        for( unsigned int i = 0; i < propertySet.length(); i++ )
113        {
114            configProperties[i].id = CORBA::string_dup( propertySet[i].id );
115            configProperties[i].value = propertySet[i].value;
116        }
117        return;
118    } else {
119        for( unsigned int i = 0; i < configProperties.length(); i++ ) {
120            for( unsigned int j = 0; j < propertySet.length(); j++ ) {
121                if( strcmp(configProperties[i].id, propertySet[i].id) == 0 ) {
122                    configProperties[i].value = propertySet[i].value;
123                }
124            }
125        }
126    } // end if-else
127}
128
129void PacketEncoder_i::configure(const CF::Properties& props)
130throw (CORBA::SystemException,
131    CF::PropertySet::InvalidConfiguration,
132    CF::PropertySet::PartialConfiguration)
133{
134    DEBUG(3, PacketEncoder, "configure() invoked")
135
136    static int init = 0;
137    if( init == 0 ) {
138        if( props.length() == 0 ) {
139            std::cout << "configure called with invalid props.length - " << props.length() << std::endl;
140            return;
141        }
142        propertySet.length(props.length());
143        for( unsigned int j=0; j < props.length(); j++ ) {
144            propertySet[j].id = CORBA::string_dup(props[j].id);
145            propertySet[j].value = props[j].value;
146        }
147        init = 1;
148    }
149
150    std::cout << "props length : " << props.length() << std::endl;
151
152    for ( unsigned int i = 0; i <props.length(); i++) {
153        std::cout << "Property id : " << props[i].id << std::endl;
154
155        if (strcmp(props[i].id, "DCE:094770a0-1017-11df-baab-001aa089d644") == 0) {
156            // fec0 (inner coding scheme)
157
158            const char * prop_str;
159            props[i].value >>= prop_str;
160
161            // convert string to FEC scheme
162            fec_inner = liquid_getopt_str2fec(prop_str);
163            if (fec_inner == LIQUID_FEC_UNKNOWN) {
164                std::cerr << "error: PacketEncoder::configure(), invalid FEC scheme: '" << prop_str << "'" << std::endl;
165                throw (0);
166            }
167        } else if (strcmp(props[i].id, "DCE:126dca6c-1017-11df-baab-001aa089d644") == 0) {
168            // fec1 (outer coding scheme)
169
170            const char * prop_str;
171            props[i].value >>= prop_str;
172
173            // convert string to FEC scheme
174            fec_outer = liquid_getopt_str2fec(prop_str);
175            if (fec_outer == LIQUID_FEC_UNKNOWN) {
176                std::cerr << "error: PacketEncoder::configure(), invalid FEC scheme: '" << prop_str << "'" << std::endl;
177                throw (0);
178            }
179        } else if (strcmp(props[i].id, "DCE:c294c02c-1de1-4f98-89ec-836158c4dd25") == 0) {
180            // check (data validity check: crc/checksum)
181
182            const char * prop_str;
183            props[i].value >>= prop_str;
184
185            // convert string to CRC scheme
186            check = liquid_getopt_str2crc(prop_str);
187            if (check == LIQUID_CRC_UNKNOWN) {
188                std::cerr << "error: PacketEncoder::configure(), invalid CRC scheme: '" << prop_str << "'" << std::endl;
189                throw (0);
190            }
191        } else {
192            std::cerr << "error: PacketEncoder::configure(), unknown property" << std::endl;
193            throw (0);
194        }
195    }
196
197    // regenerate packetizer object
198    p = packetizer_recreate(p,dec_msg_len,check,fec_inner,fec_outer);
199}
200
201void PacketEncoder_i::ProcessData()
202{
203    DEBUG(3, PacketEncoder, "ProcessData() invoked")
204
205    PortTypes::CharSequence encodedDataOut;
206
207
208    PortTypes::CharSequence *decodedDataIn(NULL);
209    CORBA::UShort decodedDataIn_length;
210
211    while(continue_processing())
212    {
213        portUncodedDataIn->getData(decodedDataIn);
214
215        decodedDataIn_length = decodedDataIn->length();
216
217        // check input length and re-create packetizer (if necessary)
218        if (dec_msg_len != decodedDataIn_length) {
219            // re-compute message lengths
220            dec_msg_len = decodedDataIn_length;
221            enc_msg_len = packetizer_compute_enc_msg_len(dec_msg_len,
222                                                         check,
223                                                         fec_inner,
224                                                         fec_outer);
225
226            // re-create packetizer object
227            p = packetizer_recreate(p,
228                                    dec_msg_len,
229                                    check,
230                                    fec_inner,
231                                    fec_outer);
232        }
233
234        // create buffers (not efficient)
235        // TODO : allocate buffers internally, realloc only when necessary
236        unsigned char dec_msg[dec_msg_len];
237        unsigned char enc_msg[enc_msg_len];
238
239        // copy input to buffer
240        for (unsigned int i=0; i<dec_msg_len; i++)
241            dec_msg[i] = (*decodedDataIn)[i];
242        portUncodedDataIn->bufferEmptied();
243
244        // encode the packet
245        packetizer_encode(p, dec_msg, enc_msg);
246
247        // copy result to output buffer
248        encodedDataOut.length(enc_msg_len);
249        for (unsigned int i=0; i<enc_msg_len; i++)
250            encodedDataOut[i] = enc_msg[i];
251
252        // push data to output
253        portCodedDataOut->pushPacket(encodedDataOut);
254    }
255}
256
257bool PacketEncoder_i::continue_processing()
258{
259    omni_mutex_lock l(processing_mutex);
260    return thread_started;
261}
262
263
Note: See TracBrowser for help on using the browser.