OpenBaseMovil
Welcome at

It was in fact a great event, where we met lots of people from all over the world. We had very interesting conversations with Openbravo ERP partners like Kenzo & Associates, SEN, Gepelia, Open Sistemas, and a lot more, now turning into successful relationships for distribution and reselling of OpenBaseMovil and BaseMovil solutions.

We also had the opportunity of presenting the new Openbravo module for the 2.50 version that integrates BaseMovil bmSales with the ERP. This allows a fast start, plug & play mobile solution to be used with Openbravo. We called it “mobility out of the box”, and we really meant it.

We now have the recording for this session, a community slot where we presented the solution and module. And we did it in less than the 10 minutes that we had to spare!

If you didn’t attend the event or you had to leave early, here’s the session’s video:

ZD YouTube FLV Player

You can also take a look at the slides on SlideShare and download the PDF.

We hope you find it interesting.

Please, leave your comments and thoughts.

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

Disclosure: We at Elondra developed and are alliance partners for RIM-BlackBerry

To us, it makes sense. BlackBerry is a business smart phone, they are friendly to developers, we are open source and it is well Blogcumented that the BlackBerry is a better more practical business phone:

  • Most of the newer BlackBerries posses GPS, which makes Google Maps much more useful, especially for turn-by-turn directions
  • The iPhone lacks basic cut and paste capabilities
  • Despite Apple’s reputation for superior user interface design, the BlackBerry possesses keyboard shortcuts that make navigation around and between applications a breeze
  • The BlackBerry’s phone quality is better than the iPhone’s
  • The Safari browser is certainly more stunning than the BlackBerry’s primitive browser, but the iPhone seems to load even text-only pages more slowly than the BlackBerry over the EDGE network
  • The BlackBerry possesses a general contacts application that makes contacting people by any given method more convenient
  • The battery runs out faster on the iPhone simply because it is used for more tasks. This makes it less reliable for when one must take the device somewhere overnight without the opportunity to recharge.

Apple gives us the feeling that even though you buy the iPhone, or you develop for the Iphone, Apple will own your application, how accessible it is and the songs you listen to while you are waiting to be approved as well.

You are not exactly forced, but are at their mercy using the App Store, They don’t seem to care if you get payed, or how long it takes to pay you, even thought they are happy to promote 1 billion apps downloaded.

I get it, they want to have control and show their big muscles to the little developers. But as the iPhone becomes more and more popular among consumers (and they are, let’s face it, the iPhone is cool and sexy) how many business people will switch to the iPhone? how many developers creating savvy business applications will follow this trend? How good will the iPhone/Apple/Mac soldiers be in convincing you?

and…How does Open source mobility fit into Apple´s overall plan?

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

We recently took part and even became Gold sponsors and the Openbravo World Conference in Barcelona. Having developed a mobility module for Openbravo´s 2.5 version ERP it made a lot of sense to present the module, what mobility can mean Openbravo Partners and their clients. What took us by surprise was the openness (the Irony, I know) that the development community and their Partners showed towards us. We shared the common goal of pushing Opensource software not just as a developing future but as an overall business objective. Yes, there was that overall challenge of having companies not confuse opensource as “FREE”, and that idea of “well if I spend hours working on a vertical application, why do YOU get to profit from it”… sort of thing. (Questions which the new Openbravo forge does somewhat answer by the way)

But the community atmosphere was all there, people from Sevilla to Saudi Arabia, sharing a common goal to be innovative and cooperative. Well known Open source companies like Ubuntu and Alfresco made their visit and presented, some awkward visits from Sun Microsystems (a day before the Oracle buy) as well as some odd snooping from a few SAP executives. It was all good fun and everyone shared business cards, coffee and tiny croissants, we did no detect any “those guys and us guys” type scenes at all.

About the module: The new module, hosted in the new Openbravo forge, uses the ERP’s Data Access Layer (DAL) to retrieve data (customers, products, prices, etc.) and sends it to Elondra’s communication middleware bmServer with our public web service API. bmServer distributes the data among the mobile devices and receives orders from them. These orders are then retrieved by the integration module and inserted right back into the ERP.

This asynchronous, decoupled process guarantees that the data is always received in a timely and secure way. Transparent for both parties, it also releases the end customer from having any kind of infrastructure. Providing an easy and fast start into mobility with little investment for the customer and recurring revenues for the partner.

Openbravo and Elondra have been collaborating to create this integration module to benefit all customers, SME and big account, and to capitalize on the web-based features of Openbravo ERP.

