J2ME - HelloWorld Application

Recently I have been experimenting J2ME with my Sony Ericsson w710i. The simplicity of J2ME application is amazing.

Let’s create a J2ME project first. Hope you have already installed the Sun Java Wirless Toolkit for CLDC. Launch the CLDC KToolbar application. Select New Project. Give HelloWorld as Project Name and MIDlet Class name. It will show the Settings screen, go to the Required section and set the MicroEdition-Configuration and MicroEdition-Profile as per your phone. Select OK.

The KToolBar would have generated your application folder structure inside the apps folder of your installation, if it is not there check out in the Documents and Settings folder, under your <login> folder it would have created the j2mewtk folder and stored you application there. You have to put all you sources in the <app_name>\src directory.

Let’s create the main application class file. Create a text file in the name of HelloWorld.java in the src folder. It is really simple, you just need to have a class that extends the MIDlet class, now you have to implement the three basic function startApp, destroyApp, pauseApp. As the name suggests these are called when you Start, Destroy or Pause your application.

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class HelloWorld extends MIDlet
{
  private Display display;

  protected void startApp()
  {
    display = Display.getDisplay(this);
  }

  protected void destroyApp(boolean unconditional)
  {
    notifyDestroyed();
  }

  protected void pauseApp()
  {
  }
}
The function startApp() is called when you launch your application, the destroyApp() function is called when you close is application, notifyDestroyed() is called to notify the system that the application is closed. The pauseApp() function is called when the application is pause by System due to a interruption like incoming call or sms.

The Display class is the highest object in the application, using display class you can show a Form in the screen.

The basic screen component in J2ME is a Form. A Form can show UI Components, a Form can be shown / hide. Let’s add a Form to the application.

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class MyFirstApp extends MIDlet
{
  private Display display;
  private Form mForm;

  protected void startApp()
  {
    display = Display.getDisplay(this);

    mForm = new Form("Sample Application");
    mForm.append("Hello World");
    display.setCurrent(mForm);
  }

  protected void destroyApp(boolean unconditional)
  {
    notifyDestroyed();
  }

  protected void pauseApp()
  {
  }
}
That’s it. Now we have added a Form with a title “Sample Application” and text “Hello World”. The form will be displayed when the display.setCurrent(mForm); is called.

Now you can Build the application and Run the application in the simulator. To see your app in the phone select Project->Package->Create Package, it will create the jad and jar file in the <app_name>\bin folder. Download the jar file to your phone via cable or Bluetooth and select the file in the phone. Follow the steps given in your phone to install and run the application.

BREW Extensions Demystified - Part IV

Please read this post for context before moving on.

We are almost there, now we need to create the supporting file mcbxml.bid and mcbxml.mif.

Creation of mcbxml.bid

#ifndef IMCBXML_BID
#define IMCBXML_BID
  #define AEECLSID_MCBXML 0x3434CD1D
#endif //IMCBXML_BID

Creation of mcbxml.mif
Launch the mif editor, go to the Extensions tab. In the Exported Classes section add the Class ID of the MCBXML i.e. 0x3434CD1D.

Congratulations, You have successfully converted the McbXML to an BREW Extension. The complete project can be downloaded here.

Now that you have successfully created your extension you might as well want to use it. To use the McbXML extension in a applicaion, include the IMcbXML.h in the applet's source file.

To create the extension, declare the necessary varibles
IMcbXML *pIMcbXML;
McbXMLElement *pRoot = NULL;
McbXMLElement *pElement = NULL;
McbXMLResults pResults;
ISHELL_CreateInstance(pIShell, AEECLSID_MCBXML,(void**)&pIMcbXML);
Once you have successfully instantiated the extension, you can call the API's
pRoot = IMCBXML_ParseXML(pIMcbXML, szXMLString,amp;pResults);
pElement = IMCBXML_FindElement(pIMcbXML, pMe->pXMLRoot,
"xml/soapenv:Envelope/soapenv:Body/Response");
IMCBXML_DeleteRoot(pIMcbXML, pRoot);
You can now extend the functionalities of the extension by adding more functions like McbCreateXMLString to the IMCBXML interface and providing the wrapper function just like IMCBXML_ParseXML function.

