Tuesday, May 10, 2011

The Dysfunctional Evolution of Wireless Applications

At the current embryonic state of the M2M industry, most wireless M2M applications are new. Many of these new M2M applications are actually existing applications that are being converted to communicate over wireless cellular connections. And even many M2M applications that are being newly developed for a wireless environment are being developed by engineers who are working on their first wireless application. Because wireless data communications is a different and uniquely challenging environment, most of these applications will take more time and effort to get working than originally projected. Many of the problems that engineers run into are architectural and fundamental, which ends up requiring an extensive redesign and rewrite of the application, or abandoning the project outright.
Why do M2M applications, and the engineers that develop them, get into this predicament? Some of the blame comes from the nature of the development process itself. Let me explain how this usually happens.
Fundamentally, most M2M applications are variants of client-server applications. A central server-based application communicates with remote devices that function as clients of the central application. The central application usually gathers data from the clients. Sometimes the central application sends commands to the clients, and sometimes the clients query data from the central application. Most M2M applications are fundamentally client-server in their architecture.
Client-server applications have been successfully architected and implemented for decades. The fundamental approaches are broadly known and practiced, and the development process is as well. And this is at the root of problems with M2M application development. Engineers who develop an M2M application like they do traditional client-server applications are prone to make architectural design decisions that, in a wireless environment, make the application perform poorly, expensive to operate, or simply unable to function.
When engineers start developing a client-server application, the application is usually initially prototyped in the lab. The server application is prototyped on a dedicated PC, and the client component of the application is simulated on a separate, dedicated PC. Usually the two PCs are connected using a direct serial connection to “simulate” the network. Sometimes the client application is actually compiled or ported to run on an actual client device, but at this stage it still communicates with the server over a direct serial connection. The basic functions of the server and the clients are implemented in this prototype, as well as the overall approach to how the server and clients will communicate with each other.
As the development of the client-server application proceeds, the functionality of the client and server components expands to meet the overall application requirements. The connection between the client and server is usually upgraded to running over a local TCP/IP-based network. The application is enhanced to deal with the aspects of communicating across a network, including dealing with multiple concurrent clients, dealing with network addressing, handling flow control, and interfacing to an underlying communications protocol stack. The fundamental architecture set in the bench prototype usually remains unchanged, however.
In the next stage, the client-server application is deployed to operate in the “field” over the public Internet. The communications capabilities of the clients are expanded to deal with static or dynamic address assignment, firewalls and routers, loss of Internet connectivity, and the slightly higher latency that can occur across the public Internet. Server applications are also enhanced to handle dynamic client addresses, the impact of firewalls at both the server and the client, and the expectation of dealing with even more concurrent clients. The fundamental architecture from the bench prototype still remains unchanged.
At this point, the communications architecture of the client-server application is pretty much set in concrete. The data model of the information being exchanged between client and server is fixed. The messaging structure and data flows between the client and server – both the messaging sequences and the message contents – are similarly embedded in the code. The application may be structured around assumptions of timing and latency, outage duration, communications bandwidth, and underlying protocol support that have been valid and worked fine over the networks on which the application has been developed so far. Circuitry has been designed, and software has been developed, tested, modified and refined.
Whether the application was intended to operate in a wireless environment from the start, or is being converted to operate wirelessly after successfully operating over wireline communications, an application developed in this sequence invariably faces serious problems when it attempts to use a wireless communications network. The developer assumes that since they are using a TCP/IP communications stack on both the server and remote client side, that they are isolated from vagaries in the underlying physical network. But many of the assumptions made about the underlying communications transport are completely invalid in a wireless network. By this point in development, however, those assumptions are deeply embedded in the application architecture and implemented in the code.
When this application is now deployed to operate over a wireless network, its performance can differ widely from what is desired or expected. The cost of usage-based charges over the wireless network is usually surprisingly high. The application will regularly experience higher latencies and prolonged loss of communications, which it may or may not handle gracefully. Communications may not be established between the remote devices and the server for reasons that are unfathomable to the developer, because a cell phone works fine in the same location. Very often, these issues are a result of the application design.
For a client-server application that was designed for a wireline transport, fixing it to work well over wireless is never easy. Making a few tweaks to try to get the application to work acceptably is almost never successful. By this stage, significant structural changes are often needed to get the application to work over a cellular transport. Sometimes the scope of those changes is so great that it would be easier to just rewrite the application. Unfortunately the same application developer whose unfamiliarity with wireless got things into this situation often does not immediately comprehend how significant the required design changes are. Not until a few fix attempts are unsuccessful does it become clearer to the developer how much the application needs to be fundamentally changed to work over a wireless transport. Now the project schedule and budget are truly blown.
Following the traditional approach of prototyping and developing client-server applications in a wireline environment, and using design practices that can be made to work over those connections, often leads novice wireless developers to develop applications that really can not work over cellular connections. Someday a large number of application developers will have experience in this environment and will avoid those mistakes. Unfortunately, we are not close to that point today.