Ray Rischpater

Subscribe to Ray Rischpater: eMailAlertsEmail Alerts
Get Ray Rischpater: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Article

Getting Started with BREW

Getting Started with BREW

With today's rapid developments in wireless terminal capabilities and increasing pressure to market data-based services, there's a huge market growing for wireless applications that reside on the handset. QUALCOMM's Binary Runtime Environment for Wireless (BREW) platform is an exciting step forward that helps developers create these applications.

Within the BREW platform there's a plethora of Application Programming Interfaces (APIs) that you use with C or C++ to build your application for wireless handsets.

What Is BREW?
One of the reasons for the BREW platform's rise to success is that it is many things to many people. To wireless operators, the platform provides a wireless application delivery system that fully integrates with the operator's billing and authentication systems. To application developers, the platform provides a component-based programming environment using C or C++ to craft applications. A number of companies have also developed Java Virtual Machines that allow apps written in the Java language to work on BREW devices as well. To handset manufacturers, the platform provides a means to meet carriers' needs - such as Verizon Wireless, Vivo, China Unicom, KTF, Telstra, ALLTEL, U.S. Cellular, and KDDI - to offer a robust and open software development environment. And to consumers, BREW operates behind the scenes, unifying the carrier's application delivery system, handset capabilities, and applications.

