Rus Eng

 

This project won Best On Technology Award at SIMagine 2003

Java Card Applets Generation Tool

Project description

Application for automated generation card applets and J2EE based proxy server. This system will allow to access web services without hard coding. The application automatically generates a card applet using just a web service definition (WSDL) file. To get web service applets will communicate with our J2EE based proxy server via SMS based custom protocol. The proxy will translate applet's requests for web services into SOAP and redirect them to the server that provides the web services in question. The SOAP responds being translated into SMS get back to the card applet. So this system will automate the process of creating and adding new elements (applications) to the SIM card menu.

Marketing appeal

Due to ever increasing Java usage it the web services area on the market, we feel strong that our approach that allows automating software development for accessing web services using cellular phones will make a difference. It may decrease development cost and time. This product could be, for example, a good add-on to Schlumberger Sema IDE.

Market applications

This system could be used not only by Telcos for fast and cheap new services development and delivery to their clients but clients themselves.

Source data and problem domain

As a matter of fact, Web Services have become a standard for businesses to make the information about the services they provide available for their current and potential clients. Web Services have an open standard in the ground, which guarantees true interoperability. For example, a Java application can access the information of an application that runs on Microsoft .NET platform.
From the point of view of a user that retrieves information about the Web Services available, each service is an XML file in WSDL (Web Service Definition Language) format. The file describes how to deal with the service, what to expect as parameters and results.

The client application generates an XML file in SOAP (Simple Object Access Protocol) format and passes it to a component with Web Services support functionality. Most often, SOAP communications between the client and the server occur via HTTP. The client sends a SOAP requests and the server, provided the requests is valid and corresponds to one of the services available, returns a SOAP respond, that is an XML file in the SOAP format.

The interface to Web Services functionality is transparent to the user.

Now about what our project is concerned with. Even the latest and most advanced Java Cards have very limited resources, which makes it impossible to include client applications into the card applet to deal with XML. The application developed within our project is consent with the Java Card development mainstream and the application on the host computer has advanced functionality to overcome above-mentioned limitations.

The host application, using a WSDL file as incoming parameter, can generate a Java Card applet in form a source file (.java file) that includes all essential logic to generate a SMS request sent to OTA application that acts as a proxy-server. This OTA application is a part of our project and has the following functionality:

  • Receives incoming SMS from the Java Card applet
  • Parses these SMS, generates a corresponding SOAP XML, and passes it to a Web service
  • Receives a SOAP respond from the Web service, parses it, generates a corresponding SMS, and sends it to the card applet that initiated the request.

This is the way that our application makes it easier and more efficient to personalize SIM-cards. New services easily become available for cellular phone users and exactly the way they were intended by businesses, that is in form of Web Services. This solution eliminates duality in Web Services design: one for non-wireless applications and the other for wireless ones.

Web Services support ensures interoperability, so the side receiving request does not have to be a Java application.

When it comes to programming the Java Card, the generator eliminates the necessity to program SIM Toolkit API calls. This could be potentially beneficial for Telcos because card personalization could be done with no involvement of programmers.

The generator is a Java application that receives a WSDL file as command line parameter and outputs applet source code on the screen (the standard output device). The output, of course, can be redirected into an arbitrary file. This solution has been chosen to make it as easier as possible to integrate with existing SIM Toolkit IDEs, for example, Schlumberger's Views). The generator comes with no GUI, which was done on purpose. GUI has to be used from the IDE the generator will be included into.

The future uses of a generator of this kind we see as a part (extension, plug-in, add-on) of SIM Toolkit applications development tools.

Developed components

The Java package (.jar file) includes the following components:
· XML parser to parse WSDL files and SIM Toolkit applet generation component
· Support classes for parsing WSDL and generating SIM Toolkit applets
· OTA application that receives SMS, containing incoming parameters from the applet; translates them into SOAP requests; then receives SOAP responds as results of those requests; and then sends SMS to the original applet.
· Helper class for all SOAP related tasks.

