0% found this document useful (0 votes)
79 views

Nokia M2M Platform Server Application: Programming Guide

Uploaded by

Eug. Sam.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
79 views

Nokia M2M Platform Server Application: Programming Guide

Uploaded by

Eug. Sam.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

SERVER APPLICATION

NOKIA M2M PLATFORM

PROGRAMMING GUIDE
Copyright © 2002-2003 Nokia. All rights reserved. Issue 7.0 9355793
Contents

ACRONYMS AND TERMS ...................................................................................................... 1


1. INTRODUCTION .............................................................................................................. 2
2. DEFINING A CORBA INTERFACE.................................................................................. 4
2.1 INTERFACE DEFINITION.......................................................................................... 4
2.2 COMPILING AN INTERFACE DEFINITION .............................................................. 5
2.3 NOKIA-SPECIFIC INTERFACES............................................................................... 6
3. CREATING A CORBA CLIENT ........................................................................................ 7
3.1 INITIALIZING AN OBJECT REQUEST BROKER...................................................... 7
3.2 RETRIEVING A CORBA NAMING SERVICE REFERENCE..................................... 8
3.3 RETRIEVING A REMOTE OBJECT REFERENCE ................................................... 8
3.3.1 Nokia Active Naming Context and M2MDevices.................................................... 9
3.3.2 Nokia Active Naming Context and iorgen............................................................. 10
3.3.3 Mobile IOR as a response to a method call ......................................................... 11
3.4 NARROWING THE RETRIEVED OBJECT REFERENCE ...................................... 11
3.5 EXECUTING THE REMOTE METHOD ................................................................... 12
4. CREATING A CORBA IMPLEMENTATION................................................................... 13
4.1 INITIALIZING AN OBJECT REQUEST BROKER.................................................... 13
4.2 CREATING AN IMPLEMENTATION........................................................................ 14
4.3 RETRIEVING A REFERENCE TO A PORTABLE OBJECT ADAPTER .................. 14
4.4 ACTIVATING THE IMPLEMENTATION WITH THE PORTABLE OBJECT
ADAPTER ................................................................................................................ 14
4.5 ACTIVATING THE PORTABLE OBJECT ADAPTER MANAGER ........................... 15
4.6 PUBLISHING THE IMPLEMENTATION OBJECT REFERENCE ............................ 15
4.7 RUNNING THE OBJECT REQUEST BROKER....................................................... 16
5. COMPILING AND RUNNING AN M2M APPLICATION ................................................. 17
6. ADVANCED CORBA PROGRAMMING......................................................................... 18
6.1 CORBA OBJECT FACTORY ................................................................................... 18
6.1.1 Tutorial2 interface definition ................................................................................. 18
6.1.2 Tutorial2 CORBA implementation ........................................................................ 19
6.1.2.1 Initialization................................................................................................20
6.1.2.2 Creating a new Portable Object Adapter ...................................................20
6.1.2.3 Creating a servant .....................................................................................21
6.1.2.4 Setting the default servant for the Portable Object Adapter ......................22
6.1.2.5 Binding to the CORBA Naming Service ....................................................22
6.1.2.6 Close method ............................................................................................22
6.1.2.7 Login method.............................................................................................23
6.1.3 Tutorial2 CORBA client ........................................................................................ 23
6.1.3.1 Initialization................................................................................................23
6.1.3.2 Retrieving a reference to the Connection interface implementation..........24
6.1.3.3 Retrieving a reference to the Hello interface implementation....................24
6.1.3.4 Executing the remote method....................................................................25
7. TROUBLESHOOTING ................................................................................................... 26
8. REFERENCES ............................................................................................................... 27
APPENDIX A: GIOP MESSAGE FRAGMENTATION ............................................................ 28
Legal Notice
Copyright © 2002-2003 Nokia. All rights reserved.
Reproduction, transfer, distribution or storage of part or all of the contents in this document in any form without the
prior written permission of Nokia is prohibited.
Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. Java and all Java-based
marks are trademarks or registered trademarks of Sun Microsystems. Other product and company names
mentioned herein may be trademarks or trade names of their respective owners.
Nokia operates a policy of continuous development. Nokia reserves the right to make changes and improvements
to any of the products described in this document without prior notice.
Under no circumstances shall Nokia be responsible for any loss of data or income or any special, incidental,
consequential or indirect damages howsoever caused.
The contents of this document are provided "as is". Except as required by applicable law, no warranties of any
kind, either express or implied, including, but not limited to, the implied warranties of merchantability and fitness
for a particular purpose, are made in relation to the accuracy, reliability or contents of this document. Nokia
reserves the right to revise this document or withdraw it at any time without prior notice.
ACRONYMS AND TERMS

Acronym/term Description
AM Application Module
ANC Active Naming Context
ASCII American Standard Code for Information
Interchange
CHAP Challenge Handshake Authentication Protocol
CORBA Common Object Request Broker Architecture
GIOP General Inter-ORB Protocol
GSM Global System for Mobile Communications
IDL Interface Definition Language
IMP Information Module Profile
IOR Interoperable Object Reference
IP Internet Protocol

J2ME Java™ 2 Micro Edition
J2SE™ Java 2 Standard Edition
M2M Machine-to-Machine
ORB Object Request Broker
POA Portable Object Adapter
SDK Software Development Kit
TCP Transmission Control Protocol
VM Virtual Machine
WAP Wireless Application Protocol
WTP Wireless Transport Protocol

1/28
1. INTRODUCTION
This document is intended to guide application developers who want to develop
customer server applications for the Nokia Machine-to-Machine (M2M)
Platform.

In the Nokia M2M system architecture, the term customer server application
refers to applications that are typically located in the customer intranet and
connected to the Nokia M2M Gateway (hereon Gateway). At the opposite end
of the Nokia M2M Platform, the counterpart of the customer server application
can be executed either in the Application Module (AM) software or an IMlet
located in the Nokia 12 GSM module (hereon Nokia 12 module).

