FileDocCategorySizeDatePackage
EmulationServer.javaAPI DocphoneME MR2 API (J2ME)13942Wed May 02 18:00:32 BST 2007com.sun.midp.jsr82emul

EmulationServer

public class EmulationServer extends Object implements Runnable
Represents an emulation server used for JSR 82 emulation environment. It is not a part of JSR 82 implementation and is only used within JSR 82 emulation mode. The emulation mode allows running tests without real native Bluetooth libraries or hardware. In the emulation mode the server runs in a sepate thread or as a standalone application. It emulates Bluetooth ether, i.e. keeps information on services being advertised and "devices" that present. Actually it keeps TCP socket connections to clients.

Fields Summary
private static boolean
launched
Shows if emulation server is already running.
private static EmulationServer
instance
The only instance of EmulationServer.
private static com.sun.midp.security.SecurityToken
internalSecurityToken
This class has a different security domain than the MIDlet suite.
private static com.sun.midp.io.j2me.serversocket.Socket
serverSocket
Server socket that accepts TCP clients connections.
private static final int
SOCKET_PORT
Port to open server socket at.
private static final int
INQUIRY_DELAY
Duration of a delay that is applied prior to start inquiry in order to let all emulated devices update their device classes.
private Hashtable
services
Keeps services being advertised in the ether.
private Hashtable
devices
Keeps devices that present in the ether.
private static final DeviceKey[]
defaultAddr
Default Bluetooth address wrapped by DeviceKey objects.
static final int
ADDR_COUNT
Amount of default addresses.
int
nextAddr
Value used to generate unique Bluetooth addresses.
Constructors Summary
Methods Summary
public ServiceConnectionDataconnectToService(ServiceConnectionData client)
Retrieves emulation (TCP) connection URL for connecting to the service represented by given JSR 82 client connection string.

param
client client connection parameters
return
ServiceConnectionData instance that either contains connection properties or error code

        
        ServiceKey key = new ServiceKey(client.address, 
            client.protocol, client.port);
        ServiceConnectionData service = 
            (ServiceConnectionData) services.get(key);
        
        // Log.log("SERVER: requested connection to service " + key);
        
        if (service == null) {
            // indicates error
            client.error = BluetoothConnectionException.FAILED_NOINFO;
            // Log.log("SERVER: service not found " + key);
        } else {
            // either accepts or sets error value
            service.accept(client);
        }
        
        return client;
    
public static com.sun.midp.jsr82emul.EmulationServergetInstance()
Retrns the only instance if the server.

return
the singleton instance of EmulationServer.

        launch();
        return instance;
    
public static synchronized voidlaunch()
Launches the server if not yet running.

        if (launched) {
            return;
        }
        
        try {
            serverSocket = new Socket();
            serverSocket.open(SOCKET_PORT, internalSecurityToken);
            
            instance = new EmulationServer();
            Thread thread = new Thread(instance);
            thread.start();        
        } catch (IOException e) {
            // server is already running within another isolate or under
            // another VM control - nothing to do
        } finally {
            launched = true;
        }
    
public static voidmain(java.lang.String[] args)
Launches the server in a standalone manner.

param
args command line arguments

    
                     
         
        launch();
    
public synchronized byte[]registerDevice(DeviceState deviceState)
Registers new device in the ether.

param
deviceState state of device that defines its current discoverable mode and class of device
return
Bluetooth addres for the registered device that identifies it in the emulated ether.

        DeviceKey key = null;
        int i;
        
        for (i = 0; i < ADDR_COUNT; i++) {
            if (!devices.containsKey(defaultAddr[i])) {
                key = defaultAddr[i];
                break;
            }
        }
        
        if (i == ADDR_COUNT) {
            byte[] btaddr = new byte[Const.BTADDR_SIZE];
            for (i = 0; i < 4; i++) {
                btaddr[i] = (byte) (nextAddr >> (8 * i));
            }
            key = new DeviceKey(btaddr);
            nextAddr = nextAddr % (Integer.MAX_VALUE - 1) + 1;
        }
        
        devices.put(key, deviceState);
        return key.getAddrBytes();
    
public com.sun.midp.jsr82emul.ServiceKeyregisterService(ServiceConnectionData service, byte[] btaddr)
Registers a service in Bluetooth ether, i.e. starts advertising it.

param
service service connection data provided by service holder
param
btaddr Bluetooth address of service holder
return
service key that identifies the service at emulation server, if registration succeeded, null otherwize

        
        ServiceKey key = new ServiceKey(
            btaddr, service.protocol, service.port);
        
        Log.log("SERVER: registreing service " + key);
        
        ServiceConnectionData registered = 
            (ServiceConnectionData) services.get(key);
            
        if (registered != null) {
            registered.setAccepting();
        } else {
            services.put(key, service);
        }
        
        return key;
    
public voidrun()
The Runnable interface implementation.

        while (true) {
            try {
                new ClientHandler(
                        (SocketConnection)serverSocket.acceptAndOpen());
            } catch (Throwable e) {
                // ignoring
            }
        }
    
public InquiryResultsrunInquiry(int discoverable, byte[] btaddr)
Performs inquiry (devices discovery).

param
discoverable discoverable mode to search devices with
param
btaddr Bluetooth address of device that performs inquiry - it should not discover itself.
return
InquiryResults instance that represents inquiry results

        try {
            // Syncronizing classes of devices for the scenario like this:
            //     - make an action that should update class of device1;
            //     - start inquiry on device2 expecting updated class of device1.
            // In this case class of device1 changes immediately locally but
            // it takes time to update it on the emulation server and affect all
            // inquiry operations. Waiting here to let class of device1 to become
            // up-to-date. 
            Thread.sleep(INQUIRY_DELAY);
        } catch (InterruptedException e) {}
        
        InquiryResults res = new InquiryResults();
        Enumeration addresses = devices.keys();
        Enumeration states = devices.elements();
                    
        while (addresses.hasMoreElements()) {
            DeviceKey addr = (DeviceKey) addresses.nextElement();
            DeviceState state = (DeviceState) states.nextElement();
             
            if (state.getDiscoverable() == discoverable && 
                    !addr.equals(btaddr)) {
                res.add(addr.getAddrBytes(), state.getCoD());
            }
        }
        
        return res;
    
public synchronized voidunregisterDevice(byte[] btaddr)
Unregisters device from the emulated ether.

param
btaddr Bluetooth address of the device to be unregistered

        devices.remove(new DeviceKey(btaddr));
    
public voidunregisterService(com.sun.midp.jsr82emul.ServiceKey key)
Stops advertising the service represented by given record.

param
key service key that represents the service to be unregistered

        Log.log("SERVER: unregistreing service " + key);
        services.remove(key);