The package uses Java classes from Java XML Pack from http://java.sun.com (available for FREE). There have been used two packages: JAXP for parsing XML files and JAXM for dealing with SOAP.

Description of the package

  • Source code (.java files) and byte code ( .class files)
  • jar file for the package ru.inetique.simsoap
  • Test WSDL file from www.xmethods.net
  • bat file to run the generator
  • Java Card applet that has been generated for the test WSDL file
  • This document
  • PowerPoint slides

Description of the files included into the package:

WSDL2Applet.java is the main class. The generator gets running by the following command (see run.bat):

java -classpath %CLASSPATH%;simsoap.jar ru.inetique.simsoap.WSDL2Applet your_WDSL_file

If you want to redirect the output into a file, you should modify the command like this:

java -classpath %CLASSPATH%;simsoap.jar ru.inetique.simsoap.WSDL2Applet wsdl.txt > TemperatureService.java

Entering that particular command generated TemperatureService.java file, which is a Java Card applet and used as a sample file.

SoapOta.java is the OTA application.

WSDLParser.java generates the code.

SAXParserWrapper.java parses the WSDL file.

SOAPBean.java sends/receives SOAP messages. SoapOta uses this class for communicating with the Web Service.

The other classes are helper objects that store WSDL description elements such as ports, messages, links, and etc. In other words, SAXParserWrapper implements Java mapping for WSDL by translating XML description into a set of Java objects.

Note: the generator and OTA application use JAXM and JAXP package, which is why they have to be available via CLASSPATH.

 

Sample applet

A WSDL file from http://www.xmethods.net has been used to generate the sample applet.The file describes the Web-service that provides with temperature forecast by zip-code:

<?xml version="1.0"?>
<definitions name = "TemperatureService" targetNamespace
    = "http://www.mycompany.com/tmodels/Temperature.wsdl"
    xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
    xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns="http://schemas.xmlsoap.org/wsdl/">

  <message name = "getTempRequest">
    <part name = "zipcode" type = "xsd:string"/>
  </message>

  <message name = "getTempResponse">
    <part name = "return" type = "xsd:float"/>
  </message>

  <portType name = "TemperaturePortType">
    <operation name = "getTemp">
      <input message = "getTempRequest" />
      <output message = "getTempResponse" />
    </operation>
  </portType>

  <binding name = "TemperatureBinding" type = "TemperaturePortType">
    <soap:binding style = "rpc" transport =
        http://schemas.xmlsoap.org/soap/http"/>

    <operation name = "getTemp">
      <soap:operation soapAction=
          "http://www.mycompany.com/Temperature/#getTemp"/>
      <input>
        <soap:body use = "encoded" namespace =
            "http://www.mycompany.com/Temperature/"
            encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/"/>
      </input>

      <output><soap:body use =
          "encoded" namespace = "http://www.mycompany.com/Temperature/"
          encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/"/>
      </output>
    </operation>
  </binding>

  <service name="TemperatureService">
    <documentation>The Temperature service provides temperature of city
                   by the zipcode
    </documentation>

    <port name="TemperaturePortType" binding="TemperatureBinding">
      <soap:address location=
        "http://www.mycompany.com/soap/servlet/rpcrouter"/>
    </port>
  </service>

</definitions>


The generator builds the following applet:

/**
 *
 * Created by: SIM Toolkit Applet Generator
 * (c) http://www.inetique.ru  info@inetique.ru ver. 1.0
 *
 * WSDL file: wsdl3.txt
 * Service: TemperatureService
 *
*/

package test;