Note: The customer server application does not necessarily function as a server
in terms of the client-server architecture, although this is often the case. See the
Nokia M2M Platform Software Developer’s Guide for a more detailed description
on the Nokia M2M system architecture.

This document focuses on those customer server applications that utilise the
Nokia M2M Platform. Thus M2M applications that do not require any
programming specific to the Nokia M2M Platform are not in the scope of this
document.

All code examples included in this document are written in the Java™
programming language. This language was chosen because it is widely used in
server side programming. Readers are expected to have a basic knowledge of
Java programming and therefore this document does not describe the basics of
Java programming in detail. The programming focus is on the M2M application
specific parts of the source code instead.

The Nokia M2M Platform utilises the Common Object Request Broker
Architecture (CORBA) as middleware and therefore the M2M applications used
in the Platform are language-independent. However, all applications must be
implemented with a programming language that enables CORBA language
mapping.

As described in CORBA literature, CORBA enables flexible programming and


there are plenty of options for implementing CORBA applications. However, in
this document the more advanced features of CORBA programming are
omitted and the focus is on making simple applications that can be used over
the Nokia M2M Platform. Occasionally this document describes some
advanced features of CORBA programming, especially when there are optional
ways of implementing something and when the implementation itself is a
significant part of the M2M application in question.

2/28
In this document it is assumed that the Nokia M2M Platform has been
successfully installed and applications can be run on top of it. For more
information on how to install and configure the components of the Nokia M2M
Platform, see the Nokia M2M Platform Software Development Kit and Nokia
M2M Gateway Trial Version Installation Guide and the Nokia M2M Platform
Configuration Manual.

3/28
2. DEFINING A CORBA INTERFACE

2.1 INTERFACE DEFINITION


The starting point for implementing an M2M application is to define a CORBA
interface with the Interface Definition Language (IDL). This interface specifies
the data types and method calls through which the two ends of the application
can interact.

In the interface definition phase, the application developer must know what kind
of data one end of the application needs to receive from the other end.
Naturally the interface can be modified as the application implementation
proceeds, but each time the interface is modified, both ends of the application
must be updated to conform to the new interface definition.

This programming guide uses the Tutorial1 application as a reference. It is a


very simple distributed application that has a CORBA client at one end of the
Nokia M2M Platform and a CORBA implementation (servant) at the other end.
The client sends a greeting string to the implementation, and the
implementation replies with another string. The application, its source code, and
the Nokia M2M Platform Software Development Kit Tutorial1 Application User
Guide can be found from the Nokia M2M Software Development Kit (SDK).

The interface used in the Tutorial1 application is defined in the tutorial1.idl


interface definition file as shown below:

module tutorial1 {

interface Hello {

exception EmptyGreetingsStringException { };

string sayHello(in string greetings)


raises (EmptyGreetingsStringException);

};

};

The first row defines the module where the interface belongs. When the
interface definition is compiled to Java code, the module is mapped to a
package called tutorial1.

On the second row, the Hello interface maps to an interface in Java code. A
servant object (CORBA implementation) then implements that interface.

The third row defines a user exception that can be thrown by the sayHello
method.

4/28
The last entry in the interface definition is the actual method call (sayHello). It
gets a string as an input parameter and returns a response string.

In the Tutorial1 application implementation the sayHello method throws an


EmptyGreetingStringException if a client greets the implementation with an
empty string (“”).

The interface definition described above contains all the necessary information
for both ends of the application. However, both the client and the
implementation utilise the code generated from the interface definition
differently. As the name implies, the implementation implements the interface.
That is, a class that implements the Hello interface must have a method
named sayHello, and its input parameter and return value must conform to
the interface definition. The client does not implement the sayHello method; it
simply calls that method from another object that implements the interface.

For detailed information about CORBA interface definitions, see


http://www.omg.org/gettingstarted/omg_idl.htm.

2.2 COMPILING AN INTERFACE DEFINITION


Before the customer server application can use the interface, it must be
compiled into stub and skeleton codes. A programming language specific stub
code is compiled for CORBA client applications and a skeleton code is
compiled for CORBA implementations.

The Java SDK 1.4 includes an executable called idlj that generates Java
source code from an interface definition. The idlj compiler can be given
different parameters and it can be used to generate, for example, only the stub
code. In the Tutorial1 application the idlj has been set to compile the interface
definitions with a –fall parameter that causes the compiler to generate all
bindings (stub and skeleton code).

Note: You may want to optimise the use of the idlj in your applications to
decrease the number of generated classes.

In addition to the –fall parameter, the interface definition of the Tutorial1


application has been compiled with another option of the idlj, namely the -
pkgPrefix. Using the -pkgPrefix option causes the IDL compiler to prefix a
given module or interface name with a package name that is given as a
parameter. All the example codes of the Nokia M2M SDK have been prefixed
with a com.nokia.m2m package name (with additional extensions in some
example codes).

Note: If you compile your applications with other prefixes (or without prefixes),
make sure that you implement the corresponding changes also to your application

5/28
source code.

The Tutorial1 interface definition can be compiled to Java source code by


executing the following command in the server directory of the Tutorial1
application:
idlj -fall -td idl_generated -pkgPrefix tutorial1
com.nokia.m2m.sdk.examples.tutorial1.idl ..\idl\tutorial1.idl

This command generates the Java source code (both stub and skeleton codes)
to an idl_generated directory. It gives a
com.nokia.m2m.sdk.examples.tutorial1.idl package prefix for the
Tutorial1 interface by using the tutorial1.idl file as an input for the IDL
compiler.

2.3 NOKIA-SPECIFIC INTERFACES


