Archive for the ‘Technical’ Category

SSH on the iPhone and iPod Touch

Wednesday, August 20th, 2008

SSH is undoubtedly a useful tool and the iPhone and iPod Touch are great portable ways of connecting to networks; put both together you can be a sysadmin on the move! So what are the options for this? The Apple AppStore currently has two SSH clients, SSH and iSSH, and I took both out for a spin.

SSH

First up is SSH, marketing at $3.99 (£2.39). Opening the program greets you with a screen where you can type in an address to connect to in the form user@hostname:port (the address is added to a list on the first screen so you don’t have to type it next time). Once this has been entered you’re presented with a password entry screen, although you have to press the password entry box to get a keyboard.

If this is successful you get a retro green monospace on black terminal, with a white command line bar at its bottom. This white command line is the only way you can send commands over ssh, you press it to bring up a keyboard with which you type your command and press ‘Send’. This command is then echoed to the terminal and executed. Basic shell commands work well, but once you want to use some basic programs such as less, more or man problems start to show.

SSH command line

Navigation is the main problem with these programs through this client, I’m used to using the arrow and return keys to navigate them (I know there are other ways, but these are the ones I remember). The client has no emulation of arrow keys, so we lose that form of navigation and there is no return key on the keyboard. After looking up some of the other navigation commands available for these programs I was able to navigate them quite successfully, but the process of touch command bar->type command->send for every bit of navigation felt very tedious.

Another basic command I tried and expected to work was top, but alas SSH fails again and produced this output:

SSH and top

which is hardly usable. You can try and scroll the output, using screen swipes, but each time top refreshes your scrolling is lost.

As arrow keys are not implemented command line history is harder, meaning you have to type in commands to access your history, which is annoying and slow if you are using SSH’s input method.

The client allows you to use control commands using the ^ key, so Ctrl-C becomes ^c. This works and is functional, but to reach the ^ key you have to go through two keyboards, which is annoying. Why can’t there be a Ctrl button on the screen ready for me to use whichever keyboard I’m in?

iSSH

Disappointed with SSH I went on to try iSSH (marketing at $4.99 or £2.99). When you start it up for the first time you must add a connection configuration. This is a form where you fill in a name for the configuration, the hostname and at your choice a username and command to execute on connection.

iSSH configuration form

There is no option for which port to connect to, you are stuck with port 22. With a configuration now saved I could choose to connect to it. This dropped me into a terminal where ssh asked me for a password, the bottom half of the screen is filled with a keyboard which types directly into the console. The terminal used is much better than the one SSH used, it has a gray monospace font on a black background, and it supports colours which makes using such a small screen more bearable.

There is a bar above the terminal which contains buttons for the Ctrl, Shift, F# and Tab keys (which can be used in combination), along with Exit. This allows you to use niceties such as tab complete on the command line, a great time saver when using the iPhone’s user input.

Seeing that SSH had been so abysmal when I tried to run top I tried to run top on iSSH, which produced this result:

iSSH with top

Hurrah! top is usable using iSSH. Running more, less and man was also successful using iSSH, which gives access to arrow keys through swiping the left 2/3 of the screen, and the keyboard has a return key (the right 1/3 of the screen is reserved for scrolling). This means you can also use the arrow key emulation to scroll the command line history.

Tilting the device the appropriate way will change the display from portrait to landscape. In landscape mode you have the option of hiding the keyboard using a button on the top bar. This is rather useful if you wish to read a file using less; you can invoke less then hide the keyboard giving the whole screen to the file which you can navigate using the emulated arrow keys.

iSSH with less

Conclusion

Comparison chart of both clients:

ssh-table

In terms of functionality iSSH beats SSH hands down, there is only one feature the latter has the former does not: port selection. For some users, this will be essential, and they will use SSH and put up with the bad user experience. For everyone else, there is iSSH, which makes ssh usable on the iPhone.

It Just (doesn’t) Work

Thursday, August 7th, 2008

The new iPhone SDK requires that developers upgrade to OS X Leopard, which is a nice excuse for most of us to drop 100 bucks on a new operating system that does, err, exactly what the old one did. I am sure I’ll come across some amazing new feature that I couldn’t live without soon enough… Obviously there is the addition of TimeMachine, but funnily enough I was already doing backups.

leopard.bmp