BREW Extensions Demystified - Part III

Please read this post for context before moving on.

Creation of IMcbXML.c
The IMcbXML.c is the main source file for our extension, it is equivalent to AEEAppGen.c and AEEModGen.c in case of BREW Applets. This file implements instantiation of the extension, setting up of VTBL and reference counting.
We need to create a class structure to hold our instance specific information such as our reference count, shell and module pointer.

typedef struct McbXML{
  DECLARE_VTBL(IMcbXML)
  uint32 m_nRefs;
  IShell *m_pIShell;
  IModule *m_pIModule;
};
Lets create the entry point for our extension, the all important AEEClsCreateInstance function.
int AEEClsCreateInstance(AEECLSID ClsId,IShell * pIShell,IModule * po, void ** ppObj)
{
  *ppObj = NULL;
  if( ClsId == AEECLSID_MCBXML )
  {
    if( McbXML_New(sizeof(McbXML_t), pIShell, po, (IModule **)ppObj) == SUCCESS )
      return AEE_SUCCESS;
  }
  return EFAILED;
}
The AEEClsCreateInstance is the entry point for the extension.
The McbXML_New is the constructor function for our extension. It allocates the memory for the class structure and VTBL, sets up the VTBL with the function pointers and stores the IShell and IModule pointers.
int McbXML_New(int16 nSize, IShell *pIShell, IModule* pIModule, IModule ** ppMod)
{
  McbXML_t *pMe = NULL;
  VTBL(IMcbXML) * modFuncs;

  if( !ppMod !pIShell !pIModule )
    return EFAILED;

  *ppMod = NULL;
  // Allocate memory for the IMcbXML object
  if( nSize < sizeof(McbXML_t) )
    nSize += sizeof(McbXML_t);

  if( (pMe = (McbXML_t*)MALLOC(nSize + sizeof(IMcbXMLVtbl))) == NULL )
    return ENOMEMORY;

  // Allocate the vtbl and assign each function pointer to the correct
  // function address
  modFuncs = (IMcbXMLVtbl *)((byte *)pMe + nSize);

  modFuncs->AddRef = McbXML_AddRef;
  modFuncs->Release = McbXML_Release;
  modFuncs->ParseXML = McbXML_ParseXML;
  modFuncs->FindElement= McbXML_FindElement;
  modFuncs->DeleteRoot = McbXML_DeleteRoot;

  //initialize the vtable
  INIT_VTBL(pMe, IModule, *modFuncs);

  //We've got one reference since this class is allocated
  pMe->m_nRefs = 1;

  // initialize our internal member variables
  pMe->m_pIShell = pIShell;
  pMe->m_pIModule = pIModule;

  //Add References to the interfaces we're using
  ISHELL_AddRef(pIShell);
  IMODULE_AddRef(pIModule);
  *ppMod = (IModule*)pMe;
  return AEE_SUCCESS;
}
Now, to manage our references we need to create the AddRef and Release functions.
static uint32 McbXML_AddRef(IMcbXML * po)
{
  return (++((McbXML_t *)po)->m_nRefs);
}

static uint32 McbXML_Release(IMcbXML * po)
{
  McbXML_t *pMe = (McbXML_t *)po;
  //Decrease the number of references. If we still
  //have some references to this object, return
  //and do not free resources
  if(-pMe->m_nRefs != 0)
    return pMe->m_nRefs;

  // Release interfaces
  ISHELL_Release(pMe->m_pIShell);
  IMODULE_Release(pMe->m_pIModule);

  //Free the object
  FREE_VTBL(pMe, IModule);
  FREE(pMe);
  return 0;
}
As you can see the AddRef function increments the m_nRefs variable, the release function will Free up the memory when the reference count reaches zero. This reference counting mechanism prevents the release of an extension when it is still used by someone.

Now, we need to create the wrapper function to call the actuan McbXML API's.
static McbXMLElement* McbXML_ParseXML(IMcbXML *po, LPCTSTR lpszXML, McbXMLResults *pResults)
{
  return McbParseXML(lpszXML, pResults);
}