In addition to the custom-made CORBA interfaces that the application
developer can define, there are Nokia-specific interfaces available in the Nokia
GSM Connectivity Terminals (hereon Nokia terminals), Nokia 12 modules and
in the Nokia M2M Gateway that can be used for application development. See
the Nokia M2M Platform Software Developer’s Guide for more details.

6/28
3. CREATING A CORBA CLIENT
This chapter describes the communication parts of the Tutorial1 customer
server application CORBA client, that is, how to invoke a remote method.

Note: Although this chapter deals with the Tutorial1 application, similar actions
must be taken in all applications that are used to make remote method
invocations over the Nokia M2M Platform.

The client part of the Tutorial1 customer server application makes a request to
the implementation (servant) part of the same application as described in
Chapter 2.1. The client communicates wirelessly with the servant over the
Nokia M2M Platform. The complete source code of the Tutorial1 application
CORBA client can be found from the Nokia M2M SDK.

To execute a remote method, the server side CORBA client application must
carry out the following steps:

1. Initialize an Object Request Broker (ORB).

2. Retrieve a reference to the CORBA Naming Service.

3. Retrieve a reference to a particular object in the other end of the M2M


application (customer remote application in this case) from the CORBA
Naming Service.

4. Narrow (cast) the retrieved CORBA object to a specific object type (type
‘hello’ in this case).

5. Execute the remote method.

The above five steps of the Tutorial1 application source code are described in
more detail in the following chapters.

3.1 INITIALIZING AN OBJECT REQUEST BROKER


Creation of the CORBA client begins with ORB initialization. Since the Nokia
M2M applications utilise CORBA as their middleware, the customer server
application needs to get a reference to an instance of the ORB class:

org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(new String[0],


null);

7/28
This is a standard procedure for Java applications to initialize an ORB and
obtain a reference for it.

In the Tutorial1 application the CORBA environment initialization code is put in


a try-catch block that can catch:

• Exceptions from the Naming Service


• CORBA COMM_FAILURE exceptions (from the communication channel
initialization towards the customer remote application object)
• Exceptions defined in the interface definition of this specific method call

The CORBA COMM_FAILURE exception is uncommon in normal CORBA


programming because the TCP/IP used in normal fixed networks is very reliable
and fast. However, GSM networks are more complex and typically not as fast
as fixed networks, and therefore communication can fail in certain situations. To
recover from failures, the Nokia M2M Platform has built-in features to help the
identification of possible communication problems.

If a CORBA COMM_FAILURE is raised in the Nokia M2M Platform, it contains


a minor exception code with a more precise description of what went wrong in
communication. For more details on COMM_FAILURE exceptions in the Nokia
M2M Platform, see Chapter 7.

3.2 RETRIEVING A CORBA NAMING SERVICE REFERENCE


CORBA Naming Service is used to resolve object references using readable
names. In general, a Naming Service makes it possible to bind names to object
references and locate object references on the basis of these names.

A CORBA client application needs a reference to a naming context object in


order to request remote object references from the Naming Service. Thus, the
Tutorial1 application uses the ORB reference to find a naming context object:

org.omg.CosNaming.NamingContextExt nc =
org.omg.CosNaming.NamingContextExtHelper.narrow(
orb.resolve_initial_references("NameService"));

The resolve_initial_references method of the ORB is a standard CORBA


solution to overcome a bootstrap problem, that is, to find the Naming Service
that can be used to get references to other objects in the network. The resolved
initial reference needs to be narrowed to the NamingContextExt type.

3.3 RETRIEVING A REMOTE OBJECT REFERENCE


There are several ways to retrieve a remote object reference, three of which are
described here. Some of them are more recommendable than others although

8/28
the best suited object reference retrieval method may vary from application to
application. The different object reference retrieval and publishing methods are
discussed in more detail in the Nokia M2M Platform Software Developer’s
Guide.

3.3.1 Nokia Active Naming Context and M2MDevices


When your software has a reference to the Naming Service, you can query for
references to CORBA objects (Interoperable Object Reference – IOR) from that
Naming Service.

The Nokia M2M Platform includes a Nokia Active Naming Context (ANC)
implementation (see the Nokia M2M Platform Active Naming Context
Programming Guide for details) called M2MDevices. This implementation is
registered to the CORBA Naming Service with the name
’NokiaANC/M2MDevices’ during the Gateway start-up.

The M2MDevices implementation can be used by making a standard CORBA


Naming Service query as follows:

org.omg.CORBA.Object helloReference =
nc.resolve(
new NameComponent[] {
new NameComponent("NokiaANC", ""),
new NameComponent("M2MDevices", ""),
new NameComponent(
terminalID
+ ";HelloServant"
,"")});

The M2MDevices implementation constructs the object reference from the


parameters it receives. The syntax is

<terminal-id>[.bearer]; <alias>, where:

• <terminal-id> is the identifier for the target Nokia terminal or Nokia 12


module found from the user information database of the Gateway
(user_information.txt file if the reference implementation is used).
• [.bearer] identifies the used the bearer [sms.wap | sms.tcp | csd.wap |
csd.tcp | gprs.wap | gprs.tcp]. The bearer parameter is optional. If not given,
the M2MDevices implementation retrieves the default bearer of the
specified terminal ID from the bearer information database of the Gateway
(bearer_information.txt file if the reference implementation is used).
• <alias> is the alias name that the M2MDevices implementation uses to
retrieve the object key and type ID from the class information database of
the Gateway (class_information.txt file if the reference implementation is
used).

9/28
The port number is retrieved either from the class information database or
bearer information database depending on the addressing type of the bearer.

Note: The port number that the NokiaANC/M2MDevices inserts to the object
reference depends on the used bearer. TCP port numbering is used for sms.tcp,
csd.tcp, and gprs.tcp bearers, and the port number is fetched from the class
information database. Wireless Transport Protocol (WTP) port numbering is used
for sms.wap, csd.wap, and gprs.wap bearers, and the port number is fetched from
the bearer information database.

