FileDocCategorySizeDatePackage
ServerConnectionImpl.javaAPI DocphoneME MR2 API (J2ME)12615Wed May 02 18:00:32 BST 2007com.sun.kvem.jsr082.obex

ServerConnectionImpl

public class ServerConnectionImpl extends ObexPacketStream implements Runnable, javax.microedition.io.Connection

Fields Summary
private static final boolean
DEBUG
Debug information, should be false for RR.
javax.obex.ServerRequestHandler
handler
private int
owner
private boolean
isConnected
private long
connId
boolean
operationHeadersOverflow
Current operation header size overflow flag.
boolean
operationClosed
Current operation state.
Constructors Summary
ServerConnectionImpl(ObexTransport transport, javax.obex.ServerRequestHandler handler, javax.obex.Authenticator auth)

        super(transport);
        this.handler = handler;
        isClient = false;
        authenticator = auth;

        // owner field of all created HeaderSets
        owner = HeaderSetImpl.OWNER_SERVER;
        new Thread(this).start();
    
Methods Summary
private voiddoConnect()

        // NOTE client may not authenticated the server and wants to
        // so allow multiple connect requests
        HeaderSetImpl inputHeaderSet = new HeaderSetImpl(owner);
        HeaderSetImpl responseHeaderSet = new HeaderSetImpl(owner);

        // server side check
        if (buffer[3] != 0x10 || packetLength < 7) {
	    // IMPL_NOTE: It is not decided what to do if the OBEX version number
	    // is different from the one we support (which is presumably 1.0).
	    // Windows uses version 1.2, Linux uses version 1.1, and we
	    // probably want to work with both.
            // throw new IOException("unsupported client obex version");
        }
        // ignore flags
        // save maximum client supported packet size
        maxSendLength = decodeLength16(5);

        if (maxSendLength > OBEX_MAXIMUM_PACKET_LENGTH) {
            maxSendLength = OBEX_MAXIMUM_PACKET_LENGTH;
        }
        parsePacketHeaders(inputHeaderSet, 7);
        // processMissingAuthentications();

        int status = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;

        try {
            status = handler.onConnect(inputHeaderSet,
                    responseHeaderSet);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        status = validateStatus(status);

        if (status != ResponseCodes.OBEX_HTTP_OK) {
            // lets client will authenticate first
            authResponses.removeAllElements();
        }

        byte[] head = new byte[] {
            (byte)status,
            0, 0, // length will be here
            0x10, // version 1.0 of OBEX
            0x0,  // flags
            (byte) (OBEX_MAXIMUM_PACKET_LENGTH / 0x100), // maximum client
            (byte) (OBEX_MAXIMUM_PACKET_LENGTH % 0x100), // supported packet
            // length
        };

        status = sendResponsePacket(head, responseHeaderSet);

        if (status == ResponseCodes.OBEX_HTTP_OK) {
            isConnected = true;
        }
    
private voiddoDelete(HeaderSetImpl inputHeaderSet)

        HeaderSetImpl responseHeaderSet = new HeaderSetImpl(owner);
        int status = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        try {
            status = handler.onDelete(inputHeaderSet, responseHeaderSet);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        status = validateStatus(status);
        byte[] head = new byte[] {
            (byte)status,
            0, 0, // length will be here
        };

        sendResponsePacket(head, responseHeaderSet);
    
private voiddoDisconnect()

        if (notConnected()) {
            return;
        }
        HeaderSetImpl inputHeaderSet = new HeaderSetImpl(owner);
        HeaderSetImpl responseHeaderSet = new HeaderSetImpl(owner);

        parsePacketHeaders(inputHeaderSet, 3);
        // processMissingAuthentications();

        try {
            handler.onDisconnect(inputHeaderSet, responseHeaderSet);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        byte[] head = new byte[] {
            (byte) ResponseCodes.OBEX_HTTP_OK,
            0, 0, // length will be here
        };

        int status = sendResponsePacket(head, responseHeaderSet);

        if (status == ResponseCodes.OBEX_HTTP_OK) {
            isConnected = false;
        }
    
private voiddoGet()

        if (notConnected()) {
            return;
        }
        int status = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        ServerOperation op =
            new ServerOperation(this);
        try {
            status = handler.onGet(op);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        status = validateStatus(status);
        if (operationHeadersOverflow) {
            status = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
        }
        op.destroy(status);
    
private voiddoPut(HeaderSetImpl inputHeaderSet)

        int status = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        ServerOperation op =
            new ServerOperation(this, inputHeaderSet);
        try {
            status = handler.onPut(op);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        status = validateStatus(status);
        if (operationHeadersOverflow) {
            status = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
        }
        op.destroy(status);
    
private voiddoPutOrDelete()

        if (notConnected()) {
            return;
        }
        HeaderSetImpl inputHeaderSet = new HeaderSetImpl(owner);

        int mode = ServerOperation.waitForData(this,
                inputHeaderSet, OPCODE_PUT);

        switch (mode) {
            case 0: sendPacket(PACKET_SUCCESS, getConnectionID(), null, true);
                    return;
            case 1: doPut(inputHeaderSet); return;
            case 2: doDelete(inputHeaderSet); return;
            default:return;
        }
    
private voiddoSetPath()

        if (notConnected()) {
            return;
        }
        HeaderSetImpl inputHeaderSet = new HeaderSetImpl(owner);
        HeaderSetImpl responseHeaderSet = new HeaderSetImpl(owner);

        // check flags
        boolean create = ((buffer[3] & 2) == 0);
        boolean backup = ((buffer[3] & 1) == 1);

        parsePacketHeaders(inputHeaderSet, 5);
        // processMissingAuthentications();
        int status = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        try {
            status = handler.onSetPath(inputHeaderSet,
                    responseHeaderSet, backup, create);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        status = validateStatus(status);
        byte[] head = new byte[] {
            (byte)status,
            0, 0, // length will be here
        };
        sendResponsePacket(head, responseHeaderSet);
    
public longgetConnectionID()

        try { // may by overloaded by user and throw exception
            long id = handler.getConnectionID();
            if (connId == id) {
                return -1;
            }
            connId = id;
            return id;
        } catch (Throwable e) {
            return -1;
        }
    
voidheaderTooLarge()


        
        operationHeadersOverflow = true;
        operationClosed = true;
    
private booleannotConnected()

        if (!isConnected) {
            HeaderSetImpl headers = new HeaderSetImpl(owner);
            headers.setHeader(HeaderSet.DESCRIPTION, "not connected");
            sendPacket(PACKET_BAD_REQUEST, getConnectionID(), headers, true);
            return true;
        }
        return false;
    
voidonAuthenticationFailure(byte[] username)

        try {
            if (DEBUG) {
                System.out.println("ServerConnectionImpl:"
                        + " handler.onAuthenticationFailure()");
            }
            handler.onAuthenticationFailure(username);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        operationClosed = true;
    
private booleanprocessRequest()
Process one client request

return
false when connection closed

        try {
            recvPacket();
        } catch (IOException e) {
            return false;
        }
        HeaderSetImpl inputHeaderSet = new HeaderSetImpl(owner);        
        operationHeadersOverflow = false;
        operationClosed = false;
        isEof = false;

        switch (packetType) {
            case OPCODE_CONNECT:
                doConnect();
                break;

            case OPCODE_DISCONNECT:
                doDisconnect();
                break;

            case OPCODE_PUT:
            case OPCODE_PUT | OPCODE_FINAL:
                doPutOrDelete();
                break;

            case OPCODE_GET:
            case OPCODE_GET | OPCODE_FINAL:
                doGet();
                break;
            case OPCODE_SETPATH:
                doSetPath();
                break;

            case OPCODE_ABORT:
                // ignore abort, it is too late, any of the operations is
                // finished
                byte[] head = new byte[] {
                    (byte) ResponseCodes.OBEX_HTTP_OK,
                    0, 0, // length will be here
                };
                sendResponsePacket(head, null);
                break;

            default:
                // wrong packet received, ignoring
                if (DEBUG) {
                    System.out.println("Wrong packet: id = " 
                            + inputHeaderSet.packetType + " length = "
                            + packetLength);
                }
                sendPacket(PACKET_NOT_IMPLEMENTED, getConnectionID(),
			   null, true);
        }
        return true;
    
public voidrun()

        try {
            while (processRequest()) {
                // if connection closed
                if (isClosed()) {
                    break;
                }
            }
        } catch (Throwable t) {
            if (DEBUG) {
                System.out.println("ServerConnectionImpl thread exception");
                t.printStackTrace();
            }
        }
        if (DEBUG) {
            System.out.println("ServerConnectionImpl: client disconnected");
        }
        close();
    
private intsendResponsePacket(byte[] head, HeaderSetImpl headers)
Modified sendPacket() function. If packet is too large - sends OBEX_HTTP_REQ_TOO_LARGE response.

        int status = head[0] & 0xFF;
        packetBegin(head);
        packetAddConnectionID(getConnectionID(), headers);
        packetAddAuthResponses();
        packetAddHeaders(headers);
        if (!queuedHeaders.isEmpty() || operationHeadersOverflow) {
            queuedHeaders.removeAllElements();
            setPacketType(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE);
        }
        packetEnd();
        return status;
    
public voidsetConnectionID(long id)

        try { // may by overloaded by user and throw exception
            connId = id;
            handler.setConnectionID(id);
        } catch (Throwable e) {
            // nothing
        }