A nice little BES / BIS “gotcha”

A nice little BES / BIS “gotcha”

A funny thing happened while testing today.

Well. It really wasn’t that funny.

Just strange.

I was testing a new Blackberry app to run solely over BIS and / or solely over BES.

And all hell started breaking loose.

JSON wouldn’t parse. Calls broke. Dogs and cats lied down next to each other.

After a little digging, I discovered that when an app makes calls over BIS or BES, there’s a good chance the data you get back will be a mixed stream of UTF-16 and UTF-8 data.

Not just a good chance. In my case, it ALWAYS returned mixed data.

Talk about your basic cluster smuck.

The fix turned out to be simple enough. I just had to set x-rim-transcode-content in my HTTP headers to none and voila! Problem solved. Nothing but good ol’ pure UTF-8.

I can’t imagine how many people out there are having this problem.  But I hope this little “heads up” can save someone a little grief.

Always Challenge Your Assumptions

Always Challenge Your Assumptions

I spent the better part of the weekend trying to fix a bug that was perplexing me and arresting my progress on a new Blackberry project.

Not that you particularly care, but it had to do with how Blackberry creates “tunnels” (connections) to communicate over the internet. There are about a dozen different ways to connect (BIS, BES, Direct/TCP, WiFi, WAP, WAP2, in HTTP and Sockets variations), and if you don’t hold your tongue ** just right ** your connections won’t happen.

Anyway, almost all of my connections were working perfectly. After all, this wasn’t my first Blackberry project and I was using a library I had developed and used on other projects.

But I had one call that was failing every time I tried to run it on a real device (and maddeningly, working perfectly under the simulator).

What was going on? I mean, I’ve used the library before with no issues whatsoever.

But I hadn’t used it in ** just ** the way I was now using it; and there was the rub.

As it turned out, I was using a call in the library that I had never used before.

And because of this, there was a place in the code where I had neglected to correctly determine the type of connection I needed to make (again with the BIS, BES, Direct/TCP, yada, yada, yada) and so my connections were failing on a real device.

It only took me two days to realize that I needed to challenge my assumptions that the library was right… and if I had done what I should have done originally (namely, examine directly the call in question) I would have had more time to myself and my family this weekend.

For the more technically inclined, I present the code I usually use to create internet connections for Blackberry apps below:

public static final int CONNECTION_DEFAULT = 0;
public static final int CONNECTION_BIS = 1;
public static final int CONNECTION_BES = 2;
public static final int CONNECTION_TCPIP = 3;
public static final int CONNECTION_WIFI = 4;
public static final int CONNECTION_WAP = 5;
public static final int CONNECTION_WAP2 = 6;

public static HttpConnection makeHttpConnection(String url,
HttpHeaders requestHeaders,
byte[] postData,
int connType,
String requestMethod,
boolean uploadData)
HttpConnection conn = null;
OutputStream out = null;