If you get a chance to check out the Openbravo community and meet some of their developers, please do so, they are truly a good bunch.

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

obwclogo

More than 300 IT professionals from around the world coming to Barcelona in April 17 to 19, 2009 with one interest in common, Open Source.

Elondra shares this platform with key market players of the Traditional source like Oracle and Sun Microsytems and open source innovators to the likes of Openbravo and IBM´s DB2 software.

The event will take place in the pleasantly centered NH Constanza Hotel right in the heart of Barcelona´s financial district.

Narciso Cerezo, CEO of Elondra, will host a session on ERP extension modules and describe the Openbravo 2.5 module, developed by Elondra in collaboration with Openbravo. This module seamlessly integrates the benefits of mobilizing a company’s sale force using standard Java phones, into the features of Openbravo.

For more information visit the Openbravo event site at www.openbravoworldconference.com

bannerobwc

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

bmSales in blackberryWhat do you get when you combine the agility and sophistication of the BlackBerry phone and email, with an integrated ordering and Sales application?
A Small company sales weapon.
Think of all the Small-Medium companies around, with sales people in the field that do push sale, but don’t necessarily need push mail. Forget the fact that BlackBerry has the reputation of a white collar executive´s phone, for one minute forget the slumping economy, the declining sales and the fact that most companies are not waiting by their desk for customers to call, they are out there meeting them, visiting them and taking their orders at their shops.
How many gallons of milk you need this week? Loafs of bread? Flour? Barrels of beers? Boxes? Pounds of cheese? When do you need the next delivery of office paper? Pens? Cement? ….
These companies, distributors, resellers are the real forgotten ones. Sure, they may have a mobile phone to recieve and place calls, but neither blackberry nor email is a necessity for them in the field. Pen and paper and a clipboard is still their best tool, the overpriced PDA solution in some cases, the humongous industrial terminal in the worst case. And the time and money they spend driving back and forth to the office, in mistakes, in duplication.
Well, Elondra has integrated their mobile technology BaseMovil into the BlackBerry bold, allowing everyone to be able to make orders on the field, with offline access to clients, products, prices, expenses, GPS, invoicing, history….everything you need to be an efficient on-the-field-sales representative.
By Elondra being a BlackBerry alliance partner, the sales application integrates easily with the other BlackBerry applications. So by accessing your ERP client list, you can easily give them a call, email them or find them on the GPS.
And with the Sales Director online tool, you can check what your sales reps are invoicing, in number of orders; revenue amounts and you can even check their geo-location and see where your sales people actually are.
And if you think it’s expensive, here is the best part: it integrates onto most of the ERP´s out there in a matter of hours, not “project days”. Its SaaS model (software as a Service) of no license and zero-to-no initial investment ensures small medium companies can afford to have accuracy and agility in their sales force and now in BlackBerry too.
You don´t believe me, contact us for a demo.

And now, after the commercial comes the good news for developers: we have developed the specific BlackBerry components integrated into the upcoming version of OpenBaseMovil.

This will lead to many changes on the ui engine, for the better of course, and will mean that your applications will run both on standard JavaME phones and on BlackBerry with a single codebase.

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

We are very excited with the upcomming version of OpenBaseMovil and the also upcomming BaseMovil development service.

Several changes are being made on OpenBaseMovil with one specific goal in mind: multi-platform application generation.

This really means a lot of changes, and we’ve been thinking about wheter to keep or not backward compatibility. We’ve finally decided to break this compatibility for the sake of creating a better platform and being really able to achieve our goals.

We are cleaning up all the references to MIDP classes from the main libraries, improving a lot the MVC model, and adjusting the XML view definition language to better fit those changes.

With this new approach, the application code is free from platform specific code, and it is linked at build time the appropriate libraries that actually provide platform specific code.

We will initially provide JavaME MIDP standard libraries as well as BlackBerry specific libraries, but then Android will be added (the time frame for Android depends on market demand and resources, if you’re willing to collaborate please contact us).

Writing applications will be a lot easier, since we will also provide automatic code generation for things that you have to code manually now (wiring code).

Also a couple of changes will be made to the database, but they will be backwards compatible, improving speed and also a wider range of supported devices with a new storage library.

We are also working to bring on-line a beta version of the BaseMovil developer site. It will allow you to create and manage a database hosted at the server, syncrhonize that database with the mobile phones and also (optional) with any backend service such as an ERP. The service also provides application OTA provisioning.