3.3.2 Nokia Active Naming Context and iorgen


The Nokia M2M Platform contains another implementation of the Nokia ANC
called iorgen. This implementation is registered to the CORBA Naming Service
with the name ’NokiaANC/iorgen’ during the Gateway start-up. The iorgen
implementation is similar to the M2MDevices implementation (see Chapter
3.3.1), but it has a different syntax.

Note: The iorgen implementation does not utilise the bearer information database
or the class information database. Therefore, all the parameters that the
M2MDevices implementation retrieves from these databases must be given
separately when using the iorgen implementation.

The iorgen implementation can be used as follows:

org.omg.CORBA.Object helloReference =
nc.resolve(
new NameComponent[] {
new NameComponent("NokiaANC", ""),
new NameComponent("iorgen", ""),
new NameComponent(
bearer
+ ";"
+ terminalID
+ ";"
+ port
+ ";ORB/OA/IDL:tutorial1/hello:1.0;"
+ tutorial1.helloHelper.id(),
"")});

The iorgen implementation constructs the object reference from the parameters
that it receives. The syntax is

<bearer>;<terminal-id>;<port>;<object-key>;<type-id> ,where:

• <bearer> identifies the used bearer [sms.wap | sms.tcp | csd.wap | csd.tcp |


gprs.wap | gprs.tcp].

10/28
• <terminal-id> is the identifier for the target Nokia terminal or Nokia 12
module found from the user information database of the Gateway
(user_information.txt file if the reference implementation is used).
• <port> identifies the port number where the object is located at the remote
end. If the selected bearer uses WTP port numbering (sms.wap, csd.wap
and gprs.wap bearers), the port number indicates the WTP port at the
remote end. If the selected bearer uses TCP port numbering (sms.tcp,
csd.tcp and gprs.tcp bearers), the port number indicates the TCP port at the
remote end.
• <object-key> identifies the object key of the remote object in American
Standard Code for Information Interchange (ASCII) mode. Object keys of
objects in devices compatible with the Nokia M2M Platform can be found
from the reference implementation of the class information database (the
class_information.txt file).
• <type-id> is the type ID of the target object interface. It can be requested
from the helper class of the interface via an id() method, for example
tutorial1.helloHelper.id(), as described in the above code example.

3.3.3 Mobile IOR as a response to a method call


If an IMlet or AM software has a method for object reference retrieval, it can be
used by the customer server application. This mechanism is used most often
when remote objects are created dynamically.

If, for example, an IMlet implements the following interface definition:

interface ObjectFactory {
Object createObject();
};

the customer server application can request for a reference to a new object
(provided that the customer server application already has a reference to the
object that implements the ObjectFactory interface) simply by executing the
following method call:

org.omg.Object o = factory.createObject();

3.4 NARROWING THE RETRIEVED OBJECT REFERENCE


After receiving the object reference to the remote object, the customer server
application must narrow (cast) the object to be of a proper type. The narrow
method is generated during the IDL compilation process for each object of the
interface definition.

11/28
In the case of the Tutorial1 application, the Hello object has its own helper
method. A CORBA object is narrowed to a Hello object with the following
command:

Hello helloInstance =
HelloHelper.narrow(helloReference);

3.5 EXECUTING THE REMOTE METHOD


After the previous steps the customer server application has a reference to a
remote object and it is ready to execute remote method calls to that object.

The Tutorial1 application executes the sayHello() method of the Hello object
in the remote Nokia terminal or Nokia 12 module:

String reply =
helloInstance.sayHello(“Greetings from the server side
application”);

The following takes place during the processing of the previous command:

1. A normal method call is executed to the sayHello() method in the stub


code that was generated during IDL compilation.

2. The stub of the sayHello() method constructs a General Inter-ORB


Protocol (GIOP) message from the method call it received. It then passes
that GIOP message to the ORB instance used by the Tutorial1 application.

3. The ORB establishes a connection to the ORB of the remote Nokia terminal
or Nokia 12 module with the help of the Gateway.

4. The ORB of the remote Nokia terminal or Nokia 12 module first receives the
GIOP message. It then finds an object (in this case Hello) that implements
the sayHello() method of the Tutorial1 interface definition.

5. The method in the remote Nokia terminal or Nokia 12 module that


implements the skeleton code of the sayHello() method, defined in the
interface definition, is executed.

At this point the Tutorial1 application has executed the remote method if the try-
block has not caught any exceptions.

12/28
4. CREATING A CORBA IMPLEMENTATION
This chapter describes the CORBA implementation part of the Tutorial1
customer server application, that is, how to make a servant.

Note: Although this chapter deals with the Tutorial1 application, similar actions
must be taken in all applications where CORBA implementations, compatible with
the Nokia M2M Platform, are made.

Implementation of the Tutorial1 customer server application creates a servant


object and makes it available for CORBA clients as described in Chapter 2.1.
The complete source code of the Tutorial1 application CORBA implementation
can be found from the Nokia M2M SDK.

To create a CORBA implementation, publish its reference, and set it running so


that it can be requested by CORBA clients, proceed as follows:

1. Initialize an ORB.

2. Create an implementation (a servant object).

3. Retrieve a reference to a Portable Object Adapter (POA).

4. Activate the created implementation with the retrieved POA.

5. Activate the POA manager.

6. Publish a servant object reference for the CORBA clients.

7. Set the ORB running and wait for incoming requests.

The above seven steps of the Tutorial1 application implementation’s source


code are described in more detail in the following chapters. There may be
different means to accomplish some of the steps, but this document focuses on
the implementation used with the Tutorial1 application.

For references on how to use other possible CORBA servant implementations,


compatible with the Nokia M2M Platform, see Chapter 8.

4.1 INITIALIZING AN OBJECT REQUEST BROKER


