Logo ©1994-2007 Kevin Boone
My professional interests
Computing
Law
Education
Science and research

My leisure interests
Martial arts
Heritage railways
Garden railways
Motorcycles
DIY

Downloads
Linux downloads
Windows downloads
Java downloads
Perl downloads
Home automation downloads

About me
Home & family
My CV

Site info
Contact the author
Download policy
Keyword index

  Home > Computing > Linux

Using Linux with the Sony-Ericsson P800

Last modified: Thu Jul 8 11:52:21 2004

The P800 is a genuinely amazing device - as well as being a mobile phone, it is also a GPRS modem, a PDA, a camera, an audio player/recorder, an e-book reader, and a load of other useful things. It can be programmed in Java (two different versions), C++, OPL, and Visual Basic. It has an impressive range of connectivity options, a quarter-VGA screen, handwriting recognition, and up to 128 Mb non-volatile RAM. Its only real disadvantage is the lack of Linux support from the vendor. I have to confess that I did try using Windows to develop software for the P800, my early attempts to get it to talk to Linux having been so fruitless. However, I did not find the reliability of Windows to have increased to a usable level since I last used it five years ago, so I abandonned this attempt (not without a sigh of relief) and redoubled my efforts on Linux. In the end, I managed to get the P800 chatting quite happily with Linux using bluetooth, and I can send and recieve files and PDA elements reliably. I can even use the P800 to control my house lighting and audio equipment via bluetooth. This article explains how.

Intended audience

This article is intended for experienced Linux users, who have some knowledge of the concepts of bluetooth. To get bluetooth support working with the P800, you will almost certainly have to recompile Linux kernel modules, and reconfigure the module loader. These are not tasks for the faint-hearted, and this article won't attempt to explain how to carry them out. There's plenty of good information on the Web on Linux kernel configuration.

Getting files to and from the P800

Apart from over-the-air transmission, the P800 supports three methods of connectivity: IrDA, USB, and bluetooth. To these may be added a very simple strategy which I find I use all the time: taking the memory stick out of the P800 and putting it in a USB memory stick reader on my laptop. Although the P800 takes the unusual `Duo' memory sticks, it is supplied with an adapter that allows the Duo stick to plug into a standard memory stick reader. For about £25 you can get a USB2.0 reader, which will usually be supported by the standard usb-storage driver in Linux (mine is a `Dazzle' (whatever that is) but these devices nearly always use the generic USB storage protocol). One should not underestimate the bandwidth that can be achieved by physically carrying memory sticks around: this method of data transfer is hugely faster than any of the high-tech options available. When it comes to, say, beaming business cards around, you can't beat the convenience of bluetooth. But if you want to transfer a 30 Mb MP3 file, for example, bear in mind that it will take a few seconds with a USB2 memory stick reader, and many minutes over bluetooth.

USB and IrDA

The P800 is supplied with a USB cable attached to a desktop cradle. There appear to be at least three version of this cradle in use, and even cradles with the same part number can have different internal chipsets. All appear to operate a simple serial protocol over USB, and could - in principle - be mapped to a serial device. It seems that the earlier cradles are supported by the serial driver for the Prolific PL2303 device, which is part of the stock Linux kernel. Later USB cradles appear to be supported by the ftdi_sio driver, also widely available. However, some cradles don't seem to be supported by either of these. Mine isn't. Even if your USB cradle is notionally supportable, you will likely find that its USB vendor/product ID is not recognized by the Linux USB infrastructure. If this is the case, you'll see a message like this in the system log when you plug it in (provided USB hot-plug support is enabled)
usb.c: USB device 2 (vend/prod 0xa33/0x2011) is not claimed 
by any active driver.
You could always try finding the relevant lines in the source code for the driver modules that you think might support your USB device, and adding your vendor/product code to the list that the driver supports. This will force the driver to be attached when you plug the device in. But don't expect miracles - I have seen very few reports of P800 users getting USB connectivity to work. If it does work, you should be able to connect a terminal emulator like minicom to the USB-serial device /dev/ttyUSB0 and communicate with the P800 as a modem (you'll need to set the cable mode to `modem' in the P800 for this to work). I can't comment further on this, as my USB cradle doesn't seem to be one of the supported types (I've tried it with all the standard USB serial drivers that come with the stock Linux kernels, in versions from 2.4.18 to 2.6.0, but no joy).

I'm given to understand that IrDA communication works fine, but since my laptop doesn't have an infra-red port, I haven't tried it. It's worth bearing in mind, if you're making a choice between buying a bluetooth adapter or an IrDA adapter, that although bluetooth is more convenient, the P800's built-in applications at present support IrDA slightly bettern (see below for workarounds).

Bluetooth configuration

My laptop has a stock 2.4.20 kernel patched for ACPI and suspend-to-disk support. This means that there are bluetooth drivers included in the kernel source; these drivers are from the Bluez project. My initial lack of success in getting the Bluez kernel drivers to work led me to do two things: (i) try the Affix bluetooth support instead, and (ii) patch the kernel to the same version of the Bluez drivers that is in the very latest kernel releases. With hindsight, I suspect that the problems I had were the result of my own ignorance, not faulty drivers. In the end I had success with the latest Bluez drivers, but not with Affix (discovery worked, but the P800 would not respond to a ping; see below). In the stock kernel, the `rfcomm' module (part of the Bluez driver set, supporting serial-type communication over bluetooth) does not appear to get compiled in a way that will work with the P800. It needs to have `TTY' support enabled. Check that your .config file has the line:
CONFIG_BLUEZ_RFCOMM_TTY=y
If this is not set, discovery will work, and you'll be able to send and receive files, but you won't be able to use PPP or dial-up networking. As well as probably patching and recompiling the kernel, you'll need the Bluez utilities and libraries. I found that the RPM binary distributions worked fine on my RedHat system, so I did not compile them myself.

