FileDocCategorySizeDatePackage
Protocol.javaAPI DocphoneME MR2 API (J2ME)10342Wed May 02 18:00:30 BST 2007com.sun.midp.io.j2me.irdaobex

Protocol

public class Protocol extends Object implements com.sun.cldc.io.ConnectionBaseInterface
Provides a wrapper for the irdaobex protocol implementation to answer the GCF style.

Fields Summary
private static com.sun.midp.security.SecurityToken
classSecurityToken
Internal security token that grants access to restricted API.
private boolean
clientPermitted
Shows whether cilent permissions checked successfilly.
private boolean
serverPermitted
Shows whether server permissions checked successfilly.
static IrOBEXControl
control
Keeps the device properties and attributes.
private final String
serverHost
Host name used for the server side.
private final String
clientHost
Host name used for the client side.
Constructors Summary
public Protocol()
Default constructor.


       
      
    
Methods Summary
private voidcheckForPermission(int permission, java.lang.String name)
Makes sure caller has the com.sun.midp permission set to "allowed".

param
permission requested permission ID
param
name resource name to check permissions against
exception
IOInterruptedException if another thread interrupts the calling thread while this method is waiting to preempt the display.

        MIDletSuite midletSuite =
            MIDletStateHandler.getMidletStateHandler().getMIDletSuite();

        // The class may be used when no suite running
        if (midletSuite == null) {
            return;
        }

        try {
            midletSuite.checkForPermission(permission, name);
        } catch (InterruptedException ie) {
            throw new InterruptedIOException(
                "Interrupted while trying to ask the user permission");
        }
    
private static booleancheckHints(java.lang.String hints)
Checks the hint bits. The number of hex digits must be even, two digits minimum, eight digits maximum.

param
hints hint bits passed in uppercase
return
true if the parameter is valid, false otherwise

        if (hints.length() < 2 || hints.length() > 8 ||
                hints.length() % 2 != 0) {
            return false;
        }

        byte[] data = hints.getBytes();
        for (int i = 0; i < data.length; i++) {
            if (data[i] >= '0" && data[i] <= '9" ||
                    data[i] >= 'A" || data[i] <= 'F") {
                continue;
            }
            return false;
        }
        return true;
    
private static booleancheckIAS(java.lang.String ias)
Checks if the IAS (Information Access Service) string complies with the grammar.

param
ias IrDA class names separated by comma
return
true if the list is valid, false otherwise

        // should not be empty, should not start or end with a comma
        if (ias.length() == 0 || ias.charAt(0) == '," ||
            ias.charAt(ias.length() - 1) == ',") {
            return false;
        }

        // add a comma to the end of the list to facilitate iteration
        ias = ias.concat(",");
        while (ias.length() > 0) {
            int index = ias.indexOf(',");
            byte[] data = ias.substring(0, index).getBytes();
            ias = ias.substring(index + 1);
            int hex = 0;
            // parse single IrDA class name
            for (int i = 0; i < data.length; i++) {
                if (hex > 0) {
                    // hex digit is expected
                    if (data[i] >= '0" && data[i] <= '9" ||
                            data[i] >= 'A" && data[i] <= 'F" ||
                            data[i] >= 'a" && data[i] <= 'f") {
                        hex--;
                        continue;
                    }
                    return false;
                }
                if (data[i] == '%") {
                    // excapedOcted should follow (two hex digits)
                    hex = 2;
                    continue;
                }
                if (data[i] >= '0" && data[i] <= '9" || data[i] == ':" ||
                        data[i] >= 'A" && data[i] <= 'Z" ||
                        data[i] >= 'a" && data[i] <= 'z") {
                    continue;
                }
                return false;
            }
            if (hex > 0) {
                return false;
            }
        }
        return true;
    
public javax.microedition.io.ConnectionopenPrim(java.lang.String name, int mode, boolean timeouts)
Returns either ClientSession or SessionNotifier for OBEX connections, depending whether client or server URL was specified.

param
name the URL for the connection (without "irdaobex:" prefix)
param
mode only READ_WRITE mode is supported by OBEX
param
timeouts ignored
return
ClientSession for client URL or SessionNotifier for server URL
exception
IllegalArgumentException if the URL specified is invalid
exception
ConnectionNotFoundException if the target cannot be found
exception
IOException if something goes wrong
exception
SecurityException if access is prohibited


        // instantiate control class on the first time of method invocation
        synchronized (Protocol.class) {
            if (control == null) {
                control = new IrOBEXControl();
            }
        }

        // save the URL for later use
        String url = "irdaobex:" + name;

        if (!name.startsWith("//")) {
            throw new IllegalArgumentException("Malformed URL: " + url);
        }

        // cut off the "//" prefix
        name = name.substring(2);

        // OBEX supports READ_WRITE mode only
        if (mode != Connector.READ_WRITE) {
            throw new IllegalArgumentException("Unsupported mode: " + mode);
        }

        String ias = "OBEX,OBEX:IrXfer"; // Default IAS

        // ";ias=" indicates the beginning of the IAS list
        int index = name.toLowerCase().indexOf(";ias=");
        if (index != -1) {
            ias = name.substring(index + ";ias=".length());
            // check IAS validity
            if (!checkIAS(ias)) {
                throw new IllegalArgumentException("Invalid IAS: " + ias);
            }
            // cut off IAS from the name
            name = name.substring(0, index);
        }

        Vector iasVector = new Vector();
        ias = ias.concat(",");
        while (ias.length() > 0) {
            index = ias.indexOf(',");
            iasVector.addElement(ias.substring(0, index));
            ias = ias.substring(index + 1);
        }

        String[] iasArray = new String[iasVector.size()];
        iasVector.copyInto(iasArray);
        String host = name.toLowerCase();
        boolean isServer;
        int hints;
        if (host.startsWith(serverHost)) {
            isServer = true;
            name = name.substring(serverHost.length());
            hints = 0x0200;
        } else if (host.startsWith(clientHost)) {
            isServer = false;
            name = name.substring(clientHost.length());
            hints = 0;
        } else {
            throw new IllegalArgumentException("Malformed URL: " + url);
        }

        if (name.length() > 0 && name.charAt(0) == '.") {
            // hint bits should follow
            String hstring = name.substring(1).toUpperCase();
            if (!checkHints(hstring)) {
                throw new IllegalArgumentException(
                    "Invalid hint bits: " + hstring);
            }
            hints |= Integer.parseInt(hstring, 16);
            hints &= 0x7f7f7f7f;
        }

        if (isServer) {
            if (!serverPermitted) {
                checkForPermission(Permissions.OBEX_SERVER, url);
                serverPermitted = true;
            }
            return new SessionNotifierImpl(
                control.createServerConnection(hints, iasArray));

        } else {
            if (!clientPermitted) {
                checkForPermission(Permissions.OBEX_CLIENT, url);
                clientPermitted = true;
            }

            return new ClientSessionImpl(
                control.createClientConnection(hints, iasArray));
        }