Like the CORBA client, the implementation also needs a reference to an ORB
instance. The ORB initialization process for the implementation is similar to the
process that is used with clients:

13/28
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(new String[0],
null);

4.2 CREATING AN IMPLEMENTATION


Creating a CORBA implementation means creating an object, that implements
the interface as defined in the interface definition file (see Chapter 2.1).

In the case of the Tutorial1 application, it means creating a class that


implements the sayHello() method. It has a string as an input parameter,
returns another string, and raises an EmptyGreetingsStringException if the
input parameter is an empty string. The implementation of the Tutorial1
interface definition does not require any other actions. The source code of the
servant object is located in the Nokia M2M SDK HelloServant.java file.

4.3 RETRIEVING A REFERENCE TO A PORTABLE OBJECT ADAPTER


Each CORBA implementation needs to be registered to an Object Adapter,
typically a POA, that is responsible for hosting servant objects. POA is a part of
the CORBA standard and it acts as a mediator between the ORB and the
servant object, dispatching requests and replying back and forth between a
servant object and its ORB. To activate a servant with a POA, a reference to
the POA must be retrieved.

Every ORB has at least one POA called the RootPOA. The Tutorial1 application
uses the RootPOA, and a reference to it is retrieved with the following
command:

org.omg.PortableServer.POA poa =
org.omg.PortableServer.POAHelper.narrow(
orb.resolve_initial_references("RootPOA"));

4.4 ACTIVATING THE IMPLEMENTATION WITH THE PORTABLE


OBJECT ADAPTER
Because the Tutorial1 application uses the RootPOA, it does not have to
explicitly activate the servant object with the POA. The servant object is
implicitly activated in the servant during object reference publishing (see
Chapter 4.6).

Tip: You can create your own POA if you want to define a different POA policy
(such as Lifespan policy or ID Assignment policy) than what is defined for the
RootPOA. Using a POA with different policies may have an effect on the source
code of the customer server application. For example, the RootPOA always uses
the Implicit Activation Policy, which means that a servant object is not explicitly
activated to a POA. Instead, it is implicitly activated during object reference
retrieval from the POA. If the POA that you use does not utilise the Implicit

14/28
Activation Policy, you need to activate the servant object explicitly with the
activate_object() or the activate_object_with_id() method.

4.5 ACTIVATING THE PORTABLE OBJECT ADAPTER MANAGER


Each POA has its own POAManager that is responsible for controlling the
processing state of all POAs associated with it.

By default, a newly created POAManager is in the ‘hold’ state meaning that all
calls to those servant objects that are associated with the newly created
POAManager via their POAs hang in queue. When a POAManager is activated,
the POAs associated with it start processing requests for their servant objects.

The POAManager is activated with the following command:

poa.the_POAManager().activate();

Tip: If it seems that the servant application does nothing and the client application
keeps waiting for a reply from the servant, it may be that the POAManager has
not been activated. In this case, activate the POAManager in your application.

4.6 PUBLISHING THE IMPLEMENTATION OBJECT REFERENCE


The object reference to the implementation must be published for the client
applications to call the methods of the CORBA implementation. Many
publishing options are available, but this document describes a typical case that
is also used in the Tutorial1 application, namely publishing a servant object
reference via the CORBA Naming Service.

The Tutorial1 application publishes the object reference of the servant object
(helloServant) by binding the reference to the Naming Service. This requires
two parameters: a name with which the object reference can be resolved from
the Naming Service and the object reference (IOR) that is returned as a reply to
the Naming Service request.

The object reference of the servant object is requested from the POA where the
servant object is registered. In the Tutorial1 application, the servant object has
not been registered with the POA at this point. However, since the Tutorial1
application uses the RootPOA and the RootPOA uses the Implicit Activation
Policy, the servant object is implicitly activated while requesting the object
reference from the POA. Therefore, the following command returns a reference
to the servant object and registers the servant object (helloServant) with the
RootPOA:

org.omg.CORBA.Object o = poa.servant_to_reference(helloServant);

15/28
After retrieving the object reference of the servant object, it must be narrowed
(cast) to a right type with the help of the class-specific helper that, in this case,
is the helloHelper class. After the narrowing operation, reference to the
servant object is ready to be bound to the Naming Service.

In the Tutorial1 application the helloServant object is registered to the


Naming Service with the name “Hello”:

helloServantReference =
tutorial1.helloHelper.narrow(o);

nc.rebind(nc.to_name("Hello"), helloServantReference);

4.7 RUNNING THE OBJECT REQUEST BROKER


After the previous steps have been completed, the orb.run() method is
called. This method blocks the ongoing execution thread and sets the ORB
waiting for incoming requests (until a shutdown method is called for the ORB
from some thread):

orb.run();

Note: It is not mandatory to call the orb.run() method, but in that case the
application should use some other means to keep the ORB thread running and
the servant object available for clients.

16/28
5. COMPILING AND RUNNING AN M2M APPLICATION

To compile the Tutorial1 application, the Java compiler needs to locate the
application source code and the stub and skeleton codes that were generated
from the interface definition.

The Tutorial1 application is deployed with the pre-compiled stub and skeleton
source codes that have been generated to the idl_generated directory. Thus,
the Tutorial1 application can be compiled by executing the following command
in the server directory of the Tutorial1 application:

