Archive for the ‘bluetooth’ Category
My bluetooth checkers game is ready to go!!!
I promise this is the last Checkers version (for a long time anyway 😉 ), and next I’ll move on to some graphics discussions. But I wanted to take one standard game and program it using a few different protocols to compare and contrast how each one works in a multiplayer game.
I think Bluetooth is a little more challenging and complicated to program than SMS. Part of the reason for that is that SMS uses the operators’ standard way of routing communications to a handset. You find the right destination by typing in the right phone number. And it’s the same phone number you’d use to route other comunications to that device. So you don’t have to reinvent the wheel to find, identify, and authenticate the device you’re looking for.
Bluetooth allows you to find all active, bluetooth-enabled devices within range and see what kind of services they offer. Each server offering a bluetooth service publishes a set of detailed service records describing the services available. So you have a fair amount of work on the server side creating useful descriptions and on the client side reading the descriptions and choosing the right service on the right device. Add to that the fact that you have the option of choosing a plain socket type connection or discrete packets, different authentication and/or encryption schemes, and even object-oriented communications using Java OBEX, you have practically unlimited potential to customize (and complicate 😉 ) your application according to your needs.
In my case, I decided I wanted to make my game’s communications as simple as possible. So I started with the assumption — since bluetooth is a protocol for local communications — that you and your friend are in the same room together and have verbally agreed to start up a game of checkers on your two handsets. My checkers game is fundamentally a peer-to-peer type game, but bluetooth is a client-server protocol, so I had my game start with a screen where the user can choose whether his handset will be acting as the client or as the server (the first player selects server and the second client).
Then there was the question of writing the code so that the two devices will find each other instead of finding other random bluetooth devices and services. Fortunately — with a simple services like this one — all you really need is a UUID. You can create your own UUID (in both Linux and Windows) using the uuidgen command. Then on the server side, all you need to do is construct your bluetooth URL using your UUID and open the connection and wait for clients to call you up. My game’s server URL looks like this:
The “btspp” indicates that I’d like to use the bluetooth streaming (socket-like) protocol, the “localhost” makes me a server; then I add on my UUID (what the “uuidgen -t” with the hyphens removed), then some attributes (the application name and the fact that I don’t want to require authorization). Opening this connection creates the corresponding service record, which you can get a handle to and add attributes to if you like. The WTK’s BluetoothDemo shows a good example of how to add additional descriptive attributes. The BluetoothDemo has a server that makes images available for bluetooth clients to download, and there you can see the programmer has added a custom attribute to give the name of the image being offered. As you can see in the ServiceRecord JavaDoc, there are a number of common standard attributes that you can use as well. The attributes aren’t too complicated to use — you just need to keep in mind that different attributes values can be of different types so the values are wrapped in DataElements that allow you to handle all of the different types of values in a consistent way.
Once your server is up and running, the next thing is to program the client to find it and connect to it. Basically, all you need to do is grab a handle to the local DiscoveryAgent and send it off in search of devices and services. It toodles around on its own thread looking for them, then it calls the assigned DiscoveryListener when it’s done.
Discovery is a two-step procedure: First you gather a list of devices, then you search the devices for the service you want. (Since I didn’t bother with any special service record attributes on the server side, when I started searching my device list for services I sent a null attrSet to the searchServices method.) Note that if you’re writing a program where the client frequently reconnects to the same set of known servers, you can optimize discovery by caching a list of known devices.
It might seem like you could simplify the discovery procedure by calling the method DiscoveryAgent.selectService() which finds all of the available connections that provide the desired service (without first getting all the devices and searching each one). Or that you could optimize by searching each device for services as you find it rather than first finding all devices and then searching them one by one. However, over on developer.sun.com I found this interesting little powerpoint presentation full of bluetooth programming best practices, and this little slideshow specifically says not to do either one of those things. Because they seem like good ideas, but really the lead to nothing but badness. And I figure that if anyone would know the people over at developer.sun.com would, so I decided to follow their advice.
Once the client side of the program and the server side find each other, the rest is a breeze! Whew! From then on it’s just standard Java socket programming. The server’s acceptAndOpen command stops blocking and returns a handle to the connection. Both the client and the server open the InputStream and OutputStream of their respective connections, and start sending each other data. All you have to do is send the right data down the stream and read it and interpret it correctly on the other side. What could be easier? 😉
For the bluetooth version of the checkers game, I eliminated the “taunt” feature I’d added for SMS Checkers. With SMS checkers, you can play against your friend wherever he may be. When you start up the game and enter your friend’s phone number — thanks to the push registry — the invitation SMS will buzz his handset to invite him to play whether he’s on the other side of the world or in a meeting or whatever. So it’s useful to be able to send a text message along with every move. In the bluetooth version you essentially have to have already agreed together that you want to play, so the taunt feature is less useful. It would have been possible to hook up the bluetooth version to the push registry as well, but I figured it was already complicated enough as it is.
So please try it out and tell me what you think!