One thing I was expecting was a seamless upgrade. I was sorely disappointed. The first complaint from the Leopard Installer DVD was that my disk had the wrong partition map. I upgraded my macbook’s hard drive a year or so ago, and apparently had selected APM instead of GUID when I installed. To fix that, I followed the instructions at http://www.macosxhints.com/article.php?story=2007102511133285 which took several hours (LOTS of copying data to/from external drives). This involved the use of an excellent program called Super Duper which I am happy to report does Just Work.

The next complaint was harder to resolve. The verification process failed half-way through installing. Skipping the verification resulted in a failed install (not on my main drive, on my backup!). Googling revealed that apparently this problem was not uncommon, and was related to after-market RAM upgrades (that’s me) - though doing a full RAM soak test revealed no problems at all. I eventually managed to install the thing by restoring the DVD onto a partition on my external drive, and then booting from that.

The iPhone SDK was, fortunately, easier to install!

Homogenous Hardware?

Wednesday, July 30th, 2008

I have just been playing around with Stylizer, a Windows CSS editor. Why, you may ask, is the CTO of a mobile software company messing around with CSS editors? A very good question. Someone was extolling the virtues of this program on the Business of Software forum, and how everyone should take a look at the first-run experience. I went to the website, which is simple, clean, and attractive, and downloaded the program, which instantly launches into the tutorial.

Stylizer’s tutorial is well implemented, and compelling. I am no expert on CSS, and not much more knowledgable about CSS than I was when I started the tutorial, but I know a bit more about how to use Stylizer, and I agree that it is easy to use. Right up to the point where it asked me to hold down my left mouse button and then click with the right while the left button was still down.

Now, not only did I have to read that twice to work out what I needed to do, I could not actually do it. I use an Apple Mighty Mouse, and it is simply not possible to press any two buttons simultaneously, unless you press very hard enough (i.e. hard enough to break it).

All mice are not equal

Up to this point, all the shortcuts had been with the keyboard, so I didn’t quite see why we were suddenly using the mouse, particularly in a click combination that is hardly standard. In the case of Stylizer, it is simple enough just to achieve the desired action (insert a new rule) using the Insert key, but I am left asking myself why someone found it necessary to come up wth a completely non-standard action to implement a common action. In the same thought, I realise that Apple disabled simultaneous button clicks on the Mighty Mouse precisely to prevent people coming up with complex, non-standard UIs. More power to them.

Mobile Device Databases

Friday, May 2nd, 2008

I’ve just been taking a look at Device Atlas, which in its own words is the “world’s most comprehensive database of mobile device information”. I had high hopes, but unfortunately it appears to be rehash of the kind of information which is readily available, without anything more useful. I appreciate that this database is not designed for my sole delectation, but I surely can’t be alone in wanting to get a list of devices running S60 FP1 which have a camera? Not only does the Device Atlas apparently not allow any sort of search, it doesn’t tell me what operating system a phone runs, what JSRs it has, or allow any kind of user commenting (e.g. “HTTPS is broken on this device”).

My favourite part of the site is in the FAQ, where it says “Can I have a job? Yes, we’re hiring world class staff for the DeviceAtlas project. Call us.” Errr, call who? There’s no phone number. Click on “Contact” on the nav bar at the bottom of the screen. Still no phone number. I presume you’re supposed to call dotMobi (one more click away) rather than Device Atlas, but that’s far from clear. Also in the FAQ, we read that “We intend this to be the single largest, most comprehensive, and accurate device database on the planet”. A worthy goal - but Device Atlas has a long way to go to reach it.

Android Code Day

Thursday, February 7th, 2008

After a much-awaited Release Day and the obligatory pub afterwards, last Thursday marked the end of January and Android Code Day in London and Tel Aviv. It was my first time in Israel, which made it more exciting As much as I’d like to visit Israel, I wouldn’t be able to justify the expense (it might happen in the future with the current trend in ticket prices). The good news is that the train journey into London is relatively short and painless.

After waiting around in the lobby, we were eventually escorted through brief NDA-signing (is it legally binding if there’s no expectation for you to read it at all?) and then upstairs, into a meeting room just big enough to hold 40 people and their laptops without feeling crowded.

The first half of the day was taken up by a brief presentation by Jason Chen, interleaved with a not-so-brief and highly interactive question-and-answer session. Then there was lunch, with the usual perks (who wouldn’t work for Google for a freezer full of Ben and Jerry’s?) and some insight into Google’s business strategy.

Top-secret plans
Top-secret plans