static McbXMLElement* McbXML_FindElement(IMcbXML *po, McbXMLElement *pHead, LPCTSTR lpszName)
{
  return McbFindElement(pHead, lpszName);
}

static void McbXML_DeleteRoot(IMcbXML *po, McbXMLElement * pElement)
{
  McbDeleteRoot(pElement);
}
In the next post we will create the supporting BID and MIF file and see how to use our extension.

BREW Extensions Demystified - Part II

Please see this post for the context before moving on.

The following files IMcbXML.c and IMcbXML.h needs to be created to convert the McbXML into a BREW Interface.

Creation of IMcbXML.h
The IMcbXML.h is the interface file for our extension, it is equivalent to AEEMenu.h or AEEText.h. To use the McbXML in a applet this header file must be included in the applet's source file.
The most important component of an extenstion is the VTBL (vector table or virtual table). The VTBL is a structure that stores a set of function pointers.
Lets create the VTBL structure for our extension.

typedef struct _IMcbXML IMcbXML;
QINTERFACE(IMcbXML)
{
  INHERIT_IBase(IMcbXML);
};
If you expand the macros, it will become

typedef struct _IMcbXML IMcbXML;
struct _IMcbXML {
  struct IMcbXMLVtbl *pvt;
};
typedef struct IMcbXMLVtbl IMcbXMLVtbl;
struct IMcbXMLVtbl
{
  uint32 (*AddRef) (IMcbXML*);
  uint32 (*Release) (IMcbXML*);
};
The structure IMcbXMLVtbl is our VTVL structure, the _IMcbXML is our interface class structure. The AddRef and Release function pointers are a must to any interface, they are used for reference counting and to decide when to unload the extension from the memory. Let's add the XML Parsing functionality to the extension, for now we will add 2 API which are supported by McbXML.

typedef struct _IMcbXML IMcbXML;
QINTERFACE(IMcbXML)
{
  INHERIT_IBase(IMcbXML);
  McbXMLElement* (*ParseXML)(IMcbXML *po, LPCTSTR lpszXML, McbXMLResults *pResults);
  McbXMLElement* (*FindElement)(IMcbXML *po, McbXMLElement *pHead, LPCTSTR lpszName);
  void (*DeleteRoot)(IMcbXML *po, McbXMLElement * pElement);
};
Finally, now we need to create macros to the function pointers of the interface VTBL.

#define IMCBXML_AddRef(p) GET_PVTBL(p,IMcbXML)->AddRef(p)
#define IMCBXML_Release(p) GET_PVTBL(p,IMcbXML)->Release(p)
#define IMCBXML_ParseXML(p, px, pr) GET_PVTBL(p,IMcbXML)->ParseXML(p, px, pr)
#define IMCBXML_FindElement(p, ph, pp) GET_PVTBL(p,IMcbXML)->FindElement(p, ph, pp)
#define IMCBXML_DeleteRoot(p, pe) GET_PVTBL(p,IMcbXML)->DeleteRoot(p, pe)
In the next post will we will continue creating the IMcbXML.c file.

BREW Extensions Demystified - Part I

The BREW extensions are nothing but custom BREW interfaces developed for a specific purpose. Every BREW extension will have its own folder in the brew directory with its mod, mif, sig and bar files.

Difference between Applets and Extensions
The basic difference BREW applets and extensions are

1. Applets are stand-alone BREW applications, whereas extensions are used by one or more applets for a specific functionality.
2. Applets must provide the IApplet interface to the BREW for reference counting and handling of events. Extensions can have its own interface.
3. Applets can be launched from BREW App Manager or ISHELL_StartApplet() or equivalent API's. Extensions are instantiated with ISHELL_CreateInstance().

Note: An extensions privileges are same as the privileges of the applet in which the extension in instantiated. For example if you are using IFile API's in your extenstion, the applet which will be using your extension should have the File Persmisson.

