root/ossiedev/branches/jgaeddert/0.8.0/components/src/FlexframeGen.cpp @ 10909

Revision 10909, 15.0 KB (checked in by jgaeddert, 19 months ago)

Flexframe: setting header size to 14 (complies with liquid-dsp v1.0.0)

Line 
1/****************************************************************************
2
3Copyright 2010 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE FlexframeGen.
6
7OSSIE FlexframeGen 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 FlexframeGen 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 FlexframeGen; 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 <string>
25#include <iostream>
26#include <stdio.h>
27
28#include "config.h"
29#include "FlexframeGen.h"
30
31// include main.cpp (must define COMPONENT_OBJECT)
32#define  COMPONENT_OBJECT FlexframeGen_i
33#include "main.cpp"
34
35FlexframeGen_i::FlexframeGen_i(const char *uuid, omni_condition *condition) :
36    Resource_impl(uuid), component_running(condition)
37{
38    headerDataPortIn = new standardInterfaces_i::realChar_p("HeaderDataIn");
39    payloadDataPortIn = new standardInterfaces_i::realChar_p("PayloadDataIn");
40    frameDataPortOut = new standardInterfaces_i::complexFloat_u("FrameSamplesOut");
41
42    // create dsp objects
43    fgprops.rampup_len  = 16;
44    fgprops.phasing_len = 64;
45    fgprops.payload_len = 256;
46    fgprops.check       = LIQUID_CRC_16;
47    fgprops.fec0        = LIQUID_FEC_NONE;
48    fgprops.fec1        = LIQUID_FEC_HAMMING128;
49    fgprops.mod_scheme  = LIQUID_MODEM_QAM;
50    fgprops.mod_bps     = 2;
51    fgprops.rampdn_len  = 16;
52
53    fg = flexframegen_create(&fgprops);
54
55    payload_len = 64;
56    payload = (unsigned char*) malloc(payload_len);
57
58    frame_len = 1024;
59    frame = (std::complex<float>*) malloc(frame_len);
60
61    // design rrc filter
62    unsigned int k=2;
63    unsigned int m=3;
64    float beta=0.7f;
65    float dt = 0;
66
67    interp = interp_crcf_create_rnyquist(LIQUID_RNYQUIST_RRC,k,m,beta,dt);
68
69    interp2 = resamp2_crcf_create(37,0,60);
70}
71
72FlexframeGen_i::~FlexframeGen_i(void)
73{
74    delete headerDataPortIn;
75    delete payloadDataPortIn;
76    delete frameDataPortOut;
77
78    flexframegen_destroy(fg);
79    interp_crcf_destroy(interp);
80    resamp2_crcf_destroy(interp2);
81
82    free(payload);
83    free(frame);
84}
85
86// Static function for omni thread
87void FlexframeGen_i::Run( void * data )
88{
89    ((FlexframeGen_i*)data)->ProcessData();
90}
91
92CORBA::Object_ptr FlexframeGen_i::getPort( const char* portName ) throw (
93    CORBA::SystemException, CF::PortSupplier::UnknownPort)
94{
95    DEBUG(3, FlexframeGen, "getPort() invoked with " << portName)
96
97    CORBA::Object_var p;
98
99    p = headerDataPortIn->getPort(portName);
100
101    if (!CORBA::is_nil(p))
102        return p._retn();
103
104    p = payloadDataPortIn->getPort(portName);
105
106    if (!CORBA::is_nil(p))
107        return p._retn();
108
109    p = frameDataPortOut->getPort(portName);
110
111    if (!CORBA::is_nil(p))
112        return p._retn();
113
114    /*exception*/
115    throw CF::PortSupplier::UnknownPort();
116}
117
118void FlexframeGen_i::start() throw (CORBA::SystemException,
119    CF::Resource::StartError)
120{
121    DEBUG(3, FlexframeGen, "start() invoked")
122        omni_mutex_lock  l(processing_mutex);
123        if( false == thread_started )
124        {
125                thread_started = true;
126                // Create the thread for the writer's processing function
127                processing_thread = new omni_thread(Run, (void *) this);
128
129                // Start the thread containing the writer's processing function
130                processing_thread->start();
131        }
132}
133
134void FlexframeGen_i::stop() throw (CORBA::SystemException, CF::Resource::StopError)
135{
136    DEBUG(3, FlexframeGen, "stop() invoked")
137        omni_mutex_lock l(processing_mutex);
138        thread_started = false;
139}
140
141void FlexframeGen_i::releaseObject() throw (CORBA::SystemException,
142    CF::LifeCycle::ReleaseError)
143{
144    DEBUG(3, FlexframeGen, "releaseObject() invoked")
145
146    component_running->signal();
147}
148
149void FlexframeGen_i::initialize() throw (CF::LifeCycle::InitializeError,
150    CORBA::SystemException)
151{
152    DEBUG(3, FlexframeGen, "initialize() invoked")
153}
154
155void FlexframeGen_i::query( CF::Properties & configProperties ) throw (CORBA::SystemException, CF::UnknownProperties)
156{
157        if( configProperties.length() == 0 )
158        {
159                configProperties.length( propertySet.length() );
160                for(unsigned int i = 0; i < propertySet.length(); i++ )
161                {
162                        configProperties[i].id = CORBA::string_dup( propertySet[i].id );
163                        configProperties[i].value = propertySet[i].value;
164                }
165                return;
166        } else {
167                for( unsigned int i = 0; i < configProperties.length(); i++ ) {
168                        for( unsigned int j = 0; j < propertySet.length(); j++ ) {
169                                if( strcmp(configProperties[i].id, propertySet[j].id) == 0 ) {
170                                        configProperties[i].value = propertySet[j].value;
171                                }
172                        }
173                }
174        } // end if-else
175}
176
177void FlexframeGen_i::configure(const CF::Properties& props)
178throw (CORBA::SystemException,
179    CF::PropertySet::InvalidConfiguration,
180    CF::PropertySet::PartialConfiguration)
181{
182    DEBUG(3, FlexframeGen, "configure() invoked")
183
184#if 0
185    // not sure what the heck this is here for...
186    static int init = 0;
187    if( init == 0 ) {
188        if( props.length() == 0 ) {
189            std::cout << "configure called with invalid props.length - " << props.length() << std::endl;
190            return;
191        }
192        propertySet.length(props.length());
193        for( int j=0; j < props.length(); j++ ) {
194            propertySet[j].id = CORBA::string_dup(props[j].id);
195            propertySet[j].value = props[j].value;
196        }
197        init = 1;
198    }
199#endif
200
201    std::cout << "props length : " << props.length() << std::endl;
202
203    unsigned int ms         = fgprops.mod_scheme;
204    unsigned int bps        = fgprops.mod_bps;
205    unsigned int fec0       = fgprops.fec0;
206    unsigned int fec1       = fgprops.fec1;
207    unsigned int check      = fgprops.check;
208    unsigned int rampup_len = fgprops.rampup_len;
209    unsigned int rampdn_len = fgprops.rampdn_len;
210    unsigned int phasing_len= fgprops.phasing_len;
211
212    for ( unsigned int i = 0; i <props.length(); i++) {
213        std::cout << "Property id : " << props[i].id << std::endl;
214
215        if (strcmp(props[i].id, "DCE:5b852bf4-6d83-11df-80dc-001aa089d644") == 0) {
216            // verbose
217            CORBA::Boolean simple_temp;
218            props[i].value >>= simple_temp;
219        } else if (strcmp(props[i].id, "DCE:c1612e14-6d83-11df-8500-001aa089d644") == 0) {
220            // mod_scheme
221
222            const char * prop_str;
223            unsigned int M;
224            props[i].value >>= prop_str;
225            std::cout << "modulation scheme: " << prop_str << std::endl;
226            if (strcmp(prop_str,"bpsk")==0) {
227                ms = LIQUID_MODEM_BPSK;
228                M = 2;
229            } else if (strcmp(prop_str,"qpsk")==0) {
230                ms = LIQUID_MODEM_QPSK;
231                M = 4;
232            } else if (strcmp(prop_str,"V29")==0) {
233                ms = LIQUID_MODEM_V29;
234                M = 16;
235            } else if (strcmp(prop_str,"arb16opt")==0) {
236                ms = LIQUID_MODEM_ARB16OPT;
237                M = 16;
238            } else if (strcmp(prop_str,"arb32opt")==0) {
239                ms = LIQUID_MODEM_ARB32OPT;
240                M = 32;
241            } else if (strcmp(prop_str,"arb64vt")==0) {
242                ms = LIQUID_MODEM_ARB64VT;
243                M = 64;
244            } else if (strncmp(prop_str,"psk",3)==0) {
245                ms = LIQUID_MODEM_PSK;
246                M = atoi(prop_str+3);
247            } else if (strncmp(prop_str,"dpsk",4)==0) {
248                ms = LIQUID_MODEM_DPSK;
249                M = atoi(prop_str+4);
250            } else if (strncmp(prop_str,"qam",3)==0) {
251                ms = LIQUID_MODEM_QAM;
252                M = atoi(prop_str+3);
253            } else if (strncmp(prop_str,"apsk",4)==0) {
254                ms = LIQUID_MODEM_APSK;
255                M = atoi(prop_str+4);
256            } else if (strncmp(prop_str,"ask",3)==0) {
257                ms = LIQUID_MODEM_ASK;
258                M = atoi(prop_str+3);
259            } else {
260                std::cerr << "error: invalid mod scheme: " << prop_str << std::endl;
261                throw (0);
262            }
263
264            // compute bits/symbol
265            switch (M) {
266            case 2:     bps = 1;    break;
267            case 4:     bps = 2;    break;
268            case 8:     bps = 3;    break;
269            case 16:    bps = 4;    break;
270            case 32:    bps = 5;    break;
271            case 64:    bps = 6;    break;
272            case 128:   bps = 7;    break;
273            case 256:   bps = 8;    break;
274            default:
275                std::cerr << "error: FlexFrameGen_i::configure(), invalid constellation size : " << M << std::endl;
276                std::cerr << "       Set mod_scheme to one of: bpsk, qpsk, psk<2..256>, dpsk<2..256>, qam<4..256>, apsk<4..128>, ask<2..256>, arb16opt, arb64vt" << std::endl;
277                throw (0);
278            }
279
280        } else if (strcmp(props[i].id, "DCE:1ca10d80-6d84-11df-b66a-001aa089d644") == 0) {
281            // phasing_length
282            CORBA::Short simple_temp;
283            props[i].value >>= simple_temp;
284            phasing_len = simple_temp;
285        } else if (strcmp(props[i].id, "DCE:29b6bcc2-6d84-11df-bfd7-001aa089d644") == 0) {
286            // ramp_length
287            CORBA::Short simple_temp;
288            props[i].value >>= simple_temp;
289            rampup_len = simple_temp;
290            rampdn_len = simple_temp;
291        } else if (strcmp(props[i].id, "DCE:dcc656f6-67e1-4f15-b919-7a9e6c181c05") == 0) {
292            // fec0 (inner coding scheme)
293
294            const char * prop_str;
295            props[i].value >>= prop_str;
296
297            // convert string to FEC scheme
298            fec0 = liquid_getopt_str2fec(prop_str);
299            if (fec0 == LIQUID_FEC_UNKNOWN) {
300                std::cerr << "error: FlexframeGen::configure(), invalid FEC scheme: '" << prop_str << "'" << std::endl;
301                throw (0);
302            }
303        } else if (strcmp(props[i].id, "DCE:8d65b6d8-df33-43c5-9e4e-238eca7c4424") == 0) {
304            // fec1 (outer coding scheme)
305
306            const char * prop_str;
307            props[i].value >>= prop_str;
308
309            // convert string to FEC scheme
310            fec1 = liquid_getopt_str2fec(prop_str);
311            if (fec1 == LIQUID_FEC_UNKNOWN) {
312                std::cerr << "error: FlexframeGen::configure(), invalid FEC scheme: '" << prop_str << "'" << std::endl;
313                throw (0);
314            }
315        } else if (strcmp(props[i].id, "DCE:6c05c229-da43-4f14-9865-d2f9bcb51013") == 0) {
316            // check (data validity check: crc/checksum)
317
318            const char * prop_str;
319            props[i].value >>= prop_str;
320
321            // convert string to CRC scheme
322            check = liquid_getopt_str2crc(prop_str);
323            if (check == LIQUID_CRC_UNKNOWN) {
324                std::cerr << "error: FlexframeGen::configure(), invalid CRC scheme: '" << prop_str << "'" << std::endl;
325                throw (0);
326            }
327        } else {
328            std::cerr << "error: unknown property" << std::endl;
329            throw (0);
330        }
331
332    }
333
334    // set frame generator properties (NOTE: actual frame generator object
335    // will be reconfigured on next frame)
336    fgprops.mod_scheme  = ms;
337    fgprops.mod_bps     = bps;
338    fgprops.fec0        = fec0;
339    fgprops.fec1        = fec1;
340    fgprops.check       = check;
341    fgprops.rampup_len  = rampup_len;
342    fgprops.rampdn_len  = rampdn_len;
343    fgprops.phasing_len = phasing_len;
344
345    printf("FlexframeGen_i::configure():\n");
346    printf("    ramp up len         :   %u\n", fgprops.rampup_len);
347    printf("    phasing len         :   %u\n", fgprops.phasing_len);
348    printf("    payload len, uncoded:   %u bytes\n", fgprops.payload_len);
349    printf("    payload crc         :   %s\n", crc_scheme_str[fgprops.check][1]);
350    printf("    fec (inner)         :   %s\n", fec_scheme_str[fgprops.fec0][1]);
351    printf("    fec (outer)         :   %s\n", fec_scheme_str[fgprops.fec1][1]);
352    printf("    modulation scheme   :   %u-%s\n",
353        1<<fgprops.mod_bps,
354        modulation_scheme_str[fgprops.mod_scheme][0]);
355    printf("    ramp dn len         :   %u\n", fgprops.rampdn_len);
356}
357
358void FlexframeGen_i::ProcessData()
359{
360    DEBUG(3, FlexframeGen, "ProcessData() invoked")
361
362    PortTypes::FloatSequence I_out, Q_out;
363
364
365    // header data
366    PortTypes::CharSequence *headerData(NULL);
367    CORBA::UShort headerData_length;
368
369    // payload data
370    PortTypes::CharSequence *payloadData(NULL);
371    CORBA::UShort payloadData_length;
372
373    unsigned int i;
374
375    verbose = 1;
376    while(continue_processing()) {
377        // get data from header port
378        headerDataPortIn->getData(headerData);
379        headerData_length = headerData->length();
380
381        payloadDataPortIn->getData(payloadData);
382        payloadData_length = payloadData->length();
383
384        // validate lengths
385        if (headerData_length != 14) {
386            std::cerr << "error: FlexframeGen header length must be 14 bytes" << std::endl;
387            throw(0);
388        }
389
390        // reallocate payload
391        payload_len = payloadData_length;
392        payload = (unsigned char*) realloc(payload, payload_len*sizeof(unsigned char));
393
394        // copy header, payload
395        for (i=0; i<14; i++)
396            header[i] = (*headerData)[i];
397        for (i=0; i<payload_len; i++)
398            payload[i] = (*payloadData)[i];
399
400        // configure fgprops on input data size
401        fgprops.payload_len = payload_len;
402        flexframegen_setprops(fg,&fgprops);
403
404        // compute frame length, reallocate memory
405        frame_len = flexframegen_getframelen(fg);
406        frame = (std::complex<float>*) realloc(frame, frame_len*sizeof(std::complex<float>));
407
408        I_out.length(4*frame_len); //must define length of output
409        Q_out.length(4*frame_len); //must define length of output
410
411        // generate the frame
412        flexframegen_execute(fg,header,payload,frame);
413
414        // run interpolator, store in output
415        std::complex<float> y[2];
416        std::complex<float> z[4];
417        for (i=0; i<frame_len; i++) {
418            // execute interpolator one sample at a time, storing in
419            // two-sample array y
420            interp_crcf_execute(interp, frame[i], y);
421
422#if 0
423            // write first interpolated sample
424            I_out[*i+0] = y[0].real();
425            Q_out[2*i+0] = y[0].imag();
426
427            // write second interpolated sample
428            I_out[2*i+1] = y[1].real();
429            Q_out[2*i+1] = y[1].imag();
430#else
431            resamp2_crcf_interp_execute(interp2, y[0], &z[0]);
432            resamp2_crcf_interp_execute(interp2, y[1], &z[2]);
433
434            unsigned int j;
435            for (j=0; j<4; j++) {
436                I_out[4*i+j] = z[j].real();
437                Q_out[4*i+j] = z[j].imag();
438            }
439#endif
440
441        }
442
443        // push output frame
444        frameDataPortOut->pushPacket(I_out, Q_out);
445
446        // free input buffers
447        headerDataPortIn->bufferEmptied();
448        payloadDataPortIn->bufferEmptied();
449    }
450}
451
452bool FlexframeGen_i::continue_processing()
453{
454        omni_mutex_lock l(processing_mutex);
455        return thread_started;
456}
457
458
Note: See TracBrowser for help on using the browser.