waveform development using software defined radio - diva portal

108
Department of Science and Technology Institutionen för teknik och naturvetenskap Linköpings Universitet Linköpings Universitet SE-601 74 Norrköping, Sweden 601 74 Norrköping Examensarbete LITH-ITN-ED-EX--06/005--SE Waveform Development using Software Defined Radio Thomas Sundquist 2006-04-25

Upload: others

Post on 11-Feb-2022

1 views

Category:

Documents


0 download

TRANSCRIPT

Department of Science and Technology Institutionen för teknik och naturvetenskap Linköpings Universitet Linköpings Universitet SE-601 74 Norrköping, Sweden 601 74 Norrköping

ExamensarbeteLITH-ITN-ED-EX--06/005--SE

Waveform Development usingSoftware Defined Radio

Thomas Sundquist

2006-04-25

LITH-ITN-ED-EX--06/005--SE

Waveform Development usingSoftware Defined Radio

Examensarbete utfört i Elektronikdesignvid Linköpings Tekniska Högskola, Campus

Norrköping

Thomas Sundquist

Handledare Annica SöderlundExaminator Ole Pedersen

Norrköping 2006-04-25

RapporttypReport category

Examensarbete B-uppsats C-uppsats D-uppsats

_ ________________

SpråkLanguage

Svenska/Swedish Engelska/English

_ ________________

TitelTitle

FörfattareAuthor

SammanfattningAbstract

ISBN_____________________________________________________ISRN_________________________________________________________________Serietitel och serienummer ISSNTitle of series, numbering ___________________________________

NyckelordKeyword

DatumDate

URL för elektronisk version

Avdelning, InstitutionDivision, Department

Institutionen för teknik och naturvetenskap

Department of Science and Technology

2006-04-25

x

x

LITH-ITN-ED-EX--06/005--SE

Waveform Development using Software Defined Radio

Thomas Sundquist

Software Defined Radio (SDR) is a conception of implementing radio functions in computer software,instead of having electronics performing the functions. This thesis aims to compare two different waysof implementing these functions, or waveforms.

The Software Communications Architecture (SCA) is an open standard developed by the United StatesDepartment of Defense. It uses a CORBA interface environment to make waveform applicationsinteroperable and platform independent. This method of developing SDR is compared to an open-sourceinitiative going by the name GNU Radio.

Two waveform applications are developed, one transmitter using SCA, and one receiver using GNURadio. The analog radio interface is simulated using the sound cards of two regular PCs. Thedevelopment is done using the C++ and Python programming languages.

This thesis examines pros and cons of the two SDR methods, as well as performing studies of SoftwareDefined Radio in general.

SDR, SCA, GNU Radio, CORBA, IDL, XML

Upphovsrätt

Detta dokument hålls tillgängligt på Internet – eller dess framtida ersättare –under en längre tid från publiceringsdatum under förutsättning att inga extra-ordinära omständigheter uppstår.

Tillgång till dokumentet innebär tillstånd för var och en att läsa, ladda ner,skriva ut enstaka kopior för enskilt bruk och att använda det oförändrat förickekommersiell forskning och för undervisning. Överföring av upphovsrättenvid en senare tidpunkt kan inte upphäva detta tillstånd. All annan användning avdokumentet kräver upphovsmannens medgivande. För att garantera äktheten,säkerheten och tillgängligheten finns det lösningar av teknisk och administrativart.

Upphovsmannens ideella rätt innefattar rätt att bli nämnd som upphovsman iden omfattning som god sed kräver vid användning av dokumentet på ovanbeskrivna sätt samt skydd mot att dokumentet ändras eller presenteras i sådanform eller i sådant sammanhang som är kränkande för upphovsmannens litteräraeller konstnärliga anseende eller egenart.

För ytterligare information om Linköping University Electronic Press seförlagets hemsida http://www.ep.liu.se/

Copyright

The publishers will keep this document online on the Internet - or its possiblereplacement - for a considerable time from the date of publication barringexceptional circumstances.

The online availability of the document implies a permanent permission foranyone to read, to download, to print out single copies for your own use and touse it unchanged for any non-commercial research and educational purpose.Subsequent transfers of copyright cannot revoke this permission. All other usesof the document are conditional on the consent of the copyright owner. Thepublisher has taken technical and administrative measures to assure authenticity,security and accessibility.

According to intellectual property law the author has the right to bementioned when his/her work is accessed as described above and to be protectedagainst infringement.

For additional information about the Linköping University Electronic Pressand its procedures for publication and for assurance of document integrity,please refer to its WWW home page: http://www.ep.liu.se/

© Thomas Sundquist

i

Abstract

Software Defined Radio (SDR) is a conception of implementing radio functions in computersoftware, instead of having electronics performing the functions. This thesis aims to comparetwo different ways of implementing these functions, orwaveforms.

The Software Communications Architecture (SCA) is an open standard developed by theUnited States Department of Defense. It uses a CORBA interfaceenvironment to make wave-form applications interoperable and platform independent. This method of developing SDR iscompared to an open-source initiative going by the name GNU Radio.

Two waveform applications are developed, one transmitter using SCA, and one receiverusing GNU Radio. The analog radio interface is simulated using the sound cards of two regularPCs. The development is done using the C++ and Python programming languages.

This thesis examines pros and cons of the two SDR methods, as well as performing studiesof Software Defined Radio in general.

Keywords: SDR, SCA, GNU Radio, CORBA, IDL, XML

ii

iii

Preface

This is a masters thesis on Waveform Development using Software Defined Radio written byThomas Sundquist and Mansour Fanni. The thesis and development work were performedduring the summer and autumn of 2005 at Ericsson Microwave Systems in Gothenburg, Swe-den.

Thesis outline

This thesis is split into 7 chapters:

Chapter 1 is an introduction to the thesis.

Chapter 2 deals with Software Defined Radio (SDR) in general.

Chapter 3 is all about CORBA.

Chapter 4 examines the SCA on a deeper level.

Chapter 5 looks into GNU Radio.

Chapter 6 introduces the MATH waveform.

Chapter 7 reflects our conclusions.

There are also several appendixes. Besides the complete source code to our applications,there is an installation guide and a document that deals withplatform-specific problems thatoccurred during our development time. The latter might comein handy when trying to compileand use our applications.

Acknowledgement

This thesis wouldn’t have made it this far without the support of several people to whom wewould like to offer our thanks.

Our supervisors at Ericsson Microwave Systems, Annica Soderlund, Daniel Guldbrandand Hakan Berggren, for helping us and guiding us through the thesis work. Ole Pedersen,our examiner at Linkoping University, who has read and criticized our report andgiven ususeful tips and pointers. And last but definitely not least, we would like to thank our familiesand friends, who have supported us in many ways throughout the project.

iv

v

Contents

Abstract i

Preface and Acknowledgement iii

1 Introduction 11.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 Software Defined Radio 32.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.1.1 Waveforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.1.2 Software Defined Radio . . . . . . . . . . . . . . . . . . . . . . . . 3

2.2 GNU Radio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.3 Software Communications Architecture . . . . . . . . . . . . . . .. . . . . 5

3 CORBA 73.1 CORBA in general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.1.1 IDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.1.2 Portable Object Adapter . . . . . . . . . . . . . . . . . . . . . . . . 93.1.3 Naming Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

4 Software Communications Architecture 114.1 Introduction and abstract . . . . . . . . . . . . . . . . . . . . . . . . .. . . 114.2 Core Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

4.2.1 Base Application Interfaces . . . . . . . . . . . . . . . . . . . . . .124.2.2 Framework Control Interfaces . . . . . . . . . . . . . . . . . . . . .13

4.2.2.1 DomainManager . . . . . . . . . . . . . . . . . . . . . . . 144.2.2.2 Application . . . . . . . . . . . . . . . . . . . . . . . . . 144.2.2.3 ApplicationFactory . . . . . . . . . . . . . . . . . . . . . 144.2.2.4 Devices and DeviceManager . . . . . . . . . . . . . . . . 14

4.3 eXtensible Markup Language . . . . . . . . . . . . . . . . . . . . . . . .. . 154.4 Domain Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154.5 SCA and CORBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174.6 SCA waveform development . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4.6.1 Development tools . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.6.2 The API of SCA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

vi

5 GNU Radio 215.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215.2 SDR Construction using GNU Radio . . . . . . . . . . . . . . . . . . . . . .215.3 Creating your own building block . . . . . . . . . . . . . . . . . . . . .. . 22

5.3.1 SWIG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225.3.2 Boost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225.3.3 Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . 225.3.4 Much more to know . . . . . . . . . . . . . . . . . . . . . . . . . . 235.3.5 The C++ Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5.4 A simple example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

6 Implementation of the MATH Waveform 276.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276.2 SCA implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

6.2.1 The beginning steps . . . . . . . . . . . . . . . . . . . . . . . . . . 286.2.2 The MATH implementation . . . . . . . . . . . . . . . . . . . . . . 296.2.3 Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306.2.4 Signaling system . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

6.3 GNU Radio implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 326.3.1 First attempt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326.3.2 Two signal-flow-graphs . . . . . . . . . . . . . . . . . . . . . . . . . 336.3.3 The actual implementation . . . . . . . . . . . . . . . . . . . . . . .33

6.3.3.1 The C++ code . . . . . . . . . . . . . . . . . . . . . . . . 346.3.3.2 The Python code . . . . . . . . . . . . . . . . . . . . . . . 34

7 Conclusions 357.1 Developing waveforms using SCA . . . . . . . . . . . . . . . . . . . . . .. 35

7.1.1 Benefits and advantages . . . . . . . . . . . . . . . . . . . . . . . . 357.1.2 Disadvantages of SCA . . . . . . . . . . . . . . . . . . . . . . . . . 367.1.3 Conclusions about the SCA . . . . . . . . . . . . . . . . . . . . . . 37

7.2 Developing waveforms using GNU Radio . . . . . . . . . . . . . . . . .. . 377.2.1 Advantages of GNU Radio . . . . . . . . . . . . . . . . . . . . . . . 377.2.2 Disadvantages and drawbacks . . . . . . . . . . . . . . . . . . . . .38

7.3 Comparison of the two methods . . . . . . . . . . . . . . . . . . . . . . . .39

References 41

Index 43

Appendixes

A Platform-related issues 47

B Installation Guide 51

C MATH GNU Radio Python application 53

D MATH SCA application 59

1

Chapter 1

Introduction

1.1 Background

The possibility to change waveform in a radio by using software or the ability to use the samesoftware in different platforms have lately become more andmore interesting. This techniqueis called Software Defined Radio. In response to this interesta standardized architecture forcreating software waveforms has been developed in the United States by the Department ofDefense. This architecture is known as the Software Communications Architecture.

There are other methods of developing software waveform applications. One of them isGNU Radio, which is an open-source initiative.

1.2 Objectives

The purpose of this master thesis is to compare waveform development using SCA versusdevelopment using GNU Radio. The comparison will use the sound cards of two regular PCsto simulate the radio interface. Pros and cons of these two ways of deploying waveforms willbe studied, and general issues regarding waveform developing in software is to be examined.The thesis includes studies in CORBA, XML, C++ and Python.

1.3 Methods

Before starting to develop a waveform using SCA or GNU Radio, a lot of studying has to bedone. Studies of the SCA specification and Developer’s Guide are needed to learn more aboutSCA and how to use it for waveform development. The understanding of CORBA is essentialfor understanding how SCA waveforms are developed and how theSCA Core Frameworkworks, thus a big portion of time is dedicated to studies of CORBA. XML is used to someextent in SCA development, so XML have to be learned. Besides touching up on C++ forthe actual development work in both SCA and GNU Radio, GNU Radio uses the powerfulscripting language Python which also needs a portion of timeto learn and comprehend.

Then the actual implementation can be started. The project aims to create an SDR trans-mitter and receiver using SCA and GNU Radio, and then transmit some sort of signal acrosstwo regular PC sound cards.

2

3

Chapter 2

Software Defined Radio

This chapter is an introduction to Software Defined Radio (SDR) in general. In section2.3 and 2.2 two different ways to implement SDR are introduced.

2.1 Introduction

The “normal” way of implementing waveforms and radio functions is having hardware-basedsystems do all the work. Generation, modulation/demodulation, filter functions, up/down-conversion of frequencies, everything is done with electronics in some way. Therefore, thereare some limitations to what a specific machine can do. For example, your normal FM-radioin your kitchen knows how to do exactly one thing, convert FM radio waves into sound youcan listen to.

Now imagine a radio technology that can turn your kitchen radio into a GSM telephone,or a GPS receiver, or maybe a satellite communications terminal. Or why not a garage dooropener? That’s exactly the opportunities that emerge with software radios!

2.1.1 Waveforms

There are a lot of references to the wordwaveformin this thesis, so we’ll start by explainingwhat we mean when we talk about waveforms.

A waveform can be described as a radiofunction, everything that is used to describe a spe-cific radio signal is included in the waveform conception. Generation, modulation, filtrationetc, all the different components of a radio function are puttogether and form the conceptionwaveform.

For instance, WCDMA (Wideband Code-Division Multiple-Access) is one of the maintechnologies for the implementation of third-generation (3G) cellular systems. This is anexample of a waveform. GSM or FM would be other examples of waveforms.

Hence, we donot only talk about the actual electromagnetic waves when we refer to awaveform, as one might think when first encountering the word.

2.1.2 Software Defined Radio

This radio technology is called Software Defined Radio (SDR), where almost all radio func-tions are moved out of hardware electronic circuits into software. The idea is to get the soft-

4 Chapter 2. Software Defined Radio

ware source code as close to the antenna as possible. Waveforms are generated, encoded,modulated, filtered and processed in computer software. So what’s so great about this? Ata first glance it might not seem very exciting, but there are a lot of benefits in the world ofsoftware radio.

• The ability to change waveform and function on-the-fly. One general-purpose devicecan be configured into whatever kind of radio you are in need ofat the moment. GPSreceiver one minute, cordless phone the next. Only the imagination sets the limits.

• Quick and easy upgrading with new and enhanced features. Upgrading the software canbe done over the air.

• Cost-effective solutions. When new waveforms are required ina system, there is noneed to purchase new hardware equipment, just upload the newsoftware remote andyou have a fully functional system with completely new features.

• Receive and broadcast multiple channels at the same time.

• Portability. An open standard architecture makes it possible for different kinds of com-municators to talk to each other. It’s not uncommon today that different types of gov-ernment organizations such as police and fire departments from different areas can’tcommunicate with each other due to the fact that they are using different types of radiosystems. With SDR the communication devices can reconfigurethemselves and thus“learn another language”.

The basic idea of SDR is shown in Figure 2.1.If we look at the receiving part, there is an antenna, an RF front end, an analog-to-digital

converter, and then the actual software code. The analog-to-digital converter (ADC) is thelink between the analog world of continuous signals and the digital world where the signalsare discrete.

The radio signal is usually broad-casted in high frequencies, several hundred or thousandsof MHz, so the job for the RF front end is to translate the signaldown to a lower frequencythat the ADC is able to handle. After the signal is digitized,it’s all up to the software to do theactual work.

2.2 GNU Radio

GNU Radio1 is a free open-source collection of software, that combinedwith minimal hard-ware can be used to receive and transmit waveforms. GNU Radio comes with a huge collectionof ready-to-use filters, modulators, demodulators, signalsources and other tools that can beused when constructing and/or receiving signals and waveforms. GNU Radio also comes withsoftware tools such as a spectrum analyzer and an oscilloscope.

And since it’s a truly free software, if there’s something missing in this vast collection oftools, anyone can develop new functions and modules. More ofhow this is done is describedin chapter 5. An article [12] published in Linux Journal magazine describes the GNU Radioproject more in detail.

1http://www.gnu.org/projects/gnuradio/

2.3. Software Communications Architecture 5

Antenna

Software

Receiving software radio

Antenna

Software

Transmitting software radio

DARF Front End

RF Front EndAD

Converter

Converter

Figure 2.1Basics of SDR

Several projects have been developed using GNU Radio including a complete HDTV re-ceiver and broadcaster and a multichannel FM receiver capable of listening to several channelsat the same time. The latter is an example of the strength of software radio.

2.3 Software Communications Architecture

In 1997 the United States Department of Defense (DoD) initiated the Joint Tactical RadioSystem (JTRS) program, as a way to try and solve the issue of a programmable, modular,multi-band, multi-mode radio, that would eventually replace over 200 different radio typeswithin the DoD. In late 1998, the first step towards the Software Communications Architecture(SCA) was taken.

The SCA is a non-proprietary, open architecture framework, to help promote the devel-opment of interoperable software and hardware. The SCA is nota system specification, asit is intended to be implementation independent, but rathera set of design constraints. If adeveloper designs a system according to the these design rules, his system will be portablewith other SCA implementations regardless of what operatingsystem or hardware that imple-mentation is based on.

The software structure of the SCA is called the Operating Environment, and consists ofthe following components:

- a Core Framework, this is the collection of interfaces and services that provide an ab-straction of the underlying layers for software application designers. The interfaces aredescribed using CORBA IDL, which is described in chapter 3, section 3.1.1.

6 Chapter 2. Software Defined Radio

- a CORBA middleware that is used for all communications withinthe waveform. Amiddleware can be described as the “glue” between software components or betweensoftware and the network.

- a POSIX-compliable operating system. We have used the GNU/Linux operating systemduring our work.

Figure 2.2SCA Software Structure

Figure 2.2 shows the relations between the operating environment and the waveform. Theapplication layer at the very top is where the actual SDR components are, i.e. the “waveform”layer. Beneath is the operating environment: the operating system with underlying hardwarebuses at the bottom layer and the Core Framework and the CORBA middleware on top of that.

The CORBA middleware and Core Framework are described more in detail in chapters 3and 4. Especially, understanding how CORBA and the SCA waveformconnect to each otherand what an SCA waveform really is, can be read about in chapter4, section 4.5.

7

Chapter 3

CORBA

Since CORBA is such an important component in the SCA, this chapter explains theessence of CORBA and what is to be understood before reading chapter 4.

3.1 CORBA in general

CORBA is an acronym for Common Object Request Broker Architecture, and is a standardfor producing client/server middleware in a distributed environment. The CORBA standard iscreated and controlled by the Object Management Group (OMG). The CORBA mechanismallows programs to be running on different machines and written in different programminglanguages while safely (and portably) exchanging data and the CORBA mechanism is idealfor classic client/server applications.

The ORB (Object Request Broker)is the piece of software running on a machine thathandles all server/client requests.

The protocol used by CORBA to communicate is the General Inter-ORB Protocol (GIOP).The GIOP maps ORB requests to different network transports, and one such implementationis the Internet Inter-ORB Protocol, IIOP.

An important issue for object interoperability is how ORBs address, or locate, objects. Anobject reference can be thought of as a trustworthy name thatalways symbolizes a specificobject. These references are standardized for all ORBs. Thus,any ORB can invoke opera-tions and calls to objects located with other ORBs. The way CORBA handles this is by theInteroperable Object Reference (IOR), which is a sequence of characters that specifies a singleCORBA object wherever in the world it is located.

3.1.1 IDL

CORBA uses OMG’s Interface Definition Language (IDL) to specify the interfaces that ob-jects will present to the world. CORBA then specifies a ”mapping” from IDL to a specificimplementation language like C++ or Java. Any client that wants to invoke an operation on aCORBA server object, must use the object’s IDL interface to specify which operation it wantsto perform.

IDL is not a programming language - it’s great for defining interfaces, but it doesn’t havethe constructs you’d need to write a program. The IDL interface defines the contract between

8 Chapter 3. CORBA

the client and server parts of your application, specifyingwhat operations and attributes areavailable. The programmer then uses an IDL compiler to generate application code, skeletonsfor the server part, and stubs for the client part. The stubs and skeletons run on top of an ObjectRequest Broker (ORB), and they work as proxies for servers and clients, respectively. Thisway, the client and server can be written in different languages and/or be running on differentplatforms and be able to communicate with each other in a safe, scalable manner [5].

Every CORBA server object has a unique object reference, and there are several waysof which the client can get a hold of this reference. Once obtained, the client can invokeoperations on the server object. The invocation is really invoked on the client stub, which usesthe ORB to forward the request to the servant object, through the server skeleton. Figure 3.1shows a model of this.

