Module bt: Bluetooth Communication

This module provides access to Bluetooth® wireless communication with other Bluetooth equipped devices. The supported functions are:

Terminology

Bluetooth is a relatively complex technology. The following is a quick crash course of the key concepts required to completely understand this module. For more information and detailed specifications, see www.bluetooth.org.

Connections Are Streams

Once created, a Bluetooth connection is accessed via module io:

Simple Example

To illustrate use of the m Bluetooth module, a trivial client-server example is presented. The server reverses each line of input it receives.

Client code:

use bt, io
// have the user select a device
dev=bt.select();
// connect to server
s=bt.conn(dev["adr"], "Reverser");
// write a line
io.writeln(s, "Hello world!");
// read the result
print io.readln(s)
→ !dlrow olleH
// and again
io.writeln(s, "Bye server");
print io.readln(s)
→ revres eyB
io.close(s)

Server code:

// a function which reverses a string
function reverse(s)
  c=code(s);
  i=0; j=len(c)-1;
  while i<j do
    h=c[i]; c[i]=c[j]; c[j]=h; i++; j--
  end;
  return char(c)
end

use bt, io
// create and advertise a service called "Reverser"
service=bt.start("Reverser");
while true do // loop forever
  // wait for a client
  io.print(io.stdout, "Waiting...");
  s=bt.accept(service);
  print bt.adr(s),"ok.";
  // read each line, writing it back reversed
  line=io.readln(s);
  while line#null do
    io.writeln(s, reverse(line));
    line=io.readln(s)
  end;
  io.close(s)
end
→ Waiting...00:0E:07:C9:EE:88 ok.
Waiting...

bt.accept

• function accept(service) → Native Object
  Permissions: FreeComm

Marks service available, then waits for a device connecting to service. When a device connects successfully, marks service as unavailable, and returns the connection stream.

See bt.start for an example.

bt.adr

• function adr(stream) → String
  Permissions: FreeComm
• function adr() → String
  Permissions: FreeComm

With one argument, returns the Bluetooth address of the device stream is connected to.

Without arguments, returns the local (own) Bluetooth address.

s=bt.accept(service);
// who connected?
print bt.adr(s)
→ 00:0E:07:C9:EE:88
// our own bluetooth address
print bt.adr()
→ 00:E0:03:5E:AF:CD

bt.chan

• function chan(service) → Array
  Permissions: FreeComm
• function chan(adr, uuid) → Array
  Permissions: FreeComm

With one argument, returns the channel number of service, in an array with the service name as key.

With two arguments, queries the service discovery database of the device with address adr for all services with the service class UUID defined by uuid, and returns their channel numbers in an array with the service names as keys. See bt.uuid for the values allowed for uuid.

// create a service on a fixed channel
s=bt.start("Sample", 18);
// obtain the channel of the service
c=bt.chan(s);
print c, keys(c)
→ [18] [Sample]
// query a device for all Obex services
c=bt.chan("00:0E:07:C9:EE:88", 4357);
print c, keys(c)
→ [9] [OBEX Object Push]
// query a device for all services using RFCOMM
c=bt.chan("00:0E:07:C9:EE:88", 3);
print c, keys(c)
→ [1,2,10,9,15,11,12,3] [Hands-Free Audio Gateway,
Headset Audio Gateway,OBEX File Transfer,OBEX Object
Push, Imaging,SyncMLClient,...<8>]

bt.conn

• function conn(adr, uuidOrChannel) → Native Object
  Permissions: FreeComm

If uuidOrChannel is an array or a string, queries the service discovery database of the device with address adr for the first service with the service class UUID defined by uuidOrChannel, then connects to the service's channel.

If uuidOrChannel is a number, connects directly to channel uuidOrChannel of the device with address adr, without querying the database.

// connect to the Obex service on a device
dev="00:0E:07:C9:EE:88";
s=bt.conn(dev, [4357]);
io.close(s)
// connect to channel 18 on the same device
s=bt.conn(dev, 18);
io.close(s)

bt.name

• function name() → String
  Permissions: FreeComm
• function name(newname) → String
  Permissions: FreeComm+WriteApp

Without an argument, returns the local (own) device name. With a single argument, set the local device name to newname and returns the old name.

// change the name, returning the old one
print bt.name("Test Device #1")
→ Nokia 6670
// get the current name
print bt.name()
→ Test Device #1

bt.scan

• function scan(limited=false) → Array
  Permissions: FreeComm
• function scan() → Array
  Permissions: FreeComm

