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

ObexPacketStream

public abstract class ObexPacketStream extends Object implements javax.microedition.io.Connection
Obex core protocol.

Fields Summary
private static final boolean
DEBUG
Debug information, should be false for RR.
private static final boolean
DEBUG2
static final int
OPCODE_CONNECT
static final int
OPCODE_DISCONNECT
static final int
OPCODE_PUT
static final int
OPCODE_GET
static final int
OPCODE_SETPATH
static final int
OPCODE_CONTINUE
static final int
OPCODE_ABORT
static final int
OPCODE_FINAL
static final int
OPCODE_GET_FINAL
static final byte[]
PACKET_ABORT
static final byte[]
PACKET_CONTINUE
static final byte[]
PACKET_DISCONNECT
static final byte[]
PACKET_SUCCESS
static final byte[]
PACKET_BAD_REQUEST
static final byte[]
PACKET_NOT_IMPLEMENTED
private static final int
HEADER_BODY
private static final int
HEADER_EOFBODY
private static final int
HEADER_CONNECTION_ID
static final int
HEADER_AUTH_CHALLENGE
static final int
HEADER_AUTH_RESPONSE
static TimeZone
utcTimeZone
private static final int
TRANSPORT_READ_INTERVAL
private ObexTransport
transport
javax.obex.Authenticator
authenticator
Vector
authResponses
Generated authentication responses. They will be send in sendPacket(). Stored in byte[] format.
Vector
authChallenges
Sent authentication challenges. They will be used for check authentication responses.
boolean
moreHeaders
True when buffer contains packet for sending and some headers can be added.
boolean
challengesToSend
Outgoing packet contains authentication challenges, so it should be sent immediatly.
boolean
headerOverflow
True if one of sending headers cannot feet in empty packet.
boolean
containsTargetHeader
True if sending packet contains target header.
Vector
queuedHeaders
Queue of outgoing headers, not feet in packet.
QueuedHeader
newHeader
Stack
emptyHeadersPool
boolean
authFailed
Set when sending auth challenge, reset when received valid auth response in next packet.
boolean
isClient
True if this is ClientSession, false in ServerConnectionImpl.
boolean
isConnected
Client is connected flag. Ignored by ServerConnectionImpl.
int
OBEX_MAXIMUM_PACKET_LENGTH
byte[]
buffer
byte[]
cache
int
packetLength
int
packetOffset
int
packetType
int
maxSendLength
boolean
dataOpened
boolean
dataClosed
boolean
isEof
int
dataOffset
Constructors Summary
ObexPacketStream(ObexTransport transport)
Connection id used in setConnectionID, getConnectioID.


               

      
        this.transport = transport;
        OBEX_MAXIMUM_PACKET_LENGTH = transport.getMaximumPacketSize();
        buffer = new byte[OBEX_MAXIMUM_PACKET_LENGTH];
        cache = new byte[OBEX_MAXIMUM_PACKET_LENGTH];
        maxSendLength = OBEX_MAXIMUM_PACKET_LENGTH;
        newHeader = new QueuedHeader(this);
        queuedHeaders = new Vector();
        emptyHeadersPool = new Stack();
    
Methods Summary
voidbrokenLink()
Sets link broken flag.

        close();
    
public voidclose()

        try {
            if (transport != null) {
                transport.close();
            }
        } catch (IOException e) {
            // nothing
        }
        transport = null;
    
private final longdecodeInt()

        return ((buffer[packetOffset+0]& 0xffl) << 24)
             + ((buffer[packetOffset+1]& 0xffl) << 16)
             + ((buffer[packetOffset+2]& 0xffl) << 8)
             +  (buffer[packetOffset+3]& 0xffl);
    
final intdecodeLength16(int off)

        return ((((int)buffer[off]) & 0xFF) << 8)
            + (((int)buffer[off + 1]) & 0xFF);
    