We expect to start rolling out the beta versions of both on 2009 Q1.

If you have suggestions about improvements or new functionalities that you’ll like in OpenBaseMovil 4, please leave them here, we will be really pleased.

And if you think this is worth reading, digg it or send it to your favourite social site!

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

We’ve been really busy this last months, hiring, planning, rising funds, but we are now ready again to publish our news on OpenBaseMovil development.

We’re also starting with a very interesting side of Open Source development: training and “evangelization”.

Tomorrow we will start a seminar on JavaME and OpenBaseMovil development at the Computer Science College, Universidad Computense de Madrid (one of the best Universities in Spain).

The seminar has raised great expectation: It will be delivered to 40 students, but over 100 will have to wait until the next session.

We plan to publish also our conclusions, part of the seminar materials, and some photos after the seminar.

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

We will now address how to create a servlet to handle RemoteCalls from our device.

The first piece of code is a very generic servlet that takes the binary data, handles it to another class, and sends back the result. That second class is the one that will do the parsing. This way is easier to perform unit testing, for example.

Here is the code for the servlet:

/*
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
*/
 
public class RPCServlet
    extends HttpServlet
{
    private String infoPage;
 
    public void init( final ServletConfig config )
    {
        infoPage = config.getInitParameter( "informationPage" );
    }
 
    protected void doGet(
            final HttpServletRequest    request,
            final HttpServletResponse response
    )
            throws ServletException,
                   IOException
    {
        request.getRequestDispatcher( infoPage ).forward( request, response );
    }
 
    protected void doPost(
            final HttpServletRequest     request,
            final HttpServletResponse   response
    )
            throws ServletException,
                   IOException
    {
        processRequest( request, response );
    }
 
    private void processRequest(
            final HttpServletRequest request,
            final HttpServletResponse   response
    )
            throws ServletException
    {
        try
        {
            // Read all the data into a byte array
            final BufferedInputStream bis = new BufferedInputStream(
                    request.getInputStream()
            );
            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int c = bis.read();
            while( c != -1 )
            {
                baos.write( c );
                c = bis.read();
            }
            final byte[] data = baos.toByteArray();
 
            // Handle the data to the RPCBroker class
            final byte[] result = RPCBroker.handle( data );
 
            // Return the result to the device
            response.setContentType( "application/octet-stream" );
            response.setContentLength( result.length );
            response.getOutputStream().write( result );
        }
        catch( Exception e )
        {
            throw new ServletException( e );
        }
    }
}
 

Now the RPCBroker has to parse the data and make the actual call. We will not be doing here the call, you can do what suits you better: from a simple if-else structure to calling objects using reflection. If you use reflection, please be careful that you allow calls to the objects you want to be called and not a generic approach, since that could lead to big security problems.

 
/*
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
*/
public class RPCBroker
{
    private static Log log = LogFactory.getLog( RPCBroker.class );
 
    public static final int RC_SUCCESS              = 0;
    public static final int RC_INVALID_OBJECT       = 1;
    public static final int RC_INVALID_METHOD       = 2;
    public static final int RC_NOT_ALLOWED          = 3;
    public static final int RC_INVALID_ARGUMENTS    = 4;
    public static final int RC_INVOKATION_EXCEPTION = 5;
    public static final int RC_INVALID_CRC          = 6;
 
    public static byte[] handle( final byte[] data )
        throws IOException,
               SerializationException
    {
        if( data == null )
        {
            return sendError( RC_INVALID_CRC, "Null data" );
        }
        try
        {
            final ByteArrayInputStream bais = new ByteArrayInputStream( data );
            final ChecksumedInputStream cis = new ChecksumedInputStream( bais );
            final SerializerInputStream in = new SerializerInputStream( cis );
            final byte      version     = in.readByte();
            final byte      encryption  = in.readByte();
            final String    deviceGuid  = in.readString();
            final long      deviceId    = in.readLong();
            final String    objectName  = in.readString();
            final String    methodName  = in.readString();
            final Object[]  parameters;
            try
            {
                parameters = (Object[]) in.readNullableObject();
            }
            catch( SerializationException e )
            {
                throw new IOException( e.getMessage() );
            }
            final long crc = cis.getCRC();
            final String    endOfData   = in.readString();
            if( endOfData.equals( "END_OF_DATA" ) )
            {
                final long originalCRC = in.readLong();
                if( originalCRC != crc )
                {
                    return sendError( RC_INVALID_CRC, "Invalid CRC" );
                }
                else
                {
                    return invoke(
                            version,
                            deviceGuid,
                            deviceId,
                            objectName,
                            methodName,
                            parameters
                    );
                }
            }
            else
            {
                return sendError( RC_INVALID_ARGUMENTS, "Wrong signature" );
            }
        }
        catch( SerializationException e )
        {
            return sendError( RC_INVALID_CRC, e.getMessage() );
        }
    }
 