We started the afternoon with a brief demo of an Android app from an audience member. It was pretty decent for only two days’ worth of code and some borrowed sprites — maybe Android phones will compete with the PSP (in keeping with tradition, they’ve tested Quake on Android prototypes, with reasonable performance).

A familiar game…
A familiar game…
... stretched by OpenGL in landscape mode
… stretched by OpenGL in landscape mode

The “hackathon” commenced, but as the average level of experience was “has compiled and run the hello world app” (and the documentation is written in the traditional Javadoc style that never manages to tell you how to do what you want to do), I don’t think much coding actually happened — that wasn’t really the point of the day. Jason Chen is a Developer Advocate; so’s Dan Morrill (the first link in this article). He writes “I get to travel the world to meet developers and talk about cool technologies. I can’t believe I get paid for this!” though Google is keen on hiring more Developer Advocates.

It’s not hard to see why: the room seemed to consist of people from handset manufacturers, mobile OS companies, people wanting to see if Android is worth investing time into, and people there just to keep track of what Google was up to — in fact, the last category seems to cover everyone.[1] One of the most promising things about Android is an abundance of cool, novel, well-written, currently nonexistent apps — it’s a chicken-and-egg, and Google can only hope that apps are easier to produce than users (what do you think the Android Developer Challenge hopes to accomplish?).

Of course, it’s really future users that give decision-makers the incentive to spend money on a particular platform. Until we invent time machines, we’ll have to settle for a significantly high probability of a significant number of future users. The greatest impediment is actually having phones for sale, but the problems there are largely political, and if I started on politics I’d be here all day. Once phones are on the market, there’s another problem:

Android has to be good.

And by “good”, I mean better than the next phone on the shelf. Of course, customers define what’s “better”, but what do you see when you go phone shopping?

  • The brand is difficult to change.
  • The design is difficult to do well, but at least the OHA has Motorola.
  • The “specs” that the shop decides to show are rather arbitrary.
  • The price matters, but in the UK, it’s largely “free on contract” (at least Android is free, so manufacturers can save on licensing fees).
  • What your friends say is even harder to change.

Word-of-mouth is often mentioned as the most important form of advertising, and also the hardest to get right (should I be worried that nobody seems to know what Android is?). But personally, if there’s anything that’ll make me recommend one phone over another, it’s the UI, probably because it’s the thing which irritates me every time I use a phone — it’s also where Android has a chance to shine, since (in theory) you can rewrite everything, even if you end up with a bloated home screen app that does everything under the sun.

Without going into technical details (there’s plenty on YouTube), Android has a few distinguishing features; the most notable is that it tries to be designed around the user experience. Intents are a key idea — they encapsulate what the user wants to do. The system passes the request to whichever app says it can fulfil the intent — apps aren’t replaced, intents are.

The problem arises when you have many apps which want to provide some basic enhancement. If I have Skype on my Android phone, here’s what I’d like to see:

  • Skype status shows up in the contact list.
  • Calling a Skype-online contact makes a Skype call over Wi-Fi.
  • Calling a Skype-online contact asks me before using HSDPA, in case I don’t want to end up with a big phone bill and violate the no-VoIP clause of the ToS.

It’s conceptually easy, with one catch: you don’t want to replace the contacts and dialler, because apps can’t access another app’s data. It’s difficult to do the right thing when you change contacts apps between adding, removing, editing, and renaming contacts, and it doesn’t work with Google-talk or Gaim Pidgin, let alone a psychic dialler which reads my brainwaves and calls the right person without me asking.

What users expect is the concept of a global address book, with each contact (an ID) optionally linked to names, phone numbers, e-mail addresses, snail-mail addresses, WGS84 coordinates, IM usernames, and anything you might associate with a person (or group of people).[2] Similarly, apps which handle intents (”send a text message”) can also advertise a “quality factor” (RFC 2616) that changes dynamically, so that Jabber’s “quality” drastically decreases when I move out of range of Starbucks and my phone starts using roaming HSDPA, hopefully going below a threshold which prompts the phone to ask me first. Suddenly, my phone has a better IM client than my computer: it’ll switch to SMS when Wi-Fi isn’t available, connect to the office’s SIP server, and give me the directions to tonight’s party.