Now that you have the basic understanding of what are applets and extensions, In the following posts we will convert the McbXML by Martyn Brown as a IMCBXML BREW interface.

Getting started with J2ME Application Development

Of late I have started developing J2ME Applications in my spare time. I initially tried to learn Symbian / C++, but I am not quite comfortable with C++ and the Nokia emulators are a pile of crap. Since I own a Sony Ericsson W710i mobile phone, I can test the application on my phone itself :-). This is my first tryst with a interpreted programming language after BASIC in my good old high school days.

To get the ball rolling, you`ll have to download and install the Sun Java Wireless Toolkit 2.5.2 for CLDC. The required JDK/JRE is also listed in the download page itself. There are loads of sample applications to test the water before jumping into development.

The most basic radical differnce for me in J2ME compared against BREW is the memory management. There is no need to manage memory in J2ME, ofcourse there are best practices and guidelines to keep you memory utilization low but it wont crash the phone as BREW apps can do. You have the system garbage collector running whenever the phone is low on memory to reclaim the unused memory.

I follow up with more posts on my experience with J2ME Apps.

Using Webservices ( SOAP ) in BREW

This post deals with making the SOAP based Webservices API to work in the BREW environment. It is not intended to be a tutorial on SOAP or webservices.
There has been a lot of confusion regarding whether the webservices API are supported in BREW or not. The correct answer is No, because BREW does not have a XML parser or a SOAP abstraction layer on its own, which is a critcal component for SOAP based webservices. However, if you are ready roll up your sleeves and get your hands dirty with low level stuff you can make SOAP based webservices work in BREW environment.
The SOAP based webservices at it core are nothing but the exchange of XML messages in accordance with the WSDL document of the webservice being used. The sample webservice we will be using now is GetAtomicNumber Operation of Periodictable API provided by Webservicex.net. The XML Parser used is a basic compact ANSI C XML parser written by Martyn Brown and modified to work in BREW environment.
As mentioned above, to use the Periodic table webservice API, all we need to do is to POST a valid HTTP request using IWEB API with appropriate headers and the XML request as the body. The response we get will contain the result in XML format.

Request and Response XML
The structure of the XML messages to retrive the AtomicNumber of a given element is as below. In the SOAP Request the query has to be a valid element name. In the SOAP Response the value contains the result.

SOAP Request

Header Information
POST /periodictable.asmx
HTTP/1.1
Host: http://www.webservicex.net/
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.webserviceX.NET/GetAtomicNumber"
XML Request
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetAtomicNumber xmlns="http://www.webservicex.net/">
<ElementName>query</ElementName>
</GetAtomicNumber>
</soap:Body>
</soap:Envelope>

SOAP Response

Header Information
HTTP/1.1 200 OK
Content-Type:
text/xml; charset=utf-8
Content-Length: length
XML Response
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetAtomicNumberResponse xmlns=""http://www.webservicex.net/">
<GetAtomicNumberResult>value</GetAtomicNumberResult>
</GetAtomicNumberResponse>
</soap:Body>
</soap:Envelope>

Making a SOAP Web Request in BREW.You have to create the XML request and hold it in the buffer.
char request[1024] = "<soap:Envelope
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <GetAtomicNumber xmlns=\"http://www.webservicex.net/\">
<ElementName>%s</ElementName>
</GetAtomicNumber> </soap:Body>
</soap:Envelope>";
The %s in the element name tag has to be replaced by the name of the element for which the AtomicNumber is requested. The variable pszElement contains the name of the element. Now, prepare the ISource pointer for the request.
ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_SOURCEUTIL, (void **)&(pMe->sourceUtil));
nLen = SNPRINTF(NULL, 0, request, pszElement);
pMe->postData = (char*)MALLOC(sizeof(char)*(nLen+1));
SNPRINTF(pMe->postData, nLen, request, pszElement);
ISOURCEUTIL_SourceFromMemory(pMe->sourceUtil, pMe->postData, nLen, NULL, NULL, &(pMe->source));
Now, initialize the callback and make the HTTP request using IWEB API.
CALLBACK_Init(&pMe->callback, webservices_GotResponse, pMe);
IWEB_GetResponse(pMe->web, (pMe->web, &pMe->webresp, &pMe->callback, "http://www.webservicex.net/periodictable.asmx",
WEBOPT_HANDLERDATA, pMe,
WEBOPT_METHOD,"POST",
WEBOPT_HEADER, "Content-Type:text/xml\r\n SOAPAction:http://www.webserviceX.NET/GetAtomicNumber\r\n",
WEBOPT_CONTENTLENGTH, pMe->postLen-1,
WEBOPT_BODY, pMe->source,
WEBOPT_HEADERHANDLER, webservices_PrintHeader,
WEBOPT_STATUSHANDLER, webservices_PrintStatus,
WEBOPT_END));

Once you have got the successfull response, you need to retrive the XML response sent by the server and parse it to get the result.
McbXMLResults pResults;
McbXMLElement *pRoot = NULL;
McbXMLElement *pResult = NULL;
pRoot = McbParseXML(pMe->response, &pResults);
pResult = McbFindElement(pRoot,
"xml/soap:Envelope/soap:Body/GetAtomicNumberResponse/GetAtomicNumberResult");
Now, the variable pResult->pEntries->node.pText->lpszValue will have the result. The complete sample application can be downloaded here. The application was developed using BREW SDK 3.1.5.

Compiling BREW Application for Phone (GNUARM)

The officially supported ARM compiler for the BREW Applications is ARM'S Real View Suite. It will cost you $1500 per seat for a node locked license. It is strongly recommended that you compile your application with the RVCT before sending it for TBT. However, you can use the free ARM Compliers for development and testing.

Compiling with GNUARM

In this section we`ll see the steps needed to compile your BREW Applciation with GNUARM Compiler. You`ll have to download and install the following tools

1. BREW SDK. The version used is 3.1.2.

2. GNUARM Compiler. The version used is 4.2.0.

3. BREW ElftoMod Tool.

4. If you do not have Microsoft Visual Studio installed in your PC. You have to download the NMAKE Make Utility from Microsoft.

Preparing your environment

1. When you install elf2mod, you'll get the elf2mod.x and GCCResolver.c files in the gnu folder. Copy these files to your project directory.

2. If you do not have Microsoft Visual Studio installed in your PC. You`ll have to Copy the NMAKE.EXE and NMAKE.ERR to your project directory.