Figure 3.1Client-server model in CORBA using stubs and skeletons.

The ORB block contains the necessary means to pass over the request from client to server.Usually the client and server are not connected to the same ORB,and the GIOP/IIOP protocolis used to forward the request. A modification showing this ispictured in figure 3.2. Thisis all transparent from the client and server view. All the client needs is the reference to theservant, and then the ORBs handle the technical stuff such as load balancing, resource controland error handling of the requests.

Figure 3.2The inter-ORB communication using GIOP/IIOP.

3.1. CORBA in general 9

A simple example of IDL is shown below. The interfaceModulator has one operationcalledModulateDatawhich takes one input argument and returns nothing (void), and has oneattribute calledModulatorStatus. It also inherits theResourceandPort interfaces from theCore Framework.

interface Modulator : CF::Resource, CF::Port{

void ModulateData(in double incoming_data);

attribute int ModulatorStatus;}

There are a lot of ORB implementations, for this masters thesis we have used the TAOORB [11] which has real time capabilities. TAO is a real-time ORB based on the SunSoft IIOPprotocol engine. TAO is targeted for applications with deterministic and statistical Quality ofService (QoS) requirements, as well as best effort requirements.

3.1.2 Portable Object Adapter

The Portable Object Adapter (POA) is a way of making implementation objects available tothe ORB for servicing requests. All CORBA calls on a CORBA object goes through thePOA. The POA maps a CORBA object ID to the actual implementationobject. Upon a serverobject initialization, it registers itself with the POA. This can be seen in our source code inappendix D.

3.1.3 Naming Service

The OMG Naming Service [7] is one of CORBA’s standardized services. The Naming Serviceprovides the principal mechanism through which most clients of an ORB-based system locateobjects that they intend to use.

The basic function of the naming service is the association of names with object references.A server object creates associations between a name and its object reference, and registers thisinformation in the Naming Service. Then a client that knows the name of an object can retrieveits object reference by querying the Naming Service. This can also be seen in our source code.

10

11

Chapter 4

Software Communications Architecture

This chapter features a more detailed description of the SCA environment, the CoreFramework and the waveform components, with emphasis on the components thatwe have used for this thesis. The Domain Profile is described, and the chapter endswith an introduction on how to develop a waveform application.

4.1 Introduction and abstract

SCA is designed to be an open, standardized architecture providing interoperability, easy in-sertion of new technology, quick upgrade capability, software reuse and scalability. Whendesigning the structure of an SCA compliant system, all thesefactors should be kept in mind.

An SCA waveform orApplicationconsists of one or more softwareResourcesand/or hard-wareDevices. A Deviceis a type ofResourceused by applications as software proxies foractual hardware devices. TheApplicationis created in anApplicationFactory, usually by theDomainManager.

Every component in an SCA compliant waveform inherits from the Core Framework in-terfaces. These interfaces are described in CORBA IDL language, and then compiled into theprogramming language of your choice.

TheDomain Profileis a set of XML files to describe the characteristics of the system, thedifferent interfaces that it is composed of and their functional capabilities and inter-dependencies.TheDomain Profileis managed by theDomainManager.

Legacy software components that don’t have CORBA support can be incorporated in anSCA system by the use of CORBA adapters, which are proxies to wrapthe functionality ofthe component in the CORBA environment.

Figure 4.1 shows the relationship between the waveform orApplicationand the OperatingEnvironment which consists of the CF, the CORBA middleware, andthe operating system.Although the SCA uses the CORBA middleware for its software bus,the application layer canreach the OS by other means. However, waveform access to the OS is highly restricted.

In section 4.6 the SCA is described from the application developers point of view.

12 Chapter 4. Software Communications Architecture

Figure 4.1Relationship between SCA structures

4.2 Core Framework

As mentioned in chapter 2, section 2.3, the Core Framework (CF)is one of the key componentsin an SCA system. The CF consists of:

• Base Application Interfaces (Port, LifeCycle, TestableObject, PropertySet, PortSupplier,ResourceFactoryandResource) that can be used by all software applications.

• Framework Control Interfaces (Application, ApplicationFactory, DomainManager, De-vice, LoadableDevice, ExecutableDevice, AggregateDevice and DeviceManager) thatprovide control of the system.

• Framework Services Interfaces (File, FileSystem, FileManagerandTimer) that supportboth core and non-core applications.

• A Domain Profile that describes the properties of hardware devices (Device Profile) andsoftware components (Software Profile) in the system.

4.2.1 Base Application Interfaces

The Base Application Interfaces are the building blocks usedto create an SCA waveform.These interfaces arePort, LifeCycle, TestableObject, PortSupplier, PropertySet, ResourceandResourceFactory.

4.2. Core Framework 13

An SCA system is made by several components, these different parts communicate witheach other throughports. ThePort interface provides two operations to set up communica-tions, connectPort() anddisconnectPort() . Components that provide ports inheritsfrom thePortSupplierinterface which defines thegetPort() operation. This is used to ob-tain a specific port from a component.

TheLifeCycleinterfaces defines two operations,initialize() andreleaseObject() .initialize() is used to set a component to a known initial state, andreleaseObject()

tears a component down when it’s not to be used any more.TestableObjectis inherited by a component to run built-in tests. The systemdesigner can

use therunTest() operation to test the component, for example to search for errors withinthe component.

ThePropertySetinterface is used to access component properties/attributes. It defines twooperations:configure() , which makes runtime configuration possible, andquery() , toallow a component to be queried of its properties.

Every software component in an SCA waveform shall inherit theResourceinterface. Thisin turn inherits fromLifeCycle, TestableObject, PortSupplierandPropertySet. Two operationsare also provided,start() and stop() , to be able to start and stop the component. AResourcecan be created by aResourceFactory, and if it is, the sameResourceFactoryshall beused to tear down theResource. TheExecutableDeviceinterface can be used as an alternativeway to create aResource.

Figure 4.2 shows theResourceinterface and its inheritances depicted in the Unified Mod-eling Language (UML). For more information on UML see [15].

PortSupplier

getPort()

LifeCycle

initialize()

releaseObject()

PropertySet

configure()

query()

TestableObject

runTest()

Resource

identifier:string

start()

stop()

Figure 4.2Resource Interface UML Diagram

4.2.2 Framework Control Interfaces

The Framework Control Interfaces consist ofDomainManager, ApplicationFactory, Appli-cation, Device, LoadableDevice, ExecutableDevice, AggregateDeviceand DeviceManager.These interfaces can be grouped as Domain Management Interfaces and Device Manage-ment Interfaces. Domain Management Interfaces areDomainManager, ApplicationFactoryandApplication. These three interfaces are coupled together and must always be delivered as

14 Chapter 4. Software Communications Architecture

a complete domain management implementation. They manage registration/deregistration ofapplications and devices within the domain, and also controlling of applications. The DeviceManagement Interfaces areDevice, LoadableDevice, ExecutableDevice, AggregateDeviceandDeviceManager. TheDeviceManagercreates and controls theDeviceinterfaces, which act asproxies for actual hardware devices in the SCA environment.

4.2.2.1 DomainManager

The DomainManagermanages a set of available hardware devices and applications. It isresponsible for the set-up and shut-down ofApplications, Devices, Servicesand DeviceM-anagers. External applications such as a user interface can obtain alist of the Applications,ServicesandDevicesthrough theDomainManager. Built-in-tests are also managed by theDomainManager. These operations increase the scalability of an SCA system by allowingruntime insertion and extraction of components.

4.2.2.2 Application

Waveforms are defined asApplicationsin an SCA system. TheApplicationinterface providesthe Domain Management interface for the control and configuration of an instantiated appli-cation in the domain. A created application instance containsResourcecomponents and mayalso contain non-CORBA components.

TheApplicationinherits theResourceinterface, and delegates it’sResourceoperations totheApplication’s Assembly Controller.

4.2.2.3 ApplicationFactory

The ApplicationFactoryinterface provides the Domain Management interface to request thecreation of a specific type ofApplicationin the domain. The type of Application created andits components is determined by the Software Assembly Descriptor file, which is described insection 4.4. EachApplicationhas anApplicationFactoryof its own.

4.2.2.4 Devices and DeviceManager

Actual hardware devices are represented asDevices in an SCA system. TheDeviceinterfaceinherits theResourceinterface and adds additional capacity and state operations. LoadableDe-viceadds the capability to load and unload files on a particular device. TheExecutableDeviceextends theLoadableDevicewith the capability to execute and terminate processes on a de-vice. If the designer wants to create and run aResourceon aDevice, this is the way go to.Finally, AggregateDevicecan be looked upon as a collection ofDevices, with operations toadd and remove a device from the collection.

The DeviceManageris responsible for controlling and managingDevicesand services,and it has operations for registering and unregistering. Itis not a factory, so it cannot initiatenewDevices. There can exist severalDeviceManagersat once, each controlling a number ofDevices.

Upon creation of theDeviceManagerseveral things happen. TheDeviceManageruse theDevice Configuration Descriptor file to discover the servicesto be deployed andDevicesto be

4.3. eXtensible Markup Language 15

created for thisDeviceManager. Then, it creates aFileSystemand mounts it to theDomain-Manager’s FileManager. Finally, theDeviceManagerregisters itself with theDomainMan-ager. Figure 4.3 shows the sequence diagram for this scenario.

Boot Up : Device: XML Parser: DeviceManager : DomainManager

launch, registerDevice,

initialize and configure are

performed for each Device in

the system.

1: create

3: Parse DCD and SPD files

8: registerDeviceManager(in DeviceManager)

7: configure(in properties)

6: initialize()

5: registerDevice(in Device)

4: launch Device

2: create FileSystem

Figure 4.3Sequence Diagram forDeviceManagerStartup

4.3 eXtensible Markup Language

Properties, capabilities, dependencies and assembly of anSCA system is made with the eX-tensible Markup Language (XML). XML was developed by an XML Working Group formedunder the oversight of the World Wide Web Consortium (W3C) in 1996. XML is a subset ofSGML, the Standard Generalized Markup Language.

XML can be used to describe data components, records and other data structures - evencomplex data structures. XML is a markup language much like HTML. It is extensible becauseit is not a fixed format like HTML (which is a single, predefinedmarkup language). Instead,XML is actually a metalanguage, a language for describing other languages which lets youdesign your own markup languages for limitless different types of documents.

To describe a language in XML, a Document Type Definition (DTD) is used. The DTDspecifies what kind of data and attributes a document consists of, and is referenced at the topof an XML document. [16]

4.4 Domain Profile

The SCA specification requires portable software componentsto provide common informationcalled aDomain Profile. The domain management functions use the component deploymentinformation expressed in this Domain Profile. The information is used to start, initialize, andmaintain the applications that are installed into the SCA-compliant system.

16 Chapter 4. Software Communications Architecture

The Domain Profile consists of a set of XML files. These files describe the componentsthat make up an SCA system, their identity, capabilities, properties and inter-dependencies ofeach other. All of the descriptive data about a system is expressed in the XML vocabulary.Figure 4.4 portrays the relationships between the different parts of the Domain Profile in SCA.

<<DTDElement>>

Device Configuration Descriptor

<<DTDElement>>

Profile Descriptor

Domain Profile

<<DTDElement>>

Software Package Descriptor

<<DTDElement>>

Properties Descriptor

<<DTDElement>>

Software Assembly Descriptor

<<DTDElement>>

Profile Descriptor

<<DTDElement>>

Software Component Descriptor

DomainManagerConfiguration Descriptor

<<DTDElement>>

Device Package Descriptor

1

1..n

0..n

0..1

1

1

1

0..n

0..n

0..n0..n

0..n

1..n

1

1

RedGreen

Figure 4.4Domain Profile Descriptor

Software Package Descriptor

The Software Package Descriptor (SPD) is an element of the Domain Profile that identifies oneor more software component implementations. General information about a software pack-age, such as the name, author, property file, implementationcode information and hardwareand/or software dependencies are contained in a Software Package Descriptor file. An SPD isassociated with one or more Software Component Descriptors.

Properties Descriptor

Basically the Properties Descriptor File is the initial configuration file which contains thedetailed settings for a component, and/or attributes for a device. These settings will be usedby a CFResourcecomponent’sconfigure() (), query() (), and runTest() operations.The reference to a component’s Properties Descriptor is obtained from the SPD file.

Software Component Descriptor

The Software Component Descriptor (SCD) is an element of the Domain Profile that containsinformation about a specific SCA software component (CFResource, CF ResourceFactory,CF Device). The SPD can contain several references to one or more Software ComponentDescriptors. For instance, there can be more than one implementation of a certain component.They can each be described in their own SCD, and then referenced with different IDs in theSPD.

4.5. SCA and CORBA 17

Software Assembly Descriptor

The Software Assembly Descriptor (SAD) is the element of theDomain Profile that containsinformation about the components that make up an application. The SAD describes how thedifferent components of anApplicationare deployed and interconnected, and is associatedwith one or more Software Package Descriptor files.

Device Configuration Descriptor

The Device Configuration Descriptor provides the means of describing the hardware compo-nents (Devices) within an application and the characteristics of a CFDeviceManager. It alsocontains information on how to obtain theDomainManagerobject reference.

Domain Configuration Descriptor

Finally, the Domain Configuration Descriptor is the file whichdescribes theDomainManager.It contains references to theDomainManagers SPD file, which in turn can be used to de-scribe the CFDomainManagerimplementation and to specify theuses portsfor the domain’sservices, for example the theDomainManager’s Log service.

4.5 SCA and CORBA

The Core Framework interfaces are expressed in CORBA IDL [9]. When implementing awaveform, all components which constitute the waveform arealso described in CORBA IDL.As written in chapter 3, section 3.1.1, IDL is a language thatdefines interfaces. So basically,an SCA waveform is a bunch of interfaces.

When compiling the CORBA IDL, server skeletons and client stubsare created. Thismeans, on a deeper level, that all the waveform components such asResourcesandDevicesare actually CORBA servants and/or clients!

The “and/or” has to be emphasized. A component can be (usually is) both server and clientat the same time. It can be illustrated with an example. Take some components, A, B and C.A has an interface that B is connected to. Busesthe interfaceprovidedby A. This makes Aa CORBA servant and B the CORBA client that connects to the servant. On the other hand,C has an interface A is connected to. In this case, C is the server and A the client. Thus, A isboth server and client at the same time.

The various components of the waveform uses the CFPort interface (remember this is alsoa CORBA IDL interface) to make connections with each other.

The termsuses portandprovides portare commonly used in SCA development. Ausesport requests data or service from another component, while aprovides portreturns requesteddata or performs a requested service. Under this model, software assumes the role of aCORBA client when it is calling through auses port, and the role of a CORBA servant whenit is answering at aprovides port[13].

18 Chapter 4. Software Communications Architecture

4.6 SCA waveform development

When developing an SCA waveform, the operating environment (Core Framework, CORBAmiddleware and operating system) is provided as the base structure. The only thing the devel-oper should need to be concerned about is the top layer in figure 2.2 on page 6, the applicationlayer.

4.6.1 Development tools

There exist several development tools and toolkits for the SCA environment. Having access tosuch a toolkit would probably making development of SCA compliant waveforms a lot easierin comparison to having to do most of the structural work on your own, as we did in this thesis.Examples of companies delivering such tools are Prismtech1 and Pentek2.

However, they are not cheap which can make it difficult for small businesses and hobbyiststo make use of them. An article [6] in an Internet forum describes such a development kit goingfor $85000.

4.6.2 The API of SCA

The SCA specification provides an Application Program Interface (API) which defines struc-tures to simplify the construction of portable SCA applications [13],[8]. These structures areorganized much like the OSI model in different layers, with each API describing a layer. Thisis shown in picture 4.5.

WaveformApplication

I/OLayer

LogicalLink Layer

ExternalNetwork

ConnectionPhysical

Layer

MACLayer

LogicalLink Layer

Network

A

A A

A

A

B

B Non-real-Time Control, Setup and Initialization, from applications, other levels, user interface

B

BB

B

AData and Real-TimeControl

Figure 4.5Organization of the API layers

Each API is then divided into what is called “Service Groups”, small groups of functionsthat are relatively closely related. This way, the developer only has to implement the specificfunctions of the API which is needed for his waveform application.

1http://www.prismtech.com2http://www.pentek.com

4.6. SCA waveform development 19

For more information on the details of the various API components, see the SCA Devel-oper’s Guide [13] and the SCA API supplement [8].

20

21

Chapter 5

GNU Radio

This chapter describes the design concepts of GNU Radio.

5.1 Overview

As stated in chapter 2, software radio is about getting the software source code as close tothe antenna as possible. Besides that all radio functions such as modulation and filteringtakes place in software, reconfiguration and even upgradingyour radio over the air to handlea completely new waveform can be done on the fly.

GNU Radio [3] is a free toolkit for learning about, building and deploying software radios.It provides a library of signal processing blocks and the glue to tie all together. It is free andthus comes with complete source code, so anyone can make changes or see how the system isbuilt.

GNU Radio is designed to be easy to use, while still be powerfulenough to handle complexdata streams at a high sample rate. Therefore, all signal processing blocks are written in C++,while the procedure of putting them together to create a waveform is done with the scriptinglanguage Python1.

5.2 SDR Construction using GNU Radio

The programmer builds a radio waveform by creating a signal-flow-graph, where signal pro-cessing blocks process infinite streams of data flowing from their input ports to their outputports. The signal processing blocks have attributes such asthe number of inputs and outputsthey have, and what kind of data the streams consist of. The most common types of data areshorts, floats and complex number data.

Some building blocks have only output ports or input ports, and these serve as datasourcesandsinks. Examples of sources include reading from a file or a block which generate sinewaves. A sink might be a sound card, an D/A converter or a graphical display.

1http://www.python.org

22 Chapter 5. GNU Radio

5.3 Creating your own building block

There might come a situation when you need a building block that is not included in the GNURadio packages. Fortunately, there is a comprehensive guideon how to write your own build-ing block, which is found at the GNU Radio web site [4]. There isalso an expanded tutorialversion of the guide written by Dawei Shen at the Department of Electrical Engineering at theUniversity of Notre Dame [14].

C++ is the language used to create signal processing blocks inGNU Radio. At a high-levelpoint of view, infinite streams of data flow through the ports as mentioned in the previoussection. At the C++ level, these streams are ordinary arrays of the particular data type used.

When developing a new building block, we need to construct it as a shared library thatcan be dynamically loaded into Python using the “import” mechanism. More information onhow “import” works can be found in the Python tutorial [17]. It’s similar to the “#include”statement in C or C++. To accomplish this,SWIGcomes into the picture!

5.3.1 SWIG

One of GNU Radio’s strengths is that it uses the powerful scripting language Python to buildthe waveform at a higher level, but uses C++ functions at a lower level of abstraction. To beable to use the C++ functions at the higher level, a “glue” called SWIG [10] is used.

SWIG is an abbreviation for Simplified Wrapper and Interface Generator. SWIG connectsprograms written i C and/or C++ with various high-level scripting languages such as Python,Perl, PHP or TCL.

5.3.2 Boost

One important thing about GNU Radio building blocks, is that they make use ofBoost smartpointers. Boost2 is a collection of C++ libraries, and is required for the installation of GNURadio. It provides powerful extensions to C++, and GNU Radio uses one of Boost’s usefulfeatures: thesmartptr library, so called smart pointers.

Smart pointers are objects which stores pointers to dynamically allocated objects. Theyautomatically delete the objects they point to at the appropriate time, since in fact the smartpointers own the object they point to, and therefore are responsible for their destruction.

Smart pointers are defined as class templates, so when we needa smart pointer to pointto our object, we make atypedefof the template to our particular class. This can be seen indetail in the source code.

The point in using smart pointers is that the programmer doesn’t have to be worried aboutmemory leaks and destruction of objects, the Boost library takes care of that. The programmertreats the Boost smart pointer as a regular C++ pointer!

5.3.3 Naming Conventions

GNU Radio uses certain naming conventions of files and classesto help the waveform devel-oper keep track of how a component works and what parameters it uses, and also to keep aconsistency in how the blocks are constructed. For instance, suffixes are used to indicate the

2http://www.boost.org

5.3. Creating your own building block 23