    private static byte[] invoke(
            final byte      version,
            final String    deviceGuid,
            final long      deviceId,
            final String    objectName,
            final String    methodName,
            final Object[]  parameters
    )
            throws IOException,
                   SerializationException
    {
        // Here is where you actually look up the object
        // make the call and return the value
 
        Object retval;
        /*
        1. Lookup object
 
        if object is not found: return sendError( RC_INVALID_OBJECT, "error message" );
 
        2. Check security, if applicable
 
        if not allowed to call: return sendError( RC_NOT_ALLOWED, "error message" );
 
        3. Make the call
 
        store the return value in the retval variable.
        if an error raises: return sendError( RC_INVOKATION_EXCEPTION, "error message" );
        */
 
        // You should perform the appropriate try-catch
        // The following code should be placed into a try block,
        // when the call has been successful
       final ByteArrayOutputStream baos = new ByteArrayOutputStream();
       final SerializerOutputStream out = new SerializerOutputStream( baos );
       out.writeInt( RC_SUCCESS );
       out.writeString( "OK" );
       out.writeNullableObject( retval );
       out.flush();
       return baos.toByteArray();
    }
 
    private static byte[] sendError( final int code, final String message )
            throws IOException,
                   SerializationException
    {
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final SerializerOutputStream out = new SerializerOutputStream( baos );
        out.writeInt( code );
        out.writeString( message != null ? message : "" );
        out.flush();
        return baos.toByteArray();
    }
}
 

With this second article you should have almost everything you need to perform remote calls.

Please, leave your comments and suggestions.

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

The Networking library in OpenBaseMovil (openbasemovil-net) provides some very useful networking methods that you can use in your applications.

One of the most useful ones is the RemoteCall class. As you can guess it is a remote call procedure, and it is a binary one. If your target platform supports the remote call or webservice optional APIs, you can use them, but we wanted to provide an approach that could be used on any device (many of the current devices in the market do not support those optional APIs). We also decided to use a binary protocol since it is more compact and more efficient for binary data, instead of XML.

We also wanted to control how the network was reached and do it in a very simple way.

The library contains three main blocks: Net, Binding and RemoteCall.

Net has all the needed constants, and also some networking wide configuration settings. It also has a checkNetwork method that will allow you to check if you have signal and if your remote server is up and running.

The synchronization engine uses the deviceGuid and deviceId settings to perform simple authentication. Those settings are sent from the server to the device when the user successfully authenticates in our system using the company name, user name and password.
You can use them for your own purposes, or you can ignore them, they are not really needed. If not set, they will be sent as an empty string and 0 respectively to the server in the remote call protocol.

The checkNetwork method provides also a small example of RemoteCall usage, as it calls a remote Object called “LoginHandler” to a method called “ping”. That checks if our server is up and running. If it can not make the call, it checks if it can read the home page of yahoo (you could put any other well known service). That is used to check if the previous error was due to the server being down or to the lack of network connectivity (we assume yahoo is up :) ).

final RemoteCall rc = new RemoteCall(
    "LoginHandler", // remote object name
    "ping",         // remote object method name
    0               // number of parameters
);
rc.invoke();

The RemoteCall class allows you to set a default url to call, so you can later just call the no argument version of invoke, but you can also provide an url for each call using the other version of invoke.
In the previous example, the Net class assumes that you have previously set the defaultURL property in the RemoteCall class. That should be done at application startup.

The RemoteCall class sends a binary stream to a remote url, using a the POST method through the Binding class. RemoteCall will try to invoke the remote method up to MAX_RETRIES (currently 5) times if there’s a network error (not if the server returns an error), providing you with a level of network security (mobile networks can be very error prone).

The protocol is very simple, and it uses the openbasemovil-core serialization tools to send and receive the data, so complex objects can be sent and received (anything that can be serialized through the SerializerOutputStream).
It is already present as a comment in the code, but I will put it here:

Device request:
 