javac -d classes -sourcepath idl_generated source/*.java

This command generates the Java byte code to the classes directory (that
directory must exist) from the Tutorial1 application’s source code. The
command uses the stub and skeleton codes that were previously generated to
the idl_generated directory.

Before running the Tutorial1 customer server application, you must start the
Nokia M2M Gateway Trial Version as described in the Nokia M2M Platform
Software Development Kit and Nokia M2M Gateway Trial Version Installation
Guide. Once it is running, you can run the application by executing the following
command in the server directory of the Tutoria1 application:

java –Dorg.omg.CORBA.ORBInitialPort=9999 -classpath classes


com.nokia.m2m.sdk.examples.tutorial1.Client

This command starts the CORBA client of the Tutorial1 application. The servant
is started with a similar command except that the Client class is replaced with
the Servant class.

The ORBInitialPort parameter is given to the ORB of the Java SDK to define
the port where the CORBA Naming Service is located. If some other ORB than
that of the Java SDK is used, the application must be told how to locate the
used ORB and Naming Service.

Note: The Tutorial1 application uses the default values for terminal ID, bearer,
and port as described in the Nokia M2M Platform Configuration Manual. If you
want to use other than the default values, you need to modify the source code
accordingly and recompile the application as instructed above.

17/28
6. ADVANCED CORBA PROGRAMMING
This chapter describes the Tutorial2 application that is also included in the
Nokia M2M SDK. In the Tutorial2 application, the CORBA implementation is in
the Java 2 Standard Edition (J2SE™) code and the CORBA client is in the Java
2 Micro Edition (J2ME™) code that conforms to the Information Module Profile
(IMP).

The application logic of the Tutorial2 application is similar to that of the Tutorial1
application: the client sends a greeting string to the servant and the servant
sends a reply string back. The difference between the Tutorial1 and Tutorial2
applications is that in the Tutorial2 application the J2SE code uses the CORBA
object factory technique to generate unique object references for the calling
clients.

6.1 CORBA OBJECT FACTORY


Instead of publishing a reference to a servant object through the CORBA
Naming Service (as in the Tutorial1 application), an application can dynamically
create and return a reference to the servant object. With this technique every
client can be given a unique object reference (referencing to the same servant
object but with a unique object reference – IOR). The gained benefit is that the
CORBA object factory technique allows the servant to know the identity of the
calling client. The CORBA object factory solution is beneficial in many M2M
applications since the M2M system architecture often has one customer server
application in the corporate intranet and several identical remote clients.

To enable meaningful processing of the data that the customer server


application receives from the remote clients, the customer server application
must be able to identify the remote application instance where the data comes
from. One option for creating a unique object ID for each remote client is to use
some type of application-specific remote end ID as the object ID. For example,
a customer sever application could assign each remote application an object ID
that is the same as the ID of the Nokia terminal or Nokia 12 module.

6.1.1 Tutorial2 interface definition


The interface definition of the Tutorial2 application defines two interfaces. The
Hello interface defines the actual application functionality and the Connection
interface is used to retrieve an object reference to the servant that implements
the Hello interface (the actual application where the greeting string handling
logic resides).

The core functionality of the CORBA object factory is thus in the Connection
interface. Implementation of the Connection interface is responsible for
generating unique object references to the Hello servant for each calling client.

18/28
The complete source code and the interface definition file for the Tutorial2
application can be found from the Nokia M2M SDK.

The interface used in the Tutorial2 application is defined in the tutorial2.idl


interface definition file as shown below:

module tutorial2{

interface Hello {

exception EmptyGreetingsStringException { };

string sayHello(in string greetings)


raises (EmptyGreetingsStringException);

void logout();

};

interface Connection {

Hello login(in string clientID);

};

};

6.1.2 Tutorial2 CORBA implementation


As defined in Chapter 6.1.1, there are two interface implementations in the
Tutorial2 application: one that implements the Hello interface and one that
implements the Connection interface. In the source code of the Tutorial2
application, these implementations can be found from the HelloImpl.java and
ConnectionImpl.java files, respectively.

The servant side also contains one additional class that has its source code in
the tutorial2.java file. This class is merely a launcher for the ConnectionImpl
servant.

The Connection interface implementation handles the following tasks:

• CORBA initialization
• POA creation
• Instantiation and reference publishing of the Hello interface implementation
• Shutting down CORBA services

The Hello interface implementation handles the application logic (accepting


greeting strings and replying to them). Also, when a client has finished

19/28
communicating with the servant, it must call a logout method of the Hello
interface implementation that deactivates the client-specific, unique CORBA
object referencing to the Hello servant.

6.1.2.1 Initialization
The Tutorial2 application is launched from the Tutorial2 class that instantiates
the ConnectionImpl class. The beginning of the ConnectionImpl code follows
the implementation of the Tutorial1 application: execution of ORB initialization,
POA reference retrieval, and POAManager activation for the RootPOA (see
Chapter 4).

The rest of the steps are done differently as described in the following chapters.

6.1.2.2 Creating a new Portable Object Adapter


The RootPOA cannot be used in the Tutorial2 application because it does not
have all of the policy settings that using a CORBA object factory requires from a
POA.

A new POA has to be created with the following policy settings:

• The ID Uniqueness policy is set to MULTIPLE_ID to allow multiple CORBA


objects (object references in Java) to refer to one servant object.
• The ID Assignment policy is set to USER_ID to allow the user (the
application) to assign the used object IDs for the generated object
references.
• The Servant Retention policy is set to NON_RETAIN to instruct the POA not
to keep track of what object refers to what servant.
• The Request Processing policy is set to USE_DEFAULT_SERVANT to
configure the POA to pass all invocations to the default servant.

With these policy settings, the new POA is configured so that it is suitable for
the CORBA object factory.

Note: The new POA needs not to be activated because it shares the same
POAManager with the RootPOA that was activated earlier.

The policy settings are set in the Java code as follows:

connectionsPOA = rootPOA.create_POA(
// Name for this POA.
"Connections-POA",
// POA manager; use the same POA manager as the root POA.
rootPOA.the_POAManager(),
// Policies:
new Policy[] {

20/28
rootPOA.create_id_uniqueness_policy(
IdUniquenessPolicyValue.MULTIPLE_ID),
rootPOA.create_id_assignment_policy(
IdAssignmentPolicyValue.USER_ID),
rootPOA.create_servant_retention_policy(
ServantRetentionPolicyValue.NON_RETAIN),
rootPOA.create_request_processing_policy(
RequestProcessingPolicyValue.USE_DEFAULT_SERVANT),
});

Tip: In the Tutorial2 application, the POA uses the USE_DEFAULT_SERVANT


Request Processing policy. It can be used in applications, such as the Tutorial2
application, where the servant does not have a great deal of state information.
However, if the servant has a great deal of state information, using the
USE_DEFAULT_SERVANT Request Processing policy can cause performance
problems because prior to each call to the servant, the POA must retrieve the
state information of the servant in question. In such cases it is recommended to
use Servant Managers. Using Servant Managers is beyond the scope of this
document. For more information on using them, please refer to the related
CORBA literature.

6.1.2.3 Creating a servant


In the Tutorial2 application, the ConnectionImpl class instantiates a
HelloImpl servant that incorporates the application logic. The Hello interface
implementation of the Tutorial2 application is no different from the servant of
the Tutorial1 application except for the servant deactivation routine. There is no
such routine in the Tutorial1 application servant because there is only one
object reference to the servant and both the servant and the CORBA object that
refer to it are destroyed when exiting the application.

With the Tutorial2 application, it is feasible to implement a servant deactivation


routine, for example, as a logout method. Each client should call the logout
method when they have finished communicating with the servant. That way
each client’s unique CORBA object reference (IOR) to the servant can be
deactivated. After that, the memory can be freed from the POA by the Java
garbage collector.

The logout method of the HelloImpl is as follows:

public void logout() {

// Get an object ID.


byte[] objectID = _object_id();

// Get the POA serving this servant.


POA poa = _poa();

// Ask the POA to deactivate this object.


try {

21/28
poa.deactivate_object(objectID);
} catch (org.omg.CORBA.UserException ignored) {
}

6.1.2.4 Setting the default servant for the Portable Object Adapter
Since the POA used in the Tutorial2 application uses the
USE_DEFAULT_SERVANT policy, the POA must be instructed of what is the
default servant. The default servant is defined with the set_servant() method.
All invocations that come to the POA used in the Tutorial2 application are
dispatched to the servant defined here:

connectionsPOA.set_servant(helloServant);

6.1.2.5 Binding to the CORBA Naming Service


The Connection servant is activated to the RootPOA. Because the RootPOA
uses the IMPLICIT_ACTIVATION policy, the Connection servant needs not be
explicitly activated. Instead, the activation takes place implicitly at the same
time with the object reference request from the RootPOA.

The Tutorial2 application binds the Connection servant to the CORBA Naming
Service. The binding is done as in the Tutorial1 application:

// Get a CORBA object reference to this instance.


org.omg.CORBA.Object ref = rootPOA.servant_to_reference(this);

// Bind the reference to the CORBA Naming Service.


nc.bind( nc.to_name(connectionName), ref);

6.1.2.6 Close method


The implementation of the Connection interface also contains a close()
method that is called from the Tutorial2 class during the shutdown procedure. It
cleans up redundant elements to free unused resources.

First, the reference to the Connection interface implementation is removed


from the CORBA Naming Service. Then, the ORB that is instantiated by the
ConnectionImpl class is shut down.

public void close() {

try { nc.unbind(nc.to_name(connectionName));
} catch (Exception ignore) { }

try { orb.shutdown(true);
} catch (Exception ignore) { }
}

22/28
6.1.2.7 Login method
The login() method of the Connection interface implementation is the core of
the object factory. It creates a unique object reference (IOR) that refers to the
HelloImpl servant (created earlier by the ConnectionImpl servant).

The object reference to be created obtains its object ID from the input
parameter of the login() method. In the Tutorial2 application, the client (IMlet
running in a Nokia 12 module) uses its terminal ID as the parameter and this is
why each calling client receives a different object reference.

public Hello login(String clientID) {

// Create an object ID using the clientID method.


byte[] oid = clientID.getBytes();

// Create a new CORBA object by asking


// the connectionsPOA to create an object-reference with
// the object ID we specify and the type ID of the
// IDL type Hello.

org.omg.CORBA.Object ref =
connectionsPOA.create_reference_with_id(oid,
HelloHelper.id());

// Narrow to the Connection type and return.


return HelloHelper.narrow(ref);
}

6.1.3 Tutorial2 CORBA client


The CORBA client in the Tutorial2 application is a J2ME application (IMlet)
running in a Nokia 12 module. It makes a login request to the Connection
servant and gets a reply that contains a unique object reference to the Hello
servant where the client then sends a greeting and receives a reply as in the
Tutorial1 application. For more information on how to program IMlets, see the
Nokia M2M Platform Nokia 12 GSM Module IMlet Programming Guide.

6.1.3.1 Initialization
The client application first creates an ORB instance and casts it to the type
com.nokia.m2m.orb.ORB. The casting is done to get access to an extra
method that the application uses later to create a named reference type
CORBA object reference. For more information on named reference and other
object referencing options available in the Nokia M2M Platform, see the Nokia
M2M Platform Software Developer’s Guide.

orb = ORB.init(new String[0], null);

com.nokia.m2m.orb.ORB nokiaorb = (com.nokia.m2m.orb.ORB) orb;

23/28
6.1.3.2 Retrieving a reference to the Connection interface implementation
The next step is to retrieve a reference to the servant that implements the
Connection interface. The reference is retrieved by creating a name
component array, passing that array (together with a Connection type ID) as
an argument to the createNamedReference() method of the nokiaorb, and
narrowing the object reference resulting from the createNamedReference()
method to be of the Connection type.

NameComponent[] nca =
new NameComponent[] {
new NameComponent("Tutorial2ConnectionServant", ""), };

org.omg.CORBA.Object namedRef =
nokiaorb.createNamedReference(nca, ConnectionHelper.id());

Connection connectionRef = ConnectionHelper.narrow(namedRef);

Note: When using the named reference mechanism, the reference retrieval does
not create any traffic over the air interface.

6.1.3.3 Retrieving a reference to the Hello interface implementation


Once the application has a reference to the Connection interface
implementation, it can call its login() method to get an object reference to the
Hello servant as a reply. Since the Tutorial2 interface definition requires that
the client supplies the Connection servant with a client ID string in the login()
method, that string must be created first.

In the Tutorial2 application, the incoming Challenge-Handshake Authentication


Protocol (CHAP) username of the Nokia 12 module is chosen as the client ID.
The incoming CHAP username maps to the remote username (terminal ID)
defined in the user information database of the Gateway.

When the Hello servant knows the identity of the calling client, it can use that
information for client-specific processing. The incoming CHAP username can
be queried from the Device object located in the Nokia 12 module ORB, but
before the application can do that, it needs a reference to the Device object.
The reference is retrieved using the corbaloc mechanism, and it is then
narrowed (cast) to the type Device:

Object devObj =
orb.string_to_object("corbaloc::127.0.0.1:19740/Device");

Device device = DeviceHelper.narrow(devObj);

The Device object has a getParam() method that can be used to query
Device object parameters described in the Nokia GSM Connectivity Terminal
and Nokia 12 GSM Module Properties Reference Guide.

24/28
The getParam() method must be given the name of the parameter to be
queried and a holder for the CORBA type any that holds the queried parameter
after the method call returns. The contents of the any type can be read from the
any holder using parameter-specific helpers.

In this case, the getParam() is queried for the


WAPParametersAuthentication parameter that contains, among other things,
the incoming CHAP username as a string.

AnyHolder anyHolder = new AnyHolder();


device.getParam("WAPParametersAuthentication", anyHolder);
String ID =
WAPParametersAuthenticationHelper.
extract(anyHolder.value).incomingCHAPUserName;

At this point the client application has an ID string it can use as a parameter for
the login() method of the Connection interface implementation:

Hello helloServerRef = connectionRef.login(ID);

6.1.3.4 Executing the remote method


Once the client application has the reference for the Hello servant, it can
execute the remote method just like in the Tutorial1 application.

String reply = helloServerRef.sayHello(inputString);

25/28
7. TROUBLESHOOTING
If the application cannot run successfully and receives a CORBA
COMM_FAILURE exception, it can use a convenience class called
GIOPMinorCodeParser (included in the Nokia M2M SDK) to print out the error
description.

You may find, for example, the following error notification in the command
prompt:
Nokia M2M Gateway - Authentication Error: The Device Information
Storage (DIS) does not have the user information for a terminal.

In this case the failure occurred because the authentication information was
missing from the user information database ( user_information.txt file if the
reference implementation is used).

If the application did not used the GIOPMinorCodeParser convenience class in


the above case, the following CORBA_COMM_FAILURE message would be
printed to the console:

org.omg.CORBA.COMM_FAILURE: vmcid: 0x4e4b1000 minor code: 769

The Nokia M2M Platform specific minor exception codes are described in the
Nokia M2M Platform GIOP Minor Exception Code Descriptions. If the
GIOPMinorCodeParser class is not used, you can check the exception code
descriptions from that document.

26/28
8. REFERENCES
Nokia M2M solution

http://forum.nokia.com/m2m - developer forum, M2M section

http://www.nokia.com/m2m - information about M2M on Nokia’s website

CORBA

http://www.omg.org - website of the organization that develops CORBA

http://www.omg.org/gettingstarted/corbafaq.htm - CORBA Frequently Asked


Questions

http://developer.java.sun.com/developer/technicalArticles/releases/corba/ - an
article about J2SE specific CORBA programming

http://developer.java.sun.com/developer/onlineTraining/corba/corba.html - short
course that teaches how to use CORBA as found in the Java 2 platform

27/28
APPENDIX A: GIOP MESSAGE FRAGMENTATION
This appendix explains how to configure the customer server application to
support fragmentation. For more information on how to configure the AM ORB
to support GIOP message fragmentation, please refer to the Nokia M2M
Platform Remote Application Programming Guide.

Note Configuring an ORB to support fragmentation is implementation-specific.


This appendix explains how the configuration is done using the Sun Java 1.4 SDK
ORB. If you are using some other ORB, please refer to the documentation of that
ORB for more information on how it is configured to use GIOP message
fragmentation.

GIOP message fragmentation in the Nokia M2M Platform


If you use a wireless bearer that utilizes the Wireless Application Protocol
(WAP) as its transport protocol [sms.wap | sms.tcp | csd.wap | gprs.wap], there
is a size limitation for a single GIOP message. If you need to use long GIOP
messages (over 1500 bytes) with such bearers, you need to configure your
ORB to support GIOP message fragmentation

If you use a wireless bearer that utilises TCP as its transport protocol [csd.tcp |
gprs.tcp], the transport protocol takes care of fragmenting long messages and
there is no need for additional configurations.

Configuring the ORB to support GIOP message fragmentation


The Java 1.4 SDK ORB is configured to support fragmentation by giving the
Java Virtual Machine (VM) an extra system property. You can, for example, edit
the batch file that starts the application. For example, if you want the CORBA
client of the customer server application in the Tutorial1 application to support
512-byte-fragments, you need to add the following string to the batch file that
starts the application (client.bat):

-Dcom.sun.CORBA.giop.ORBFragmentSize=512

Thus the client.bat file would look as follows:


java -Dcom.sun.CORBA.giop.ORBFragmentSize=512 –
Dorg.omg.CORBA.ORBInitialPort=9999 -classpath classes
com.nokia.m2m.sdk.examples.tutorial1.Client
%1 %2 %3 %4 %5 %6 %7 %8

28/28

You might also like