if (StringUtilities.startsWithIgnoreCase(url, "www.")) {
url = "http://" + url;

try {
if (url.indexOf(";deviceside=") == -1) {
switch (connType) {
url = url + ";deviceside=false";
url = url + ";deviceside=false;connectiontype=mds-public";
url = url + ";deviceside=true";
url = url + ";interface=wifi";
url = buildWAP2(url);
System.out.print("\n****\nThis is what we're trying to open: " + url);

conn = (HttpConnection) Connector.open(url, Connector.READ_WRITE);
try {
if (1==0) {
ConnectionFactory connFact = new ConnectionFactory();
TransportDescriptor[] transports = TransportInfo.getAvailableTransports();
System.out.println( "Available transports: " + transports.length );
for ( int i = 0; i < transports.length; i++ ) { TransportDescriptor t = transports[ i ]; int type = t.getTransportType(); boolean hasCoverage = TransportInfo.hasSufficientCoverage( type ); System.out.println( "Type: " + TransportInfo.getTransportTypeName( type ) ); System.out.println( "Coverage: " + hasCoverage ); System.out.println( "Cid: " + t.getCid() ); System.out.println( "Uid: " + t.getUid() ); System.out.println( "\n" ); } int preferredTransportTypes[] = {TransportInfo.TRANSPORT_BIS_B, TransportInfo.TRANSPORT_TCP_WIFI, TransportInfo.TRANSPORT_MDS, TransportInfo.TRANSPORT_WAP2, TransportInfo.TRANSPORT_TCP_CELLULAR,}; ConnectionDescriptor connDesc; connFact.setPreferredTransportTypes(preferredTransportTypes); connDesc = connFact.getConnection("http://myserver.gr"); if (connDesc != null) { conn = (HttpConnection) connDesc.getConnection(); final int code = conn.getResponseCode(); System.out.println("Code: " + code); } else { System.out.println("No connection"); } } } catch (Exception e) { System.out.println("Exception: " + e.getClass().toString() + " -> " + e.getMessage());

if (requestHeaders != null) {
String referer = requestHeaders.getPropertyValue("referer");

boolean sendReferrer = true;

if (referer != null &&

StringUtilities.startsWithIgnoreCase(referer, "https:") &&

!StringUtilities.startsWithIgnoreCase(url, "https:"))
sendReferrer = false;

int size = requestHeaders.size();
for (int i = 0; i < size;) {
String header = requestHeaders.getPropertyKey(i);
if (!sendReferrer && header.equals("referer")) {

String value = requestHeaders.getPropertyValue(i++);
if (value != null) {
conn.setRequestProperty(header, value);

conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.0");

if (requestMethod.equalsIgnoreCase("PUT") || requestMethod.equalsIgnoreCase("POST")) {

if (postData!=null) {
conn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LENGTH, String.valueOf(postData.length));
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
out = conn.openOutputStream();
catch (IOException e1) {
System.out.println("makeHttpConnection: " + e1.toString());
close(conn, null); // Close the connection
conn = null;
finally {
close(null, out); // Close the output, but keep connection open

return conn;

public static int getCoverageBasedConnectionType() {
int preferredTransportTypes[] = {TransportInfo.TRANSPORT_BIS_B, TransportInfo.TRANSPORT_TCP_WIFI, TransportInfo.TRANSPORT_MDS, TransportInfo.TRANSPORT_WAP2, TransportInfo.TRANSPORT_TCP_CELLULAR,};
ConnectionFactory cf = new ConnectionFactory();
ConnectionDescriptor cd = cf.getConnection("http://www.google.com");
if (cd!=null) {
TransportDescriptor transportUsed = cd.getTransportDescriptor();
int _transportMode = transportUsed.getTransportType();
System.out.println("\n\n_____\n\nTransportType: " + _transportMode + "\n\n_____\n\n");
switch (_transportMode) {
case TransportInfo.TRANSPORT_BIS_B:
System.out.println("Transport: BIS");
case TransportInfo.TRANSPORT_MDS:
System.out.println("Transport: MDS");
System.out.println("Transport: Cell (Direct TCP)");
case TransportInfo.TRANSPORT_TCP_WIFI:
System.out.println("Transport: Wi-Fi");
case TransportInfo.TRANSPORT_WAP:
System.out.println("Transport: WAP");
case TransportInfo.TRANSPORT_WAP2:
System.out.println("Transport: WAP2");
System.out.println("Transport: WAP");


static String buildWAP2(String url) {
ServiceBook sb = ServiceBook.getSB();
ServiceRecord[] records = sb.findRecordsByCid("WPTCP");
String uid = null;

for(int i=0; i < records.length; i++)
//Search through all service records to find the
//valid non-Wi-Fi and non-MMS
//WAP 2.0 Gateway Service Record.
if (records[i].isValid() && !records[i].isDisabled())

if (records[i].getUid() != null && records[i].getUid().length() != 0)
if ((records[i].getUid().toLowerCase().indexOf("wifi") == -1) &&
(records[i].getUid().toLowerCase().indexOf("mms") == -1))
uid = records[i].getUid();

if (uid != null)

//open a WAP 2 connection
return url + ";ConnectionUID=" + uid;
{return "";}