input and output types of a block. The first character in the suffix shows the input type, whilethe second indicates the type of the output stream. An example is the blockgr_add_ff wherethe output is the sum of all the inputs. Here_ff says that the input and output streams consistof float types. Several other naming conventions exist, and can be found in the tutorial.

5.3.4 Much more to know

Then there are other things needed to be known when creating anew building block, such asthe correct directory structure for the files, how to use the GNU autotools for compilation, andhow to modify the makefiles. All of these subjects is quite lengthy in detail, and can be readabout in the tutorial [14]. We won’t explain them all in this thesis. Some things should be saidabout the C++ class though.

5.3.5 The C++ Class

When constructing a new building block, one creates three files. The.h file where the classdeclaration goes, the.cc where the actual class implementation is, and a SWIG file,.i , whichtells SWIG the gluing guidelines for the building block.

It is common practice when creating the class declaration inGNU Radio to make theconstructorprivate. This of course prevents the programmer from creating a new object likethis:

square_ff * my_squaring_object = new square_ff();

This is because we always want to make use of the Boost smart pointers! Doing like abovewould only create a normal C++ pointer. Instead we have a method in the class which returnsa Boost smart pointer to the desired object, like this:

\\ This is the header file:

typedef boost::shared_ptr<square_ff> square_ff_sptr;square_ff_sptr make_square_ff();

class square_ff{

private:

square_ff();friend square_ff_sptr make_square_ff();

}

\\ This is the implementation file:

square_ff_sptr make_square_ff(){

return square_ff_sptr (new howto_square_ff());}

24 Chapter 5. GNU Radio

square_ff::square_ff(){

// In this example we do nothing}

In this example, we first make a type definition thatsquare_ff_sptr shall be a Boostsmart pointer to asquare_ff object. Then we declare the methodmake_square_ff()

which returns a Boost smart pointer to asquare_ff object. This method is afriend of thesquare_ff class, and therefore have access to thesquare_ff constructor! The implemen-tation ofmake_square_ff() simply returns a typecast Boost smart pointer to asquare_ff

object, and we use this method whenever we want a newsquare_ff object. This way wemake sure that there will never be any regular C++ pointers to objects in our program!

5.4 A simple example

We end this chapter with a small example of how to use GNU Radio from the end user’s pointof view. The following Python example illustrates a simple signal generator, and is taken fromthe article Exploring GNU Radio [12].

#!/usr/bin/env python

from gnuradio import grfrom gnuradio import audio

def build_graph ():sampling_freq = 48000ampl = 0.1

fg = gr.flow_graph ()src0 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE, 3 50, ampl)src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE, 4 40, ampl)dst = audio.sink (sampling_freq)fg.connect ((src0, 0), (dst, 0))fg.connect ((src1, 0), (dst, 1))

return fg

if __name__ == ’__main__’:fg = build_graph ()fg.start ()raw_input (’Press Enter to quit: ’)fg.stop ()

We start by creating a flow graph to hold the blocks and connections between them. Thetwo sine waves are generated by thegr.sig_source_f calls. The f suffix indicates that thesource produces floats. One sine wave is at 350 Hz, and the other is at 440 Hz. Together, theysound like the US dial tone.

5.4. A simple example 25

The blockaudio.sink() is a sink that writes its input to the sound card. It takes one ormore streams of floats in the range -1 to +1 as its input. We connect the three blocks togetherusing theconnect() method of the flow graph.

The connect() method takes two parameters, the source endpoint and the destinationendpoint, and creates a connection from the source to the destination. An endpoint has twocomponents: a signal processing block and a port number. Theport number specifies whichinput or output port of the specified block is to be connected.In the most general form, anendpoint is represented as a Python tuple like this: (block,port number). When portnumberis zero, the block may be used alone.

Once the graph is built, we start it. Callingstart() forks one or more threads to run thecomputation described by the graph and returns control immediately to the caller. In this case,we simply wait for any keystroke.

26

27

Chapter 6

Implementation of the MATH Waveform

In this chapter the MATH (MAnsour-THomas) Waveform is described, and in sec-tion 6.2 and section 6.3 our two different implementations of the MATH waveform arediscussed.

6.1 Introduction

At the stage in our thesis work when we had acquired knowledgeabout SCA and CORBA,studied GNU Radio and Python and tried some programming in a CORBA environment tolearn even more, we sat down and thought about what kind of waveform we would implement.We figured out that maybe a simple FM or AM waveform would be nice, but after somethinking we thought that wasn’t good enough for the SCA implementation.

One necessary thing to have in mind was that we would use the sound cards of ordinaryPCs as the analog part of the radio system. Instead of having a real radio transmitter andreceiver, we would simply connect two sound cards together and send the data, whatever itmight be, over this simulated “radio interface”.

After some discussion with our supervisor Daniel, he suggested that we should skip theactual modulation of the signal to begin with, and concentrate on the digital signal pathway inthe SCA implementation. The important thing wasn’t the modulation, but to understand theSCA way of designing Software Radio. We would just let the soundcards act as regular D/Aand A/D converters.

We thought that it would be nice to have some sort of configurable waveform, since this isone of the basic ideas of a software radio. So we decided that we should be able to transmitordinary sound, but also be able to switch to a text mode whereregular text messages couldbe typed in and transmitted.

We named this waveform MATH, which is a sort of abbreviation of our names, Mansourand Thomas. Keep in mind that we hadn’t decided anything about what kind of modulationthat could or should be used, this was a decision we postponed.

To sum things up, we wanted a waveform that should be configurable to transmit andreceive ordinary sound or text messages, and it should have no modulation to start with. Thenthe actual work began, and we started with the SCA implementation since we realized thiswould consume most of our time.

28 Chapter 6. Implementation of the MATH Waveform

6.2 SCA implementation

We figured out almost from the beginning that the SCA implementation would take a lot moretime than the GNU Radio implementation.

First of all, we had to get a working development environmentup and running. We knewthat we were supposed to develop an SCA waveform, and for that we needed an SCA CoreFramework. It turned out that most Core Frameworks were closed source and had to be pur-chased. Our supervisors then found a suitable CF called OSSIE, an open source initiative atVirginia Tech University. They gave us the address to the OSSIE web page, and we were off.

6.2.1 The beginning steps

This section is a description on what went on during the first time of our SCA development.

Understanding of CORBA

Before we approached SCA we had to have understanding of CORBA. A good start was theCORBA FAQ at OMG’s web site [5]. After we had gotten some comprehension of whatCORBA was and how it worked, we installed the TAO ORB [11] which our supervisors hadsuggested we would use.

At the TAO web page we found some CORBA tutorials which we examined thoroughly,and we proceeded by implementing a simple client-server application using the tutorials ashelp. We then extended this application to include support for the CORBA Naming Service.

Now we thought we were ready to take on SCA.

The test example

We started by examining the example of an SCA waveform that wasshipped with OSSIE. Itwas a nasty composition of files which didn’t make much sense to us at all. This was evenbefore we had decided what kind of waveform we would develop,we just wanted some hands-on feeling on SCA development. After a lot of reading the source code back and forth, we hadsomewhat sense of how things worked. Or at least how the OSSIEteam thought things shouldwork.

Our first attempt

We then tried to do something similar to what the OSSIE team had done, which were moredifficult than we expected. Our first attempt at creating a small test-application took us at leasta couple of weeks. A lot of time was spent on debugging the OSSIE source code to find outwhy our application wouldn’t install in the DomainManager.

At last we had a small SCA waveform which did absolutely nothing, but at least it wasinstalled within the SCA Domain and everything worked as expected!

SCA Developer’s Guide

At this point in time, our supervisor Daniel mentioned a document called “SCA Developer’sGuide” [13]. We had completely missed this highly informative document on the JTRS web

6.2. SCA implementation 29

site! This document turned out to be a huge step forward in understanding SCA and SCAwaveform development.

The SCA Developer’s Guide is a comprehensive document prepared by the RaytheonCompany in 2002. It has an overview of the SCA and all it’s components, on overview ofthe APIs and domain profile components, and a full chapter with recommendations and pro-cedures the developer can follow during the course of waveform development.

6.2.2 The MATH implementation

After we have studied the developer’s guide and discussed matters with our supervisor, wedecided to create a model of our application. This model is shown in figure 6.1.

WaveformPhysical Layer

WaveformMAC Layer

UI

AssemblyController

Soundcard"Modem"

Real Time

Non-Real Time

Figure 6.1Model of the MATH waveform

In this model, we see several blocks. The two most important blocks are the Physicaland MAC, which represent the two layers “Physical Layer” and “MAC Layer” mentioned inchapter 4, section 4.6.2. Connected to them is the Assembly Controller. It is a required partof an SCA waveform, and the SCAApplicationcomponent delegates allResourceoperationsother thangetPort() to the Assembly Controller. It also handles the communication withcomponents outside the waveform, and in picture 6.1 we see that the graphical user interfaceis connected to the Assembly Controller.

30 Chapter 6. Implementation of the MATH Waveform

6.2.3 Functionality

During sending, the signal originates in the MAC layer, and is then sent down to the Physicallayer which transmits the signal out on the sound card. The Assembly Controller handlesconfiguration of both the Physical and MAC components.

There is a signaling system used in the MAC and Physical layerto handle the data com-munications. This system is described in section 6.2.4.

Due to time limitations we never implemented an SCA receiver,therefore only the down-stream real-time transmission line in the picture is used, the one from MAC to Physical. Other-wise, in receiving mode, the Physical component would receive the signal and send it upstreamto the MAC component which would handle it in the appropriateway. There is some sourcecode for the receiver though, a sort of skeleton which could be made into a receiver.

For that same reason as well as a lot of problems with the soundcard, we never finishedthe text function. As recalled, we wanted to be able to send both audio and text messages. Butas we didn’t modulate the signal, the text function wasn’t easy to implement.

An easy way would be to modulate 1 bit of the text message as a 16bit word, since thesound card uses 16 bit words. But experiments with the sound card showed that this was nota good idea. A better way to go would be to implement QPSK or BPSKmodulation, but thiswas something we didn’t look much into due to lack of time.

The C++ source code to these components can be found in appendix D.

MAC component

We decided that we would transmit ordinary wave sound files, 16 bit, 2 channels and 44100kbps. After the application has started, these events occurin the MAC component:

1. A wave file is opened using the Core Framework’sFileSystem. This file is chosenthrough a file dialog in the user interface. The result is a CoreFrameworkFile.

2. A small chunk, which size is configurable, is read from the file. The Core Framework’sFile interface reads the data into a CORBA::OctetSequence, which is a sequence ofCORBA::Octets that can be unlimited.

3. The file chunk is then repacked and converted into a CORBA::ShortSequence, which isthe same as above, but has 16-bit data fields instead of 8-bit.We do this because thesound card is a 16-bit sound card, and therefore it would be nice to have the data in a16-bit format.

4. Finally, the stream of data packets is sent to the Physicallayer.

5. Step 2 to 4 are repeated until the application is stopped.

The wave file can be changed when the application is not running. More exactly, it can bechanged at any time through the user interface, but it is not until the application is stopped andstarted again that the old one is replaced.

6.2. SCA implementation 31

Physical component

This is where the actual transmitting of the signal takes place. Embedded in the Physicalcomponent is a C++ class for sound functionality since a soundcard is to be used for theactual analog transmission. The sound class developed usesALSA (Advanced Linux SoundArchitecture) [1] to communicate with the sound card.

Assembly Controller component

The Assembly Controller directs the configure parameters from the user interface to the correctcomponent. It also handles thestart() andstop() methods for the wholeApplication.

The Assembly Controller is a component required by the SCA specification. It doesn’thave to be a separate component, another SCA component can actas the Assembly Controlleras well. We decided however to put it in a separate block.

The Graphical User Interface

In figure 6.2, a picture of the user interface is shown. When starting our application, this iswhat the user see. There are buttons for installing and uninstalling an SCAApplication intotheDomain Manager. Any SAD file can be chosen to be installed. When installed, thestartand stop buttons can be used to start and stop theApplication. There are also functions tochoose which wave file to be played, if the application shouldbe in audio or text mode and acheckbox to inhibit or shut down the physical transmission.

Figure 6.2The SCA implementation of MATH

6.2.4 Signaling system

On a lower layer of description, the data that is moved from the MAC component to thePhysical is stored in buffers. To prevent these buffer to be congested, a signaling system isused. This system is taken from the SCA API building blocks, and is called SignalsBB.

SignalsBB has three methods,signalHighwatermark, signalLowwatermarkandsignalEmpty.When the receiving buffer in the Physical component is starting to get full, Physical sends a

32 Chapter 6. Implementation of the MATH Waveform

signalHighwatermarkto MAC to indicate what is happening. MAC then stops the data streamto let the Physical process the data in the buffer. When the receiving buffer in the Physicalcomponent is starting to be depleted, Physical sends asignalLowwatermarkin order for MACto start sending more data.

The third signal,signalEmpty, is used to check the status of a buffer. This method return“true” if the buffer is empty.

6.3 GNU Radio implementation

In GNU Radio, the scripting programming language Python is used to connect blocks together,and to start and stop the application. The basic idea is that the waveform developer designs asignal-flow-graph in Python using the GNU Radio building blocks.

To start the waveform, the Python application calls thestart() method on the signal-flow-graph. Then there is a runtime system which does all the work of instantiating the correctclasses and libraries, creating threads for execution, andmakes sure there is a correct data flowbetween the different blocks. The runtime system is provided in the GNU Radio Core package,and one doesn’t have to worry about it at all as a waveform developer.

When we got to the GNU Radio implementation time was running short, so we decidedthat we should only try to model and implement the receiving part of MATH in GNU Radio.The SCA implementation was as recalled modeled to be both transmitter and receiver, thoughonly the transmitting part was actually implemented.

Since GNU Radio is totally different from SCA in the meaning that a lot of buildingblocks already exist, we started by examining what blocks already existed, and what we mightneed for our waveform. We expected that at least one GNU Radio building block had to beimplemented, some kind of MATH decoding block.

6.3.1 First attempt

When we first attacked the problem, we thought that a structureas shown in figure 6.3 wouldbe a good start for the MATH waveform. The figure shows the signal-flow-graph which wouldlater be created in Python.

The MATH demux building block would take care of the separation of audio and text, andsend them to the correct place. The audio sink would play sound, after it had been low passfiltered. The text output block would print the text messages.

The FIR filter block comes in the GNU Radio core package for bothfloats and complexinput and output streams, and the audio source and sink are also available in a separate pack-age. So we didn’t have to implement these. It turned out that we couldn’t find a block thatsimply printed text on a terminal, so besides the MATH demux block this block had to beimplemented as well.

But after studying the build-your-own-block-tutorial and doing some work on the MATHdemux block, we encountered a problem. The current version of GNU Radio only supportsthe samedata rate for all output streams. We couldn’t shut off the pathway to the text boxwhen audio is coming in, or have the audio sink not receiving any data if we are in text mode.This was a major setback, so we had to find another solution.

6.3. GNU Radio implementation 33

Figure 6.3First model for GNU Radio implementation of MATH

6.3.2 Two signal-flow-graphs

One way of solving the problem would be to havetwo signal flow graphs. One to use in textmode, and one for the audio mode. These two graphs would then be started and stopped inPython, accordingly to which mode we wanted to be in. Figure 6.4 shows a model of this.

FIR filter audio sink

Terminaltext output

audiosource

audiosource

Textdecoding

math_text_graph:

math_audio_graph:

Figure 6.4Second model for GNU Radio implementation of MATH

The text decoding block and the text output block could perhaps be combined to one blockas well, as they both needed to be implemented.

6.3.3 The actual implementation

Since stated earlier in this thesis, we never got to implement the text part of the MATHwaveform. Therefore, the text decoding block doesn’t contain much. We gave it the namemath_console_writer_f , where the_f states that the block takes floats as input. The ideais to decode the input stream, and print the message on stdoutor some other output console.Though our block doesn’t perform any signal processing, it integrates and works in the GNURadio environment nevertheless!

The block was implemented as sort of a “black hole”, is just takes data on the input anddoes nothing with it.

34 Chapter 6. Implementation of the MATH Waveform

6.3.3.1 The C++ code

It is not that hard to implement your own building block, we just followed the example in thetutorial [14], which is really good and comprehensive. It mostly involves following a recipewhere you besides writing the class for your block, replace some rows in the GNU autotoolsconfiguration files and the SWIG configuration file. These files can be downloaded togetherwith the tutorial at the GNU Radio web site.

The documentation on these GNU autotools files is very sparsein the tutorial, and it isrecommended that anyone who wants to develop own signal processing blocks learns how touse, create and modify them. We ran into some problems when compiling our block, and thiswas related to the fact we didn’t know how these files worked. But after some troubleshootingthings worked as expected.

We can mention that there is some SWIG magic behind the scenes when the block com-piles. This way, we can access themath_console_writer_f block using the regular Pythonnotationmath.console_writer_f() .

The C++ source code can be found in appendix C.

6.3.3.2 The Python code

We started off in an uncommon way by implementing the Graphical User Interface (GUI)first. We wanted to have a similar look as the SCA implementation, so wxPython1 was theway to go. More information about this way of writing portable user interfaces can be foundin appendix A.

The application consists of two signal-flow-graphs as shownin figure 6.4, which we thencould alternate between using two common radio buttons in the GUI. The GUI also providesa way of starting and stopping the waveform.

The signal-flow-graphs are quite simple. The first which implements the audio part consistof an audio source, where the signal is received from the sound card. It is followed by a low-pass FIR filter to filter out any high-frequency noise components in the signal. Finally, the sig-nal is connected to an audio sink. The other signal-flow-graph which would implement the textpart is even simpler. It starts with an audio source, followed by ourmath_console_writer

block.The Python code can be found in appendix C.

1http://www.wxpython.org

35

Chapter 7

Conclusions

In this chapter we draw conclusions of our work. Pros and cons of the two differentways of developing Software Radio are presented, and we end the chapter with acomparison of the two methods.

7.1 Developing waveforms using SCA

7.1.1 Benefits and advantages

First of all, the SCA is a well defined, open standard. There areno license costs or other meanswhich may prevent developers of using it. This make it a good base for interoperability andinformation exchange.

Second, the SCA is a strictly defined set of guidelines. If these guidelines are followed, itis very easy to make portable waveforms. Parts of one waveform on one platform can easilybe re-used in another waveform on another platform.

Benefits using CORBA IDL structures

The CORBA IDL is a very strictly defined language, which makes sure that the resulting codebehaves exactly the same way regardless of what language it is compiled into, or on whatplatform. This is good for a developer using CORBA IDL, since hecan be 100 % sure thathis application will be platform independent, and work in any environment. CORBA itself isdeveloped with high performance and scalability in mind, which makes it a good choice as theSCA middleware.

Since the interfaces that the SCA CF consists of are defined in CORBA IDL they canbe used on any platform or CPU, and waveforms can be developed using any programminglanguage as long as there is an IDL compiler for it. This way, the SCA makes it very easyto develop portable waveforms. The possibility of easily taking building blocks from onewaveform and using them in another can help cut the development time and costs significantly.Also, different parts of a waveform application can run on different machines or devices usingdifferent operating systems and CPUs.

Using CORBA as middleware does not only ease communications within the waveformand makes sure strict interfaces are defined, it also separates the underlying operating systemfrom the application which aids portability.

36 Chapter 7. Conclusions

Easy generating new interfaces

Once the waveform developer has come across the initial quite high step of gaining the re-quired knowledge regarding SCA, it it fairly easy to create new interfaces and waveform mod-els and integrate these into a waveform application. For instance, one can model the interfacesin UML and then generate the appropriate IDL from the UML.

7.1.2 Disadvantages of SCA

We have found several difficulties with the SCA, and they are presented below.

High learning threshold

In the beginning of our work we almost immediately came across what we think is the biggestdisadvantage of SCA, it takes a lot of time understanding whatit is all about! Our first en-counter with SCA was the picture on page 6, which didn’t make sense at all, and a printout ofthe huge SCA specification[9]. It took us weeks just to get an overview of how the structureswork, and even now when we are finished it still can be difficultto understand and rememberhow some things work and are used.

The SCA is a very complex specification, with a lot of differentfiles and events that muchoccur in order to have a working application. This in combination with sparse detailed doc-umentation how to develop waveform applications creates a rather high threshold of under-standing to overcome, before being able to begin the work on the actual waveform.