import javacard.framework.*;
import sim.toolkit.*;
public class TemperatureService extends Applet implements
                         ToolkitInterface, ToolkitConstants {

    private ToolkitRegistry reg;

    private ProactiveResponseHandler prh;

    private static final byte[] MENU_ENTRY={(byte)'T', (byte)'e',
         (byte)'m', (byte)'p', (byte)'e', (byte)'r', (byte)'a',
         (byte)'t', (byte)'u', (byte)'r', (byte)'e', (byte)'S',
         (byte)'e', (byte)'r', (byte)'v', (byte)'i', (byte)'c',
         (byte)'e'};

    private static final byte[] soapAction={(byte)'h', (byte)'t',
         (byte)'t', (byte)'p', (byte)':', (byte)'/', (byte)'/',
         (byte)'w', (byte)'w', (byte)'w', (byte)'.', (byte)'m',
         (byte)'y', (byte)'c', (byte)'o', (byte)'m', (byte)'p',
         (byte)'a', (byte)'n', (byte)'y', (byte)'.', (byte)'c',
         (byte)'o', (byte)'m', (byte)'/', (byte)'T', (byte)'e',
         (byte)'m', (byte)'p', (byte)'e', (byte)'r', (byte)'a',
         (byte)'t', (byte)'u', (byte)'r', (byte)'e', (byte)'/',
         (byte)'#', (byte)'g', (byte)'e', (byte)'t', (byte)'T',
         (byte)'e', (byte)'m', (byte)'p'};

    private static final byte[] operationName={(byte)'g', (byte)'e',
         (byte)'t', (byte)'T', (byte)'e', (byte)'m', (byte)'p'};

    private static final byte[] location={(byte)'h', (byte)'t',
         (byte)'t', (byte)'p', (byte)':', (byte)'/', (byte)'/',
         (byte)'w', (byte)'w', (byte)'w', (byte)'.', (byte)'m',
         (byte)'y', (byte)'c', (byte)'o', (byte)'m', (byte)'p',
         (byte)'a', (byte)'n', (byte)'y', (byte)'.', (byte)'c',
         (byte)'o', (byte)'m', (byte)'/', (byte)'s', (byte)'o',
         (byte)'a', (byte)'p', (byte)'/', (byte)'s', (byte)'e',
         (byte)'r', (byte)'v', (byte)'l', (byte)'e', (byte)'t',
         (byte)'/', (byte)'r', (byte)'p', (byte)'c', (byte)'r',
         (byte)'o', (byte)'u', (byte)'t', (byte)'e', (byte)'r'};

    // address to send SMS
    private static final byte[] OTA_ADDRESS =
            {(byte)0x0B, (byte)0x91, (byte)0x33, (byte)0x86,
            (byte)0x05, (byte)0x00,(byte)0x81, (byte)0xF0};

    private static final byte[] TAR =
            {(byte)0x31,(byte)0x32,(byte)0x33};

    private static final byte FIRST_BYTE =
              (byte)0x41;   // TP-MTI + TP-RD + TP-VPF
                            // + TP-RP + TP-UDHI + TP-SRR

    private static final byte TP_MR = (byte)0x01;    // TP-Message-Reference

    private static final byte TP_PID = (byte)0x00;   // TP-Protocol-Identifier

    private static final byte TP_DCS = (byte)0xF6;   // TP-Data-Coding-Scheme

    private static final byte TP_VP = (byte)0x01;    // TP-Validity-Period

    private static final byte PROFILE_GET_INPUT = (byte)18;

    private static final byte PROFILE_SEND_SMS  = (byte)25;

    private static byte [] zipcodeName =
          {(byte)'z',(byte)'i',(byte)'p',(byte)'c',(byte)'o',
          (byte)'d',(byte)'e'};

    private static byte [] zipcodeType =
          {(byte)'x',(byte)'s',(byte)'d',(byte)':',(byte)'s',(byte)'t',
          (byte)'r',(byte)'i',(byte)'n',(byte)'g'};

    private static byte [] zipcode;

    private short zipcodeLength;

    private short tpudLengthOffset;

    private static byte [] userData;

    private short userDataLength;

    public TemperatureService() {
        // Register to the SIM Toolkit Framework
        reg = ToolkitRegistry.getEntry();
        // Define the menu entry
        reg.initMenuEntry(MENU_ENTRY, (short)0, (short)MENU_ENTRY.length,         PRO_CMD_DISPLAY_TEXT, false, (byte)0, (short)0);
        reg.setEvent(EVENT_FORMATTED_SMS_PP_ENV);
        zipcode = new byte[20];
        userData = new byte[150];
    }

    // install method
    public static void install(byte[] buffer,short offset, byte length)
                                                      throws ISOException {
        TemperatureService myService = new TemperatureService();
        myService.register();
    }

    // process method
    public void process(APDU apdu) throws ISOException {
    // add your commands here
}

    // process toolkit method
    public void processToolkit( byte event) throws ToolkitException {

        ProactiveHandler ph = ProactiveHandler.getTheHandler();
        short i;

        switch (event) {
            case EVENT_MENU_SELECTION:
                if (MEProfile.check(PROFILE_SEND_SMS) &&
                                    MEProfile.check(PROFILE_GET_INPUT)) {
                    zipcodeLength =
                                 getInput(zipcodeName, zipcode, (byte)1,
                                 (byte)20, (byte)1);
                    byte[] tpduSubmit = new byte [120];
                    short tpduSubmitLength  = (short)(28 + OTA_ADDRESS.length +
                                 location.length + soapAction.length +
                                 operationName.length + zipcodeLength);
                    tpduSubmit [0] = FIRST_BYTE;
                    tpduSubmit [1] = TP_MR;

                    for (i = 0; i< OTA_ADDRESS.length; i++) {
                        tpduSubmit [(short)(i+2)] = OTA_ADDRESS [i];
                    }

                    tpduSubmit [(short)(OTA_ADDRESS.length + 2)] = TP_PID;
                    tpduSubmit [(short)(OTA_ADDRESS.length + 3)] = TP_DCS;
                    tpduSubmit [(short)(OTA_ADDRESS.length + 4)] =
                            (byte)(tpduSubmitLength - (5 + OTA_ADDRESS.length));
                    tpduSubmit [(short)(OTA_ADDRESS.length + 5)] = (byte)0x02;
                    tpduSubmit [(short)(OTA_ADDRESS.length + 6)] = (byte)0x70;
                    tpduSubmit [(short)(OTA_ADDRESS.length + 7)] = (byte)0x00;
                    tpduSubmit [(short)(OTA_ADDRESS.length + 8)] = (byte)0x00;
                    tpduSubmit [(short)(OTA_ADDRESS.length + 9)] =
                            (byte)(tpduSubmitLength - (10 + OTA_ADDRESS.length));
                    tpduSubmit [(short)(OTA_ADDRESS.length + 10)] = (byte)0x0D;

                    for (i = 0; i< 4; i++) {
                        tpduSubmit [(short)(OTA_ADDRESS.length + 11 + i)] =
                                   (byte)0x00;
                    }

                    for (i = 0; i< 3; i++) {
                        tpduSubmit [(short)(OTA_ADDRESS.length + 15 + i)] =
                                                           TAR [i];
                    }

                    for (i = 0; i< 4; i++) {
                        tpduSubmit [(short)(OTA_ADDRESS.length + 18 + i)] =
                                                          (byte)0x00;
                    }

                    tpduSubmit [(short)(OTA_ADDRESS.length + 22)] = (byte)0x01;
                    tpduSubmit [(short)(OTA_ADDRESS.length + 23)] = (byte)0x00;

                    // we have to send: location, soapAction,
                    // operation name and parameters (name, type, value)
                    tpduSubmit [(short)(OTA_ADDRESS.length + 24)] =
                                                (byte)(location.length);
                    for (i = 0 ; i < location.length ; i++) {
                        tpduSubmit [(short)(OTA_ADDRESS.length + 25 + i)] =
                                                location [i];
                    }

                    tpduSubmit [(short)(OTA_ADDRESS.length + 25 +
                             location.length)] = (byte)(soapAction.length);
                    for (i = 0 ; i < soapAction.length ; i++) {
                        tpduSubmit [(short)(OTA_ADDRESS.length + 26 +
                                          location.length + i)] = soapAction [i];
                    }

                   tpduSubmit [(short)(OTA_ADDRESS.length +
                            26 + location.length + soapAction.length)] =
                                                  (byte)(operationName.length);
                    for (i = 0 ; i < operationName.length ; i++) {
                        tpduSubmit [(short)(OTA_ADDRESS.length +
                              27 + location.length + soapAction.length + i)] =
                                                            operationName [i];
                    }

                    short delta=(short)(OTA_ADDRESS.length +
                          27 + location.length + soapAction.length +
                                                            operationName.length);

                    // submit parameters
                    // parameter's name
                    tpduSubmit [delta]=(byte)zipcodeName.length;
                    delta++;
                    for (i = 0 ; i < zipcodeName.length ; i++) {
                        tpduSubmit [delta] = zipcodeName [i];
                        delta++;
                    }

                    // parameter's type
                    tpduSubmit [delta]=(byte)zipcodeType.length;
                    delta++;
                    for (i = 0 ; i < zipcodeType.length ; i++) {
                        tpduSubmit [delta] = zipcodeType [i];
                        delta++;
                    }

                    // parameter's value
                    tpduSubmit [delta]= (byte)zipcodeLength;
                    delta++;
                    for (i = 0 ; i < zipcodeLength ; i++) {
                        tpduSubmit [delta] = zipcode [i];
                        delta++;
                    }

                    ph.init(PRO_CMD_SEND_SHORT_MESSAGE, (byte)0, DEV_ID_NETWORK);
                    ph.appendTLV(TAG_SMS_TPDU, tpduSubmit, (short)0,
                                        (short)tpduSubmitLength);
                    ph.send();
                }
                break;
            case EVENT_FORMATTED_SMS_PP_ENV:
                EnvelopeHandler eh = EnvelopeHandler.getTheHandler();
                eh.findTLV(TAG_SMS_TPDU, (byte)1);
                tpudLengthOffset = eh.getTPUDLOffset();
                userDataLength = (short)(eh.getValueByte(tpudLengthOffset) - 19);

                for (i=0; i<userDataLength; i++) {
                    userData [i] =
                             eh.getValueByte((short)(tpudLengthOffset + i + 20));
                }

                ph.init(PRO_CMD_DISPLAY_TEXT, (byte)0x81, DEV_ID_DISPLAY);
                ph.appendTLV(TAG_TEXT_STRING,
                      (byte)0x04, userData, (short)0,(short)userDataLength);
                ph.send();
                break;
            default:
                break;
        }
    }

    private short getInput(byte name[], byte nameGiven[], short minResponse,
                                           short maxResponse, byte qualifier) {

        ProactiveHandler ph = ProactiveHandler.getTheHandler();
        ph.initGetInput(qualifier, DCS_8_BIT_DATA,
                name, (short)0, (short)name.length, minResponse, maxResponse);
        ph.send();
        ProactiveResponseHandler prh =
        ProactiveResponseHandler.getTheHandler();
        prh.findTLV(TAG_TEXT_STRING, (byte)1);
        short nameGivenLength = prh.copyTextString(nameGiven, (short)0);
        return(nameGivenLength);
    }
}


Applet requests a zip code from the user and passes this information alongside with web-services description to the OTA application. The address of the application is stored in the array OTA_ADDRESS.

Further development

This is what could be added later:

1. Using standard mapping for WSDL when it is included in Java (now it is JSR 110).
2. Paging for long messages, that is splitting long messages into several parts for the applet and SoapOta.
3. Better type support.
4. Data processing, according to the business rules, before sending back to the applet.
5. A demo Web Service could be done by using XML Pack too. Therefore the whole demo project could be done by using Sun software only. Also UDDI accessing facilities could be added to the project (that is, the process of getting WSDL files to process could be automated). Because these facilities do not interfere with the Java Card application itself, they have not been included into our project.


For further information please do not hesitate to contact us at: info@inetique.ru

Rambler's Top100