I bought a Belkin F8T001 bluetooth USB dongle; PCMCIA bluetooth devices are also available, but slightly more expense. The price of a bluetooth adapter increases with its range. The Belkin cost about £40, and is claimed to have a 100m range. I haven't tested this, but it certainly works from one end of my house to the other.
      The bluetooth specifications define a mapping between bluetooth protocols and USB protocols, so in principle the Bluez hci_usb driver should support all USB bluetooth dongles. However, it turns out that the F8T001, and other devices based on the Broadcom BCM2033 chipset, need to have firmware downloaded before they can do anything useful. They won't be handled by the hci_usb driver until this is done. Part of the Bluez package is a firmware downloader (which is needed for Affix as well) called bluefw. This is not a driver, it is a utility that must be execuded once whenever the bluetooth dongle is plugged in. It is run like this: bluezfw usb XXX/YYY where the `XXX/YYY' part is the pseudo-file entry under proc/bus/usb that maps to the USB dongle. For example, on my system I have two USB buses, so under /proc/bus/usb I have directories 001 and 002. Under these directories are entries for each device on the bus. Device numbers are assigned whenever a new device is plugged in. So if the USB dongle is the first device on bus 1, you need to run bluezfw like this: bluezfw usb 001/001 The `001's are not numbers, they're directories, so it doesn't work if you say bluezfw usb 1/1 Note that bluefw does not produce any error message if it fails. It does, however, print a success message if it works. So if you run it, the absence of error messages does not mean it worked. In addition, the absence of the firmware won't stop the hci_usb module being loaded, but it won't do anything useful.
      The RPM package of bluefw configures the USB hotplug agent to execute bluefw whenever the dongle is inserted. This works on my desktop system, but not my laptop; both have almost identical kernel configurations, and both are based on RedHat 9, so I don't know why one should work and the other not. In any event, it's easy enough to run the firmware downloader if it doesn't get done automatically.

To use the bluez software with the P800 as described below, the following modules need to be loaded: bluez, l2cap, sco rfcomm, and hci_usb. You can configure these to load automatically when the system tries to bring up the bluetooth interface hci0, by creating an alias in modules.conf from net-pf-31 to rfcomm. However, with the F8T001 and similar devices, the fact that the device won't have its firmware installed when it is plugged into the bus means you'll still have to load hci_usb manually (or in a script). So, on my system I have just arranged for all the modules to be loaded at boot time.
      You'll also need to set up modules.conf to associate the modules with their device major IDs, as follows:

alias net-pf-31 hci_usb 
alias bt-proto-0 l2cap 
alias bt-proto-2 sco 
alias char-major-216 rfcomm
alias tty-ldisc-3 ppp_async
The last one is needed for PPP interactions.

With the modules loaded and the firmware installed, you should be able to do

hciconfig hci0 up
to make the bluetooth interface available to the rest of the bluetooth protocol stack. If you run hciconfig hci0 you should see output like:
hci0:   Type: USB
        BD Address: 00:03:C9:2E:46:E3 ACL MTU: 377:10  SCO MTU: 16:0
        UP RUNNING PSCAN ISCAN
        RX bytes:188 acl:0 sco:0 events:17 errors:0
        TX bytes:42 acl:0 sco:0 commands:10 errors:0
The `BD Address' (usually shortened to `BDAddr') is the unique hardware address of the bluetooth adapter. When you scan for other bluetooth devices, you should get their BDAddrs. Do this:
hcitool inq
and make a note of the BDAddr of your P800, because you'll need it later. You can test that basic connectivity is in place between the Linux box and the P800 using l2ping, which sends a test packet that the P800 echos back:
l2ping [BDAddr]
This is a good test because it doesn't require any of the higher-level protocol elements (like RFCOMM) to be working, so it is unlikely to fail because of a trivial misconfiguration. So long as the bluetooth adapter is working, and the firmware installed, the ping should succeed.