Disadvantages regarding CORBA

Another major issue we had lots of problems with was the CORBA environment. CORBAitself is not difficult to understand and use. It was when we had several programs that were tointeract with each other the problems occurred.

Our Physical and MAC resources were both CORBA servers and clients at the same time,and the problem was really how to use the CORBA event loop and theORB itself in a goodfashion without losing performance. We spent many days searching for good ways of doingthis, and tried different solutions. We once even rewrote our whole CORBA initialization codefrom scratch in despair.

Here is the scenario: The server part of each resource has to wait for incoming CORBA re-quests, which is done by a call to theORB::run() method or to theORB::perform_work()method. The first is a call which never returns unless the ORB isshut down or destroyed. Butin our case it didn’t even return if the ORB was destroyed, for reasons we were unable tofind. The latter method performs one unit of work, and then returns. There is also a methodcalledORB::work_pending() which checks if there is any CORBA work to be done fora particular servant, and this is used in conjunction withORB::perform_work() .

We weren’t able to use theORB::run() call since we couldn’t shut down our processesupon exiting the application, so our application usesORB::perform_work() . Our prob-lems showed up as time delays and hang-ups when callingORB::perform_work() fromseveral processes.

At first there was just a major hang-up in all the processes. None of the componentsworked, they were all waiting for their ORB calls to return, asthey depended on each other

7.2. Developing waveforms using GNU Radio 37

to finish. This was finally solved by studying our particular ORB in detail. We managed toconfigure the ORB in such a way that it created a new processing thread for every incomingcall, making it possible to have several calls at once to the ORB. The problem and solutionprobably took us a week to find and solve.

Then another problem occurred. When the processes calledORB::perform_work()in their main loop, there were sometimes long time delays until the call returned. This inturn produced an output audio signal with “gaps” in it, thus making it far from a real-timeapplication. This was unacceptable of course, and much timewere spent finding a solution.Finally, we tried to remove theORB::perform_work() call from one of our processes.We didn’t expect that this component would work at all by doing this, but to our surprise thewhole application worked super smooth!

We never found out exactly what happened or why the components worked after this, itseemed to us like some CORBA magic. This became a very annoying solution to our problem,since we didn’t understand it. But then again, time was running short, and we had to move on.

7.1.3 Conclusions about the SCA

In our work we have discovered that a lot of our time was spent examining and debuggingthe SCA CF, and even more time was spent getting a well working multi-component CORBAapplication. This steals the focus of the actual waveform application, the part that really shouldmatter! Also, having to write all the XML and get that syntactically right, generating UUIDnumbers etc, is something that isn’t essential to a waveformdeveloper and he shouldn’t haveto be concerned about it. In general, XML is good for computers to read, not people.

All of this is however good for the understanding how the SCA works, and we wouldrecommend for an SCA waveform developer to at least have triedit once.

It would beveryappreciated when developing SCA waveform applications to have somesort of development tool which takes care of not only handling of the CF, but also the CORBAintegration and generation of the XML needed for the application. All setup of the componentsand their communications channels, the XML generation and well as all the setup regardingthe DomainManager etc could be auto generated by such a development tool-kit.

It should of course be highly configurable, detailed description possibilities regarding in-ternal communications channels in an application should for example be provided. Further-more, the waveform developer should be able to perform most or all of the work “by hand” ifhe wanted.

7.2 Developing waveforms using GNU Radio

7.2.1 Advantages of GNU Radio

GNU Radio has several advantages, in this section we present the benefits of using GNU Radiothat we have found.

• It is very easy to get started! This is probably one of the greatest things about GNURadio. After installation and reading the GNU Radio documentation [2] for new users,it doesn’t take more than a few minutes to have a small waveform application going.

38 Chapter 7. Conclusions

• GNU Radio is free open-source software. This makes it possible for anyone to expandthe GNU Radio tool-kit with new functions and signal processing blocks.

• Good run-time system. The waveform developer doesn’t have to be concerned aboutdata rates, memory allocation for communication buffers and so forth. One specifieswhat kind of data a block uses, and what data rate the inputs and outputs shall use. Thenthe run-time system does all the hard underlying work.

• Many tools and components are provided. Included in GNU Radio’s core package is avast number of ready-to-use components such as filters, signal sources and modulatorsfor the waveform developer to use. It also comes with a spectrum analyzer and anoscilloscope.

• There exists cheap development hardware. The Universal Software Radio Peripheral(USRP) is piece of hardware developed by the GNU Radio team. It consists of a moth-erboard equipped with an FPGA for some basic DSP functions, and can hold up to 4daughterboards used for transmitting and receiving. The USRP is open source as well,and if a developer doesn’t want to build one of his own it can bepurchased for about$100–$150.

7.2.2 Disadvantages and drawbacks

As with all software implementations, GNU Radio has some drawbacks as well.

Lack of documentation

The underlying run-time system of GNU Radio is difficult to understand and get a grip of.There are some SWIG “magic” functions and other parts that aren’t easy to apprehend. Mostof this is due to the shortage of documentation, especially when it comes to development ofnew building blocks.

There is a tutorial on the GNU Radio web site, and during our thesis work a more compre-hensive version was released. But there is very little, one might even sayno documentationon how the underlying run-time system works. There is of course the freely distributed sourcecode to read, but that is not an easy task for most people.

Environment limitations

When using GNU Radio, Python is the language which the user writes his application in. Ifthe user wants to develop a new building block, this is done inC++. In other words, thedevelopment and usage languages are limited to these two. One can imagine that a developercould write a building block in some other language, but it would probably be difficult to insertinto the GNU Radio run-time system.

The operating system is also a limiting factor. GNU Radio is primarily developed for theLinux platform. There are reports that it compiles on certain variants of Solaris and somepeople are trying to get it to work on the Windows platform. However, if one wants to be sureto have a working GNU Radio system, Linux is the operating system to use.

7.3. Comparison of the two methods 39

7.3 Comparison of the two methods

A comparison between the SCA and GNU Radio is not easy to make since they are so different.One of the most important differences is that SCA is a kind ofspecificationused to helpdevelopers produce interoperable, portable radio waveforms. The SCA is a set of guidelines,and it is up to the software developer to choose how the application will look like, as long ashe follows the SCA guidelines.

This in comparison to GNU Radio, which is animplementationof a software radio, with aunderlying run-time system and a lot of building blocks. It is basically a ready-to-use toolboxof various waveform components! It is more like a box of LEGO,the developer only has toput together already finished pieces to produce a software radio.

Difficulty and understanding issues

GNU Radio could be considered a lot simpler than the SCA. It takes a short amount of timeto create a working SDR, compared to creating one the SCA way.

If one wants an SDR right away, preferably yesterday, and since GNU Radio is an imple-mentation as opposed of the SCA, GNU Radio is a good alternative. On the other hand, ifone wants an SDR that is compatible with other JTRS waveforms and portable among severaldifferent platforms, SCA is a better way to go.

Development costs

GNU Radio is probably cheaper than the SCA. There exist developer kits for the SCA, butthey have a rather high price compared to the free GNU Radio. For the amateur or smallcompany, many of these kits aren’t even worth considering. One could of course use an opensource Core Framework as we did in this thesis, which cuts the costs. But this way, the SCAtakes a lot more time to apprehend, which produces higher costs as well in terms of developerssalaries.

40

41

References

[1] Advanced linux sound architecture.<URL:http://www.alsa-project.org> .

[2] Exploring GNU Radio, .<URL:http://www.gnu.org/software/gnuradio/doc/

exploring-gnuradio.html> .

[3] The GNU Radio web site, .<URL:http://www.gnu.org/software/gnuradio/> .

[4] How to write your own GNU Radio building block.<URL:http://www.gnu.org/software/gnuradio/doc/

howto-write-a-block.html> .

[5] OMG CORBA web site.<URL:http://www.omg.org/gettingstarted/corbafaq.htm >.

[6] Pentek offering an SCA development kit.<URL:http://www.linuxdevices.com/news/NS3911104852. html> .

[7] SCA Naming Service Specification version 1.3.<URL:http://www.omg.org/technology/documents/formal /naming_

service.htm> .

[8] SCA Specifications and Requirements v3.0.<URL:http://jtrs.army.mil/sections/technicalinforma tion/

technical_SCA-Specification-Requirements.html> .

[9] Software Communications Architecture Specification v3.0.<URL:http://jtrs.army.mil/documents/sca_documents/V 3.0/

SCARelease3.0.pdf> .

[10] SWIG - Simplified Wrapper and Interface Generator.<URL:http://www.swig.org> .

[11] The TAO (Ace Orb) web site.<URL:http://www.cs.wustl.edu/ ˜ schmidt/TAO.html> .

[12] Eric Blossom. GNU radio: Tools for Exploring the Radio Frequency Spectrum.<URL:http://www.linuxjournal.com/article/7319> .

42 References

[13] Raytheon Company. Joint Tactical Radio System(JTRS) SCA Developer’s Guide.<URL:http://jtrs.army.mil/sections/technicalinforma tion/

technical_SCADevGuide.html> .

[14] 2005 Dawie Shen May 19. GNU Radio Installation Guide - Step by Step.<URL:http://www.nd.edu/ ˜ dshen/GNU/> .

[15] Ivar Jacobson Grady Booch, James Rumbaugh.The Unified Modeling Language UserGuide. Addison-Wesley, 1999. ISBN 0-201-57168-4.

[16] Erik T. Ray.Learning XML, Second Edition. O’Reilly, 2003. ISBN 0-596-00420-6.

[17] Guido van Rossum and editor Fred L. Drake, Jr. Python Tutorial Release 2.4.1.<URL:http://docs.python.org/tut/tut.html> .

43

Index

AADC (Analog-to-Digital Converter), 4AggregateDevice, 12–14ALSA (Advanced Linux Sound Architecture), 31Application, 11, 14Application Program Interface (API), 18ApplicationFactory, 12–14Assembly Controller, 14audio.sink(), 25

BBoost smart pointers, 22, 24

CC++, 21, 34CF (Core Framework), 1, 5, 9, 11, 12, 28configure(), 13, 16connectPort(), 13CORBA (Common Object Request Broker Architecture), 1, 6, 7, 17, 28CORBA middleware, 6, 11, 18

DDCD (Device Configuration Descriptor), 17Device, 12–14, 17DeviceManager, 12–14disconnectPort(), 13DoD (Department of Defense), 5Domain Profile, 11, 12, 15DomainManager, 12–14, 17DTD (Document Type Definition), 15

EExecutableDevice, 12–14

FFileManager, 15FileSystem, 15FIR (Finite Impulse Response) filter, 32

44 Index

GgetPort(), 13GIOP (General Inter-ORB Protocol), 7, 8GNU Radio, 1, 4, 21, 24GPS receiver, 4GSM telephone, 3GUI (Graphical User Interface), 34

HHDTV (High-Definition TeleVision), 5HTML (HyperText Markup Language), 15

IIDL (Interface Definition Language, 5IDL (Interface Definition Language), 7, 11, 17IIOP (Internet Inter-ORB Protocol), 7, 8initialize(), 13IOR (Interoperable Object Reference), 7

JJTRS (Joint Tactical Radio System), 5

LLifeCycle, 12Linux Journal, 4LoadableDevice, 12–14

MMATH (MAnsour-THomas waveform, 27MATH (MAnsour-THomas waveform), 27

NNaming Service, 9, 28

OOE (Operating Environment), 5OMG (Object Management Group), 7ORB (Object Request Broker), 7, 9OSSIE (Open Source SCA Implementation::Embedded), 28

PPerl, 22PHP (Hypertext Preprocessor), 22POA (Portable Object Adapter), 9Port, 12PortSupplier, 12POSIX (Portable Operating System Interface Standard), 6PRF (Properties Descriptor File), 16PropertySet, 12

Index 45

provides port, 17Python, 21, 24, 25, 34Python tutorial, 22

QQoS (Quality of Service), 9query(), 13, 16

RreleaseObject(), 13Resource, 11, 13, 16, 17ResourceFactory, 12RF front end, 4runTest(), 13, 16

SSAD (Software Assembly Descriptor), 17SCA (Software Communications Architecture), 1, 5, 11SCD (Software Component Descriptor), 16SDR (Software Defined Radio), 1, 3, 4, 21SGML (Standard Generalized Markup Language), 15signal-flow-graph, 21, 32, 33Software Profile, 12SPD (Software Package Descriptor), 16start(), 13stop(), 13SWIG (Simplified Wrapper and Interface Generator), 22, 23, 34

TTAO (The Ace Orb), 9TCL (Tool Command Language), 22TestableObject, 12

UUML (Unified Modeling Language), 13Universal Software Radio Peripheral (USRP), 38uses port, 17

WWaveform, 3, 27waveform, 11WCDMA (Wideband Code-Division Multiple-Access), 3wxPython, 34

XXML (eXtensible Markup Language), 11, 15

46

47

Appendix A

Platform-related issues

This appendix deals with the problems and issues with compilers, libraries and otherplatform related concerns we’ve had during our thesis work.

Introduction

During our work there has been several software related problems, some which have beeneasily resolved, and others that were a harder nut to crack. Much time and effort has beenspent to solve these problems, and this appendix could be of help to others who are trying todevelop Software Defined Radio using a Linux platform.

As the general platform, we used the Linux distribution Fedora Core 3 (FC3) as recom-mended. This platform uses the RPM packaging system, which none of us had used muchbefore. The choice of FC3 turned out to be not such a good idea for our development work.

GNU Radio issues

GNU Radio was very easy to install, just grab the packages fromthe GNU Radio downloadsite1, unpack them, compile and install using the standard GNU autotools.

There was one major problem during the installation of GNU Radio, the SWIG libraryneeded for GNU Radio to compile had to be of version 1.3.24 or later. The version comingwith FC3 was version 1.3.21. After a lot of hassle with searching for RPM packages of theright version we found a source RPM for SWIG 1.3.24, and managedto compile that into anRPM package and install into our system.

A small problem occurred with the ALSA support for GNU Radio. ALSA is the soundapplication interface used in Linux operating systems, andthe ALSA modules for GNU Radiois fairly new and in a high beta stage. As it says in the README file, “This is currently awork-in-progress and is not ready for use”. In order to get a 48000 samples/second samplingfrequency with GNU Radio, we had to use the older way to implement sound in Linux, theOSS interface. The OSS module for GNU Radio turned out to work fine, but in order for it towork at all, OSS support has to be installed in the Linux Kernel.

1http://comsec.com/wiki?GnuRadio2.X

48 Appendix A. Platform-related issues

SCA issues

During the time we spent trying to understand and develop an SCA waveform, a lot ofplatform-related problems occurred.

TAO and gcc

At the time, OSSIE was using TAO (The ACE ORB) for its CORBA-relatedoperations, so wehad to install TAO to begin with. First of all, compiling ACE and TAO takes a lot of time, andwe had to do it a couple of times to get things right. Approximately two days were all aboutcompiling TAO.

Then it turned out that TAO has a major flaw! The TAO IDL compiler produces C++source code which cannot be compiled with gcc 3.4. Guess which version of gcc is shippedwith Fedora Core 3? We didn’t know at first what the problem was,we just couldn’t compilethe source code. Then we read at the OSSIE web page that they had had issues with gcc 3.4as well, and recommended gcc 3.3 instead.

Getting gcc 3.3 installed in FC3 was easier than we first thought. After a couple of daysof struggling with RPM packages and dependencies, we found a package called compat-gccwhich included the next latest compiler. This was in our casegcc 3.3!

But this was really an ugly workaround. In the next release of Fedora, gcc 4.0 is standardand gcc 3.4 is the compat-gcc. This means that Fedora Core 4 won’t work with TAO. Herewe started to regret that we used Fedora instead of the Debiandistribution. In Debian, gccpackages exist for most versions and can easily be installedwithout any fuss at the same time.

By the way, GNU Radio has compile issues with gcc 3.3, and gcc 3.4is recommended . . .

ALSA

The Linux sound API is named ALSA, and since we were supposed to use sound cards totransmit and receive the data, we had to learn how to program the ALSA API as well. It turnedout that the ALSA version shipped with FC3 was not up-to-date with the ALSA tutorials wewanted to use, so we had to find and install the latest version of ALSA instead.

Hardware

The computers we used during the thesis came equipped with built-in sound cards. Thesedidn’t quite work as expected, we weren’t able to record any sound at all with them! Notwith our own developed software, nor with any other program we had at hand. The only waywe could detect that an audio signal actually was received onthe other end was that it wentstraight through from the input connector to some built-in speaker. Very strange behaviorindeed.

Luckily the department approved of our request of having newPCI sound cards purchased,and after we had received these everything worked as expected. But approximately a week ofour time was lost due to this sound card debugging.

49

wxGTK

A test example of an SCA waveform was bundled with OSSIE, and for the graphical stuff itused wxWidgets2. The version of wxWidgets we wanted was wxGTK 2.4.2, which compiledand installed nicely. But the test application wouldn’t work! We couldn’t first figure out whatwas wrong, everything seemed to be in order.

After a lot of debugging and googling we finally had the solution. It turned out thatwxGTK 2.4.2 had an issue with GTK 2.4.x, which is the graphical tool-kit wxGTK is com-piled against. There had been some internal changes in laterversions of GTK 2.4 and wxGTK2.4.2 hadn’t accounted for these changes. Of course the version shipped with FC3 had theseinternal changes. Luckily we found and applied a wxGTK 2.4.2patch to fix this problem andthen things worked as expected.

OSSIE

Finally, the Core Framework that we used, OSSIE, turned out tobe in an early beta stage, andwas full of bugs. Alot of time has been spent chasing and correcting bugs in OSSIE. This wasgreat for a deeper insight in the SCA structures, but it was something we hadn’t expected wewould have to do.

2http://www.wxwindows.org

50

51

Appendix B

Installation Guide

This appendix should have all the information needed to install and try our implemen-tation of the MATH waveform. It is assumed that the reader has some knowledge ofUnix’s shell environments, and of Linux in general.

GNU Radio implementation

First of all Python needs to be installed, but as Python comesinstalled as default with mostLinux distributions, we assume that this already is done.

Go to the GNU Radio download page1 and the grab the latest GNU Radio core packages,the audio packages alsa and oss, and the wx package. Follow the installation instructionsprovided in these packages to compile and install GNU Radio.

Then simply put the MATH Python source code somewhere, and run the Python applica-tion! Simple as that.

SCA implementation

In order for the SCA transmitter to compile and run, some additional software has to be in-stalled. Also, don’t forget to set the correct shell variables as stated in the last section of thisappendix.

• OSSIEThis is the Core Framework used in our project. The source codecan be found at<URL:

http://ossie.mprg.org> . We have been using version C which can be found at thedownload page, but that version willnot work with our application since we had to fixbugs in it for things to work.

One way to find a better version of OSSIE is to go to the OSSIE bulletin board, thereis a link at the web site. More recent snapshots of OSSIE can befound there. The bestway of running our application and to make sure it works, is touse our bugfixed versionof OSSIE, which can be found bundled together with the complete MATH source codeat <URL:http://theblacklodge.org/ ˜ fringe/MATH+ossie.tar> . This is thesame source code as found in appendix D and C.

1http://comsec.com/wiki?GnuRadio2.X

52 Appendix B. Installation Guide

• TAO ORBTAO is the ORB used in this project. It’s probably the one thingwhich takes the mosttime to compile. The source can be found at the TAO web page [11]. Grab version ACE-5.4+TAO-1.4 which is the same as we have used and follow the installation instructions.

• Xerces-C++Xerces-C++ is the XML parser needed by the OSSIE CF. Download and install it beforetrying to compile OSSIE. Xerces-C++ can be found at<URL:http://xml.apache.

org/xerces-c/> , we have used version 2.6.0 in this project.

When all additional software is installed and the correct shell variables have been set upas stated last in this appendix, the SCA MATH source code should compile and run withoutany problems. The correct way of compiling is to go to the mainsource directory, type “makeidl” to compile the IDL source, and then “make” to compile allof the C++ source code.

wxWidgets

Both applications uses the portable graphical user interface wxWidgets which can be foundat <URL:http://www.wxwindows.org> . The GNU Radio application uses the Pythonversion of wxWidgets, this is found at<URL:http://www.wxpython.org> . Download thelatest version and install, and the applications should work fine.

Shell variables

In order for things to work correctly, several shell variables have to be set. Some of themrelates to TAO ORB, others to OSSIE and some to GNU Radio. These variables are usedduring compilation and running of the applications.

Below are the relevant lines extracted from the bash initialization file∼/.bashrc:

export ACE_ROOT=/usr/src/ACE_wrappersexport TAO_ROOT=$ACE_ROOT/TAOexport XERCESCROOT=/usr/local/xerces-c-src_2_6_0

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfigexport PATH=$PATH:$XERCESROOT/binexport PATH=$PATH:$ACE_ROOT/binexport PYTHONPATH=/usr/local/lib/python2.3/site-pack ages/

export OSSIEROOT=$HOME/src/ossieexport OSSIEIDL=$HOME/src/ossie/ossieidlexport OSSIEPARSER=$HOME/src/ossie/ossieparserexport OSSIECF=$HOME/src/ossie/ossiecf

export LD_LIBRARY_PATH=/usr/local/lib:$XERCESCROOT/l ib:$ACE_ROOT/lib:\$ACE_ROOT/ace:$OSSIECF/lib:$OSSIEPARSER/lib:$OSSIEI DL/lib

Add these lines to your∼/.bashrc file, or equivalent file if you are using another shell. Ofcourse you have to modify them to suit your installation of TAO, Python etc.

53

Appendix C

MATH GNU Radio Python application

This appendix includes the Python and C++ source code to the MATH waveform.

Python source codeThis is the main Python application, including the GUI.

#!/usr/bin/python

import osimport wxfrom gnuradio import grfrom gnuradio import audio_ossfrom gnuradio import math

ID_ABOUT=1ID_EXIT=2ID_START=3ID_STOP=4ID_MODESEL=5

# GNU Radio signal-flow-graph functions

# Sample rate throughout the whole graphsampling_freq = 48000

# Input and outputsignal_in = audio_oss.source(sampling_freq)signal_out = audio_oss.sink(sampling_freq)

def build_audio_graph ():# volume gain for the FIR filtergain = 1# cut-off frequencycutfreq = 20000# width of transition bandtranswidth = 1000

# Compute FIR filter tapstaps = gr.firdes.low_pass (gain,

sampling_freq,cutfreq,transwidth,gr.firdes.WIN_HAMMING) # Using Hamming window

# The FIR filter

54 Appendix C. MATH GNU Radio Python application

mathFIR_left = gr.fir_filter_fff(1, taps)mathFIR_right = gr.fir_filter_fff(1, taps)

# Create a signal-flow-graphfg = gr.flow_graph()

# Connect the building blocksfg.connect ((signal_in, 0), mathFIR_left)fg.connect ((signal_in, 1), mathFIR_right)fg.connect (mathFIR_left, (signal_out, 0))fg.connect (mathFIR_right, (signal_out, 1))

return fg

def build_text_graph ():

# our MATH text decoding blockmath_block = math.console_writer_f()

# Create a signal-flow-graphfg = gr.flow_graph()

# connect the graphfg.connect((signal_in,0), math_block)

return fg

# Create a main MATH frame class which inherits from wxFrame# This is where all the GUI thingies are.class MATHframe(wx.Frame):

# Override the __init__ method inherited from wxFramedef __init__(self,parent,id,title):

wx.Frame.__init__(self, parent, wx.ID_ANY, title, size= (350,250),pos=(50,50),style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)

# Create a status barself.CreateStatusBar()

# A small menu.mathmenu= wx.Menu()mathmenu.Append(ID_ABOUT, "&About"," Information about this program")mathmenu.AppendSeparator()mathmenu.Append(ID_EXIT,"E&xit"," Terminate the progra m")

# Creating the menubar.menuBar = wx.MenuBar()menuBar.Append(mathmenu,"Menu") # Adding the "mathmenu" to the MenuBarself.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content.

# Events when menuitems are chosen or buttons clicked.wx.EVT_MENU(self, ID_ABOUT, self.OnAbout)wx.EVT_MENU(self, ID_EXIT, self.OnExit)wx.EVT_BUTTON(self, ID_EXIT, self.OnExit)wx.EVT_BUTTON(self, ID_START, self.OnStart)wx.EVT_BUTTON(self, ID_STOP, self.OnStop)wx.EVT_RADIOBOX(self, ID_MODESEL, self.OnRadioButton)

# Create sizers to hold the buttonsself.mainsizer = wx.BoxSizer(wx.VERTICAL)self.buttonsizer1 = wx.BoxSizer(wx.HORIZONTAL)self.buttonsizer2 = wx.BoxSizer(wx.HORIZONTAL)

self.buttonsizer1.Add(wx.Button(self, ID_START, "Star t",wx.Point(-1,-1), wx.Size(-1,-1)),

0, wx.ALL, 10)self.buttonsizer1.Add(wx.Button(self, ID_STOP, "Stop" ,

wx.Point(-1,-1), wx.Size(-1,-1)),

55

0, wx.ALL, 10)

self.modelist = [’Audio’, ’Text’]

self.buttonsizer1.Add(wx.RadioBox(self, ID_MODESEL, ’ Mode Selection’,choices = self.modelist,majorDimension = 1,style = wx.RA_SPECIFY_COLS),

0, wx.ALL, 10)

self.buttonsizer2.Add(wx.Button(self, ID_EXIT, "Quit" ,wx.Point(-1,-1), wx.Size(-1,-1)),

0, wx.ALL, 10)

self.mainsizer.Add(self.buttonsizer1, 0, wx.ALIGN_LEF T)self.mainsizer.Add(self.buttonsizer2, 0, wx.ALIGN_LEF T)

self.SetSizer(self.mainsizer)self.SetAutoLayout(1)self.mainsizer.Fit(self)

self.Show(True)

# set up waveformself.audio_fg = build_audio_graph()self.text_fg = build_text_graph()self.is_running = 0self.main_fg = self.audio_fg

def OnAbout(self,event):# Create a message dialog boxd=wx.MessageDialog(self,

"This is the GNU Radio implementation of the MATH waveform","About MATH", wx.OK)