(data:
{byte       version}        // RPC version, currently 2
{byte       encryption}     // Encryption: 0 - none, 1 - Blowfish
{String     deviceGuid}     // Device Globally Unique Identifier
{long       deviceId}       // Device remote id
{String     object}         // Name of object to call
{String     method}         // Object method to call
{byte[]     parameters}     // Parameters serialized using
                            // SerializerOutputStream
                            // writeNullableObject method
)
{String     "END_OF_DATA"}      // Constant text to identify
                                // data boundary
{long       CRC}                // Adler32 CRC code of the data
 
Server response:
 
{int        responseCode}       // Result of the method call
{String     responseMessage}    // Result message
{byte[]     responseData}       // An object serialized using
                                // SerializerOutputStream
                                // writeNullableObject method
 
responseCode can be one of:
 
0 - RC_SUCCESS
Everything went fine
1 - RC_INVALID_OBJECT
The requested object is invalid
2 - RC_INVALID_METHOD
The object has no method with the requested name
3 - RC_NOT_ALLOWED
The caller is not allowed to execute the requested method
4 - RC_INVALID_ARGUMENTS
The arguments passed are invalid
5 - RC_INVOKATION_EXCEPTION
The method produced an exception when invoked
6 - RC_INVALID_CRC
The CRC of the data sent is invalid

So you can code a Servlet (or whatever) in your server, handle the post request, and parse the data sent using the openbasemovil-core SerializerInputStream class. Then is your turn to locate the object, the method, make sure you want the device make that call, make the call, and finally send the response back using the SerializerOutputStream class.
For the response, the responseCode and responseMessage are mandatory, and if the call is successful then the responseData is also mandatory.
responseData will be read by the device using SerializerInputStream.readNullableObject.

Your server side code should check that after the incomming data the END_OF_STREAM string si found and also the CRC code. And you should also perform the CRC checking using the openbasemovil-core Adler32 class, to make sure that everything arrived ok.

A bit more complex example of RemoteCall use, calling a remote object called “MyServer”, to a method called “sendImage” which receives three paremeters, a String, a byte array, and a Vector of String objects.

// Somewhere in your code at startup you will set the default URL
RemoteCall.setDefaultURL( "http://myserver/rpc" );
 
// Now we will make the call
/**
 * Send an image to the server.
 * @param name image file name
 * @param data image raw data
 * @param attributes image attributes, a collection of Strings
 */
public Long sendImage(
                 final String name,
                 final byte[] data,
                 final Vector attributes
)
    throws RemoteCallException
{
    final RemoteCall rc = new RemoteCall(
                                   "MyServer",
                                   "sendImage",
                                   3
    );
    rc.setParameter( 0, name );
    rc.setParameter( 1, data );
    rc.setParameter( 2, attributes );
    return (Long) rc.invoke();
}

The RemoteCall method uses the Binding class to actually call the remote server with a POST method.

The Binding class provides an easy and extensible way to abstract you from the real method used to make the call. It also controls all the open bindings, allowing you to close them all at once to make sure that there’re no connections open.

Binding is an abstract class that by default uses the provided sublcass HttpBinding. As you can imagine, the HttpBinding class uses the javax.microedition.connection to actually create an http or https connection.

With the Binding framework you could create other Binding subclasses and use other means for connecting to the network. For example, in future versions we will provide a BluetotthBinding and a Java SE Proxy. With them you will be able to connect your phone through bluetooth using the proxy running on a PC. And everything will work exactly the same.

To create a new Binding class and use it you simply need to subclass Binding, implement the needed methods, and then set it as the binding factory with:

// For CLDC 1.0
Binding.setFactory( new BluetoothBinding().getClass() );

or

// For CLDC 1.1
Binding.setFactory( BluetoothBinding.class );

This introduction to the networking part of OpenBaseMovil will be included in the next revisions of the documentation.
We look forward for your comments to enhance and clarify it before it is actually included.

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati

BarCampWe’ve just returned from the WES, and we will be at another event soon: The second Barcamp at Open Movil Forum. Open Movil Forum is an initiative of Movistar, the Spanish network operator, around open source software and mobility.

We made a quick presentation at the first Barcamp, now we will be showing a more in depth look at our flagship application bmSales, which will be soon released under an Apache or BSD license.

This is a powerful application that has been running on real customers for the last two years, with many functionalities, that illustrates how to get the best of the OpenBaseMovil framework.

If you’re in Madrid next May 27th, you can sign up for free and attend the event.

BlogLines del.icio.us Digg Facebook Google Google Reader Yahoo! MyWeb Newsgator Newsvine reddit SlashDot StumbleUpon Technorati