Modifying the Make file

You can download the sample make file from here. This sample make file compiles the whiteboard example in the BREW SDK. If you cannot download this file leave a comment with your email. I`ll send you the file.

Make sure you have set the GCCHOMEPATH to your GNUARM installation folder and BREW_PATH to your BREW SDK Installation foler.

Executing the make file

Open the windows command prompt. Change the directory to your project directory in this case whiteboard folder in the examples folder of BREW SDK. Execute nmake whiteboard.mak.

Downloading the Mod file

You are all set to execute your BREW Application on the phone. Download the generated whiteboard.mod, whiteboard.bar, whiteboard.mif along with the whiteboard.sig file to your phone into the appropriate directories using BREW AppLoader. Launch your application by selecting the whiteboard icon from the BREW AppManager Menu.

Compiling with other Toolchains

1. Compiling with GNUDE from BREW Forums.

2. Compiling with WINARM from Ward Willat.

Common reasons for Application Crash in BREW

The most common and fatal issue in BREW Applicaion is crashes. When you get a Application crash you are almost certain that you are accessing a invalid pointer. It means you are either using a NULL pointer are a pointer which is already free'd. In both these cases it will cause the application to crash. You can easily check the statement causing the crash using the Visual Studio IDE and check the call stack if needed. These are the most common reasons for such crashes.

1. Calling a BREW API with a invalid interface pointer.

E.g. ITAPI_MakeVoiceCall(pITAPI, pApp->szPhoneNumber, 0);

The above API will crash if the pITAPI is not created previously or a invalid pointer.

2. Double Free problem.

Sometimes your application will crash when you call FREE(), even when the pointer you are passing to FREE() shows a address in the watch window. In this case the pointer has been free'd earlier, check your code for instances of freeing that particular pointer. The easiest possible solution for this problem is replace all your FREE() to FREEIF() calls.

3. Double Release problem.

In this case, your application will crash when you release a interface, the reason is same as the double free problem above. You are trying to release a interface that is already released. To fix this problem replace all your IXXX_Release() calls to RELEASEIF() macro.

Add the below definition to your source file.

#define RELEASEIF(p) if( (p) != NULL){ \

IBASE_Release((IBase*)p);\

(p) = NULL; \

}

Unlike a JAVA Application which will throw an exception, the invalid memory access could crash the entire phone causing it to restart.

Components of a BREW Application

Executable file

Windows executable (.dll)

The BREW Application executable file is a native win 32 dll file, when you compile the application using a Microsoft C/C++ compiler to run in the BREW Simulator.

ARM executable (.mod)

The BREW Application executable file is a native ARM Module file, when you compile the application using a ARM compiler to run in the Phone

MIF file (.mif)

MIF is the Module Information File of your application. As the name suggests it holds the information about your application like Applet name, Class ID, Icon, Privileges, Notification flags, dependencies etc. The MIF file is generated using the BREW MIF Editor in BREW SDK Tools folder. In later versions of MIF Editor, the file generated will have a .mfx extension, you have to compile it to get the .mif file.

BID file (.BID)

Every BREW Application will have a BID file in the name .BID, in which the applications unique Class ID is defined. The Class ID can be generated locally for development and testing from the BREW MIF Editor, but when you commercialize your application you need to generate your Class ID from Qualcomm's Website. The BID file must be included in you application .c file.

Resource file (.bar)

The Resource file contains the resources needed by your application like Strings, Images, Binary files, Objects etc. The Resource file is generated using the BREW Resource Editor in BREW SDK Tools folder. The Resource Editor will generate a .brx file, which is a XML file containing the definitions of the resources, this file is compiled to generate the .bar file.

Signature file (.sig)

The signature file is needed if you want to run your application in the phone. You can generate a signature file for your phone for from the Qualcomm's Website by entering your phones ESN. You need to be a authenticated BREW developer to generate a test signature file.

What is BREW?

BREW stands for Binary Runtime Environment for Wireless debuted in 2001 by Qualcomm. It is a platform providing rich set of API's to develop applications targeting wireless environment. Qualcomm's BREW is NOT a hobbyist platform. There are costs involved if you want to distribute your application or just want to run it in your mobile for personal use. Presently, the BREW platform is available only in CDMA Phones, which is a Qualcomm's forte. However, you can freely download the SDK from Qualcomm and develop application that will run in BREW Simulator.


The programming language for BREW is C and C++. BREW is written in C and so its all of the API's. You can start your BREW Application development with your PC and port it to your phone late

Getting Started with PC
When you are developing BREW in a simulator environment the applicaton will be compiled as native Win32 dll file using the Microsoft C/C++ Compiler.
You need to download and install the following tools

  1. Microsoft Visual Studio 6 or above to compile the BREW for Simulator envionment.
  2. BREW SDK from Qualcomm's website .
  3. BREW SDK TOOLS from Qualcomm's website .

Note: You can also use the free express edition of the Microsoft Visual C++, but then you have to do the project settings yourself. In case on Microsoft Visual Studio you get a BREW AppWizard in your Project Dialog box, which will create a barebone BREW App for you.


Now, that you have successfully setup your environment, you can start developing you BREW application. There are some nice sample application that comes along with the SDK, try to understand them. The BREW API Reference document is the most important document you need when you develop any BREW Application. It is a comprehensive documentation of all the BREW API's.

Introduction

I have been thinking of starting a technology blog on mobiles for quite some time and now I have enough time to spare to create this blog and start sharing what I have learnt. The mobile platforms I will be concentrating for the time being are Qualcomm's BREW and Sun's J2ME. I intend this blog to become a repository of knowledge, which will solve most of the "newbie" problems and be a comprehensive diving pad for these technologies. I am open to critiques on anything that is wrong or mis-intrepereted on this blog.