d.ShowModal()d.Destroy() # finally destroy it when finished.

def OnExit(self,event):self.Close(True) # Close the frame.

def OnStart(self, event):if self.is_running == 1:

self.SetStatusText("Already running!")

else:self.is_running = 1# Start waveformself.main_fg.start()self.SetStatusText("Starting waveform")

def OnStop(self, event):if self.is_running == 1:

# Stop waveformself.main_fg.stop()self.SetStatusText("Stopping waveform")self.is_running = 0

else:self.SetStatusText("Can’t stop, waveform is not running. ")

def OnRadioButton(self, event):

if self.is_running == 1:self.SetStatusText("Please stop application before chan ging mode.")

elif event.GetInt() == 0:self.SetStatusText("Audio mode selected.")self.main_fg = self.audio_fg

else:self.SetStatusText("Text mode selected")self.main_fg = self.text_fg

56 Appendix C. MATH GNU Radio Python application

# The MATH class which inherits from wx.Appclass MATH(wx.App):

def OnInit(self):

# The main frameframe = MATHframe(None, -1, "GNU Radio MATH waveform")

self.SetTopWindow(frame)frame.Show(True)return True

# The main application init functionif __name__ == "__main__":

application = MATH(0)application.MainLoop()

C++ source code

Here is the declaration and implementation of our mathconsolewriter f signal processingblock.

Declaration

#ifndef INCLUDED_MATH_CONSOLE_WRITER_F_H#define INCLUDED_MATH_CONSOLE_WRITER_F_H

#include <gr_block.h>

class math_console_writer_f;

typedef boost::shared_ptr<math_console_writer_f> math _console_writer_f_sptr;

// This is the public interface to the class.math_console_writer_f_sptr math_make_console_writer_ f();

class math_console_writer_f : public gr_block{private:

// math_make_console_writer_f has to be a friend of the clas s// to be able to call the private constructor.friend math_console_writer_f_sptr math_make_console_w riter_f();

math_console_writer_f(); // Private contructor

public:˜math_console_writer_f(); // Public destructor

// general_work is where everything really happens.// It’s a virtual method from gr_block which is overridden he re.

int general_work (int noutput_items,gr_vector_int &ninput_items,gr_vector_const_void_star &input_items,gr_vector_void_star &output_items);

};

#endif / * INCLUDED_MATH_CONSOLE_WRITER_F_H* /

Implementation

#ifdef HAVE_CONFIG_H#include "config.h"

57

#endif

#include <math_console_writer_f.h>#include <gr_io_signature.h>#include <iostream>

// This is effectively the constructor of the classmath_console_writer_f_sptrmath_make_console_writer_f(){

// Make a cast to a Boost smart pointerreturn math_console_writer_f_sptr (new math_console_wr iter_f());

}

// Specify constraints on the number of inputs and outputs.

static const int MIN_IN = 1; // mininum number of input stream sstatic const int MAX_IN = 1; // maximum number of input stream sstatic const int MIN_OUT = 0; // minimum number of output stre amsstatic const int MAX_OUT = 0; // maximum number of output stre ams

// The private constructormath_console_writer_f::math_console_writer_f()

: gr_block("console_writer_f",gr_make_io_signature(MIN_IN, MAX_IN, sizeof(float)),gr_make_io_signature(MIN_OUT, MAX_OUT, sizeof(float)) )

{// We don’t need anything else in our constructor

}

// Destructormath_console_writer_f::˜math_console_writer_f(){}

// general_work, an overridden virtual method// where all the work is doneintmath_console_writer_f::general_work(int noutput_item s,

gr_vector_int &ninput_items,gr_vector_const_void_star &input_items,gr_vector_void_star &output_items)

{const float * math_in = (const float * ) input_items[0];

// Since the text mode isn’t implemented, we are doing nothin g here.// Decoding the input stream "math_in" and printing the mess age to stdout or some// other output stream would be enough.

std::cout << "This is the MATH GNU Radio application running in text mode"<< std::endl;

// Though, we still tell runtime system how many output items we produced.// This block can be seen as a "black hole" right now.

return noutput_items;}

The SWIG file math.iThis is how the SWIG configuration file used for our block looks like.

/ * - * - c++ - * - * /

%feature("autodoc", "1"); // generate python docstrings

%include "exception.i"%import "gnuradio.i" // the common stuff

58 Appendix C. MATH GNU Radio Python application

%{#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix#include "math_console_writer_f.h" // Our MATH include fi le#include <stdexcept>%}

// ------------------------------------------------- ---------------

/ ** GR_SWIG_BLOCK_MAGIC does some behind-the-scenes magic so we can

* access math_console_writer_f from python as math.console _writer_f

** First arg ’math’ is the package prefix.

* Second arg is the name of the class minus the prefix.

* /GR_SWIG_BLOCK_MAGIC(math,console_writer_f);

math_console_writer_f_sptr math_make_console_writer_ f();

/ * Class declaration * /class math_console_writer_f : public gr_block{private:

math_console_writer_f(); // the private constructor};

59

Appendix D

MATH SCA application

This is the complete source code to the SCA MATH waveform. This appendix isdivided into several parts, one for each source code file. Each part has a commentattached to it. A picture on the structure of the different components is shown insection 6.2.2

The complete source code together with our hacked version of the OSSIE CoreFramework can be found at <URL:http://theblacklodge.org/ ˜ fringe/MATH+ossie.

tar>

IDL and C++ source code

This section contains all of the IDL and C++ source code. In thenext section the XMLrequired is presented.

MATH.idlThis is the IDL source code which implements all the necessary interfaces. This code is com-piled with the TAO IDL compiler, and CORBA server skeletons andclient stubs are created.These are in turn compiled and linked with the MATH application.

/ * IDL for the MaTh (Mansour-Thomas) waveform * /

#include <ossieidl/cf.idl>#include <ossieidl/PortTypes.idl>

module MATH {

module Common_RT {

/ * Instantiate PacketBB from RT API * // * We’re using an enumeration as ControlType * // * and a sequence of shorts as PayloadType * /

enum ControlType {null, sync};

interface PacketBB {

readonly attribute unsigned short maxPayloadSize;readonly attribute unsigned short minPayloadSize;readonly attribute octet numOfPriorityQueues;

60 Appendix D. MATH SCA application

oneway void pushPacket (in octet priority, in ControlType c ontrol,in PortTypes::ShortSequence payload);

unsigned short spaceAvailable(in octet priorityQueueID) ;void enableFlowControl(in boolean enable);void enableEmptySignal(in boolean enable);void setNumOfPriorityQueues(in octet numOfPriorities);

};

/ * Instantiate SignalsBB from RT API * /

interface SignalsBB {

void signalHighWatermark(in octet priorityQueueID);void signalLowWatermark(in octet priorityQueueID);void signalEmpty();

};};

module Common_NRT {

// Enumeration common for all Resourcesenum running_t { STANDBY, RUNNING, EXITING };enum IO_Mode_Type {TRANSMIT_MODE, RECEIVE_MODE};

interface RunningStatus {running_t get_running_status();

};

/ * Contruct new API Service Class IOMode * // * to be able to choose whether we are transmitting * // * or receiving data * /

interface IOMode {void setIOMode (in IO_Mode_Type newIOMode);IO_Mode_Type getIOMode ();

};};

module MAC_RT {

interface DataProcess {void generate_data();void receive_data();

};};

module MAC_NRT {

/ * Contruct new API Service Class DataMode * // * to handle different kinds of data * /

enum Data_Mode_Type{AUDIO, TEXT};

interface DataMode {void setDataMode(in Data_Mode_Type newDataMode);Data_Mode_Type getDataMode();

};};

module Physical_RT {

interface Modem {void transmit();void receive();

};};

module Physical_NRT {

61

/ * Use Transmit_Inhibit from existing NRT API * /

interface Transmit_Inhibit {boolean inhibitTransmit (in boolean Inhibit);

};};

/ * The "main" interfaces, Physical and MAC, * // * representing two layers in the SCA API model * // * and an Assembly Controller. * /

interface Physical :CF::Resource, CF::Port,Common_NRT::IOMode, Physical_NRT::Transmit_Inhibit,Common_RT::PacketBB, Common_RT::SignalsBB,Common_NRT::RunningStatus, Physical_RT::Modem

{

};

interface MAC :CF::Resource, CF::Port,MAC_NRT::DataMode, MAC_RT::DataProcess,Common_RT::PacketBB, Common_RT::SignalsBB,Common_NRT::RunningStatus, Common_NRT::IOMode

{

};

interface AssemblyController :CF::Resource, CF::Port,Common_NRT::RunningStatus

{void configure_resource(in string resourceID, in CF::Pro perties config_properties);

};};

MATH i.hHere is the declaration for the main application.

#ifndef MATH_I_H#define MATH_I_H

#include "wx/wx.h"#include <ossiecf/DomainManager_impl.h>#include "ResourceFactory_i.h"

class MATH_Frame : public wxFrame{public:

MATH_Frame (const wxString& title, const wxPoint& pos, con st wxSize& size);

int MATHinit();void MATHshutdown();

void close(wxCloseEvent & event);

void OnQuit(wxCommandEvent & event);void OnAbout(wxCommandEvent & event);void OnStart(wxCommandEvent & event);void OnStop(wxCommandEvent & event);void OnInstall(wxCommandEvent & event);void OnUnInstall(wxCommandEvent & event);void OnFileChanged(wxCommandEvent & event);void OnInhibit(wxCommandEvent & event);

62 Appendix D. MATH SCA application

wxCheckBox * inhibitCheckbox;

private:CF::DomainManager::ApplicationFactorySequence_var ap plication_factories;CF::Application_ptr OurApp;CORBA::ORB_var orb;DomainManager_impl * ourDM;ResourceFactory_i * ourRF;

MATH::AssemblyController_var _externalPort;

int _app_running;int _app_installed;

};

class MATH_i : public wxApp{public:

virtual bool OnInit();// int OnExit();

private:

MATH_Frame * topFrame;

};

enum {ID_Quit=1,ID_About,ID_Start,ID_Stop,ID_Install,ID_UnInstall,ID_ChangeFile,ID_Transmit_Inhibit

};

#endif // MATH_H

MATH.cppThis is the implementation of the main application. Besides setting up the SCA environment,the GUI is included here as well.

// #ifdef MATH_VERBOSE#include <iostream>// #endif#include "MATH_i.h"

using namespace std;

// Macro for the main application.// It includes the main() function// among other things.IMPLEMENT_APP(MATH_i);

// OnInit is the "main" programboolMATH_i::OnInit(){

topFrame = new MATH_Frame("Mansour-Thomas Waveform SCA In terface",wxPoint(50,50), wxSize(350,250));

topFrame->Connect (ID_Quit, wxEVT_COMMAND_MENU_SELECT ED,

63

(wxObjectEventFunction) & MATH_Frame::OnQuit);topFrame->Connect (ID_About, wxEVT_COMMAND_MENU_SELEC TED,

(wxObjectEventFunction) & MATH_Frame::OnAbout);topFrame->Connect (ID_Start, wxEVT_COMMAND_MENU_SELEC TED,

(wxObjectEventFunction) & MATH_Frame::OnStart);topFrame->Connect (ID_Stop, wxEVT_COMMAND_MENU_SELECT ED,

(wxObjectEventFunction) & MATH_Frame::OnStop);

topFrame->Connect (ID_Start, wxEVT_COMMAND_BUTTON_CLI CKED,(wxObjectEventFunction) & MATH_Frame::OnStart);

topFrame->Connect (ID_Stop, wxEVT_COMMAND_BUTTON_CLIC KED,(wxObjectEventFunction) & MATH_Frame::OnStop);

topFrame->Connect (ID_Quit, wxEVT_COMMAND_BUTTON_CLIC KED,(wxObjectEventFunction) & MATH_Frame::OnQuit);

topFrame->Connect (ID_Install, wxEVT_COMMAND_BUTTON_C LICKED,(wxObjectEventFunction) & MATH_Frame::OnInstall);

topFrame->Connect (ID_UnInstall, wxEVT_COMMAND_BUTTON _CLICKED,(wxObjectEventFunction) & MATH_Frame::OnUnInstall);

topFrame->Connect (ID_ChangeFile, wxEVT_COMMAND_BUTTO N_CLICKED,(wxObjectEventFunction) & MATH_Frame::OnFileChanged);

topFrame->Connect (ID_Transmit_Inhibit, wxEVT_COMMAND _CHECKBOX_CLICKED,(wxObjectEventFunction) & MATH_Frame::OnInhibit);

topFrame->Connect (wxID_ANY, wxEVT_CLOSE_WINDOW,(wxObjectEventFunction) & MATH_Frame::close);

topFrame->Show(TRUE);SetTopWindow(topFrame);

return TRUE;}

intMATH_Frame::MATHinit(){

// Initialize ORBconst char * ORBID = "SCA_ORB";char * orb_argv[1];orb_argv[0] = "./MATH";int orb_argc = 1;

orb = CORBA::ORB_init(orb_argc, orb_argv, ORBID);

// Create a Domain ManagerourDM = new DomainManager_impl();ourDM->init(orb_argc, orb_argv, ORBID);

// Create a ResourceFactoryourRF = new ResourceFactory_i("/DomainName1/ResourceFa ctory");

// Let the Application pointer point to a "nil" Application O bjectOurApp = CF::Application::_nil();

return 0;}

voidMATH_Frame::MATHshutdown(){

// Shutdown Resource Factory and destroy objectourRF->shutdown();delete ourRF;

// Destroy Domain Managerdelete ourDM;

// Destroy ORB

64 Appendix D. MATH SCA application

orb->shutdown(true);orb->destroy();

}

MATH_Frame::MATH_Frame (const wxString& title,const wxPoint& pos, const wxSize& size)

: wxFrame((wxFrame * )NULL,-1,title,pos,size,wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCAPTION , "MATH")

{_app_running = 0;_app_installed = 0;

wxBoxSizer * main_sizer = new wxBoxSizer(wxVERTICAL);wxBoxSizer * button_sizer1 = new wxBoxSizer(wxHORIZONTAL);wxBoxSizer * button_sizer2 = new wxBoxSizer(wxHORIZONTAL);wxBoxSizer * button_sizer3 = new wxBoxSizer(wxHORIZONTAL);

wxString modelist[2] = {"Audio", "Text"};

button_sizer1->Add(new wxButton(this, ID_Start,"Start\nApp", wxPoint(-1, -1)),

0, wxALL, 10);button_sizer1->Add(new wxButton(this, ID_Stop,

"Stop\nApp", wxPoint(-1,-1)), 0, wxALL, 10);

button_sizer1->Add(new wxRadioBox(this, -1, "Mode Selec tion",wxPoint(-1,-1), wxSize(-1,-1),2, modelist, 1, wxRA_SPECIFY_COLS)

, 0, wxALL, 10);button_sizer2->Add(new wxButton(this, ID_Install, "Ins tall\nApp",

wxPoint(-1,-1)),0, wxALIGN_RIGHT|wxALL, 10);

button_sizer2->Add(new wxButton(this, ID_UnInstall,"Uninstall\nApp", wxPoint(-1,-1)),

0, wxALIGN_RIGHT|wxALL, 10);button_sizer2->Add(new wxButton(this, ID_ChangeFile,

"Change\naudiofile", wxPoint(-1,-1)),0, wxALIGN_RIGHT|wxALL, 10);

button_sizer3->Add(new wxButton(this, ID_Quit, "Quit",wxPoint(-1,-1)), 0, wxALL, 10);

inhibitCheckbox = new wxCheckBox(this, ID_Transmit_Inhi bit,"Inhibit Transmission");

button_sizer3->Add(inhibitCheckbox);

main_sizer->Add(button_sizer1, 0, wxALIGN_LEFT);main_sizer->Add(button_sizer2, 0, wxALIGN_LEFT);main_sizer->Add(button_sizer3, 0, wxALIGN_LEFT);

SetSizer(main_sizer);

// create menubarwxMenuBar * menuBar = new wxMenuBar;// create menuwxMenu * menu = new wxMenu;// append menu entriesmenu->Append(ID_Start, "Start App", "Start Application" );menu->Append(ID_Stop, "Stop App", "Stop Application");menu->AppendSeparator();menu->Append(ID_About,"&About...", "Display an about wi ndow");menu->Append(ID_Quit,"E&xit", "Quit this program");// append menu to menubarmenuBar->Append(menu,"&Menu");// set frame menubarSetMenuBar(menuBar);

// create frame statusbarCreateStatusBar();// set statusbar text

65

SetStatusText("This is the status bar :)");

MATHinit();}

voidMATH_Frame::OnInstall(wxCommandEvent & event){

if (_app_installed == 0) {

SetStatusText("Installing Application, please wait ..." );Refresh();wxString filename = wxFileSelector("Choose an SAD file to o pen", "", "", "",

" * SAD* ", wxOPEN);

if (! filename.empty()) {// Try to install the application on the Domain Managertry {

ourDM->installApplication(filename);

// Get list of ApplicationFactories and the first Applicati onFactoryapplication_factories = ourDM->applicationFactories() ;CF::ApplicationFactory_var application_factory = ( * application_factories)[0];

CF::Properties AppFacProps(0);CF::DeviceAssignmentSequence DevSeq(0);

// Try to create the Application in ApplicationFactoryOurApp = application_factory->create(application_fact ory->name(), AppFacProps,

DevSeq);

// Get a reference to the Assembly Controller for the UI to use .// OSSIE’s implementation of Application::getPort doesn’ t follow the// SCA standard (yet), so we don’t have to use external ports i n the SAD.CORBA::Object_ptr _port;_port = OurApp->getPort("AssemblyController_NRT_out") ;_externalPort = MATH::AssemblyController::_narrow(_po rt);

SetStatusText("Application installed!");_app_installed = 1;

}catch(CF::InvalidFileName error) {

wxString msg = (wxString) error.msg;SetStatusText(msg, 0);

}catch(CF::DomainManager::ApplicationInstallationErr or error) {

wxString msg = (wxString) error.msg;SetStatusText(msg, 0);

}// Catch all exceptions.catch (...) {

SetStatusText("Error in Application installation!");}

}else