private final java.util.CalendardecodeTime8601()

        int year, month, date, hour, minute, second;

        int len = decodeLength16(packetOffset) - 3;
        packetOffset += 2;

        if (len < 15 || len > 16 
                || buffer[packetOffset + 8] != 0x54 // 'T'
                || (len == 16 && buffer[packetOffset + 15] != 0x5A)) { // 'Z'
	    packetOffset += len;
            throw new IOException("corrupted time header");
        }
        for (int i = 0; i < 14; i++) {
            if (i == 8) continue;
            int chr = buffer[packetOffset + i] - 0x30; // '0'
            if (chr < 0 || chr > 9) {
		packetOffset += len;
                throw new IOException("corrupted time header");
            }
        }

        year = (buffer[packetOffset+0] - 0x30) * 1000
             + (buffer[packetOffset+1] - 0x30) * 100
             + (buffer[packetOffset+2] - 0x30) * 10
             + (buffer[packetOffset+3] - 0x30);
        month = (buffer[packetOffset+4] - 0x30) * 10
	    + (buffer[packetOffset+5] - 0x30);
        date = (buffer[packetOffset+6] - 0x30) * 10
             + (buffer[packetOffset+7] - 0x30);

        hour = (buffer[packetOffset+9] - 0x30) * 10
             + (buffer[packetOffset+10] - 0x30);
        minute = (buffer[packetOffset+11] - 0x30) * 10
             + (buffer[packetOffset+12] - 0x30);
        second = (buffer[packetOffset+13] - 0x30) * 10
             + (buffer[packetOffset+14] - 0x30);

        // is check validness of time fields required?

        Calendar cal;
	// 'len' value 15 means local time,
	// 16 means UTC (in this case time string has 'Z' suffix)
        if (len == 16) {	
            cal = Calendar.getInstance(utcTimeZone);
        } else {
            cal = Calendar.getInstance();
        }
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1); // Calendar.JANUARY = 0
        cal.set(Calendar.DATE, date);
	
	// ISO 8601 standard uses the 24-hour clock
	// Therefore you use HOUR_OF_DAY not HOUR
        cal.set(Calendar.HOUR_OF_DAY, hour);
	
        cal.set(Calendar.MINUTE, minute);
        cal.set(Calendar.SECOND, second);
	
        // set milliseconds to zero since
        // ISO 8601 uses only second precision
	cal.set(Calendar.MILLISECOND, 0);

        packetOffset += len;
        return cal;
    
private final voidencodeInt(long val)

        buffer[packetLength++] = (byte)(val >> 24);
        buffer[packetLength++] = (byte)(val >> 16);
        buffer[packetLength++] = (byte)(val >> 8);
        buffer[packetLength++] = (byte)val;
    
public abstract longgetConnectionID()

intgetPacketLength()

        return packetLength;
    
public javax.microedition.io.ConnectiongetTransport()

        if (transport == null) {
            throw new IOException("connection error");
        }
        return transport.getUnderlyingConnection();
    
abstract voidheaderTooLarge()
This method is called to handle a situation than header is too large.

throws
IOException

booleanisClosed()

        return transport == null;
    
abstract voidonAuthenticationFailure(byte[] username)
Called when requested authentication failed. Implemented on server to call handler.

voidonMissingAuthResponse()