In my experience, the P800 is only happy to receive files from hosts that it has explicitly been associated (`bonded') with. In addition, it can only send files to systems that it can find by discovery - there is no procedure by which you can specify the hardware address of the host. Moreover, I don't believe the phone can respond to an incoming request for bonding - it has to initiate one itself (using the bluetooth properties dialog). In consequence, the Linux box needs to able to respond to bonding requests from the P800, which means that it must be running the hcid daemon, at least until the bonding is complete. On a RedHat system, the script /etc/init.d/bluetooth start starts the hcid daemon, and also sdpd. The latter responds to service discovery requests. I'm not sure that the P800 makes service discovery requests: it seems to assume that services are on hard-coded channel numbers (see below). If anyone can confirm or refute this, I'd be interested to know.
      hcid reads two configuration files; by default the main configuration file is at /etc/bluetooth/hcid.conf, and the PIN number (for the host, not the remote device) is at /etc/bluetooth/pin. Most mobile phones only support numeric PIN numbers.

So, in summary, the process for intializing the bluetooth protocol stack using the F8T001 USB adapter is:

  • Load the modules bluez, rfcomm, bnep, l2cap, sco and hci_usb
  • Use bluefw to install the firmware in the USB dongle
  • Using hciconfig hci0 up to bring up the interface
  • Start the hcid and (perhaps) sdpd daemons.
The process should, in principle, be identical for other USB bluetooth dongles, except that you won't normally have to install firmware. Note that the firmware install is not a one-off process; it needs to be repeated whenever the dongle has been unplugged.

Sending and receiving data using P3NFS

P3NFS is an NFS emulation that was originally developed for the Psion range of PDAs. You can get the latest version (5.14 at the time of writing) from Rudolf König's Web site. The software has two parts: one (p3nfsd) for the Linux machine and one for the P800. It's very likely that you'll need to compile the Linux part: only the latest versions work with the P800, and there aren't many binaries around yet. The P800 part is distributed as a standard Symbian .sis file, and can be installed in the any of the usual ways. If you don't want to use a Windows machine for this, you could e-mail it to yourself, for example, and view the e-mail on the P800. You could also use ussp-push to send the .sis file bluetooth (see below for details).
      The P800 application appears on the launcher and can be run in the usual way. When it's running, you can use the jogwheel to select the protocol (jogwheel down) and debug level (jogwheel up). Increasing the debug level significantly slows down file transfers, and may cause a large transfer to the P800 to fail completely - presumably because the P800 can't keep up with the incoming data. The P800 part of N3NFS expects the host to establish communication within 30 seconds. If this doesn't happen, you may find you need to restart it.
      To use the Linux part of P3NFS over bluetooth, you must first establish an RFCOMM protocol channel using the rfcomm utility. A bluetooth device will support a number of different services, and each has its own channel number. What the rfcomm utility does is to link a particular bluetooth logical channel to a device entry in /dev (you'll also need to do this to `beam' files using OBEX: see below). Typically the devices are /dev/rfcomm0, /dev/rfcomm1, etc. All have major ID 216, and minor IDs from 0 upwards. If you don't have these devices (they aren't installed by default on RedHat 9) you can make them:
mknod -m 666 /dev/rfcomm0 c 216 0
mknod -m 666 /dev/rfcomm0 c 216 1
...
Each bluetooth channel can be assigned to a different /dev/rfcommXXX entry, or you can use the same entry and assign it to different channels according to what kind of service you want to use. Since the P800 appears to use fixed channel numbers for all its services, the latter approach is quite convenient. I have created the device /dev/rfcomm_p3nfs for P3NFS communication (always channel 4), /dev/rfcomm_obex for OBEX (see below), which appears to stick to channel 3, and so on.

To link the bluetooth channel to the device, use rfcomm like this:

/bin/rfcomm bind [rfcomm_device_number] [BDAddr] [channel_number]
rfcomm_device_number should match the minor device number of the special file in /dev: 0, 1, etc. BDAddr is the hardware address of the P800, and channel_number is the channel that the P800 is listening on. With P3NFS this is channel 4 (the P800 nfsapp application indicates this when you select the bluetooth protocol). On my system, I do:
rfcomm bind 0 00:0a:d9:5c:0a:51 4
which makes /dev/rfcomm0 available to support communication on logical channel 4. Actually, it makes the device whose major number is 216 and minor number 0, available; you don't have to call that device /dev/rfcomm0 if you don't want to.

With the RFCOMM bind set up, and the Linux part of P3NFS compiled, to start P3NFS:

p3nfsd -UIQ -tty /dev/rfcomm0 
This mounts the filesytem /mnt/psion. You can override this behaviour using a command-line switch to p3nfsd, but in any case the directory must exist. If you look in the directory /mnt/psion, you should see directories called A:, C:, D:, Z:. That's right - Symbian uses drive letters to identify disk devices, just like DOS. Yeugh. C: is the internal memory, D: is the memory stick, and A: and Z: are pseudo-filesytems in the P800 firmware. You should be able to copy files to and from these filesystems just like any other NFS share, but don't expect blazing performance. The fastest I've had it working is about 500 kB per minute (i.e., two hours to fill a 64 Mb memory stick!)
      The elegant way to disconnect the Linux box from the P800 when using P3NFS is to read the (non-existent) file /mnt/psion/exit. This is detected by the P3NFS daemon, which should shut down gracefully.
      OBEX push (described next) is faster than P3NFS, but offers less flexibility in where the files go.

Beaming files to the P800 using OBEX push over bluetooth

The OBEX (object exchange) protocol is essentially a way of sending e-mail attachments without the e-mail. You can use the OBEX protocol to `beam' files to the P800 and (perhaps) vice versa (see next section). Strictly speaking, you can only `beam' using light, not radio waves, and most of the applications on the P800 change their `Beam' menu command to say `Send to' when bluetooth is enabled. For simplicity, I will use the word `beam' anyway. To `beam' to the P800 you will need two things, in addition to what we've discussed so far: the openobex libraries, and a version of the ussp-push utility hacked to work with Bluez. You can get openobex from SourceForge, and ussp-push from here. Both will need to be compiled and installed. Note: on my system, for reasons I can't explain, the configure script from openobex failed to detect that there was a bluetooth installation. This failure is invisible, until it comes to using OBEX over bluetooth. Then everything will fail for no obvious reason. I was not able to get to the bottom of this problem, but a nasty fix is to run the configure utility in the openobex source in the usual way, and then add the line
#define HAVE_BLUETOOTH
to the end of the generated config.h.

To use ussp-push to beam a file, you'll need to know the RFCOMM channel that the P800 is listening on. You can find this from the output of sdptool browse. On my system, the relevant entries look like this:

Service Name: OBEX Object Push
Service RecHandle: 0x10003
Service Class ID List:
  "OBEX Object Push" (0x1105)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 3
  "OBEX" (0x0008)
Profile Descriptor List:
  "OBEX Object Push" (0x1105)
    Version: 0x0100
This indicates that channel 3 is the one we want. So, first we bind /dev/rfcomm0 (or whatever RFCOMM device you want) to channel 3:
rfcomm bind 0 [BDAddr] 3
putting in the appropriate hardware address for your P800. Then, send the file:
ussp_push /dev/rfcomm0 [source_file] [target_file]
ussp_push sends files in blocks (block size is 1 kB on my system); I found the transfer rate to be about 1.5 Mb per minute. Again, not scorchingly fast, but still faster than P3NFS.

When files arrive on the P800, they get put in the messaging Inbox, so you'll need to change to the messaging application to find them. Some P800 applications automatically move files out of the Inbox into their own application-specific file systems. For example, if you send a .pdb file, and your have Mobipocket Reader installed, when you select the .pdb file in the Inbox, Reader moves it to documents/unfiled.

Beaming files from the P800 using OBEX push over bluetooth

This is where things start to get a bit speculative. openobex supports the receipt of pushed objects at the library level, but it does not provide any client application to make use of this support. There are a few applications around that use openobex to provide an object push receiver. I have had some success with Beier and Dauskardts' OPD. This, like everything else described so far, must generally be compiled. When executed, it listens on a particular RFCOMM channel (the default is channel 1) until an object is pushed by a bluetooth device. The data that it receives is simply saved in a directory (defaults to /tmp). To run opd with these defaults, all you need to do is:
opd --mode OBEX --sdp
and then wait. If you select an item from the Contacts or Calendar applications on the P800, then choose `Send as' and then `Bluetooth' from the menu, it should just happen. opd does not work (for me at least) on any other RFCOMM channel than 1. The application does register itself with the host's sdp daemon, and the P800 should be able to do an SBP operation to find the channel. However, either the P800 always uses channel 1, or the sdp implementation or the opd application are not doing what they should. Note that you don't need to do anything with the rfcomm utility on the Linux box for opd to work - it doesn't use the /dev/rfcomm devices.

All that opd does is to store the files received from the P800. It's up to you what you do with them after that. Calendar and tasklist entries are transferred as VCAL files. Contacts are sent as VCARDs. These formats are both widely supported by Linux PIM applications. The other applications mostly send data as it is stored; so photos, for example, as sent as JPG file (a picture in maximum size and quality takes about 5 seconds to send by OBEX push).

The fly in the ointment is the Jotter application, which uses a proprietary format that I've not been able to decipher. For some reason, although the P800 says that it is `compressing' the data for transmission, a one-line jotter note ends up as a 6 kB file. Happily, there are other `Jotter' applications around that use plain text.

Irritatingly, although the P800 File Manager application has the ability to send any file, it can only send by IrDA. It doesn't support bluetooth at all. As a result, you can only send by bluetooth files that are associated with a specific application, and which have made provision for bluetooth. However, there is a neat utility called SMan which provides, among other things, the ability to send any file, or collection of files, by bluetooth. However, SMan only recognizes host devices whose bluetooth `device class' is `computer', which is not the default for Bluez. This is easy to fix:

hciconfig hci0 class 001001

OBEX FTP

The OBEX protocols support an alternative to object push called OBEX FTP. As the name suggests, it is a general file transfer protocol, like ordinary FTP but stateless. However, the P800 does not support OBEX FTP.

Modem support, PPP, and dial-up networking

If you've got everything described above working, you'll find that using the P800 as a modem - and thereby providing Internet access to your laptop, for example - is fairly straightforward. There's plenty of documentation on this subject; once you've got a modem connection between the P800 and the Linux box, you can use PPP to establish the connection to your ISP just as for a real modem. I'm not really interested in this, because I'm happy enough to use the P800 itself for mobile Internet access. With the Opera Web browser (not the horrid built-in thing) I can look at Web sites (even with frames, etc), which means I can also use web-based mail clients. What I'm more interested in is going the other direction, that is, using the P800 to look at systems on my local network. This is because I have a fairly sophisticated home automation system, all controlled by a web-based interface. In addition, if I can see the local network from the P800, then I can see the Internet through my local router and DSL connection. Getting Internet access this way avoids the use of GPRS/GSM, which can be expensive. Of course, this will only work if the P800 is within range of a computer with bluetooth support.

If you do want to use the P800 as a modem over bluetooth, the procedure is to bind an RFCOMM channel to the P800's `Dial-up networking' channel (do sdptool browse) to find which channel this is). This establishes a virtual serial port on, say, /dev/rfcomm0. You can then configure PPP (or whatever your ISP supports) almost exactly as you would for a real modem, but supplying /dev/rfcomm0 as the modem's serial port. Note that to connect using GSM, you would typically supply an ordinary telephone number in the PPP chat script - just as you might for a telephone dial-up connection. However, the P800 will operate as a GPRS modem as well, which has its own AT commands. In particular, to dial a connection you will need something like:

ATD* 99* 1#

Connecting the P800 to a LAN over bluetooth

For connecting to a local area network the P800 uses something called the `mrouter' protocol, which is essentially PPP with extensions. The LAN may consist of only the P800 and one other computer, or it may be a real network: it doesn't really make any difference to the P800. The use of PPP for LAN access is not the same as using it for ISP access. When the P800 is acting as a GPRS modem, it isn't talking PPP itself - the PPP session is between your computer and the ISP, with the P800 simply acting as a modem. To use the P800 on a LAN, the P800 itself must talk PPP to its host computer. When the PPP channel is established, all it gives you is a `tunnel' between the P800 and the host, with an IP number at each end; what gets sent down the tunnel is up to the applications at each end. I understand that the Windows applications supplied with the P800 use TCP/IP over PPP to communicate with the P800, but there is little or no documentation on this subject. What is more interesting is that some P800 applications will use the PPP channel for networking, rather than the GPRS or GSM stuff, so long as PPP is up. The Opera browser, for example, works fine. The built-in browser won't work, because it uses WAP protocols, not TCP, to carry the HTTP requests. The SyncML client built into the P800 also works, which opens up the possibility of synchronizing your P800 with Linux PIM applications that support SyncML. Ximian Evolution has SyncML support but, at the time of writing, it isn't quite stable.
      In the explanation that follows, the local area network has the following structure. All the workstations have IP numbers in the range 192.168.1.*. The Linux box that hosts the PPP session has its main IP number as 192.168.1.20, but it will get an additional IP at 192.168.1.23 when the PPP connection is set up. The P800 will get 192.168.1.24. There is an Internet router and DNS server both at 192.168.1.5.
      There are a number of complications with using PPP to get LAN access from the P800. First, the P800 will not (as far as I know) accept incoming requests to initiate a PPP session - it expects to initiate the session itself. There doesn't appear to be any way to tell the P800 to do this explicitly. The documented technique for setting up a session is to have the host computer attempt to establish a PPP session on the P800, which the P800 closes down immediately. The P800 then calls the computer, and asks it to set up a session.
      Because the computer will be responding to an incoming PPP call, as well as initiating one, it needs first of all to be aware that a call is coming in. This implies that something must monitor for RFCOMM connection requests originating from the P800 (since we don't have a real cable between the phone and the computer). There are at least two utilities for this: rfcommd, and dund. I understand that rfcommd is on its last legs, and dund is the recommended utility. All dund does, as far as P800 interaction is concerned, is to listen for RFCOMM activity on a particular channel and, when a call comes in, to spawn a pppd to do the real work. So, the overall sequence of interactions looks something like this.
  • The computer attempts to initiate a PPP session on the P800's virtual serial line (which is RFCOMM channel 1, at least on my P800). To do this it must bind an RFCOMM device to channel 1, then use it as the port for a PPPD call:
    rfcomm bind 1 [BDAddr] 1
    pppd call\
      /dev/rfcomm1 115200\
      noauth\ 
      user ppp\ 
      crtscts\
      lock\ 
      local\ 
      proxyarp\ 
      passive\
      192.168.1.23:192.168.1.24
    
    In practice the PPP settings won't go on the command line (although that should work), but in a file under /etc/ppp/peers. Then you can just do:
    pppd call [filename]
    
    for convenience. The IP numbers in the PPP settings are the addresses of the two ends of the PPP tunnel, in the order `local:remote'. The host computer is the `local' end of the tunnel in this case, and the P800 at the `remote' end. I'm not sure these addresses are actually relevant, because...
  • When the PPP session is established, it is closed by the P800 immediately. You should see something like this in the system log:
    pppd[4517]: found interface eth0 for proxy arp
    pppd[4517]: local  IP address 192.168.1.23
    pppd[4517]: remote IP address 192.168.1.24
    pppd[4517]: LCP terminated by peer
    pppd[4517]: Connection terminated.
    pppd[4517]: Connect time 0.2 minutes.
    pppd[4517]: Sent 93 bytes, received 119 bytes.
    pppd[4517]: Exit.
    
  • The P800 then does an SDP query to find the channel number of the `SP' (serial port) profile on the computer. It will only find one if it has been explicitly added to the computer's SDP daemon using, e.g., sdptool.
    sdptool add --channel=3 SP
    
    This command tells the SDP server on the Linux machine that its serial port service is on RFCOMM channel 3. I have picked channel 3 because it isn't doing anything else on my host computer; the number is arbitrary so long as it doesn't clash with anything (e.g., OBEX push daemon). All the sdptool command does is to identify a particular channel as hosting a particular service; it does not make any service available.
  • Having got the channel number of serial port service, the P800 then initiates a PPP session on it. For this to work, there needs to be something listening on the appropriate RFCOMM channel on the host computer. So we establish a listener on channel 3 using dund:
    dund --listen --channel 3 --msdun call [filename]
    
    The `--listen' argument should be fairly obvious, as should `--channel'. `--msdun' tells the daemon to enable Microsoft-specific extentions to the PPP protocol. I understand that these extensions are widely used, and I could not get the PPP process to work without using this switch. Finally `call [filename]' is the command-line arguments that dund will pass to to the pppd daemon when it detects an incoming call. The filename is of a file in /etc/ppp/peers, and contains the PPP settings for the incoming connection. Here is what works for me:
    noauth 
    debug
    115200
    crtscts 
    lock 
    local 
    proxyarp 
    ms-dns 192.168.1.5
    192.168.1.23:192.168.1.24
    
    The ms-dns switch specifies the DNS server that the P800 should use. This setting is required by the Microsoft-specific extentions to PPP, and is important (see below for why).
          When the P800 calls back on the computer, you should see something like this in the system log:
    dund[5200]: New connection from 00:0A:D9:5C:0A:51
    pppd[5201]: pppd 2.4.1 started by root, uid 0
    pppd[5201]: Using interface ppp0
    pppd[5201]: Connect: ppp0 <--> /dev/rfcomm1
    pppd[5201]: found interface eth0 for proxy arp
    pppd[5201]: local  IP address 192.168.1.23
    pppd[5201]: remote IP address 192.168.1.24
    
  • Once the PPP session is set up, the P800 immediately attempts to find the IP number of a router (gateway). This operation must succeed, or the P800 will drop the connection. The P800 attempts to find the router by doing a DNS lookup for the host wsockhost.mrouter on the DNS server it found during the PPP setup (remember the ms-dns PPP setting?). It follows that (i) there must be a DNS server reachable from P800 end of the PPP tunnel when the PPP session is being set up, and (ii) it must be capable of resolving names in the `mrouter' domain. I am using BIND9 for DNS; my zone file for the `mrouter' domain looks like this:
    $TTL	86400
    $ORIGIN mrouter.
    @ 1D IN SOA	@ root (
      42		; serial (d. adams)
      3H		; refresh
      15M		; retry
      1W		; expiry
      1D )		; minimum
    
    1D IN NS	@
    1D IN A		127.0.0.1
    
    wsockhost.mrouter.  IN  A 192.168.1.5
    
    There is only one entry, and it points the P800 at 192.168.1.5, the Internet router for the LAN. The router doesn't need to be able to route IP packets - although this might be useful - but it does need to be a real IP number.

    So that's the PPP session established, and it should then be possible to talk TCP/IP between the P800 and the Linux box. What you do with this facility is up to you.

Here are a few other things to watch out for with this set-up.
  • If you're using the P800 to view LAN resources, the DNS server and router need not be on the same machine as the bluetooth and PPP stuff, so long as they are reachable from a partly-configured PPP session. Remember that the DNS server needs to be reachable before the default gateway is supplied to the P800 (after all, it is the DNS server that will be supplying the gateway). So the DNS server must be on the same IP subnet as the P800.
  • Most Linux distributions are not set up to enable IP packet forwarding by default. What this means is that a packet sent from the P800 to the computer's end of the PPP tunnel will only get to the host computer, and no further. If you want to communicate from the P800 to other systems on the LAN, you must enable forwarding, like this:
    echo 1 > /proc/sys/net/ipv4/ip_forward
    
    In fact, for reasons explained below, you always want to enable packet forwarding when talking to the P800, even if your network consists only of the P800 and one Linux box.
  • If you only want to use PPP to have the P800 talk to, say, your laptop, you still need all the steps described above. You will need to run BIND, or something like, it on the laptop, or the P800 will drop its end of the PPP session.
  • BIND does not, by default, accept requests on any old IP interface. Its normal behaviour is to bind to all the interfaces it can find when it starts up. If a new interface comes up when BIND is running, it is ignored. Now, when the PPP session is initiated by the P800, the host computer will get a new interface (typically ppp0). BIND won't be listening on that interface. So, even though you've got a correctly configured DNS service, the session will still fail because packets from the P800 don't get through to the DNS server. What this means is that you can't set ms-dns in the PPP settings to point to the computer's end of the PPP tunnel, even though this is the correct host. What you need to do is to point ms-dns at a pre-existing IP number on the same subnet as the PPP tunnel. In many cases this can be the Linux box's primary network interface. If your Linux box doesn't have a primary interface (e.g., a laptop with no network adapters), or if the IP address of the PPP tunnel has to be on a different subnet, then configure a loopback interface on the same subnet as the PPP tunnel. However you do it, there must be an IP number available to BIND when it starts up, and it must be on the same subnet as the PPP IP number. In addition, because the computer end of the PPP tunnel is a different network interface to the one on which BIND is listening, you must enable IP forwarding, as described above.

Sound complicated? Well, it is complicated. But all the above steps can be scripted, and once everything is configured all you need to do is run the script to start the whole process.
      You may be wondering why getting the P800 to talk to a computer is so complicated. The P800 knows how to talk ordinary PPP, because this is how the built-in applications get IP access over GPRS. When you connect to an e-mail server, for example, the P800 dials the GPRS connect string, and initiates a PPP call on the ISP. Why can't it do the same thing over bluetooth, and initiate a PPP session on the computer (avoiding all this mrouter nonsense?) When you create a new Internet account on the P800, there does not appear to be a way to specify a bluetooth or even a cable connection - only dial up connections are supported. This is a shame, because all the required functionality is already there in firmware. I understand that in earlier versions of the Symbian OS, there was the ability to control the connection type in this way, and that this facility has been deliberately removed in later versions. There is a program called gnubox that works on some Symbian devices, which programatically modifies the Internet connection database to use bluetooth rather than GPRS. However, I don't think that gnubox works on the P800.

Using the P800 with OBEX for home automation

The problem with using PPP to talk to a LAN from the P800 is not really the complexity - once it's set up, it's set up - but the fact that you have to initiate the connection from the host computer. As far as home automation is concerned, if you're within arm's reach of a computer, you can probably use the computer to do what you want anyway. I'm interested in using a mobile phone handset to do home automation operations without needing to have a computer within reach. I'd like, for example, to be able to change tracks on my MP3 player, switch lights on and off, and adjust the central heating thermostat, all from a phone handset. I can already do all these things from a computer using the X10 system; the tricky part is doing them from the phone handset. Now my X10 system has a web-based interface, so I can establish a LAN connection from the P800, then use Opera to view the interface. The problem is that if the P800 goes out of range of the host computer, or gets switched off, it drops its connection. It then needs to be reinitiated from a computer on the LAN. This obviates all the convenience of home automation. In any case, I'd like to be able to use other bluetooth devices as well as the P800; my Nokia 6310i, for example, doesn't have a proper Web browser.
      So, what can all bluetooth enabled PDAs and phones do, that can be initiated from the handset? The lowest common denominator is, I think, an OBEX push. All devices can `beam' a business card. On my Linux box, all the home automation operations can be controlled by shell scripts. So, what we need is a way to link the beaming of business cards over bluetooth to the execution of scripts on the Linux box. This way you can create a business card for a person called, for example, `Coffee On'; beaming that card would switch the coffee machine on. Or whatever. The business card contains, in its comments field, a particular string that identifies the card as being a task to carry out, not a real business card to be send to the PIM software.
      It turned out that this was surprisingly easy to set up. I just took the source code for the OBEX push daemon, and modified it so that when a file is received, but before it is written out to disk, the program looks for a particular pattern of characters in the received file. If that pattern is found, it uses the filename of the business card as the name of a script to execute. All in all, it only required the addition about about a dozen lines of C code. This modification allows any bluetooth-enabled device to run certain scripts on the Linux system.
      The great advantage of the system described above, over the use of a browser-based automation system, is that actions are initiated entirely from the handset. Even if the handset goes out of range, or gets switched off, it starts working again as soon as the handset is on and in range. It is mildly inconvenient using business cards as the communications medium, because beaming a card takes a fair number of keypresses or stylus taps. However, this approach should work not just with the P800, but with any bluetooth-enabled PDA. On the P800, it would interesting to write a program that presented a list of commands, then beamed one to a designated target as an OBEX object when clicked. This, however, is a job for another day.

Conclusion - where things stand

So, at present I am able to do the following things on my P800 using Linux:
  • `Beam' contacts, tasks and calendar entries from my Linux box to my P800 using bluetooth, and vice versa, and have them understood at both ends of the link
  • `Beam' other files to the P800 using bluetooth, which the P800 either may or may not understand
  • `Beam' files from the P800 using bluetooth, provided that they are recognized by a specific application, or by using SMan, which can send any file
  • Read and write the P800 file system using P3NFS (but slow)
  • Transfer large files quickly using a memory stick reader
  • Develop and test J2ME and PersonalJava applications (see this article for details)
  • Control my hi-fi system and electrical appliances from the P800 (and any other bluetooth handset)

   
Search

WebThis site

Shameless plug

By the author of this site. Buy on-line from Amazon USA | UK

Editorial
So you want to be a university lecturer? Read this first!

Speak like your boss: new developments in managerese

Computing features
File handling in the Linux kernel: an in-depth look at how Linux handles files, filesystems, and file I/O

All sorts of Linux stuff

Confused about CLASSPATH? answers are here

First steps in EJB using jBoss (recently revised for jBoss 3.2)