SetStatusText("Installation cancelled ...");}else

SetStatusText("Application is already installed!");}

voidMATH_Frame::OnInhibit(wxCommandEvent & event){

if(_app_installed == 1) {

CORBA::Boolean inhibit;

if (inhibitCheckbox->IsChecked()) {

66 Appendix D. MATH SCA application

inhibit = true;SetStatusText("Transmission is inhibited");

}else {

inhibit = false;SetStatusText("Transmission is not inhibited");

}CF::Properties _props;_props.length(1);_props[0].id = CORBA::string_dup("Transmit_Inhibit");_props[0].value <<= CORBA::Any::from_boolean(inhibit) ;

_externalPort->configure_resource("MATH_Physical_Re source", _props);}else

SetStatusText("Application is not installed");}

voidMATH_Frame::OnUnInstall(wxCommandEvent & event){

if (_app_running == 0) {if (_app_installed == 1) {

SetStatusText("Uninstalling Application, please wait .. .");Refresh();

CORBA::String_var app_identifier = OurApp->identifier( );

// Release ApplicationOurApp->releaseObject();OurApp = CF::Application::_nil();

// Uninstall Application in Domain Manager.ourDM->uninstallApplication(app_identifier);

SetStatusText("Application uninstalled");_app_installed = 0;

}else

SetStatusText("Application is not installed");}else

SetStatusText("Can’t uninstall while Application is runn ing!");}

voidMATH_Frame::OnQuit(wxCommandEvent & event){

SetStatusText("Shutting down ...");Close(TRUE);

}

voidMATH_Frame::OnAbout(wxCommandEvent & WXUNUSED(event)){

SetStatusText("Showing about ...");wxMessageBox("This is the SCA implementation of the MATH wa veform.","About MATH",

wxOK|wxICON_INFORMATION, this);}

voidMATH_Frame::OnFileChanged(wxCommandEvent & WXUNUSED(e vent)){

if (_app_installed) {wxString filename = wxFileSelector("Choose a new audio fil e", "", "", "",

" * wav* ", wxOPEN);

CF::Properties _props;_props.length(1);_props[0].id = CORBA::string_dup("audio_filename");

67

_props[0].value <<= filename;

_externalPort->configure_resource("MATH_MAC_Resourc e", _props);SetStatusText("File changed");

}else

SetStatusText("Install Application first!");}

voidMATH_Frame::OnStart(wxCommandEvent & WXUNUSED(event)){

if (_app_installed == 1) {SetStatusText("Starting Application ... ");Refresh();OurApp->start();SetStatusText("Application started.");_app_running = 1;

}else

SetStatusText("Install Application first.");}

voidMATH_Frame::OnStop(wxCommandEvent & WXUNUSED(event)){

if (_app_running == 1) {SetStatusText("Stopping Application ... ");Refresh();OurApp->stop();SetStatusText("Application has stopped.");_app_running = 0;

}else

SetStatusText("You haven’t started the Application!");}

voidMATH_Frame::close(wxCloseEvent & event){

if (_app_running == 1) {wxMessageBox("You forgot to stop the Application!", "Hold it right there!",

wxOK, this);}else if (_app_installed == 1) {

wxMessageBox("You forgot to uninstall the Application!", "Hold it right there!",wxOK, this);

}else {

SetStatusText("Shutting down ...");Refresh();

MATHshutdown();

// Destroy frame (close the window and exit)this-Destroy();

}}

main.cpp

Here is the file containing the main() method for the MAC component. The Physical andAssemblyController has similar main() functions, it only differs by a small amount in themain loop. The CORBA setup is the same.

#include "MATH_MAC_i.h"

68 Appendix D. MATH SCA application

#include <tao/corba.h>#include "orbsvcs/CosNamingC.h"

intmain( int argc, char ** argv ){

// CORBA Object initializing

const char * ORBID = "SCA_ORB";char * orb_argv[1];orb_argv[0] = "./MATH";int orb_argc = 1;

CORBA::ORB_var orb = CORBA::ORB_init(orb_argc, orb_argv , ORBID);

// Get Root POACORBA::Object_var poaobj = CORBA::Object::_nil();while (CORBA::is_nil(poaobj))

poaobj = orb->resolve_initial_references("RootPOA");PortableServer::POA_var root_poa = PortableServer::POA ::_narrow(poaobj.in());

// Activate the POA ManagerPortableServer::POAManager_var manager;manager = root_poa->the_POAManager();manager->activate();

// Create servantMATH_MAC_i mac_i;

// Activate servant and get object referenceMATH::MAC_var mac = mac_i._this();

// Get Naming ServiceCORBA::Object_var nameobj = CORBA::Object::_nil();while (CORBA::is_nil(nameobj))

nameobj = orb->resolve_initial_references("NameServic e");CosNaming::NamingContext_var naming_context = CosNamin g::NamingContext::_narrow(nameobj.in());

CosNaming::Name namebinding;namebinding.length(2);namebinding[0].id = CORBA::string_dup ("DomainName1");namebinding[1].id = CORBA::string_dup ("MATH_MAC");

naming_context->rebind(namebinding, mac.in());

ACE_Time_Value time_out = ACE_Time_Value(0,200);

while (1) {

switch (mac->get_running_status()) {

// Wait until application is started// We need to perform some ORB-related// work in STANDBY mode, such as configuring// and assembling.

case MATH::Common_NRT::STANDBY:if (orb->work_pending())

orb->perform_work();ACE_OS::sleep(time_out);break;

case MATH::Common_NRT::RUNNING:

mac->generate_data();ACE_OS::sleep(time_out);

break;

69

case MATH::Common_NRT::EXITING:

naming_context->unbind(namebinding);

PortableServer::ObjectId_var oid = root_poa->reference _to_id(mac);root_poa->deactivate_object(oid);

return 0;}

}}

AssemblyController i.hDeclaration for the AssemblyController used to control the other parts of the MATH waveformapplication.

#ifndef ASSEMBLYCONTROLLER_I_H#define ASSEMBLYCONTROLLER_I_H

#include "../MATHS.h"#include <ossiecf/Resource_impl.h>

class MATH_AssemblyController_i :public virtual POA_MATH::AssemblyController,public virtual POA_CF::Resource,public virtual POA_CF::Port,public Resource_impl

{

public:

MATH_AssemblyController_i();˜MATH_AssemblyController_i();

// Core Framework interfaces:

CORBA::Object_ptr getPort (const char * name)ACE_THROW_SPEC ((CORBA::SystemException, CF::PortSupp lier::UnknownPort));

void connectPort (CORBA::Object_ptr connection, const ch ar * connectionId)ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort,

CF::Port::OccupiedPort));

void disconnectPort (const char * connectionId)ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort));

void start ()ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StartError));

void stop ()ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StopError));

void initialize ()ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::InitializeError));

void releaseObject ()ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::ReleaseError));

// Waveform interfaces

void configure_resource(const char * resourceID,const CF::Properties & config_properties)

ACE_THROW_SPEC ((CORBA::SystemException));

MATH::Common_NRT::running_t get_running_status()ACE_THROW_SPEC ((CORBA::SystemException));

private:

70 Appendix D. MATH SCA application

MATH::Common_NRT::running_t _runningMode;

MATH::MAC_var _MAC_IOPort;MATH::Physical_var _Physical_IOPort;

};

#endif // ASSEMBLYCONTROLLER_I_H

AssemblyController i.cppAssemblyController implementation.

#include "MATH_AssemblyController_i.h"

// ContructorMATH_AssemblyController_i::MATH_AssemblyController_ i(){

// Start in STANDBY mode_runningMode = MATH::Common_NRT::STANDBY;

// Initialize object references_MAC_IOPort = MATH::MAC::_nil();_Physical_IOPort = MATH::Physical::_nil();

}

// DestructorMATH_AssemblyController_i::˜MATH_AssemblyController _i(){}

// Core Framework interfaces:

CORBA::Object_ptrMATH_AssemblyController_i::getPort (const char * name)

ACE_THROW_SPEC ((CORBA::SystemException, CF::PortSupp lier::UnknownPort)){

if (ACE_OS::strcmp(name, "AssemblyController_NRT_out" ) == 0)return this->_this();

return CORBA::Object::_nil();}

voidMATH_AssemblyController_i::connectPort (CORBA::Objec t_ptr connection,

const char * connectionId)ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort,

CF::Port::OccupiedPort)){

if (ACE_OS::strcmp(connectionId, "AssemblyController_ to_Physical") == 0)_Physical_IOPort = MATH::Physical::_narrow(connection );

else if (ACE_OS::strcmp(connectionId, "AssemblyControl ler_to_MAC") == 0)_MAC_IOPort = MATH::MAC::_narrow(connection);

elsethrow CF::Port::InvalidPort();

}

voidMATH_AssemblyController_i::disconnectPort (const char * connectionId)

ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort)){

if (ACE_OS::strcmp(connectionId, "Physical_NRT_in") == 0)_Physical_IOPort = MATH::Physical::_nil();

else if (ACE_OS::strcmp(connectionId, "MAC_NRT_in") == 0 )_MAC_IOPort = MATH::MAC::_nil();

}

void

71

MATH_AssemblyController_i::initialize ()ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::InitializeError))

{}

voidMATH_AssemblyController_i::releaseObject ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::ReleaseError)){

// Let child exit_runningMode = MATH::Common_NRT::EXITING;

}

voidMATH_AssemblyController_i::start ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StartError)){

_runningMode = MATH::Common_NRT::RUNNING;

// Start MAC and Physical_MAC_IOPort->start();_Physical_IOPort->start();

}

voidMATH_AssemblyController_i::stop ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StopError)){

_runningMode = MATH::Common_NRT::STANDBY;_MAC_IOPort->stop();_Physical_IOPort->stop();

}

// Waveform interfacesvoidMATH_AssemblyController_i::configure_resource(const char * resourceID,

const CF::Properties & config_properties)ACE_THROW_SPEC ((CORBA::SystemException))

{if (strcmp(resourceID, "MATH_Physical_Resource") == 0) {

if (strcmp(config_properties[0].id, "Transmit_Inhibit ") == 0) {CORBA::Boolean inhibit;config_properties[0].value >>= CORBA::Any::to_boolean (inhibit);_Physical_IOPort->inhibitTransmit(inhibit);

}else

_Physical_IOPort->configure(config_properties);}else if (strcmp(resourceID, "MATH_MAC_Resource") == 0) {

_MAC_IOPort->configure(config_properties);}else {

}}

MATH::Common_NRT::running_tMATH_AssemblyController_i::get_running_status()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _runningMode;}

MATH Physical i.hDeclaration for the Physical layer of the waveform.

#ifndef PHYSICAL_I_H

72 Appendix D. MATH SCA application

#define PHYSICAL_I_H

#include <iostream>

#include <ossiecf/Resource_impl.h>#include "../MATHS.h"#include "../alsa_wrapper/alsa_wrapper.h"#include "../buffer/buffer.h"

class MATH_Physical_i :public virtual POA_MATH::Physical,public virtual POA_CF::Resource,public virtual POA_CF::Port,public Resource_impl

{

public :

MATH_Physical_i ();˜MATH_Physical_i ();

// Core Framework interfaces:

CORBA::Object_ptr getPort (const char * name)ACE_THROW_SPEC ((CORBA::SystemException, CF::PortSupp lier::UnknownPort));

void connectPort (CORBA::Object_ptr connection, const ch ar * connectionId)ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort,

CF::Port::OccupiedPort));

void disconnectPort (const char * connectionId)ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort));

void start ()ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StartError));

void stop ()ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StopError));

void initialize ()ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::InitializeError));

void releaseObject ()ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::ReleaseError));

// Waveform interfaces:

void transmit()ACE_THROW_SPEC ((CORBA::SystemException));

void receive()ACE_THROW_SPEC ((CORBA::SystemException));

::MATH::Common_NRT::running_t get_running_status()ACE_THROW_SPEC ((CORBA::SystemException));

void setIOMode (MATH::Common_NRT::IO_Mode_Type newIOMo de)ACE_THROW_SPEC ((CORBA::SystemException));

MATH::Common_NRT::IO_Mode_Type getIOMode ()ACE_THROW_SPEC ((CORBA::SystemException));

CORBA::Boolean inhibitTransmit (CORBA::Boolean Inhibit )ACE_THROW_SPEC ((CORBA::SystemException));

void pushPacket(CORBA::Octet priority, MATH::Common_RT ::ControlType control,const PortTypes::ShortSequence & payload)

ACE_THROW_SPEC ((CORBA::SystemException));

73

CORBA::UShort spaceAvailable(CORBA::Octet priorityQue ueID)ACE_THROW_SPEC ((CORBA::SystemException));

void enableFlowControl (CORBA::Boolean enable)ACE_THROW_SPEC ((CORBA::SystemException));

void enableEmptySignal (CORBA::Boolean enable)ACE_THROW_SPEC ((CORBA::SystemException));

void setNumOfPriorityQueues (CORBA::Octet numOfPriorit ies)ACE_THROW_SPEC ((CORBA::SystemException));

void signalHighWatermark (CORBA::Octet priorityQueueID )ACE_THROW_SPEC ((CORBA::SystemException));

void signalLowWatermark (CORBA::Octet priorityQueueID)ACE_THROW_SPEC ((CORBA::SystemException));

void signalEmpty ()ACE_THROW_SPEC ((CORBA::SystemException));

// These should be attributes, but TAO IDL compiler generate s methods.

CORBA::UShort maxPayloadSize ()ACE_THROW_SPEC ((CORBA::SystemException));

CORBA::UShort minPayloadSize ()ACE_THROW_SPEC ((CORBA::SystemException));

CORBA::Octet numOfPriorityQueues ()ACE_THROW_SPEC ((CORBA::SystemException));

private:

// Waveform attributes:

MATH::MAC_var _MAC_ProvidesPort;

MATH::Common_NRT::running_t _runningMode;

CORBA::UShort _maxPayloadSize;CORBA::UShort _minPayloadSize;CORBA::Octet _numOfPriorityQueues;

CORBA::Boolean _flowControl;CORBA::Boolean _emptySignal;

MATH::Common_NRT::IO_Mode_Type _IOMode;CORBA::Boolean _inhibit;

// Internal attributes:int sent_LowWatermark;int sent_HighWatermark;

buffer * my_buffer;alsa_wrapper * my_alsa;

};

#endif // PHYSICAL_I_H

MATH Physical i.cppPhysical layer implementation.

#include "MATH_Physical_i.h"

// ContructorMATH_Physical_i::MATH_Physical_i(){

74 Appendix D. MATH SCA application

// Start in STANDBY mode_runningMode = MATH::Common_NRT::STANDBY;

// Initialize object references_MAC_ProvidesPort = MATH::MAC::_nil();

}

// DestructorMATH_Physical_i::˜MATH_Physical_i(){

// Release alsa_wrapperif (my_alsa != NULL)

delete my_alsa;// Release bufferif (my_buffer != NULL)

delete my_buffer;}

// Core Framework interfaces:CORBA::Object_ptrMATH_Physical_i::getPort (const char * name)

ACE_THROW_SPEC ((CORBA::SystemException, CF::PortSupp lier::UnknownPort)){

if (ACE_OS::strcmp(name, "Physical_RT_out") == 0)return this->_this();

return CORBA::Object::_nil();}

voidMATH_Physical_i::connectPort (CORBA::Object_ptr conne ction, const char * connectionId)

ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort,CF::Port::OccupiedPort))

{if (ACE_OS::strcmp(connectionId, "Physical_to_MAC") == 0)

_MAC_ProvidesPort = MATH::MAC::_narrow(connection);}

voidMATH_Physical_i::disconnectPort (const char * connectionId)

ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort)){

_MAC_ProvidesPort = MATH::MAC::_nil();}

voidMATH_Physical_i::start ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StartError)){

_runningMode = MATH::Common_NRT::RUNNING;}

voidMATH_Physical_i::stop ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StopError)){

_runningMode = MATH::Common_NRT::STANDBY;my_buffer->reset();

}