The platform provides components that your application can use to perform common operations including:

  • Telephony operations such as initiating a voice or data call, or sending or receiving an SMS message
  • Graphics operations ranging from simple line and bitmap rendering to complex object-oriented shape drawing and bitmap scaling and translation
  • User interface components to present text, bitmaps, text input controls, and menus.
  • Network components to support TCP, UDP, and HTTP communications
  • Data-management components to support file system access and persistent data storage
  • IShell, a component that provides access to system services such as object creation, timers, and alarms

    You can get the necessary tools for developing applications for BREW from QUALCOMM at www.qualcomm.com/brew.

    The BREW Distribution System
    A key part of the BREW solution is one that as a developer you never use directly: the BREW Distribution System (BDS). The BDS interfaces to the carrier's billing system, and allows carriers to sell the applications you write to their subscribers. The BDS handles all of the complexities of application distribution and customer billing, integrating application distribution with the network and billing with the customer.

    The BDS is a key reason for the rapid adoption and success of BREW-based applications. By managing the aspects of application distribution and monetization, the BDS provides wireless subscribers with a one-stop shop for application downloads. By integrating with a carrier's billing system, the BDS provides carriers with a secure, convenient mechanism to distribute applications to subscribers. And by providing the delivery channel to developers, it frees you to do what you do best: deliver applications.

    Îf you want more details, QUALCOMM has written a white paper about the BDS that's available on their Web site : www.qualcomm.com/brew/about/whitepaper.html.

    The Anatomy of an Application
    As an application developer, you need to understand how the platform represents applications. The platform provides a component-based environment in which each component is a module, a chunk of executable code, much like a shared library on other platforms. Modules contain definitions of classes, the implementation of interfaces you use to build applications. Many modules are loaded from the handset's Read-Only Memory (ROM) on demand when your application needs to use them; however, you can define your own classes in your module to use in your application. When you do so, you can also choose to share these classes with other developers. In this case the module is called an extension because it's a module the handset obtains online when the classes are required.

    As on most other object-oriented platforms, your applet (BREW's name for applications) itself is a class - specifically, a subclass of the IApplet class. It must implement the interface defined by the IApplet class to process events the system sends in response to system and user interface events. Note, too, that because an application is simply a class, a module can contain more than one applet.

    Every class - be it a system class, one of your classes, or an applet - must have a unique class identifier (or class ID). A class ID is a 32-bit integer and is allocated by QUALCOMM as a service to registered developers on the BREW extranet (www.qualcomm.com/brew/extranet).

    When obtaining an instance - called an interface, in BREW parlance - to a class, you must use its class ID to request the interface from the system shell, the only interface loaded when your applet first runs. (Exceptions to this are the IShell, IModule, and IDisplay interfaces; your application will receive instances of these interfaces when they're executed.)

    You build modules in two ways when developing your applet. During most of your development, you use Microsoft Visual Studio to build dynamically linked libraries (DLLs) that you invoke through the BREW handset simulator running on a Microsoft Windows workstation. Periodically you build your modules using the ARM compiler (available from ARM, Inc., or GNU) and BREW tool chain, resulting in module files (which end in .mod) that you transfer to your handset for on-device testing.

    Application Resource and Information Files
    Modules are accompanied by two additional kinds of information, one optional and one required. Many modules must include resources, static bits of data such as strings, graphics, or dialog layouts. In addition, all modules must contain a module information file, which includes salient details about a module such as its icon, title, and an enumeration of the privileges it requires in order to operate.

    In many of your applets, you want to include strings, icons, and dialog boxes. You can include these items in your application using the BREW Resource Editor, which lets you add items to your application. Once you use the BREW Resource Editor to add items to your application, it will create a C header file and a resource file (called a bar file, short for BREW Application Resource file) for your application. You use the constants defined in the header file to access specific resources, much as you would on other platforms such as the Palm Powered platform.

    In addition to your applet's module file, your applet or extension must include an MIF file to describe the applet to the handset's runtime. As the handset starts up, it reads each applet's MIF file to determine the applet's name, icons, and class ID. The MIF file also contains additional information, such as the author of the application and a set of flags delineating various kinds of behaviors the application performs (such as file system access or network transactions.) You build MIF files using the BREW MIF Editor, an application included with the free BREW SDK.

    Application Flow
    Because your application is a component, the shell on demand must create it. Thus, your application's entry point is actually its constructor, just as it would be with a Java application. By convention, the entry point must be named AEEClsCreateInstance, and it must return a success code and a pointer to your application's module, which must implement the IApplet interface. To help you do this, the SDK QUALCOMM provides includes a set of utility functions that implements most of this interface.

    Once your application has been created, it will receive events from the system's event pump. Many, but not all, of these events will be familiar to you if you've programmed for other event-driven systems. These familiar events include user key presses, changes in handset state, application launch and termination, and so on. Your application must handle each of these events as needed, using the events to drive application execution.

    Two events that may be new to you that your application must handle are events that notify your application when it must suspend operation, freeing as many resources as it can; and when it can resume operation. Typically, your application receives the suspend event when the handset must divert resources elsewhere, such as to handle an incoming voice call or SMS message. Similarly, once the user has finished handling an incoming call or SMS message, your application receives the resume event and can continue operation.

    Application Execution
    You can execute your application in one of two ways: on your desktop workstation using the BREW Emulator, an application that emulates a BREW-enabled handset; or by installing your application, its resources, and MIF files on a developer-enabled handset.

    To developer-enable a handset, you must join the BREW developer program and send them a commercially available handset. They'll make the necessary changes to the handset's configuration that lets you use the BREW AppLoader (provided with the software developer kit) to install the module file, resource file, and MIF file on the handset's flash file system.

    Writing Your First Application
    With the tools installed, it's time to write your first application. Let's start with the simple Hello World application that launches and draws the words Hello World on the display. You can see the implementation in Listing 1.

    When the user selects the application from the handset's application manager, the system first obtains the desired class ID of the user's selection and then queries each module's AEEClsCreateInstance function to see if it will create a module that matches the desired class ID. The AEEClsCreateInstance function uses the BREW-supplied AEEApplet_New function to handle the implementation of the interface to the IApplet interface, so all I need to provide is a pointer to the shell instantiating the application, its class ID and module, and a pointer to the application's event handler.

    Once the module has been created and initialized, the system begins sending events to the application, starting with the EVT_APP_START event. When the event handler receives this event (or the EVT_APP_RESUME event), it creates a static text control that implements the IStatic component interface to display the text using the shell method, ISHELL_CreateInstance, the usual way to create instances of components. Once it's created, the application sets its text and bounds, redraws it, and updates the screen. Application cleanup - signalled by the EVT_APP_STOP or the EVT_APP_SUSPEND events - simply frees the static control, returning the resources it consumed to the system.

    Conclusion
    The BREW platform provides an innovative mix of familiar object- and component-oriented software development tools and new objects and resources to enable wireless terminal application developers to bring their application to market quickly. Its use of familiar software technology makes learning the platform easy, while the wealth of components makes building complex applications a relatively simple process.

    * * *

    This article has been adapted, with permission from the publisher, from the forthcoming book Software Development for the QUALCOMM BREW Platform by Ray Rischpater, available from APress, LLC.

    * * *

    SIDEBAR

    SDK Availability
    The Windows-based BREW SDK is available free of charge. As for compilers, there is a free GNU compiler available as well as a Windows-based ARM BREW Builder package, designed by ARM specifically for BREW developers, for $1,500. For full details, see www.brewdeveloper.com.

    Source Code

    LISTING 1

    /**
    * @name Hello.c
    *
    * @author Ray Rischpater
    * Copyright (c) 2001 - 2002 Ray Rischpater.
    * Portions copyright (c) 2001 - 2002 QUALCOMM, Inc.
    * @doc
    * A sample application that draws hello world.
    */
    #include "AEEModGen.h" // Module interface definitions
    #include "AEEAppGen.h" // Applet interface definitions
    #include "AEEDisp.h" // Display interface definitions
    #include "AEEShell.h" // Shell interface definitions
    #include "hello.bid" // our applet ClassID

    typedef struct
    {
    AEEApplet a; // Must always come first
    // Our application variables follow
    IStatic *pIStatic;
    } App, *AppPtr;

    /*
    * Private function prototypes
    */
    static boolean HelloWorld_HandleEvent( IApplet * pi,
    AEEEvent eCode,
    uint16 wParam,
    uint32 dwParam );

    /**
    * Create an instance of this class. This constructor is
    * invoked by the BREW shell when the applet is launched.
    *
    * @param AEECLSID clsID: class ID of the class being requested
    * @param IShell *pIShell: a pointer to the BREW shell
    * @param IModule *po: a pointer to the current module
    * @param void **ppObj: a pointer to the created applet
    * @return AEE_SUCCESS on success, with the applet in *pobj.
    */
    int AEEClsCreateInstance( AEECLSID clsID,
    IShell *pIShell,
    IModule *po,
    void **ppObj )
    {
    boolean result = FALSE;
    *ppObj = NULL;

    // If it's this class being requested...
    if( clsID == AEECLSID_HELLOWORLD )
    {
    // Use the BREW helper function to
    // create an instance of this class
    result= AEEApplet_New( sizeof(App), // How much to allocate
    clsID, // This class ID
    pIShell, // The shell
    po, // The module
    (IApplet**)ppObj, // The result
    (AEEHANDLER)HelloWorld_HandleEvent,
    NULL); // Destructor
    }
    return result ? AEE_SUCCESS : EFAILED;
    }

    /**
    * Handles incoming events from the shell.
    *
    * @param IApplet *pi: pointer to this applet.
    * @param AEEEvent eCode: event to handle
    * @param int wParam: word argument associated with event
    * @param uint32 dwParam: double word arg associated with event
    * @return TRUE if the event was handled, FALSE otherwise.
    */
    static boolean HelloWorld_HandleEvent( IApplet *pi,
    AEEEvent eCode,
    uint16 wParam,
    uint32 dwParam )
    {
    AECHAR szBuf[] = {'H','e','l','l','o',' ',
    'W','o','r','l','d','\0'};
    AppPtr pThis = (AppPtr)pi;
    boolean handled = FALSE;
    AEERect rc;

    // mark these as unused for the sake of warnings.
    wParam;
    dwParam;

    // Decide what to do with the incoming event.
    switch (eCode)
    {
    // The application is launching.
    case EVT_APP_START:
    case EVT_APP_RESUME:
    // Clear the display.
    IDISPLAY_ClearScreen( pThis->a.m_pIDisplay );
    // Create a static text control.
    ISHELL_CreateInstance( pThis->a.m_pIShell,
    AEECLSID_STATIC,
    (void *)&pThis->pIStatic );
    if ( pThis->pIStatic )
    {
    // Set the content
    ISTATIC_SetText( pThis->pIStatic,
    NULL, // Title
    szBuf, // Contents
    AEE_FONT_NORMAL,
    AEE_FONT_NORMAL );
    // Set the bounds
    rc.x = 0;
    rc.y = 0;
    rc.dx = 60;
    rc.dy = 60;
    ISTATIC_SetRect( pThis->pIStatic, &rc );
    // Activate the control
    ISTATIC_SetActive( pThis->pIStatic, TRUE );
    ISTATIC_Redraw( pThis->pIStatic );
    }
    // Populate it with a message

    // Redraw the display to show the drawn text
    IDISPLAY_Update(pThis->a.m_pIDisplay );
    handled = TRUE;
    break;

    // Application is closing
    case EVT_APP_STOP:
    case EVT_APP_SUSPEND:
    ISTATIC_Release( pThis->pIStatic );
    handled = TRUE;
    break;
    default:
    break;
    }
    return handled;
    }

  • More Stories By Ray Rischpater

    Ray Rischpater is a software engineer and writer who has focused on mobile computing since 1995. During that time, he has developed countless applications for Fortune 500 companies using handheld computers and wireless interfaces for enterprise and commercial deployment. He is the author of 7 books and 47 articles on mobile and wireless computing.

    Comments (0)

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.