There’s been little work on any platform to address these; as a result, there always tends to be one app that ends up on top with everything else struggling to catch up — IM clients throughout the decades have followed this trend. Phones are a different matter, and unless something reaches critical mass, we’ll just end up with a lot of fragmentation. While compatibility issues aren’t an aspect of fragmentation that the audience seemed to be worrying about (people seemed more worried about OEMs taking Android and making it proprietary), they’re important to the user experience: seamlessly integrating apps together is an important part of a good UI.

Another thing which doesn’t exist in Android is input methods — the current emulator only supports primitive touch screen and a keyboard. How will multitap work? What about graffiti, handwriting recognition, or an on-screen keyboard? These tend to require extra screen space, which means it has to be coded into each app or provided by the system; there’s currently no easy way to give another app a certain portion of your screen. Besides, the keyboard should only appear when I’ve selected a text field (and it should let me write/graffiti directly into a text field). What about gestures? Or force-input?[3]

When you control nearly everything about a device, it’s much easier to make a good UI instead of just a decent one — the iPhone kept coming up as an example of a good UI throughout the day.[4] Android will stand between everybody’s apps and the underlying hardware, whether there are 30 keys or none, and it needs to provide enough abstraction so that developers can rely on the system to do the Right Thing and still give a good user experience. It’s what Android is designed around.

At last, the day came to an end, and I left for King’s Cross. Though the room was teeming with skepticism, Android is something that I’d like to succeed, and I’ll be watching the OHA’s four handset manufacturers closely over the next few months (maybe Motorola will finally make a phone that looks pretty but doesn’t irritate me every time I try to use it).

There’s going to be another Android Code Day in Boston on the 23rd. It’s worth going to, especially if the impending SDK update, happens first. Besides, you can always enjoy the Ben & Jerry’s on the mission to uncover Google’s master plan.

  1. Working with mobile software imparts a strong urge to know what everyone else is doing, possibly to learn from those who have done it better than you, or in search of the next great platform which is reasonably profitable and both a joy to use and code for (my recent experiences with a certain OS/IDE/build system can be summarised as it should not be this difficult!).
  2. One can only hope that it won’t be implemented using XML.
  3. Want to turn the alarm off? Hit it. This is probably patented. The W380a lets you turn off the alarm by waving at the camera.
  4. The iPhone and the BlackBerry the two phones which I hear described as good, not just better-than-something-else.

Why should I use static_cast?

Wednesday, January 30th, 2008

I recently had the dubious pleasure of debugging a User 42 Panic on a piece of Symbian code that was given to me by another company. You always need to make sure you understand what the system is telling you, so I went straight to the documentation:

User 42: This panic is raised by a number of RHeap member functions, AllocLen(), Free(), FreeZ(), ReAlloc(), ReAllocL(), Adjust() and AdjustL() when a pointer passed to these functions does not point to a valid cell.

Hmmm. That didn’t really give me many clues. Well, I needed to figure out how to reproduce the bug anyway. That was relatively easy, I could reproduce it with a User::Leave(). The leave was being trapped, and the debugger showed the panic was being issued between the Leave and the TRAP, so that pointed to a problem on the CleanupStack (which agreed with what the documentation said). Isolating the problem even further showed that I could reproduce the problem by doing this:

CItemBase* item = (CItemBase*)decoder->ReadItemLC();
CleanupStack::PopAndDestroy(item);

For reference, ReadItemLC() constructed an MDecodable, and the inheritance hierarchy looked like:

MultipleInheritance

Ignoring the fact that a function called ReadItemLC() should return a CItemBase*, not an MDecodable*, the problem here is that in that inheritance hierarchy, both CItemBase and MDecodable have their own data (MDecodable has a vtable pointer, even though it’s an abstract class). Consequently when you cast a pointer from an MDecodable* to a CItemBase* you get a different pointer value. Try the attached code on any system for a demonstration of the problem.

However, in the code sample above, the CItemBase class had not been fully defined; we had simply forwarded-declared CItemBase. That meant the compiler couldn’t do the necessary arithmetic (subtract 4) to convert an MDecodable* to a CItemBase* - because it didn’t know whether they were actually part of the same inheritance tree, or completely dissociated types. So it did the equivalent of a reinterpret_cast.

When I changed the code to do the correct C++ style cast:

CItemBase* item = static_cast<CItemBase*>(decoder->ReadItemLC());
CleanupStack::PopAndDestroy(item);

It promptly failed to compile, because CItemBase hadn’t been fully defined. Adding

#include "ItemBase.h"

at the top of the file fixed the compile - and fixed my User 42 Panic as well.