voidMATH_Physical_i::initialize ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::InitializeError)){

// set waveform attributes_maxPayloadSize = 8000; // Maximum of 500 16-bit samples_minPayloadSize = 1000; // Minimum of 125 16-bit samples

_numOfPriorityQueues = 1;

sent_LowWatermark = 0;

75

sent_HighWatermark = 0;

enableFlowControl(true);enableEmptySignal(false);

_IOMode = MATH::Common_NRT::TRANSMIT_MODE;_inhibit = false;

// Set up the alsa_wrapper object, with SND_PCM_STREAM_PLA YBACK// as default mode.// If we want to change direction from output to input, we have to// call alsa_wrapper::shutdownPCM(), then initialize aga in// with SND_PCM_STREAM_CAPTURE instead.

try {my_alsa = new alsa_wrapper;my_alsa->setmode(SND_PCM_STREAM_PLAYBACK);my_alsa->createPCM(2); // 2 channels

}catch (char * errormsg) {

_runningMode = MATH::Common_NRT::EXITING;throw (CF::LifeCycle::InitializeError (1));

}

// Create a new buffer from buffer class// to hold the data which comes from MAC layer.my_buffer = new buffer(60 * my_alsa->get_buffer_size());}

voidMATH_Physical_i::releaseObject ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::ReleaseError)){

// Let child exit_runningMode = MATH::Common_NRT::EXITING;

}

// Real-Time Waveform interfaces:voidMATH_Physical_i::pushPacket(CORBA::Octet priority,

MATH::Common_RT::ControlType control,const PortTypes::ShortSequence & payload)

ACE_THROW_SPEC ((CORBA::SystemException)){

// Put data from MAC in storage buffermy_buffer->insert(payload);

unsigned int b_size = my_buffer->get_size();

if (b_size > 700000) {if (sent_HighWatermark == 0) {

_MAC_ProvidesPort->signalHighWatermark(0);sent_HighWatermark = 1;

}}else

sent_HighWatermark = 0;}

voidMATH_Physical_i::transmit()

ACE_THROW_SPEC ((CORBA::SystemException)){

unsigned int b_size = my_buffer->get_size();

// Send signalLowWatermark if there is a small amount of data in bufferif (b_size < 300000)

_MAC_ProvidesPort->signalLowWatermark(0);

unsigned int frames_played;

76 Appendix D. MATH SCA application

unsigned int chunk_size = 2800;

// Try to get ’chunk_size’ chunk of the buffer.// The actual amount is returned in ’chunk_size’.char * chunk_ptr = my_buffer->get_chunk(chunk_size);

// "Send" ’chunk_size’ of data if transmitter is not inhibit ed// to transmit.if (! _inhibit)

frames_played = my_alsa->play(chunk_ptr, chunk_size);}

voidMATH_Physical_i::receive()

ACE_THROW_SPEC ((CORBA::SystemException)){

// Haven’t implemented receiver (yet :)}

CORBA::UShortMATH_Physical_i::spaceAvailable(CORBA::Octet priorit yQueueID)

ACE_THROW_SPEC ((CORBA::SystemException)){

return my_buffer->get_size();}

voidMATH_Physical_i::enableFlowControl (CORBA::Boolean en able)

ACE_THROW_SPEC ((CORBA::SystemException)){

_flowControl = enable;}

voidMATH_Physical_i::enableEmptySignal (CORBA::Boolean en able)

ACE_THROW_SPEC ((CORBA::SystemException)){

_emptySignal = enable;}

voidMATH_Physical_i::setNumOfPriorityQueues (CORBA::Octe t numOfPriorities)

ACE_THROW_SPEC ((CORBA::SystemException)){

_numOfPriorityQueues = numOfPriorities;}

voidMATH_Physical_i::signalHighWatermark (CORBA::Octet pr iorityQueueID)

ACE_THROW_SPEC ((CORBA::SystemException)){

// To implement later in receiver.}

voidMATH_Physical_i::signalLowWatermark (CORBA::Octet pri orityQueueID)

ACE_THROW_SPEC ((CORBA::SystemException)){

// To implement later in receiver.}

voidMATH_Physical_i::signalEmpty ()

ACE_THROW_SPEC ((CORBA::SystemException)){}

// Non-Real-Time Waveform Interfaces:MATH::Common_NRT::running_tMATH_Physical_i::get_running_status()

77

ACE_THROW_SPEC ((CORBA::SystemException)){

return _runningMode;}

voidMATH_Physical_i::setIOMode (MATH::Common_NRT::IO_Mod e_Type newIOMode)

ACE_THROW_SPEC ((CORBA::SystemException)){

_IOMode = newIOMode;}

MATH::Common_NRT::IO_Mode_TypeMATH_Physical_i::getIOMode ()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _IOMode;}

CORBA::BooleanMATH_Physical_i::inhibitTransmit (CORBA::Boolean Inhi bit)

ACE_THROW_SPEC ((CORBA::SystemException)){

_inhibit = Inhibit;// Return true if we succeeded to stop transmission.// In this case, we always do :)return true;

}

// These should be attributes, but TAO IDL compiler generate s methods.// Workaround, just return a private attribute.

CORBA::UShortMATH_Physical_i::maxPayloadSize ()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _maxPayloadSize;}

CORBA::UShortMATH_Physical_i::minPayloadSize ()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _minPayloadSize;}

CORBA::OctetMATH_Physical_i::numOfPriorityQueues ()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _numOfPriorityQueues;}

MATH MAC i.hDeclaration for the MAC layer of the waveform.

#ifndef MAC_I_H#define MAC_I_H

#include <iostream>

#include <ossiecf/Resource_impl.h>#include <ossieparser/orb_wrap.h>#include "../MATHS.h"#include <ossiecf/DomainManager_impl.h>

class MATH_MAC_i :public virtual POA_MATH::MAC,

78 Appendix D. MATH SCA application

public virtual POA_CF::Resource,public virtual POA_CF::Port,public Resource_impl

{

public:

MATH_MAC_i ();˜MATH_MAC_i ();

// Core Framework interfaces:

CORBA::Object_ptr getPort (const char * name)ACE_THROW_SPEC ((CORBA::SystemException, CF::PortSupp lier::UnknownPort));

void connectPort (CORBA::Object_ptr connection, const ch ar * connectionId)ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort,

CF::Port::OccupiedPort));

void disconnectPort (const char * connectionId)ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort));

void start ()ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StartError));

void stop ()ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StopError));

void initialize ()ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::InitializeError));

void releaseObject ()ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::ReleaseError));

// Waveform interfaces:

void generate_data()ACE_THROW_SPEC ((CORBA::SystemException));

void receive_data()ACE_THROW_SPEC ((CORBA::SystemException));

MATH::Common_NRT::running_t get_running_status()ACE_THROW_SPEC ((CORBA::SystemException));

void setIOMode (MATH::Common_NRT::IO_Mode_Type newIOMo de)ACE_THROW_SPEC ((CORBA::SystemException));

MATH::Common_NRT::IO_Mode_Type getIOMode ()ACE_THROW_SPEC ((CORBA::SystemException));

void setDataMode (MATH::MAC_NRT::Data_Mode_Type newDat aMode)ACE_THROW_SPEC ((CORBA::SystemException));

MATH::MAC_NRT::Data_Mode_Type getDataMode ()ACE_THROW_SPEC ((CORBA::SystemException));

void pushPacket(CORBA::Octet priority, MATH::Common_RT ::ControlType control,const PortTypes::ShortSequence & payload)

ACE_THROW_SPEC ((CORBA::SystemException));

CORBA::UShort spaceAvailable(CORBA::Octet priorityQue ueID)ACE_THROW_SPEC ((CORBA::SystemException));

void enableFlowControl (CORBA::Boolean enable)ACE_THROW_SPEC ((CORBA::SystemException));

void enableEmptySignal (CORBA::Boolean enable)ACE_THROW_SPEC ((CORBA::SystemException));

79

void setNumOfPriorityQueues (CORBA::Octet numOfPriorit ies)ACE_THROW_SPEC ((CORBA::SystemException));

void signalHighWatermark (CORBA::Octet priorityQueueID )ACE_THROW_SPEC ((CORBA::SystemException));

void signalLowWatermark (CORBA::Octet priorityQueueID)ACE_THROW_SPEC ((CORBA::SystemException));

void signalEmpty ()ACE_THROW_SPEC ((CORBA::SystemException));

CORBA::UShort maxPayloadSize ()ACE_THROW_SPEC ((CORBA::SystemException));

CORBA::UShort minPayloadSize ()ACE_THROW_SPEC ((CORBA::SystemException));

CORBA::Octet numOfPriorityQueues ()ACE_THROW_SPEC ((CORBA::SystemException));

private:

ORB_WRAP orb;

CF::FileManager_ptr _file_mgr;CF::File_ptr _audiofile;

MATH::Common_NRT::running_t _runningMode;

MATH::Physical_var _Physical_ProvidesPort;

CORBA::UShort _maxPayloadSize;CORBA::UShort _minPayloadSize;CORBA::Octet _numOfPriorityQueues;

CORBA::Boolean _flowControl;CORBA::Boolean _emptySignal;

CORBA::Boolean _send_enable;

CORBA::Boolean _audiofile_is_open;

MATH::MAC_NRT::Data_Mode_Type _datamode;MATH::Common_NRT::IO_Mode_Type _IOMode;

};

#endif // MAC_I_H

MATH MAC i.cppMAC layer implementation.

#include "MATH_MAC_i.h"

using namespace MATH::MAC_NRT;

// ContructorMATH_MAC_i::MATH_MAC_i(){

// Start in STANDBY mode_runningMode = MATH::Common_NRT::STANDBY;

// Initialize object reference_Physical_ProvidesPort = MATH::Physical::_nil();

}

80 Appendix D. MATH SCA application

// DestructorMATH_MAC_i::˜MATH_MAC_i(){}

// Core Framework interfaces:

CORBA::Object_ptrMATH_MAC_i::getPort (const char * name)

ACE_THROW_SPEC ((CORBA::SystemException, CF::PortSupp lier::UnknownPort)){

if (ACE_OS::strcmp(name, "MAC_RT_out") == 0)return this->_this();

return CORBA::Object::_nil();}

voidMATH_MAC_i::connectPort (CORBA::Object_ptr connection , const char * connectionId)

ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort,CF::Port::OccupiedPort))

{if (ACE_OS::strcmp(connectionId, "MAC_to_Physical") == 0)

_Physical_ProvidesPort = MATH::Physical::_narrow(conn ection);}

voidMATH_MAC_i::disconnectPort (const char * connectionId)

ACE_THROW_SPEC ((CORBA::SystemException, CF::Port::In validPort)){

if (ACE_OS::strcmp(connectionId, "MAC_ProvidesPort") = = 0)_Physical_ProvidesPort = MATH::Physical::_nil();

}

voidMATH_MAC_i::initialize ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::InitializeError)){

// set waveform attributes_maxPayloadSize = 5000;_minPayloadSize = 500;

_numOfPriorityQueues = 1;

_flowControl = false;_emptySignal = false;

_send_enable = false;

_audiofile_is_open = false;

// AUDIO is default data mode._datamode = AUDIO;// _datamode = TEXT;_IOMode = MATH::Common_NRT::TRANSMIT_MODE;

// Get pointer to FileManager from DomainManager.// FIXME, rewrite ORB lookupCORBA::Object_var dm_object = CORBA::Object::_nil();while (CORBA::is_nil(dm_object))

dm_object = orb.lookup("/DomainName1/DomainManager");

CF::DomainManager_var dm = CF::DomainManager::_narrow( dm_object);_file_mgr = dm->fileMgr();

}

voidMATH_MAC_i::releaseObject ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::LifeCycl e::ReleaseError)){

81

// Let child exit_runningMode = MATH::Common_NRT::EXITING;

// Close fileif (_audiofile_is_open)

_audiofile->close();}

voidMATH_MAC_i::start ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StartError)){

_send_enable = true;_runningMode = MATH::Common_NRT::RUNNING;

}

voidMATH_MAC_i::stop ()

ACE_THROW_SPEC ((CORBA::SystemException, CF::Resource ::StopError)){

_send_enable = false;_runningMode = MATH::Common_NRT::STANDBY;if (_audiofile_is_open)

_audiofile->close();_audiofile_is_open = false;

}

// Waveform interfacesvoidMATH_MAC_i::generate_data()

ACE_THROW_SPEC ((CORBA::SystemException)){

// What kind of data should we generate?if (_send_enable) {

switch (_datamode) {

case AUDIO:{

if (_audiofile_is_open == false) {

CF::Properties props;props.length(1);props[0].id = CORBA::string_dup("audio_filename");

query(props);const char * _filename;props[0].value >>= _filename;

// Open data file._audiofile = _file_mgr->open(_filename, true);

// Skip wav header_audiofile->setFilePointer(44);

_audiofile_is_open = true;}

CF::OctetSequence_var _tmpdata;_audiofile->read(_tmpdata, 540);

// End of file? Then set file pointer to beginning of data.if (_tmpdata->length() == 0) {

_audiofile->setFilePointer(44);}else {

PortTypes::ShortSequence_var _payload = new PortTypes:: ShortSequence;_payload->length(_tmpdata->length()/2);

82 Appendix D. MATH SCA application

// Re-pack the data, going from octets to shorts.for (unsigned int t = 0; t < _payload->length(); t++) {

_payload[t] = _tmpdata[t * 2];_payload[t] = _payload[t] << 8;_payload[t] = _payload[t] | _tmpdata[t * 2+1];

}

// Priority of this packet sequence. We only have one priorit y level :)CORBA::Octet prio = 0;// Control information accompanying the sequence.// Not used at this point, just send the ’null’ control field.MATH::Common_RT::ControlType ct = MATH::Common_RT::nul l;

// Push data to Physical Layer._Physical_ProvidesPort->pushPacket(prio, ct, _payload );

}break;

}

case TEXT:

// TEXT is far from implemented. The data has to be modulated i n some way// to be able to be transmitted over the sound card without loo sing information.// An easy way would be to modulate 1 bit as a 16 bit word, since t he sound card// uses 16 bit words. But experiments with the sound card show s this is not// a good idea. A better way to go would be to implement QPSK or B PSK modulating.// All this should of course be handled in Physical Resource.// Below are some remains of the trial-and-error testing wit h the sound card.

int _ptestsize = 8 * 100;

char * _pteststring = "A small teststring";

PortTypes::ShortSequence_var _payload = new PortTypes:: ShortSequence;_payload->length(_ptestsize);

// Priority of this packet sequence. We only have one priorit y level :)CORBA::Octet prio = 0;

// Set the sync-flagMATH::Common_RT::ControlType ct = MATH::Common_RT::syn c;

short one = 0x4000;short zero = 0x9000;char tecken;

for (int c=0; c < _ptestsize; c++) {

// tecken = _pteststring[c];

// for (int i=0; i<=7; i++) {// if ((tecken << i) & 128)// _payload[c * 8 + i] = one;// else// _payload[c * 8 + i] = zero;// }

_payload[c] = one;}

_Physical_ProvidesPort->pushPacket(prio, ct, _payload );

break;}

}}

voidMATH_MAC_i::receive_data()

ACE_THROW_SPEC ((CORBA::SystemException)){

83

// Receiver not implemented (yet)}

MATH::Common_NRT::running_tMATH_MAC_i::get_running_status()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _runningMode;}

voidMATH_MAC_i::setDataMode (MATH::MAC_NRT::Data_Mode_Ty pe newDataMode)

ACE_THROW_SPEC ((CORBA::SystemException)){

_datamode = newDataMode;}

MATH::MAC_NRT::Data_Mode_TypeMATH_MAC_i::getDataMode ()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _datamode;}

voidMATH_MAC_i::setIOMode (MATH::Common_NRT::IO_Mode_Typ e newIOMode)

ACE_THROW_SPEC ((CORBA::SystemException)){

_IOMode = newIOMode;}

MATH::Common_NRT::IO_Mode_TypeMATH_MAC_i::getIOMode ()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _IOMode;}

voidMATH_MAC_i::pushPacket(CORBA::Octet priority, MATH::C ommon_RT::ControlType control, const PortTypes::ShortS equence

ACE_THROW_SPEC ((CORBA::SystemException)){

// Haven’t implemented receiver.}

CORBA::UShortMATH_MAC_i::spaceAvailable(CORBA::Octet priorityQueu eID)

ACE_THROW_SPEC ((CORBA::SystemException)){

// Haven’t implemented receiver.return 0;

}

voidMATH_MAC_i::enableFlowControl (CORBA::Boolean enable)

ACE_THROW_SPEC ((CORBA::SystemException)){

_flowControl = enable;}

voidMATH_MAC_i::enableEmptySignal (CORBA::Boolean enable)

ACE_THROW_SPEC ((CORBA::SystemException)){

_emptySignal = enable;}

voidMATH_MAC_i::setNumOfPriorityQueues (CORBA::Octet numO fPriorities)

84 Appendix D. MATH SCA application

ACE_THROW_SPEC ((CORBA::SystemException)){

_numOfPriorityQueues = numOfPriorities;}

voidMATH_MAC_i::signalHighWatermark (CORBA::Octet priorit yQueueID)

ACE_THROW_SPEC ((CORBA::SystemException)){

cout << "MAC got signalHighWatermark" << endl;_send_enable = false;

}

voidMATH_MAC_i::signalLowWatermark (CORBA::Octet priority QueueID)

ACE_THROW_SPEC ((CORBA::SystemException)){

cout << "MAC got signalLowWatermark" << endl;_send_enable = true;

}

voidMATH_MAC_i::signalEmpty ()

ACE_THROW_SPEC ((CORBA::SystemException)){

_send_enable = true;}

CORBA::UShortMATH_MAC_i::maxPayloadSize ()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _maxPayloadSize;}

CORBA::UShortMATH_MAC_i::minPayloadSize ()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _minPayloadSize;}

CORBA::OctetMATH_MAC_i::numOfPriorityQueues ()

ACE_THROW_SPEC ((CORBA::SystemException)){

return _numOfPriorityQueues;}

alsa wrapper.hThis class is used to handle the sound card functions, and is used in the Physical layer.

#ifndef ALSA_WRAPPER_H#define ALSA_WRAPPER_H

#include <alsa/asoundlib.h>

class alsa_wrapper{

public:

alsa_wrapper();˜alsa_wrapper();

int play(void * data, int size);

int get_buffer_size();

85

void setmode(snd_pcm_stream_t newmode);void createPCM(int number_of_channels);void shutdownPCM();

snd_pcm_t * pcm_handle;

private:snd_pcm_hw_params_t * hw_params;snd_pcm_stream_t mode;

snd_pcm_stream_t stream;snd_pcm_uframes_t frames;

int direction;unsigned int bps_value;int buffer_size;

};

#endif // ALSA_WRAPPER_H

alsa wrapper.cppALSA functions implementation.

#include "alsa_wrapper.h"

//#define OPEN_MODE SND_PCM_NONBLOCK#define OPEN_MODE 0

//#define TESTFILE

#ifdef TESTFILEint foo;#endif