With a single argument, scans for other visible bluetooth devices in the neighborhood, and returns the first device found, or null if there is no visible device.
If limited=false, the scan is performed with general unlimited inquiry access code (IAC), returning all devices.
If limited=true, the scan is performed with the faster limited IAC, but only returning devices which are scanning with limited IAC.

Without an argument, continues scanning, and returns the next device found, or null if there are no more devices.

Making an SDP request (bt.chan, bt.conn) ends the current scan, i.e. the next call to bt.scan will always start a new scan.

Each device found is returned as an array with the following keys:

KeyMeaningType
adrDevice addressString
nameDevice nameString
classDevice classNumber

dev=bt.scan(false);
// print each device
while dev#null do
  print dev;
  // get the next device
  dev=bt.scan()
end
→ [00:E0:03:5E:AF:CD,Test Device #1,5243404]
→ [00:0E:07:C9:EE:88,Test Device #2,5251596]

bt.select

• function select() → Array
  Permissions: FreeComm

Shows an interactive dialog scanning for Bluetooth devices and allowing the user to select one. Returns the selected device in the same format as returned by bt.scan, or null if the user cancelled the selection.

print bt.select()
→ [00:E0:03:5E:AF:CD,Test Device #1,5243404]

bt.start

• function start(name, uuidOrChannel=null, flags=0) → Native Object
  Permissions: FreeComm

Creates a service with name name and returns it. To accept an incoming connection on the service, use bt.accept.

If uuidOrChannel is an array or a string, bt.start finds an unused channel and creates a service with the UUID defined by uuidOrChannel. The service is advertised in the service discovery database of the device.

uuidOrChannel=null is equivalent to uuidOrChannel=name.

If uuidOrChannel is a number, listens directly on channel uuidOrChannel, without advertising the service.

The security imposed on incoming connections is defined by flags, which is a combination of the following values:

• const authenticate = 1 Connecting devices must be paired, or mutual password authentication is requested.

• const encrypt = 2 Data transfers are encrypted.

• const authorise = 4 The user is asked for authorisation whenever a device attempts to connect to the channel.

// create a service with the UUID of the Fax
// service class, and asking for authorisation
service1=bt.start("My Fax", [4369], bt.authorise);
// wait for a connection
conn=bt.accept(service1);
...
// create a service listening on channel 18
service2=bt.start("Sample", 18);
conn2=bt.accept(service2);
...

bt.stop

• function stop(service) → null
  Permissions: FreeComm

Stops service. If it has been advertised, it is removed from the service discovery database.

bt.timeout

• function timeout() → Number
  Permissions: FreeComm
• function timeout(ms) → Number
  Permissions: FreeComm

Gets or sets the timeout used during most functions of this module. Without arguments, returns the current timeout in milliseconds. With one argument, returns the old timeout, and sets the new timeout to ms. Setting the timeout to zero (the default) or a negative value disables timeouts, i.e. Bluetooth operations can block indefinitely, or use a timeout defined by the underlying system.

Throws ExcValueOutOfRange if ms exceeds 2147483 (35 minutes and 47.483 seconds).

The timeout is used in all following calls: whenever an operation does not complete within the given number of milliseconds, it throws ErrTimedOut.

 // allow 10 seconds to connect
bt.timeout(10000);
try
  s=bt.conn("00:E0:03:5E:AF:CD", 4)
  // connection successful...
catch e by
  if index(e, "ErrTimedOut") # 0 then throw e end;
  print "Could not connect within 10 seconds"
end

bt.uuid

• function uuid(uuid) → Array
  Permissions: FreeComm

Converts a number, string or array to a 128 bit UUID, and returns the UUID as an array of four integers.

All other values throw ErrArgument.

print bt.uuid(12345);
→ [12345,4096,2147483776,1604007163]
print bt.uuid([12345]);
→ [12345,4096,2147483776,1604007163]
print bt.uuid("Sample")
→ [1398893936,1818558464,0,0]
print bt.uuid([1,2])
→ ErrArgument thrown

bt.visible

• function visible() → Boolean
  Permissions: FreeComm
• function visible(newvisible) → Boolean
  Permissions: FreeComm+WriteApp
  Capabilities: certified

  
Compatibility of function bt.visible
Nokia phones before Symbian 8[12]ok
Nokia phones with Symbian 8[13]ErrNotSupported
Symbian 3rd/5th Edition and Sony Ericsson phones[14]ErrNotSupported

Without an argument, returns the current visibility state of this device: true if the device is detectable by others, false if it is not visible. With an argument, sets the visibility to newvisible, and returns the old visibility state.

// make the device visible
bt.visible(true)
// is it visible?
print bt.visible()
→ true


© 2004-2010 airbit AG, CH-8008 Zürich
Document AB-M-LIB-871