Lesson: next time I get code from another source, check the casting is done properly.

MOTODEV Summit, London

Wednesday, November 14th, 2007

Last Friday I had the opportunity to head down to London to see the Motorola MOTODEV Summit world tour come to town. MOTODEV is Motorola’s attempt to woo the developers of the world to their platforms and devices - attempt to capture some mind-share and give us some insight into what is around the corner for their technology.

Lobby
The main lobby of “The Brewery”.

It was a pretty small gathering, at “The Brewery” near Liverpool Street Station in the heart of “The City”, an area of London frequented by blokes in suits carrying Blackberries and shouting “Sell! Sell!” in increasingly fervent tones. Members of Motorola’s “ecosystem” were there, and about 24 low-key stands were put up so that various parties could hawk their wares.

Main Hall
The main hall, first thing. The exhibition, “breakfast” and lunch were all served in here.

About half of the people there seemed to be Motorolans (yes, that’s what they call themselves. I know this ’cause I used to be one…), and there were quite a few suits and ties. I recognised a few faces from the MoMo London events, and a few folks from overseas had even come in for the occasion - I spotted some Israelis, a few of the nice folk from Funambol in Italy and I spoke to someone who had come in from Barcelona. It’s fair to say things even felt a little European.

Obviously, there’s a lot of buzz about Motorola. For all of the horrendous history they have on the user interface front, Captain Zander and the gang have been doing some hard work whipping their phone platform into shape for the 21st Century. They have a great bunch of engineers and their “feature phone” devices are some of the most popular in the world - the bestselling device of 2006 I believe was the RAZR - but these “big hits” are few and far between, and Motorola just hasn’t managed to build the sheer volume of models that companies like Nokia have. Motorola has become pretty strong on style, but their software has unfortunately been weak - it’s fine in the guts of the thing but the bits the user sees have been very poorly thought out. They were a bit late to the UI party. So I was certainly interested to hear what they had planned.

Despite the advertised breakfast, a woefully small stack of pastries was on offer (note to event organisers - please - a proper feed in future?) but free WiFi and a lounge-like atmosphere made for a nice escape from the biting cold outside. The keynote kicked off at about 9:30 and Christy Wyatt greeted us with Motorola’s perspective on where the big challenges were in the mobile industry and how Motorola was going to address them.

Keynote
The main theatre where the keynote was given.

(Christy was actually pretty refreshing. I’m becoming slightly tired of the woeful presentation skills shown at these events and she was great. No notes, spoke well to the audience and didn’t stumble or start, despite some technical outages. Bravo.)

Christy Wyatt
Christy Wyatt, VP for ecosystem and market development @ Motorola, delivers the keynote.

Here’s where it got interesting. The single biggest issue facing the mobile market from a developer’s perspective is - fragmentation. But instead of addressing the issue by driving their platform strategies to minimise this (like Nokia does), Motorola are determined to go bananas and back pretty much every platform under the sun. So Motorola has;

  • AJAR (The “low-end” platform MIDP 2.0, migrating to MIDP 3.0 in the coming year or so)
  • MOTOMAGX (The “feature” platform - Linux, MIDP and WebUI)
  • UIQ (”High-end multimedia” platform)
  • Windows Mobile (”Enterprise Mobility”)

So Motorola is exhibiting the broader malaise of the mobile industry. They are fragmenting their platform strategy. Frankly, this isn’t a help to developers, but a hindrance. They offer a confusing array of development choices and no way of addressing their handset base with a single effort. Perhaps it’s unfair to think that this is even possible, but it looks to me like they are backing every horse - a bet which is going to be expensive and inefficient.

The question on everyone’s minds, of course, was - what about the Open Handset Alliance? Motorola are part of the gang there, so what are they doing about it? Can they tell us anything about the platform and when are they going to launch something with it? Predictably, the nice people at Motorola looked a bit like rabbits caught in headlights - because although they were part of the OHA, they had no idea of the shape of Android was actually going to take. So the OHA doesn’t look like a club of collaborators so much as a group of companies interested in the rabbit that Google is going to pull out from their hat.

So the sparsely populated hall emptied out - Motorola had put on a wide spread of talks in 5 different tracks that people could attend. The one that had really caught my eye was the presentation on the MOTOMAGX platform. I knew from the past that Motorola had been trying to do something with Linux but had thus far been unsuccessful in their attempts to commercialise it. How far had they come? Had they done it yet?