alsa_wrapper::alsa_wrapper(){#ifdef TESTFILE

foo = open("utfil", O_WRONLY | O_APPEND | O_TRUNC);#endif}

alsa_wrapper::˜alsa_wrapper(){

shutdownPCM();

#ifdef TESTFILEclose(foo);

#endif}

voidalsa_wrapper::setmode(snd_pcm_stream_t newmode){

mode = newmode;}

voidalsa_wrapper::shutdownPCM(){

snd_pcm_hw_params_free(hw_params);snd_pcm_drain(pcm_handle);snd_pcm_close(pcm_handle);

}

voidalsa_wrapper::createPCM(int number_of_channels){

86 Appendix D. MATH SCA application

// A call to setmode() _must_ be done before createPCM()

if (snd_pcm_open(&pcm_handle, "default", mode, OPEN_MOD E) < 0) {throw "Error opening PCM device";

}

// Allocate a hardware parameters object.snd_pcm_hw_params_malloc(&hw_params);

// Fill it in with default values.snd_pcm_hw_params_any(pcm_handle, hw_params);

// Set the desired hardware parameters:

// Interleaved modesnd_pcm_hw_params_set_access(pcm_handle, hw_params, S ND_PCM_ACCESS_RW_INTERLEAVED);

// Signed 16-bit little-endian formatsnd_pcm_hw_params_set_format(pcm_handle, hw_params, S ND_PCM_FORMAT_S16_LE);

// One channel (mono)snd_pcm_hw_params_set_channels(pcm_handle, hw_params , number_of_channels);

// sample rateif (mode == SND_PCM_STREAM_PLAYBACK)

bps_value = 44100;else

bps_value = 48000;

direction = 1;snd_pcm_hw_params_set_rate_near(pcm_handle, hw_param s, &bps_value, &direction);

// snd_pcm_hw_params_set_rate(handle, params, &val, &di r);

// Try to set period size.// The actual number of frames is returned in ’frames’.frames = 3999;snd_pcm_hw_params_set_period_size_near(pcm_handle, h w_params, &frames, &direction);

// Write parameters to driverif (snd_pcm_hw_params(pcm_handle, hw_params) < 0) {

throw "Unable to set hardware parameters";}

// Buffer size.// Each frame is 4 bytes (16 bit sample, 2 channels)buffer_size = frames * number_of_channels * 2;

}

intalsa_wrapper::play(void * data, int size){#ifdef TESTFILE

write(foo, data, size);#endif

int res;res = snd_pcm_writei(pcm_handle, data, size/4);

if (res == -EPIPE) {// EPIPE means underrun.// A call to snd_pcm_prepare fixes the stream.snd_pcm_prepare(pcm_handle);

}// Return number of frames played.return res;

}

intalsa_wrapper::get_buffer_size() {

87

return buffer_size;}

buffer.hThe buffer class is used in the Physical layer to hold the datacoming from MAC layer.

#ifndef BUFFER_H#define BUFFER_H

#include <stdlib.h>#include "../MATHS.h"

class buffer{public:

buffer (size_t size);˜buffer ();

void insert(const PortTypes::ShortSequence & input);char * get_chunk(unsigned int & size);unsigned int get_size();void reset();

private:char * _buffer;char * _in_ptr;char * _out_ptr;char * _end_ptr;

};

#endif // BUFFER_H

buffer.cppThe buffer implementation.

#include "buffer.h"

//Contructorbuffer::buffer(size_t size){

_buffer = (char * ) malloc(size);

if (_buffer == NULL)throw (CF::LifeCycle::InitializeError (1));

_in_ptr = _buffer;_out_ptr = _buffer;_end_ptr = _buffer + size;

}

//Destructorbuffer::˜buffer(){

if (_buffer != NULL)free(_buffer);

}

voidbuffer::insert(const PortTypes::ShortSequence & indata ){

// Number of incoming _shorts_unsigned int indata_size = indata.length();// Space until end of buffer, measures in _bytes_unsigned int space_until_end = _end_ptr - _in_ptr;

88 Appendix D. MATH SCA application

// Put incoming data in buffer.// If the incoming data doesn’t fit between the// _in_ptr and the end of buffer, wrap around// to the beginning of the buffer, and put// the rest there.if (indata_size * 2 < space_until_end) {

for (unsigned int g = 0; g < indata_size; g++) {_in_ptr[2 * g] = indata[g] >> 8;_in_ptr[2 * g+1] = indata[g];

}_in_ptr += indata_size * 2;

}else if (indata_size * 2 > space_until_end) {

for (unsigned int g = 0; g < space_until_end / 2 ; g++) {_in_ptr[2 * g] = indata[g] >> 8;_in_ptr[2 * g+1] = indata[g];

}_in_ptr = _buffer;for (unsigned int g = 0; g < indata_size - space_until_end / 2; g++) {

_in_ptr[2 * g] = indata[g + space_until_end / 2] >> 8;_in_ptr[2 * g+1] = indata[g + space_until_end / 2];

}_in_ptr += (indata_size - space_until_end / 2) * 2;

}// If the data fits _exactly_ up to the end of// the buffer, set _in_ptr to beginning of buffer// after copy.else {

for (unsigned int g = 0; g < indata_size; g++) {_in_ptr[2 * g] = indata[g] >> 8;_in_ptr[2 * g+1] = indata[g];

}_in_ptr = _buffer;

}}

// Return a pointer to a chunk of data which is then// assumed to be "consumed"char *buffer::get_chunk(unsigned int & size){

char * tmp = _out_ptr;

if (size > get_size())size = get_size();

if ((unsigned int) (_end_ptr - _out_ptr) > size) {_out_ptr += size;

}else if (_end_ptr - _out_ptr) {

size = _end_ptr - _out_ptr;_out_ptr = _buffer;

}return tmp;

}

unsigned intbuffer::get_size(){

unsigned int size;

if (_in_ptr >= _out_ptr) {size = _in_ptr - _out_ptr;

}else {

size = _end_ptr - _out_ptr;size += _in_ptr - _buffer;

}return size;

89

}

voidbuffer::reset(){

_in_ptr = _buffer;_out_ptr = _buffer;

}

ResourceFactoryi.hDeclaration of the ResourceFactory used for our project.

// Implementation of a ResourceFactory.

#ifndef RESOURCEFACTORY_I_H#define RESOURCEFACTORY_I_H

#include "MATHS.h"#include "orb_wrap.h"

#ifdef MATH_VERBOSE#include <iostream>#endif

class ResourceFactory_i :public virtual POA_CF::ResourceFactory

{

public:

ResourceFactory_i();ResourceFactory_i(const char * ResourceFactoryName);

˜ResourceFactory_i();

char * identifier()throw (CORBA::SystemException)

{return CORBA::string_dup(_identifier);

}

CF::Resource_ptrcreateResource (const char * _resourceID, const CF::Properties& _qualifiers)

throw (CF::ResourceFactory::CreateResourceFailure, CO RBA::SystemException);

void releaseResource(const char * _rscId)throw (CF::ResourceFactory::InvalidResourceId, CORBA: :SystemException);

void shutdown()throw (CF::ResourceFactory::ShutdownFailure, CORBA::S ystemException);

protected:

CORBA::String_var _name;CORBA::String_var _identifier;

int _numPhysical;int _numMAC;int _numAssemblyController;

MATH::Physical_var _resourcePhysical;MATH::MAC_var _resourceMAC;MATH::AssemblyController_var _resourceAssemblyContro ller;

ORB_WRAP orb;

void init();

90 Appendix D. MATH SCA application

};

#endif // RESOURCEFACTORY_I_H

ResourceFactoryi.cppOur implementation of a ResourceFactory.

#include "ResourceFactory_i.h"

// ContructorResourceFactory_i::ResourceFactory_i(const char * ResourceFactoryName){

_numPhysical = 0;_numMAC = 0;_numAssemblyController = 0;

_resourcePhysical = MATH::Physical::_nil();_resourceMAC = MATH::MAC::_nil();_resourceAssemblyController = MATH::AssemblyControlle r::_nil();

_name = ResourceFactoryName;// L ater identifier vara lika med namnet p a ResourceFactory_identifier = _name;

init();}

// DestructorResourceFactory_i::˜ResourceFactory_i(){}

voidResourceFactory_i::init(){

// Register with POA and Naming Service.try {

// Get Root Portable Object AdapterPortableServer::POA_ptr root_poa = orb.getPOA();

// Aktivera objektet i POA och f a Object ID.PortableServer::ObjectId_var oid=root_poa->activate_ object(this);CORBA::Object_var rscFacObjReference = root_poa->id_to _reference(oid.in());

// H amta Naming ContextCosNaming::NamingContext_var naming_context = orb.getN amingContext();

// S att namnet p a objektet som det ska ha i Naming ServiceCosNaming::Name namebinding;orb.getCosName(namebinding, _name);

// Stoppa in objektet i Naming Servicenaming_context->rebind(namebinding, rscFacObjReferen ce.in());

}catch (CORBA::Exception & ) {

throw CF::Resource::StartError(CF::CFEDOM, "Error in MA TH_Physical Constructor");}

}

CF::Resource_ptrResourceFactory_i::createResource (const char * _rscId, const CF::Properties& qualifiers)

throw (CORBA::SystemException, CF::ResourceFactory::C reateResourceFailure){

// This is the hard-coded section of the waveform launcher.

if (strcmp(_rscId, "MATH_Physical_Resource") == 0){

// Is there already a Resource of this type?

91

if (CORBA::is_nil(_resourcePhysical)){

// No, create a new one.int pid;

#ifdef MATH_VERBOSEstd::cout << "Starting Physical" << std::endl;

#endif// fork process into main and child, if it fails return// a pointer to a _nil()-object.if ((pid = fork()) < 0)

return CF::Resource::_nil();

if (pid == 0)// In child process{

execl("Physical/Physical", "Physical/Physical", NULL) ;// If execl returns, there has been an error.

#ifdef MATH_VERBOSEstd::cout << strerror(errno) << std::endl;

#endifexit (-1);

}

// In main process:

// Find CORBA object through Naming Service// The child above registers in the Naming Service// so it could take a while before it’s registered.

CORBA::Object_var _obj = CORBA::Object::_nil();while( CORBA::is_nil(_obj))

_obj = orb.lookup("/DomainName1/MATH_Physical");

// Narrow down from general object to this particular one._resourcePhysical = MATH::Physical::_narrow(_obj);

}

// Increase Resource counter, and return a copy of the// CORBA object._numPhysical++;return MATH::Physical::_duplicate(_resourcePhysical) ;

}

if (strcmp(_rscId, "MATH_MAC_Resource") == 0){

if (CORBA::is_nil(_resourceMAC)){

int pid;

#ifdef MATH_VERBOSEstd::cout << "Starting MAC" << std::endl;

#endifif ((pid = fork()) < 0)

return CF::Resource::_nil();if (pid == 0)

{execl("MAC/MAC", "MAC/MAC", NULL);

#ifdef MATH_VERBOSEstd::cout << strerror(errno) << std::endl;

#endifexit (-1);

}

CORBA::Object_var _obj = CORBA::Object::_nil();while( CORBA::is_nil(_obj))

_obj = orb.lookup("/DomainName1/MATH_MAC");

_resourceMAC = MATH::MAC::_narrow(_obj);

92 Appendix D. MATH SCA application

}

_numMAC++;return MATH::MAC::_duplicate(_resourceMAC);

}

if (strcmp(_rscId, "MATH_AssemblyController_Resource" ) == 0){

if (CORBA::is_nil(_resourceAssemblyController)){

int pid;

#ifdef MATH_VERBOSEstd::cout << "Starting AssemblyController" << std::endl;

#endifif ((pid = fork()) < 0)

return CF::Resource::_nil();if (pid == 0)

{execl("AssemblyController/AssemblyController",

"AssemblyController/AssemblyController", NULL);#ifdef MATH_VERBOSE

std::cout << strerror(errno) << std::endl;#endif

exit (-1);}

CORBA::Object_var _obj = CORBA::Object::_nil();while( CORBA::is_nil(_obj))

_obj = orb.lookup("/DomainName1/MATH_AssemblyControll er");

_resourceAssemblyController = MATH::AssemblyControlle r::_narrow(_obj);}

_numAssemblyController++;return MATH::AssemblyController::_duplicate(_resourc eAssemblyController);

}

// Couldn’t create requested Resource, return a nil()-obje ct.return CF::Resource::_nil();

}

voidResourceFactory_i::releaseResource (const char * _rscId)

throw (CORBA::SystemException, CF::ResourceFactory::I nvalidResourceId){

// This is the reverse of createResource, and as such is hard- coded

if (strcmp(_rscId, "MATH_Physical_Resource") == 0){

if (CORBA::is_nil(_resourcePhysical))return;

// More than one client can be connected to this servant.// As long as the number of Resources "created"// is larger than one, we shouldn’t execute// the releaseObject-method, only decrease counter// until the last client wants to disconnect.// Then we destroy object.

if (_numPhysical > 0)_numPhysical--;

if (_numPhysical == 0){

_resourcePhysical->releaseObject();// Wait for child to exitint status;

93

wait(&status);_resourcePhysical = MATH::Physical::_nil();

}#ifdef MATH_VERBOSE

cout << "Physical has shut down." << endl;#endif

}

else if (strcmp(_rscId, "MATH_MAC_Resource") == 0){

if (CORBA::is_nil(_resourceMAC))return;

if (_numMAC > 0)_numMAC--;

if (_numMAC == 0){

_resourceMAC->releaseObject();// Wait for child to exitint status;wait(&status);_resourceMAC = MATH::MAC::_nil();

}#ifdef MATH_VERBOSE

cout << "MAC has shut down." << endl;#endif

}

else if (strcmp(_rscId, "MATH_AssemblyController_Resou rce") == 0){

if (CORBA::is_nil(_resourceAssemblyController))return;

if (_numAssemblyController > 0)_numAssemblyController--;

if (_numAssemblyController == 0){

_resourceAssemblyController->releaseObject();// Wait for child to exitint status;wait(&status);_resourceAssemblyController = MATH::AssemblyControlle r::_nil();

}#ifdef MATH_VERBOSE

cout << "AssemblyController has shut down." << endl;#endif

}else

{throw CF::ResourceFactory::InvalidResourceId();

}}

voidResourceFactory_i::shutdown()

throw (CORBA::SystemException, CF::ResourceFactory::S hutdownFailure){

_resourcePhysical = MATH::Physical::_nil();_resourceMAC = MATH::MAC::_nil();_resourceAssemblyController = MATH::AssemblyControlle r::_nil();

// Remove object from Naming Service and deactivate it in roo tPOAPortableServer::POA_ptr root_poa = orb.getPOA();CosNaming::NamingContext_var naming_context = orb.getN amingContext();PortableServer::ObjectId_var oid = root_poa->servant_t o_id(this);

CosNaming::Name namebinding;orb.getCosName(namebinding, "/DomainName1/ResourceFa ctory");

94 Appendix D. MATH SCA application

naming_context->unbind(namebinding);

root_poa->deactivate_object(oid);}

95

Domain Profile XML

These are the XML files needed for our application. Not all files are included, since many ofthem look quite the same. This section is only here to give an example of how they look like.

MATH SAD.xmlThe Software Assembly Descriptor describes what kind of components the Application con-sists of, and how they are interconnected. It also states which component is to be the Assem-blyController.

<?xml version="1.0"?><!DOCTYPE softwareassembly SYSTEM "dtd/softwareassembl y.dtd"><softwareassembly id="DCE:bb359773-61b7-4b0b-85c0-c2 b7be803768" name="MATH Waveform">

<description>The Mansour-Thomas (MATH) Waveform</descr iption>

<componentfiles><componentfile id="PhysicalSPD" type="SPD">

<localfile name="/DomainProfile/Physical_SPD.xml"/></componentfile>

<componentfile id="MACSPD" type="SPD"><localfile name="/DomainProfile/MAC_SPD.xml"/>

</componentfile>

<componentfile id="AssemblyControllerSPD" type="SPD"><localfile name="/DomainProfile/AssemblyController_S PD.xml"/>

</componentfile>

<componentfile id="ResourceFactorySPD" type="SPD"><localfile name="/DomainProfile/ResourceFactory_SPD. xml"/>

</componentfile></componentfiles>

<partitioning>

<!-- ApplicationFactory in OSSIE assumes 1 componentinsta ntiation for each componentplacement -->

<componentplacement><componentfileref refid="ResourceFactorySPD"/><componentinstantiation id="DCE:d95533be-f8b5-469a-8 b59-a64e5edd32ac">

<findcomponent><namingservice name="/DomainName1/ResourceFactory"/>

</findcomponent></componentinstantiation>

</componentplacement>

<componentplacement><componentfileref refid="PhysicalSPD"/><componentinstantiation id="DCE:0a2e64bd-0ef3-4ff0-9 777-709a531db052">

<findcomponent><componentresourcefactoryref refid="DCE:d95533be-f8b 5-469a-8b59-a64e5edd32ac"></componentresourcefactoryref>

</findcomponent></componentinstantiation>

</componentplacement>

<componentplacement><componentfileref refid="MACSPD"/><componentinstantiation id="DCE:c9984546-1ae8-4094-b 67e-32c20fdd23f2">

<findcomponent><componentresourcefactoryref refid="DCE:d95533be-f8b 5-469a-8b59-a64e5edd32ac"></componentresourcefactoryref>

</findcomponent></componentinstantiation>

</componentplacement>

96 Appendix D. MATH SCA application

<componentplacement><componentfileref refid="AssemblyControllerSPD"/><componentinstantiation id="DCE:5e785151-bbb0-42dd-8 63b-893fc72c3478">

<findcomponent><componentresourcefactoryref refid="DCE:d95533be-f8b 5-469a-8b59-a64e5edd32ac"></componentresourcefactoryref>

</findcomponent></componentinstantiation>

</componentplacement>

</partitioning>

<assemblycontroller><componentinstantiationref refid="DCE:5e785151-bbb0- 42dd-863b-893fc72c3478"/>

</assemblycontroller>

<connections>

<connectinterface id="MAC_to_Physical"><usesport>

<usesidentifier>MAC_RT_out</usesidentifier><findby>

<namingservice name="/DomainName1/MATH_MAC"/></findby>

</usesport><providesport>

<providesidentifier>Physical_RT_in</providesidentif ier><findby>

<namingservice name="/DomainName1/MATH_Physical"/></findby>

</providesport></connectinterface>

<connectinterface id="Physical_to_MAC"><usesport>

<usesidentifier>Physical_RT_out</usesidentifier><findby>

<namingservice name="/DomainName1/MATH_Physical"/></findby>

</usesport><providesport>

<providesidentifier>MAC_RT_in</providesidentifier><findby>

<namingservice name="/DomainName1/MATH_MAC"/></findby>

</providesport></connectinterface>

<connectinterface id="AssemblyController_to_MAC"><usesport>

<usesidentifier>AssemblyController_NRT_out</useside ntifier><findby>

<namingservice name="/DomainName1/MATH_AssemblyContr oller"/></findby>

</usesport><providesport>

<providesidentifier>MAC_NRT_in</providesidentifier><findby>

<namingservice name="/DomainName1/MATH_MAC"/></findby>

</providesport></connectinterface>

<connectinterface id="AssemblyController_to_Physical "><usesport>

<usesidentifier>AssemblyController_NRT_out</useside ntifier><findby>

<namingservice name="/DomainName1/MATH_AssemblyContr oller"/></findby>

</usesport>

97

<providesport><providesidentifier>Physical_NRT_in</providesidenti fier><findby>

<namingservice name="/DomainName1/MATH_Physical"/></findby>

</providesport></connectinterface>

</connections>

</softwareassembly>

SPD, SCD and PRF files

These are the Software Package Descriptor (SPD), Software Component Descriptor (SCD)and Properties Descriptor (PRF) files for the MAC component. These files also exist foreach of the Physical, AssemblyController and ResourceFactory components, as well as forthe DomainManager.

MAC SPD.xml

<?xml version="1.0"?><!DOCTYPE softpkg SYSTEM "dtd/softpkg.dtd"><softpkg id="DCE:377f2210-8c57-42ed-a42c-98caf6da634 a" name="MATH_MAC_Resource">

<author><name>Thomas Sundquist</name>

</author>

<descriptor><localfile name="/DomainProfile/MAC_SCD.xml"/>

</descriptor>

<implementation id="DCE:b4aaaf71-171e-4196-b5be-42da 42559b3a">

<code type="Executable"><localfile name="MAC/MAC"/>

</code>

<propertyfile type="PRF"><localfile name="/DomainProfile/MAC_PRF.xml"/>

</propertyfile>

</implementation>

</softpkg>

MAC SCD.xml

<?xml version="1.0"?><!DOCTYPE softwarecomponent SYSTEM "dtd/softwarecompon ent.dtd">

<softwarecomponent>

<componentrepid repid="IDL:CF/Resource:3.0"/>

<componenttype>resource</componenttype>

<componentfeatures><ports>

<uses repid="IDL:MATH/MAC:3.0" usesname="MAC_RT_out"><porttype type="data"/>

</uses>

98 Appendix D. MATH SCA application

<provides repid="IDL:MATH/MAC:3.0" providesname="MAC_ RT_in"><porttype type="data"/>

</provides><provides repid="IDL:MATH/MAC:3.0" providesname="MAC_ NRT_in">

<porttype type="control"/></provides>

</ports></componentfeatures>

<interfaces><interface repid="IDL:MATH/MAC:3.0" name="MAC"/>

</interfaces>

</softwarecomponent>

MAC PRF.xml

<?xml version="1.0"?><!DOCTYPE properties SYSTEM "dtd/properties.dtd"><properties>

<description>Properties for the MAC Resource</descripti on><simple id="audio_filename" type="string">

<description>File name of audio file to be transmitted</de scription><value>/home/ethosun/project/sdr/MATH/audio/spiritu als_proclamation.wav</value><kind kindtype="configure"/>

</simple></properties>