voidpacketAddAuthResponses()

        try {
            for (int i = 0; i < authResponses.size(); i++) {
                if (DEBUG) {
                    System.out.println(
                            "packetAddAuthResponses(): added response");
                }
                ObexAuth response = (ObexAuth) authResponses.elementAt(i);
                int len = response.replyAuthChallenge(buffer, packetLength,
                        authenticator);
                packetLength += len;
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            throw new IOException("auth response request too large");
        }
        if (packetLength > maxSendLength) {
            throw new IOException("auth response request too large");
        }
    
final voidpacketAddConnectionID(long id, HeaderSetImpl headers)
Connection Identifier: * must be first header in packet * 0xFFFFFFFF considered invalid - it is up to application * can't be sent on connect() request * can't be used with Target header in one packet

        // SPEC: Illegal to send a Connection Id and a Target header
        // in the same operation.
        if (headers != null
                && headers.getHeader(HeaderSetImpl.TARGET) != null) {
            return;
        }
        if (id < 0L || id > 0xFFFFFFFFL) {
            return;
        }
        buffer[packetLength++] = (byte)HEADER_CONNECTION_ID;
        encodeInt(id);
    
intpacketAddData(byte[] data, int offset, int length)

        if (DEBUG) {
            System.out.println("packetAddData()");
        }
        // preventing writing several data blocks, just in case
        if (dataClosed)
	    return 0;

        if (!dataOpened) {
            // let it be at least 3 bytes workload to create new Body header
            if (packetLength + 6 > maxSendLength) {
                return 0;
            }
            buffer[packetLength] = HEADER_BODY;
            dataOffset = packetLength;
            packetLength += 3;
            dataOpened = true;
        }

        int len;
        if (packetLength + length > maxSendLength) {
            len = maxSendLength - packetLength;
        } else {
            len = length;
        }
        System.arraycopy(data, offset, buffer, packetLength, len);
        packetLength += len;
        return len;
    
final voidpacketAddHeaders(HeaderSetImpl headers)
Adds the specified headers to the packet.

        if (DEBUG) {
            System.out.println("packetAddHeaders()");
        }
        headerOverflow = false;
        newHeader.sendAllQueued();

        if (headers == null) {
            return;
        }

        int[] idList = headers.getHeaderList();

        if (!headers.challenges.isEmpty()) {
            newHeader.sendOrQueue(HEADER_AUTH_CHALLENGE,
                    headers.challenges);
        }

        if (idList == null) {
            return;
        }

        for (int i = 0; i < idList.length; i++) {
            int id = idList[i];
            Object value = headers.getHeader(id);
            newHeader.sendOrQueue(id, value);
        }
    
voidpacketBegin(byte[] head)

        if (DEBUG) {
            System.out.println("packetBegin()");
        }

        containsTargetHeader = false;
        moreHeaders = true;
        challengesToSend = false;
        System.arraycopy(head, 0, buffer, 0, head.length);
        packetLength = head.length;
        authChallenges.removeAllElements();
        dataOpened = false;
        dataClosed = false;
        dataOffset = -3; // generate aoobe when accessed
    
booleanpacketEOFBody()

        if (DEBUG) {
            System.out.println("packetEOFBody()");
        }
        if (dataClosed) {
            return false;
        }
        if (dataOpened) {
            buffer[dataOffset+0] = HEADER_EOFBODY;
            return true;
        } else {
            if (packetLength + 3 > maxSendLength) {
                return false;
            }
            buffer[packetLength++] = HEADER_EOFBODY;
            buffer[packetLength++] = 0; // length
            buffer[packetLength++] = 3;
            return true;
        }
    
voidpacketEnd()

        if (DEBUG) {
            System.out.println("packetEnd()");
        }
        moreHeaders = false;

        if (transport == null) {
            throw new IOException("connection error");
        }

        if (dataOpened) {
            // closing Body header
            int len = packetLength - dataOffset;
            buffer[dataOffset+1] = (byte)(len >> 8);
            buffer[dataOffset+2] = (byte)len;
            dataOpened = false;
            dataClosed = true;
        }
        // update packet length field
        buffer[1] = (byte)(packetLength / 0x100);
        buffer[2] = (byte)(packetLength % 0x100);

        if (DEBUG) {
            int len = packetLength;
            if (!DEBUG2 && len > 20) {
                len = 20;
            }
            System.out.println("send:");
            for (int i = 0; i < len; i++) {
                System.out.print(" 0x" + Integer.toHexString(buffer[i] & 0xFF));
                int chr = buffer[i] & 0xFF;
                if (chr >= 32 && chr < 128) {
                    System.out.print("(" + (char)(buffer[i] & 0xFF) + ")");
                }
            }
            if (packetLength != len) {
                System.out.print("...");
            }
            System.out.println("");
        }
        try {
            transport.write(buffer, packetLength);
        } catch (IOException e) {
            brokenLink();
            throw e;
        }
    
voidpacketEndStripConnID()
Finish packet and send it. Remove Connection ID header if packet also contains TARGET header.


        // first header id is in 3 byte on all packet except CONNECT
        // and this function is known not to be called for connect() operation.
        if ((buffer[3] & 0xFF) == HeaderSetImpl.TARGET) {
            packetLength -= 5;

            // length of Connection ID packet is 5 bytes:
            //  1 byte header + 4 byte int value
            for (int i = 3; i < packetLength; i++) {
                buffer[i] = buffer[i + 5];
            }
        }
        packetEnd();
    
voidpacketMarkFinal()

        if (DEBUG) {
            System.out.println("packetMarkFinal()");
        }
        buffer[0] |= 0x80;
    
private final voidparseConnectionID()


        int headerId = buffer[packetOffset] & 0xFF;
        // parse connection ID
        if (packetOffset + 5 > packetLength
                || headerId != HEADER_CONNECTION_ID) {
            return;
        }
        packetOffset++;
        long id = decodeInt();
        packetOffset += 4;
        setConnectionID(id);
    
final voidparseEnd()

        if (DEBUG) {
            System.out.println("parseEnd()");
        }
        if (authFailed) {
            authFailed = false;
            onMissingAuthResponse();
        }
    
private final voidparseHeader(HeaderSetImpl headers)

        if (DEBUG) {
            System.out.println("parseHeader()");
        }
        try {
            int headerId = buffer[packetOffset++] & 0xff;
            int inputType = headerId >> 6;
            int outputType = HeaderSetImpl.internalType(headerId);
            if (outputType != HeaderSetImpl.TYPE_UNSUPPORTED) {
                inputType = outputType;
            }

            Object result = null;

            switch (inputType) {
                // ids which require special handling
                case HeaderSetImpl.TYPE_SPECIAL_TIME_ISO:
		    try {
                	result = decodeTime8601();
		    } catch (IOException e) {
			// IMPL_NOTE: Got invalid time header,
			// should probably just ignore it.
		    }
                    break;

                case HeaderSetImpl.TYPE_SPECIAL_TIME_4:
                    long date = decodeInt();
                    Calendar cal = Calendar.getInstance(utcTimeZone);
                    cal.setTime(new Date(date * 1000L));
                    result = cal;
                    packetOffset += 4;
                    break;

                case HeaderSetImpl.TYPE_SPECIAL_TYPE:
                    int len = decodeLength16(packetOffset) - 3;
                    packetOffset += 2;
                    if (buffer[packetOffset + len - 1] != 0) {
                        throw new IOException(
                                "protocol error, " 
                                + "type field not null terminated");
                    }
                    result = new String(buffer, packetOffset, len - 1,
                            "ISO-8859-1");
                    packetOffset += len;
                    break;

                    // normal ids
                case HeaderSetImpl.TYPE_LONG:
                    result = new Long(decodeInt());
                    packetOffset += 4;
                    break;

                case HeaderSetImpl.TYPE_UNICODE:
                    len = decodeLength16(packetOffset) - 3;
                    packetOffset += 2;
                    if (len < 2 || buffer[packetOffset + len - 1] != 0
                            || buffer[packetOffset + len - 2] != 0) {
                        throw new IOException("protocol error, " +
                                "unicode string is not null terminated");
                    }
                    result = new String(buffer,
                                   packetOffset, len - 2, "UTF-16BE");
                    // result = new String(buffer, packetOffset, len,
                    //        "ISO-8859-1");
                    packetOffset += len;
                    break;

                case HeaderSetImpl.TYPE_BYTEARRAY:
                    len = decodeLength16(packetOffset) - 3;
                    packetOffset += 2;
                    result = new byte[len];
                    System.arraycopy(buffer, packetOffset, result, 0, len);
                    packetOffset += len;
                    break;

                case HeaderSetImpl.TYPE_BYTE:
                    result = new Byte(buffer[packetOffset++]);
                    break;

                case HeaderSetImpl.TYPE_AUTH_CHALLENGE:
                    len = decodeLength16(packetOffset);
                    ObexAuth response =
                        ObexAuth.parseAuthChallenge(buffer, packetOffset-1,
						    len);
                    if (response != null)
                        authResponses.addElement(response);
                    packetOffset += len - 1;
                    return;

                case HeaderSetImpl.TYPE_AUTH_RESPONSE:
                    len = decodeLength16(packetOffset);
                    boolean good =
                        ObexAuth.checkAuthResponse(buffer, packetOffset-1, len,
                                this, authChallenges);
                    if (good) authFailed = false;
                    packetOffset += len - 1;
                    if (DEBUG) {
                        System.out.println("checkAuthResponse() = " + good);
                    }
                    return;
            }

            if (packetOffset > packetLength) {
                throw new IOException("protocol error");
            }

            if (outputType != HeaderSetImpl.TYPE_UNSUPPORTED) {
                headers.setHeader(headerId, result);
            } else if (DEBUG) {
                System.out.println("unsupported header id = 0x"
                        + Integer.toHexString(headerId).toUpperCase());
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            throw new IOException("protocol error");
        }
    
final intparsePacketData(HeaderSetImpl headers, byte[] output, int outputOffset, int outputLength)
Parse packet headers, put BODY field content (data) in specified output array. If output is null, search for a BODY block and return 1 if it is found.

return
number of bytes put in output.

        if (DEBUG2) {
            System.out.println("parsePacketData()");
        }
        int result = 0;
        while (true) {
            int len = packetOffset - dataOffset;
            if (DEBUG2) {
                System.out.print("packetOffset = "+packetOffset+
                        " dataOffset = " +dataOffset);
                System.out.println(" len = " + len);
            }
            if (len > 0) {
                if (output == null) {
                    // special case for serching first data block
                    // without actual read
                    return 1;
                }
                if (len > outputLength) len = outputLength;
                System.arraycopy(buffer, dataOffset,
                        output, outputOffset, len);
                outputOffset += len;
                outputLength -= len;
                dataOffset += len;
                result += len;
                if (outputLength == 0)
		    return result;
                continue;
            }

            if (DEBUG) {
                System.out.println("packetOffset = " + packetOffset
                        +" packetLength = " + packetLength);
            }
            if (packetOffset == packetLength) {
                return result;
            }
            int headerId = buffer[packetOffset] & 0xff;

            if (headerId == HEADER_BODY || headerId == HEADER_EOFBODY) {
                isEof = (headerId == HEADER_EOFBODY);
                dataOffset = packetOffset + 3;
                int length = decodeLength16(packetOffset + 1);
                if (packetOffset + length > packetLength) {
                    throw new IOException("protocol error");
                }
                packetOffset += length;
                continue;
            }

            parseHeader(headers);
            dataOffset = packetOffset;
        }
    
final voidparsePacketDataBegin(HeaderSetImpl headers, int offset)
Begin parsing packet headers in packet possibly containing BODY (data fields).

        if (DEBUG) {
            System.out.println("parsePacketDataBegin()");
        }
        packetOffset = offset;
        headers.packetType = buffer[0] & 0xFF;

        parseConnectionID();
        dataOffset = packetOffset;
    
final voidparsePacketHeaders(HeaderSetImpl headers, int offset)
Parser all packet headers, BODY headers should not apear and silently ignored.

        if (DEBUG) {
            System.out.println("parsePacketHeaders()");
        }

        packetOffset = offset;
        headers.packetType = buffer[0] & 0xFF;

        parseConnectionID();

        while (packetOffset != packetLength) {
            parseHeader(headers);
        }
        parseEnd();
    
private intreadLeast(int offset, int length)
Reads at least length bytes starting from the given offset into the internal buffer. More than length bytes may be actually read. The calling function must ensure the buffer is large enough to store the entire packet.

param
offset starting offset in the destination buffer
param
length minimum number of bytes to read
return
number of bytes actually read
throws
IOException if an I/O error occurs

        if (transport == null) {
            throw new IOException("connection error");
        }
        int read = 0;
        while (read < length) {
            int count = transport.read(cache);
    	    System.arraycopy(cache, 0, buffer, offset + read, count);
            read += count;
            if (read < length) {
                try {
                    Thread.sleep(TRANSPORT_READ_INTERVAL);
                } catch (InterruptedException e) {
                    throw new InterruptedIOException(e.getMessage());
                }
            }
        }
        return read;
    
final voidrecvPacket()

        authResponses.removeAllElements();
        if (transport == null) {
            throw new IOException("connection error");
        }
        try {
	    int read = readLeast(0, 3);
	    packetType = buffer[0] & 0xff;
	    packetLength = ((buffer[1] & 0xff) << 8) + (buffer[2] & 0xff);
	    if (DEBUG) {
		Logging.report(Logging.INFORMATION, 0,
		    "Expecting " + packetLength + " bytes to arrive...");
	    }
	    if (read < packetLength) {
		readLeast(read, packetLength - read);
	    }

            // dump packet:
            if (DEBUG) {
                int len = packetLength;
                if (!DEBUG2 && len > 20) {
                    len = 20;
                }

                System.out.println("recv: ");
                for (int i = 0; i < len; i++) {
                    System.out.print(" 0x" 
                            + Integer.toHexString(buffer[i] & 0xFF)
				     .toUpperCase());
                }
                if (len != packetLength) System.out.print("...");
                System.out.println("");
            }
        } catch (IOException e) {
            brokenLink();
            throw e;
        }
    
voidrestorePacketLength(int len)

        packetLength = len;
    
final voidsendPacket(byte[] head, long connectionId, HeaderSetImpl headers, boolean allHeaders)

        packetBegin(head);
        packetAddConnectionID(connectionId, headers);
        packetAddAuthResponses();
        packetAddHeaders(headers);
        if (allHeaders && !queuedHeaders.isEmpty()) {
            queuedHeaders.removeAllElements();
            throw new IOException("packet too large for peer");
        }
        packetEnd();
    
public voidsetAuthenticator(javax.obex.Authenticator authenticator)

        if (authenticator == null) {
            throw new NullPointerException("null authenticator");
        }
        this.authenticator = authenticator;
    
public abstract voidsetConnectionID(long id)

voidsetPacketType(int type)

        if (DEBUG) {
            System.out.println("setPacketType()");
        }
        buffer[0] = (byte) type;
    
booleanshouldSendAuthResponse()

        return (packetType == ResponseCodes.OBEX_HTTP_UNAUTHORIZED)
            && (authResponses.size() != 0);
    
static intvalidateStatus(int status)

        switch (status) {
            case ResponseCodes.OBEX_DATABASE_FULL:
            case ResponseCodes.OBEX_DATABASE_LOCKED:
            case ResponseCodes.OBEX_HTTP_ACCEPTED:
            case ResponseCodes.OBEX_HTTP_BAD_GATEWAY:
            case ResponseCodes.OBEX_HTTP_BAD_METHOD:
            case ResponseCodes.OBEX_HTTP_BAD_REQUEST:
            case ResponseCodes.OBEX_HTTP_CONFLICT:
            case ResponseCodes.OBEX_HTTP_CREATED:
            case ResponseCodes.OBEX_HTTP_ENTITY_TOO_LARGE:
            case ResponseCodes.OBEX_HTTP_FORBIDDEN:
            case ResponseCodes.OBEX_HTTP_GATEWAY_TIMEOUT:
            case ResponseCodes.OBEX_HTTP_GONE:
            case ResponseCodes.OBEX_HTTP_INTERNAL_ERROR:
            case ResponseCodes.OBEX_HTTP_LENGTH_REQUIRED:
            case ResponseCodes.OBEX_HTTP_MOVED_PERM:
            case ResponseCodes.OBEX_HTTP_MOVED_TEMP:
            case ResponseCodes.OBEX_HTTP_MULT_CHOICE:
            case ResponseCodes.OBEX_HTTP_NO_CONTENT:
            case ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE:
            case ResponseCodes.OBEX_HTTP_NOT_AUTHORITATIVE:
            case ResponseCodes.OBEX_HTTP_NOT_FOUND:
            case ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED:
            case ResponseCodes.OBEX_HTTP_NOT_MODIFIED:
            case ResponseCodes.OBEX_HTTP_OK:
            case ResponseCodes.OBEX_HTTP_PARTIAL:
            case ResponseCodes.OBEX_HTTP_PAYMENT_REQUIRED:
            case ResponseCodes.OBEX_HTTP_PRECON_FAILED:
            case ResponseCodes.OBEX_HTTP_PROXY_AUTH:
            case ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE:
            case ResponseCodes.OBEX_HTTP_RESET:
            case ResponseCodes.OBEX_HTTP_SEE_OTHER:
            case ResponseCodes.OBEX_HTTP_TIMEOUT:
            case ResponseCodes.OBEX_HTTP_UNAUTHORIZED:
            case ResponseCodes.OBEX_HTTP_UNAVAILABLE:
            case ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE:
            case ResponseCodes.OBEX_HTTP_USE_PROXY:
            case ResponseCodes.OBEX_HTTP_VERSION:
                return status;
            default:
                return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
        }