MOTOMAGX presenters
The MOTOMAGX presenters prepare to start.

I was pleased to discover that they had. MOTOMAGX really is Linux and it really is running on their new feature phone devices - from the RAZR 2 onwards. There is the plan to offer a Linux SDK from H2 2008 onwards, and QT 2.3 is currently being used for the UI. So there really is an “open source phone”, although of course you can’t rebuild the kernel for this particular device…

MOTOMAGX Block Diagram
A block diagram of the MOTOMAGX solution. 3 different development options on the one device. Ouch.

The most surprising thing for me was Motorola’s efforts to offer the “widget” model of application development to the community. The newer devices sport WebKit and Motorola are adding a broad JavaScript extension model in order to allow proper off-line applications. I’m pretty skeptical about how successful this will be for mobile applications (Widgets aren’t really useful for desktop applications; why does anyone want to use them for mobile applications?) but it is interesting to see how broadly WebKit is now being used in the mobile market. Nokia, Motorola, Apple and now Google are all behind it and shipping it as their on-device browser of choice.

Oh, and all of these SDKs will be in a single “unified” development environment (Eclipse, of course). They should all be available in H2 2008, and we are certainly looking forward to the possibilities - particularly in the native application space.

So - even more fragmentation. There are 3 different application frameworks to choose from - on the one device platform!

MOTOMAGX Mob
The presenters are mobbed. The offer of early access to the MOTOMAGX SDK proves too much for the huddled masses.

The MOTODEV road show heads off to Beijing next in order to spread the news. But a fragmented mobile world we live in today looks set to get even more so in the coming years. It’s going to get a lot worse before it starts to get better.

Using ILogger

Friday, November 2nd, 2007

It’s strange how many BREW specialists you can talk to who have never used ILogger. It’s not hard to see why, though: the API reference only sometimes tells you the details of how to use it, and while the ILogger overview notionally tells you what it does, you have to read it very carefully to figure out how to use it.

And when you find out what it does, it doesn’t seem like the most appropriate thing to use.

Because you don’t want to be bored with the details (otherwise you’d be reading the API reference, hoping to find out what you’re missing), I’ll give you a code example:

#include "AEELogger.h"
void log_something(AEEApplet* pMe)
{
    int bucket = 0;

    ILogger *pILogger;

    // Error checking has been omitted in this example for clarity
    ISHELL_CreateInstance(pMe->m_pIShell,
                                    AEECLSID_LOGGER_WIN,
                                    (void**)&pILogger);
    ILOGGER_SetParam(pILogger,
                              AEE_LOG_PARAM_FILTER_ONE,
                              bucket,
                              (void*)TRUE);

    // Do the actual logging
    LOG_TEXT(pILogger, bucket, "Hello world");

    // Cleanup
    ILOGGER_Release( pILogger );
    pILogger = NULL;
}

As mentioned in the comments, error handling has been omitted: if ISHELL_CreateInstance() fails, your app will crash (ISHELL_CreateInstance(), ILOGGER_SetParam(), and LOG_TEXT() return error codes; ILOGGER_Release() returns the ramining reference count). In English, what it does is pretty simple:

  1. Create an ILogger instance, which logs to the BREW output window.
  2. Enable log bucket 0.
  3. Log a test message.
  4. Release the logger, and set the pointer to NULL (generally good practice).

The log output appears a bit cryptic at first: the log message is prefixed with the log bucket, the record type, your app’s class ID, and the ILogger’s instance ID.

There are three classes implementing ILogger mentioned in the API references:

  • AEECLSID_LOGGER_FILE logs to a file
  • AEECLSID_LOGGER_SERIAL logs to the serial port, and
  • AEECLSID_LOGGER_WIN logs to the BREW Simulator output window.

Already, you’ve probably realised something: It doesn’t log to the serial port or BREW output window as appropriate, unlike DBGPRINTF(). Of course, you can probably do something with an #ifdef. [1]

You set parameters with a call to ILOGGER_SetParam() (parameters are defined in AEELogParamType). While param is usually a uint32, pParam is sometimes a uint32pretending to be a void*, and the documentation isn’t that clear on this.

There are 256 log buckets, which can be filtered by the app (call ILOGGER_SetParam and set AEE_LOG_PARAM_FILTER_ONE with the bucket in param and (void*)TRUE or (void*)FALSE in pParam), and by the log parser, so it’s good for tagging different sections of code so you can switch logging for, say, your network code on at runtime. There are also 256 instance IDs, and the default is 0; you set it by setting AEE_LOG_PARAM_INSTANCE_ID. If you do it at runtime with some sort of thread ID, you can distinguish between threads.

There are 65536 record types, defined in AEELogItemType:

  • 0 is text,
  • 1 is a “binary message”,
  • 2 is a “binary block” (a BLOB), and
  • anything 0×100 or over is in a “user-defined format”.

A binary message is typically produced from ILOGGER_PutMsg(). The format is defined in AEELogBinMsgType, but to summarise, they’re fixed at 112 bytes (supposedly this makes logging faster), and store four uint32s and two strings totalling 80 bytes (including null terminators); the first uint32 is meant to be __LINE__ and the first string is meant to be __FILE__ (and standard log parsers probably assume this). The current implementation (3.1.5 simulator) also outputs some contents of your stack if you don’t fill 80 bytes with the two strings, this is a security risk (it ought to zero them anyway to make log entries cleaner).

A binary block is just a byte array, and you’ll have to find a way of distinguishing between them (like user-defined formats, or a prefix string, or XML).

If you’re logging to a file, you’ll have to call ILOGGER_SetParam() with AEE_LOG_PARAM_FILE_NEW and a file name (drive letters don’t work; for testing, just use something like “LogFile”). You need to #include "AEEFile.h" for the file modes.

You’ll notice that logs are actually in a binary format. It’s defined in the API (AEELogRecord, AEELogRcdHdrType), but I haven’t found something that will parse the log files, let alone let you filter for specific buckets and class IDs, let you have pluggable pretty printing for your user-defined log format, or save a BLOB to a file. ILogger could prove to be a useful general logging tool (all apps spam the serial port, and the receiver filters), but for most purposes, it’s a bit overkill.

[1] The BREW Tools Suite’s BREW Logger is meant to be able to connect to the BREW Simulator, but I haven’t managed this. Anyone?

Persistent Storage on BlackBerry Curve 8300

Tuesday, October 30th, 2007

There are three persistent storage methods available directly for Java CLDC applications on BlackBerry devices:

  1. The MIDP record store
  2. RIM’s persistent object API
  3. The file system, which is newly available in version 4.2 of the OS, and permits storage of multimedia files.

The record store and persistent object API are typically used by applications for storing configuration and other data so that it is hidden from other applications. We thought it would be interesting to compare the MIDP record store and the persistent object API, since they probably share at least some of the same underlying implementation, but code using the record store should be easier to port to other devices.

We tested reading and writing a 10-byte buffer to/from persistent storage, using each of the MIDP record store interface (javax.microedition.rms) and the RIM persistent object interface (net.rim.device.api), on a BlackBerry Curve 8300 running BlackBerry OS v4.2.2.114 (platform 2.4.0.53):

Writes Reads
Persistent Object Store 18.5 ± 0.4 ms/write 13.6 ± 0.2 us /read
MIDP Record Store 16.7 ± 0.3 ms/write 57.7 ± 4.6 us/read

These were estimated using 10 runs of 1000 writes and 10 runs of 10000 reads; the ± figures denote standard deviation. Note how read speed is an order of magnitude faster than write.

The persistent object store read takes about a quarter of the time of the MIDP record store read, presumably because no copy is required (the persistent object store just returns a reference to an already instantiated object) and there is no indexing overhead, just a hash table lookup to find the reference.

So, use the Persistent Object Store unless you really value the additional portability or the 2 ms time difference on writes.

Airsource are recruiting

Wednesday, August 15th, 2007

If you’ve been following our blog, you’ll notice things have been a bit quiet recently. Business is good - and we need another software engineer. If you’re good, and willing to work in Cambridge (that would be Cambridge UK, for our US readers), then we’d love to hear from you. Experience counts, but so does passion and talent.

Degrees? We’ve met PhDs who can’t, and 15 year-olds who can. If you’re looking for your first full-time software job, then you will learn more in a month with us than in a year at a big corporate. If you’ve been watching your company fail to learn from history for, well, what seems like long enough to *be* history, then come talk to us. If you want to be in early on a successful startup, whether in a junior or senior role, send your CV to jobs@airsource.co.uk. More details at http://www.airsource.co.uk/jobs.

Agency emails will go straight on our spam filter. If we want an agency, we’ll call you.