diff options
author | Tao Liejun <a19884@motorola.com> | 2009-07-02 19:29:09 +0800 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2009-07-07 13:53:11 -0700 |
commit | 3998bf009acaf8cde4d7f837f8b8e41ae0a65141 (patch) | |
tree | 76d91113f5c059f685da151177d53cc8f6383137 /obex | |
parent | d719890cab1eec09cbf556a3b86cc02b0f0ef8d7 (diff) | |
download | frameworks_base-3998bf009acaf8cde4d7f837f8b8e41ae0a65141.zip frameworks_base-3998bf009acaf8cde4d7f837f8b8e41ae0a65141.tar.gz frameworks_base-3998bf009acaf8cde4d7f837f8b8e41ae0a65141.tar.bz2 |
Obex library cleanup, third pass
- Change variable namings
- Remove interface public modifier
- Move 2 duplicate methods to ObexSession
- Removed unused code and variables
- Use static variables for some protocol defines
Diffstat (limited to 'obex')
-rw-r--r-- | obex/javax/obex/ApplicationParameter.java | 42 | ||||
-rw-r--r-- | obex/javax/obex/Authenticator.java | 6 | ||||
-rw-r--r-- | obex/javax/obex/BaseStream.java | 8 | ||||
-rw-r--r-- | obex/javax/obex/ClientOperation.java | 383 | ||||
-rw-r--r-- | obex/javax/obex/ClientSession.java | 315 | ||||
-rw-r--r-- | obex/javax/obex/HeaderSet.java | 239 | ||||
-rw-r--r-- | obex/javax/obex/ObexHelper.java | 150 | ||||
-rw-r--r-- | obex/javax/obex/ObexSession.java | 176 | ||||
-rw-r--r-- | obex/javax/obex/Operation.java | 26 | ||||
-rw-r--r-- | obex/javax/obex/PasswordAuthentication.java | 22 | ||||
-rw-r--r-- | obex/javax/obex/PrivateInputStream.java | 66 | ||||
-rw-r--r-- | obex/javax/obex/PrivateOutputStream.java | 83 | ||||
-rw-r--r-- | obex/javax/obex/ResponseCodes.java | 19 | ||||
-rw-r--r-- | obex/javax/obex/ServerOperation.java | 374 | ||||
-rw-r--r-- | obex/javax/obex/ServerRequestHandler.java | 49 | ||||
-rw-r--r-- | obex/javax/obex/ServerSession.java | 538 | ||||
-rw-r--r-- | obex/javax/obex/SessionNotifier.java | 17 |
17 files changed, 1118 insertions, 1395 deletions
diff --git a/obex/javax/obex/ApplicationParameter.java b/obex/javax/obex/ApplicationParameter.java index e808360..a62210f 100644 --- a/obex/javax/obex/ApplicationParameter.java +++ b/obex/javax/obex/ApplicationParameter.java @@ -37,9 +37,11 @@ package javax.obex; */ public final class ApplicationParameter { - private byte[] b_array; - private int length; - private int max_length = 1000; + private byte[] mArray; + + private int mLength; + + private int mMaxLength = 1000; public static class TRIPLET_TAGID { public static final byte ORDER_TAGID = 0x01; @@ -91,7 +93,6 @@ public final class ApplicationParameter { public static class TRIPLET_LENGTH { public static final byte ORDER_LENGTH = 1; - //public final byte SEARCH_VALUE_LENGTH = 0x02; public static final byte SEARCH_ATTRIBUTE_LENGTH = 1; public static final byte MAXLISTCOUNT_LENGTH = 2; @@ -107,34 +108,27 @@ public final class ApplicationParameter { public static final byte NEWMISSEDCALLS_LENGTH = 1; } - /* - public class TRIPLET_STRUCTURE{ - TRIPLET_TAGID id; - TRIPLET_LENGTH length; - byte[] value; - } - */ public ApplicationParameter() { - b_array = new byte[max_length]; - length = 0; + mArray = new byte[mMaxLength]; + mLength = 0; } public void addAPPHeader(byte tag, byte len, byte[] value) { - if ((length + len + 2) > max_length) { - byte[] array_tmp = new byte[length + 4 * len]; - System.arraycopy(b_array, 0, array_tmp, 0, length); - b_array = array_tmp; - max_length = length + 4 * len; + if ((mLength + len + 2) > mMaxLength) { + byte[] array_tmp = new byte[mLength + 4 * len]; + System.arraycopy(mArray, 0, array_tmp, 0, mLength); + mArray = array_tmp; + mMaxLength = mLength + 4 * len; } - b_array[length++] = tag; - b_array[length++] = len; - System.arraycopy(value, 0, b_array, length, len); - length += len; + mArray[mLength++] = tag; + mArray[mLength++] = len; + System.arraycopy(value, 0, mArray, mLength, len); + mLength += len; } public byte[] getAPPparam() { - byte[] para = new byte[length]; - System.arraycopy(b_array, 0, para, 0, length); + byte[] para = new byte[mLength]; + System.arraycopy(mArray, 0, para, 0, mLength); return para; } } diff --git a/obex/javax/obex/Authenticator.java b/obex/javax/obex/Authenticator.java index 90da7ba..7246e91 100644 --- a/obex/javax/obex/Authenticator.java +++ b/obex/javax/obex/Authenticator.java @@ -106,8 +106,8 @@ public interface Authenticator { * @return a <code>PasswordAuthentication</code> object containing the * user name and password used for authentication */ - public PasswordAuthentication onAuthenticationChallenge(String description, - boolean isUserIdRequired, boolean isFullAccess); + PasswordAuthentication onAuthenticationChallenge(String description, boolean isUserIdRequired, + boolean isFullAccess); /** * Called when a client or server receives an authentication response @@ -120,5 +120,5 @@ public interface Authenticator { * @return the correct password for the user name provided; if * <code>null</code> is returned then the authentication request failed */ - public byte[] onAuthenticationResponse(byte[] userName); + byte[] onAuthenticationResponse(byte[] userName); } diff --git a/obex/javax/obex/BaseStream.java b/obex/javax/obex/BaseStream.java index 67581bf..c32717f 100644 --- a/obex/javax/obex/BaseStream.java +++ b/obex/javax/obex/BaseStream.java @@ -47,7 +47,7 @@ public interface BaseStream { * * @throws IOException if the object is closed */ - public void ensureOpen() throws IOException; + void ensureOpen() throws IOException; /** * Verifies that additional information may be sent. In other words, the @@ -55,7 +55,7 @@ public interface BaseStream { * * @throws IOException if the operation is completed */ - public void ensureNotDone() throws IOException; + void ensureNotDone() throws IOException; /** * Continues the operation since there is no data to read. @@ -69,7 +69,7 @@ public interface BaseStream { * * @throws IOException if an IO error occurs */ - public boolean continueOperation(boolean sendEmpty, boolean inStream) throws IOException; + boolean continueOperation(boolean sendEmpty, boolean inStream) throws IOException; /** * Called when the output or input stream is closed. @@ -79,5 +79,5 @@ public interface BaseStream { * * @throws IOException if an IO error occurs */ - public void streamClosed(boolean inStream) throws IOException; + void streamClosed(boolean inStream) throws IOException; } diff --git a/obex/javax/obex/ClientOperation.java b/obex/javax/obex/ClientOperation.java index 5bc302a..b3807af 100644 --- a/obex/javax/obex/ClientOperation.java +++ b/obex/javax/obex/ClientOperation.java @@ -47,104 +47,82 @@ import java.io.ByteArrayOutputStream; */ public final class ClientOperation implements Operation, BaseStream { - /** - * Defines the basic packet length used by OBEX. Event OBEX packet has the - * same basic format:<BR> - * Byte 0: Request or Response Code - * Byte 1&2: Length of the packet. - */ - private static final int BASE_PACKET_LENGTH = 3; - - private ClientSession parent; - - private InputStream socketInput; - - private PrivateInputStream privateInput; + private ClientSession mParent; - private PrivateOutputStream privateOutput; + private boolean mInputOpen; - private boolean isClosed; + private PrivateInputStream mPrivateInput; - private String exceptionMessage; + private boolean mPrivateInputOpen; - private int maxPacketSize; + private PrivateOutputStream mPrivateOutput; - private boolean isDone; + private boolean mPrivateOutputOpen; - private boolean isGet; + private String mExceptionMessage; - private HeaderSet requestHeaders; + private int mMaxPacketSize; - private HeaderSet replyHeaders; + private boolean mOperationDone; - private boolean isEndOfBodySent; + private boolean mGetOperation; - private boolean inputStreamOpened; + private HeaderSet mRequestHeader; - private boolean outputStreamOpened; + private HeaderSet mReplyHeader; - private boolean isValidateConnected; + private boolean mEndOfBodySent; /** * Creates new OperationImpl to read and write data to a server - * - * @param in the input stream to read from - * * @param maxSize the maximum packet size - * * @param p the parent to this object - * - * @param headers the headers to set in the initial request - * * @param type <code>true</code> if this is a get request; * <code>false</code. if this is a put request + * @param headers the headers to set in the initial request * * @throws IOExcpetion if the an IO error occured */ - public ClientOperation(InputStream in, int maxSize, ClientSession p, HeaderSet header, - boolean type) throws IOException { - - parent = p; - isEndOfBodySent = false; - socketInput = in; - isClosed = false; - isDone = false; - maxPacketSize = maxSize; - isGet = type; + public ClientOperation(int maxSize, ClientSession p, HeaderSet header, boolean type) + throws IOException { - inputStreamOpened = false; - outputStreamOpened = false; - isValidateConnected = false; + mParent = p; + mEndOfBodySent = false; + mInputOpen = true; + mOperationDone = false; + mMaxPacketSize = maxSize; + mGetOperation = type; - privateInput = null; - privateOutput = null; + mPrivateInputOpen = false; + mPrivateOutputOpen = false; + mPrivateInput = null; + mPrivateOutput = null; - replyHeaders = new HeaderSet(); + mReplyHeader = new HeaderSet(); - requestHeaders = new HeaderSet(); + mRequestHeader = new HeaderSet(); int[] headerList = header.getHeaderList(); if (headerList != null) { for (int i = 0; i < headerList.length; i++) { - requestHeaders.setHeader(headerList[i], header.getHeader(headerList[i])); + mRequestHeader.setHeader(headerList[i], header.getHeader(headerList[i])); } } - if ((header).authChall != null) { - requestHeaders.authChall = new byte[(header).authChall.length]; - System.arraycopy((header).authChall, 0, requestHeaders.authChall, 0, - (header).authChall.length); + if ((header).mAuthChall != null) { + mRequestHeader.mAuthChall = new byte[(header).mAuthChall.length]; + System.arraycopy((header).mAuthChall, 0, mRequestHeader.mAuthChall, 0, + (header).mAuthChall.length); } - if ((header).authResp != null) { - requestHeaders.authResp = new byte[(header).authResp.length]; - System.arraycopy((header).authResp, 0, requestHeaders.authResp, 0, - (header).authResp.length); + if ((header).mAuthResp != null) { + mRequestHeader.mAuthResp = new byte[(header).mAuthResp.length]; + System.arraycopy((header).mAuthResp, 0, mRequestHeader.mAuthResp, 0, + (header).mAuthResp.length); } - // requestHeaders = (HeaderSet)header; } /** @@ -163,24 +141,24 @@ public final class ClientOperation implements Operation, BaseStream { // } //no compatible with sun-ri - if ((isDone) && (replyHeaders.responseCode != ObexHelper.OBEX_HTTP_CONTINUE)) { + if ((mOperationDone) && (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE)) { throw new IOException("Operation has already ended"); } - exceptionMessage = "Operation aborted"; - if ((!isDone) && (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE)) { - isDone = true; + mExceptionMessage = "Operation aborted"; + if ((!mOperationDone) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { + mOperationDone = true; /* * Since we are not sending any headers or returning any headers then * we just need to write and read the same bytes */ - parent.sendRequest(0xFF, null, replyHeaders, null); + mParent.sendRequest(ObexHelper.OBEX_OPCODE_ABORT, null, mReplyHeader, null); - if (replyHeaders.responseCode != ResponseCodes.OBEX_HTTP_OK) { + if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_OK) { throw new IOException("Invalid response code from server"); } - exceptionMessage = null; + mExceptionMessage = null; } close(); @@ -199,12 +177,12 @@ public final class ClientOperation implements Operation, BaseStream { */ public synchronized int getResponseCode() throws IOException { //avoid dup validateConnection - if ((replyHeaders.responseCode == -1) - || (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE)) { + if ((mReplyHeader.responseCode == -1) + || (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { validateConnection(); } - return replyHeaders.responseCode; + return mReplyHeader.responseCode; } /** @@ -226,7 +204,7 @@ public final class ClientOperation implements Operation, BaseStream { */ public String getType() { try { - return (String)replyHeaders.getHeader(HeaderSet.TYPE); + return (String)mReplyHeader.getHeader(HeaderSet.TYPE); } catch (IOException e) { return null; } @@ -242,7 +220,7 @@ public final class ClientOperation implements Operation, BaseStream { */ public long getLength() { try { - Long temp = (Long)replyHeaders.getHeader(HeaderSet.LENGTH); + Long temp = (Long)mReplyHeader.getHeader(HeaderSet.LENGTH); if (temp == null) { return -1; @@ -262,27 +240,23 @@ public final class ClientOperation implements Operation, BaseStream { * @throws IOException if an I/O error occurs */ public InputStream openInputStream() throws IOException { - // TODO: this mode is not set yet. - // if ((parent.mode & Connector.READ) == 0) - // throw new IOException("write-only connection"); ensureOpen(); - if (inputStreamOpened) + if (mPrivateInputOpen) throw new IOException("no more input streams available"); - if (isGet) { + if (mGetOperation) { // send the GET request here validateConnection(); - isValidateConnected = true; } else { - if (privateInput == null) { - privateInput = new PrivateInputStream(this); + if (mPrivateInput == null) { + mPrivateInput = new PrivateInputStream(this); } } - inputStreamOpened = true; + mPrivateInputOpen = true; - return privateInput; + return mPrivateInput; } /**8 @@ -304,27 +278,25 @@ public final class ClientOperation implements Operation, BaseStream { * @throws IOException if an I/O error occurs */ public OutputStream openOutputStream() throws IOException { - // TODO: this mode is not set yet. - // if ((parent.mode & Connector.WRITE) == 0) - // throw new IOException("read-only connection"); + ensureOpen(); ensureNotDone(); - if (outputStreamOpened) + if (mPrivateOutputOpen) throw new IOException("no more output streams available"); - if (privateOutput == null) { + if (mPrivateOutput == null) { // there are 3 bytes operation headers and 3 bytes body headers // - privateOutput = new PrivateOutputStream(this, maxPacketSize - 6); + mPrivateOutput = new PrivateOutputStream(this, mMaxPacketSize - 6); } - outputStreamOpened = true; + mPrivateOutputOpen = true; - return privateOutput; + return mPrivateOutput; } public int getMaxPacketSize() { - return maxPacketSize - 6; + return mMaxPacketSize - 6; } /** @@ -344,10 +316,10 @@ public final class ClientOperation implements Operation, BaseStream { * @throws IOException if the operation has already ended or is closed */ public void close() throws IOException { - isClosed = true; - inputStreamOpened = false; - outputStreamOpened = false; - parent.setRequestInactive(); + mInputOpen = false; + mPrivateInputOpen = false; + mPrivateOutputOpen = false; + mParent.setRequestInactive(); } /** @@ -359,10 +331,10 @@ public final class ClientOperation implements Operation, BaseStream { * * @throws IOException if this <code>Operation</code> has been closed */ - public HeaderSet getReceivedHeaders() throws IOException { + public HeaderSet getReceivedHeader() throws IOException { ensureOpen(); - return replyHeaders; + return mReplyHeader; } /** @@ -381,18 +353,18 @@ public final class ClientOperation implements Operation, BaseStream { */ public void sendHeaders(HeaderSet headers) throws IOException { ensureOpen(); - if (isDone) { + if (mOperationDone) { throw new IOException("Operation has already exchanged all data"); } if (headers == null) { - throw new NullPointerException("Headers may not be null"); + throw new IOException("Headers may not be null"); } int[] headerList = headers.getHeaderList(); if (headerList != null) { for (int i = 0; i < headerList.length; i++) { - requestHeaders.setHeader(headerList[i], headers.getHeader(headerList[i])); + mRequestHeader.setHeader(headerList[i], headers.getHeader(headerList[i])); } } } @@ -406,49 +378,50 @@ public final class ClientOperation implements Operation, BaseStream { * * @throws IOException if an IO error occurred */ + /* private boolean readResponse() throws IOException { - replyHeaders.responseCode = socketInput.read(); - int packetLength = socketInput.read(); - packetLength = (packetLength << 8) + socketInput.read(); + mReplyHeader.responseCode = mInput.read(); + int packetLength = mInput.read(); + packetLength = (packetLength << 8) + mInput.read(); if (packetLength > ObexHelper.MAX_PACKET_SIZE_INT) { - if (exceptionMessage != null) { + if (mExceptionMessage != null) { abort(); } throw new IOException("Received a packet that was too big"); } - if (packetLength > BASE_PACKET_LENGTH) { - int dataLength = packetLength - BASE_PACKET_LENGTH; + if (packetLength > ObexHelper.BASE_PACKET_LENGTH) { + int dataLength = packetLength - ObexHelper.BASE_PACKET_LENGTH; byte[] data = new byte[dataLength]; - int readLength = socketInput.read(data); + int readLength = mInput.read(data); if (readLength != dataLength) { throw new IOException("Received a packet without data as decalred length"); } - byte[] body = ObexHelper.updateHeaderSet(replyHeaders, data); + byte[] body = ObexHelper.updateHeaderSet(mReplyHeader, data); if (body != null) { - privateInput.writeBytes(body, 1); + mPrivateInput.writeBytes(body, 1); /* * Determine if a body (0x48) header or an end of body (0x49) * was received. If we received an end of body and * a response code of OBEX_HTTP_OK, then the operation should * end. - */ - if ((body[0] == 0x49) && (replyHeaders.responseCode == ResponseCodes.OBEX_HTTP_OK)) { + * + if ((body[0] == 0x49) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_OK)) { return false; } } } - if (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE) { + if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { return true; } else { return false; } } - + */ /** * Verifies that additional information may be sent. In other words, the * operation is not done. @@ -456,7 +429,7 @@ public final class ClientOperation implements Operation, BaseStream { * @throws IOException if the operation is completed */ public void ensureNotDone() throws IOException { - if (isDone) { + if (mOperationDone) { throw new IOException("Operation has completed"); } } @@ -467,12 +440,12 @@ public final class ClientOperation implements Operation, BaseStream { * @throws IOException if an exception needs to be thrown */ public void ensureOpen() throws IOException { - parent.ensureOpen(); + mParent.ensureOpen(); - if (exceptionMessage != null) { - throw new IOException(exceptionMessage); + if (mExceptionMessage != null) { + throw new IOException(mExceptionMessage); } - if (isClosed) { + if (!mInputOpen) { throw new IOException("Operation has already ended"); } } @@ -486,7 +459,7 @@ public final class ClientOperation implements Operation, BaseStream { ensureOpen(); // to sure only one privateInput object exist. - if (privateInput == null) { + if (mPrivateInput == null) { startProcessing(); } } @@ -501,13 +474,13 @@ public final class ClientOperation implements Operation, BaseStream { * * @throws IOException if an IO error occurs */ - protected boolean sendRequest(int type) throws IOException { + private boolean sendRequest(int type) throws IOException { boolean returnValue = false; ByteArrayOutputStream out = new ByteArrayOutputStream(); int bodyLength = -1; - byte[] headerArray = ObexHelper.createHeader(requestHeaders, true); - if (privateOutput != null) { - bodyLength = privateOutput.size(); + byte[] headerArray = ObexHelper.createHeader(mRequestHeader, true); + if (mPrivateOutput != null) { + bodyLength = mPrivateOutput.size(); } /* @@ -518,40 +491,39 @@ public final class ClientOperation implements Operation, BaseStream { * length, but it is a waste of resources if we can't send much of * the body. */ - if ((BASE_PACKET_LENGTH + headerArray.length) > maxPacketSize) { + if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length) > mMaxPacketSize) { int end = 0; int start = 0; // split & send the headerArray in multiple packets. while (end != headerArray.length) { //split the headerArray - end = ObexHelper.findHeaderEnd(headerArray, start, maxPacketSize - - BASE_PACKET_LENGTH); + end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketSize + - ObexHelper.BASE_PACKET_LENGTH); // can not split if (end == -1) { - isDone = true; + mOperationDone = true; abort(); - // isDone = true; - exceptionMessage = "Header larger then can be sent in a packet"; - isClosed = true; + mExceptionMessage = "Header larger then can be sent in a packet"; + mInputOpen = false; - if (privateInput != null) { - privateInput.close(); + if (mPrivateInput != null) { + mPrivateInput.close(); } - if (privateOutput != null) { - privateOutput.close(); + if (mPrivateOutput != null) { + mPrivateOutput.close(); } throw new IOException("OBEX Packet exceeds max packet size"); } byte[] sendHeader = new byte[end - start]; System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length); - if (!parent.sendRequest(type, sendHeader, replyHeaders, privateInput)) { + if (!mParent.sendRequest(type, sendHeader, mReplyHeader, mPrivateInput)) { return false; } - if (replyHeaders.responseCode != ObexHelper.OBEX_HTTP_CONTINUE) { + if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { return false; } @@ -569,27 +541,27 @@ public final class ClientOperation implements Operation, BaseStream { if (bodyLength > 0) { /* - * Determine if I can send the whole body or just part of + * Determine if we can send the whole body or just part of * the body. Remember that there is the 3 bytes for the * response message and 3 bytes for the header ID and length */ - if (bodyLength > (maxPacketSize - headerArray.length - 6)) { + if (bodyLength > (mMaxPacketSize - headerArray.length - 6)) { returnValue = true; - bodyLength = maxPacketSize - headerArray.length - 6; + bodyLength = mMaxPacketSize - headerArray.length - 6; } - byte[] body = privateOutput.readBytes(bodyLength); + byte[] body = mPrivateOutput.readBytes(bodyLength); /* * Since this is a put request if the final bit is set or * the output stream is closed we need to send the 0x49 * (End of Body) otherwise, we need to send 0x48 (Body) */ - if ((privateOutput.isClosed()) && (!returnValue) && (!isEndOfBodySent) + if ((mPrivateOutput.isClosed()) && (!returnValue) && (!mEndOfBodySent) && ((type & 0x80) != 0)) { out.write(0x49); - isEndOfBodySent = true; + mEndOfBodySent = true; } else { out.write(0x48); } @@ -603,13 +575,13 @@ public final class ClientOperation implements Operation, BaseStream { } } - if (outputStreamOpened && bodyLength <= 0 && !isEndOfBodySent) { + if (mPrivateOutputOpen && bodyLength <= 0 && !mEndOfBodySent) { // only 0x82 or 0x83 can send 0x49 if ((type & 0x80) == 0) { out.write(0x48); } else { out.write(0x49); - isEndOfBodySent = true; + mEndOfBodySent = true; } @@ -619,19 +591,19 @@ public final class ClientOperation implements Operation, BaseStream { } if (out.size() == 0) { - if (!parent.sendRequest(type, null, replyHeaders, privateInput)) { + if (!mParent.sendRequest(type, null, mReplyHeader, mPrivateInput)) { return false; } return returnValue; } if ((out.size() > 0) - && (!parent.sendRequest(type, out.toByteArray(), replyHeaders, privateInput))) { + && (!mParent.sendRequest(type, out.toByteArray(), mReplyHeader, mPrivateInput))) { return false; } // send all of the output data in 0x48, // send 0x49 with empty body - if ((privateOutput != null) && (privateOutput.size() > 0)) + if ((mPrivateOutput != null) && (mPrivateOutput.size() > 0)) returnValue = true; return returnValue; @@ -646,41 +618,41 @@ public final class ClientOperation implements Operation, BaseStream { */ private synchronized void startProcessing() throws IOException { - if (privateInput == null) { - privateInput = new PrivateInputStream(this); + if (mPrivateInput == null) { + mPrivateInput = new PrivateInputStream(this); } boolean more = true; - if (isGet) { - if (!isDone) { - replyHeaders.responseCode = ObexHelper.OBEX_HTTP_CONTINUE; - while ((more) && (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE)) { + if (mGetOperation) { + if (!mOperationDone) { + mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; + while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { more = sendRequest(0x03); } - if (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE) { - parent.sendRequest(0x83, null, replyHeaders, privateInput); + if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { + mParent.sendRequest(0x83, null, mReplyHeader, mPrivateInput); } - if (replyHeaders.responseCode != ObexHelper.OBEX_HTTP_CONTINUE) { - isDone = true; + if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { + mOperationDone = true; } } } else { - if (!isDone) { - replyHeaders.responseCode = ObexHelper.OBEX_HTTP_CONTINUE; - while ((more) && (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE)) { + if (!mOperationDone) { + mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; + while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { more = sendRequest(0x02); } } - if (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE) { - parent.sendRequest(0x82, null, replyHeaders, privateInput); + if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { + mParent.sendRequest(0x82, null, mReplyHeader, mPrivateInput); } - if (replyHeaders.responseCode != ObexHelper.OBEX_HTTP_CONTINUE) { - isDone = true; + if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { + mOperationDone = true; } } } @@ -697,45 +669,45 @@ public final class ClientOperation implements Operation, BaseStream { public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream) throws IOException { - if (isGet) { - if ((inStream) && (!isDone)) { + if (mGetOperation) { + if ((inStream) && (!mOperationDone)) { // to deal with inputstream in get operation - parent.sendRequest(0x83, null, replyHeaders, privateInput); + mParent.sendRequest(0x83, null, mReplyHeader, mPrivateInput); /* * Determine if that was not the last packet in the operation */ - if (replyHeaders.responseCode != ObexHelper.OBEX_HTTP_CONTINUE) { - isDone = true; + if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { + mOperationDone = true; } return true; - } else if ((!inStream) && (!isDone)) { + } else if ((!inStream) && (!mOperationDone)) { // to deal with outputstream in get operation - if (privateInput == null) { - privateInput = new PrivateInputStream(this); + if (mPrivateInput == null) { + mPrivateInput = new PrivateInputStream(this); } sendRequest(0x03); return true; - } else if (isDone) { + } else if (mOperationDone) { return false; } } else { - if ((!inStream) && (!isDone)) { + if ((!inStream) && (!mOperationDone)) { // to deal with outputstream in put operation - if (replyHeaders.responseCode == -1) { - replyHeaders.responseCode = ObexHelper.OBEX_HTTP_CONTINUE; + if (mReplyHeader.responseCode == -1) { + mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; } sendRequest(0x02); return true; - } else if ((inStream) && (!isDone)) { + } else if ((inStream) && (!mOperationDone)) { // How to deal with inputstream in put operation ? return false; - } else if (isDone) { + } else if (mOperationDone) { return false; } @@ -752,23 +724,23 @@ public final class ClientOperation implements Operation, BaseStream { * @throws IOException if an IO error occurs */ public void streamClosed(boolean inStream) throws IOException { - if (!isGet) { - if ((!inStream) && (!isDone)) { + if (!mGetOperation) { + if ((!inStream) && (!mOperationDone)) { // to deal with outputstream in put operation boolean more = true; - if ((privateOutput != null) && (privateOutput.size() <= 0)) { - byte[] headerArray = ObexHelper.createHeader(requestHeaders, false); + if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) { + byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false); if (headerArray.length <= 0) more = false; } // If have not sent any data so send all now - if (replyHeaders.responseCode == -1) { - replyHeaders.responseCode = ObexHelper.OBEX_HTTP_CONTINUE; + if (mReplyHeader.responseCode == -1) { + mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; } - while ((more) && (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE)) { + while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { more = sendRequest(0x02); } @@ -777,61 +749,60 @@ public final class ClientOperation implements Operation, BaseStream { * only have a single reply to send. so we don't need the while * loop. */ - while (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE) { + while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { sendRequest(0x82); } - isDone = true; - } else if ((inStream) && (isDone)) { + mOperationDone = true; + } else if ((inStream) && (mOperationDone)) { // how to deal with input stream in put stream ? - isDone = true; + mOperationDone = true; } } else { - isValidateConnected = false; - if ((inStream) && (!isDone)) { + if ((inStream) && (!mOperationDone)) { // to deal with inputstream in get operation // Have not sent any data so send it all now - if (replyHeaders.responseCode == -1) { - replyHeaders.responseCode = ObexHelper.OBEX_HTTP_CONTINUE; + if (mReplyHeader.responseCode == -1) { + mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; } - while (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE) { + while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { if (!sendRequest(0x83)) { break; } } - while (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE) { - parent.sendRequest(0x83, null, replyHeaders, privateInput); + while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { + mParent.sendRequest(0x83, null, mReplyHeader, mPrivateInput); } - isDone = true; - } else if ((!inStream) && (!isDone)) { + mOperationDone = true; + } else if ((!inStream) && (!mOperationDone)) { // to deal with outputstream in get operation // part of the data may have been sent in continueOperation. boolean more = true; - if ((privateOutput != null) && (privateOutput.size() <= 0)) { - byte[] headerArray = ObexHelper.createHeader(requestHeaders, false); + if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) { + byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false); if (headerArray.length <= 0) more = false; } - if (privateInput == null) { - privateInput = new PrivateInputStream(this); + if (mPrivateInput == null) { + mPrivateInput = new PrivateInputStream(this); } - if ((privateOutput != null) && (privateOutput.size() <= 0)) + if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) more = false; - replyHeaders.responseCode = ObexHelper.OBEX_HTTP_CONTINUE; - while ((more) && (replyHeaders.responseCode == ObexHelper.OBEX_HTTP_CONTINUE)) { + mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; + while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { more = sendRequest(0x03); } sendRequest(0x83); // parent.sendRequest(0x83, null, replyHeaders, privateInput); - if (replyHeaders.responseCode != ObexHelper.OBEX_HTTP_CONTINUE) { - isDone = true; + if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { + mOperationDone = true; } } diff --git a/obex/javax/obex/ClientSession.java b/obex/javax/obex/ClientSession.java index f65ded9..d554922 100644 --- a/obex/javax/obex/ClientSession.java +++ b/obex/javax/obex/ClientSession.java @@ -38,13 +38,11 @@ import java.io.InputStream; import java.io.OutputStream; /** - * This class implements the <code>Operation</code> interface. It will read - * and write data via puts and gets. + * This class in an implementation of the OBEX ClientSession. * * @hide */ -public final class ClientSession implements ObexSession { - private Authenticator mAuthenticator; +public final class ClientSession extends ObexSession { private boolean mOpen; @@ -53,8 +51,6 @@ public final class ClientSession implements ObexSession { private byte[] mConnectionId = null; - private byte[] mChallengeDigest = null; - /* * The max Packet size must be at least 256 according to the OBEX * specification. @@ -67,14 +63,14 @@ public final class ClientSession implements ObexSession { private final OutputStream mOutput; - public ClientSession(ObexTransport trans) throws IOException { + public ClientSession(final ObexTransport trans) throws IOException { mInput = trans.openInputStream(); mOutput = trans.openOutputStream(); mOpen = true; mRequestActive = false; } - public HeaderSet connect(HeaderSet header) throws IOException { + public HeaderSet connect(final HeaderSet header) throws IOException { ensureOpen(); if (mObexConnected) { throw new IOException("Already connected to server"); @@ -119,7 +115,7 @@ public final class ClientSession implements ObexSession { } HeaderSet returnHeaderSet = new HeaderSet(); - sendRequest(0x80, requestPacket, returnHeaderSet, null); + sendRequest(ObexHelper.OBEX_OPCODE_CONNECT, requestPacket, returnHeaderSet, null); /* * Read the response from the OBEX server. @@ -147,21 +143,23 @@ public final class ClientSession implements ObexSession { ensureOpen(); + HeaderSet head; if (header == null) { - header = new HeaderSet(); + head = new HeaderSet(); } else { - if (header.nonce != null) { + head = header; + if (head.nonce != null) { mChallengeDigest = new byte[16]; - System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16); + System.arraycopy(head.nonce, 0, mChallengeDigest, 0, 16); } } // Add the connection ID if one exists if (mConnectionId != null) { - header.connectionID = new byte[4]; - System.arraycopy(mConnectionId, 0, header.connectionID, 0, 4); + head.mConnectionID = new byte[4]; + System.arraycopy(mConnectionId, 0, head.mConnectionID, 0, 4); } - return new ClientOperation(mInput, maxPacketSize, this, header, true); + return new ClientOperation(maxPacketSize, this, head, true); } /** @@ -178,7 +176,7 @@ public final class ClientSession implements ObexSession { Operation op = put(header); op.getResponseCode(); - HeaderSet returnValue = op.getReceivedHeaders(); + HeaderSet returnValue = op.getReceivedHeader(); op.close(); return returnValue; @@ -200,8 +198,8 @@ public final class ClientSession implements ObexSession { } // Add the connection ID if one exists if (mConnectionId != null) { - header.connectionID = new byte[4]; - System.arraycopy(mConnectionId, 0, header.connectionID, 0, 4); + header.mConnectionID = new byte[4]; + System.arraycopy(mConnectionId, 0, header.mConnectionID, 0, 4); } head = ObexHelper.createHeader(header, false); @@ -212,13 +210,13 @@ public final class ClientSession implements ObexSession { // Add the connection ID if one exists if (mConnectionId != null) { head = new byte[5]; - head[0] = (byte)0xCB; + head[0] = (byte)HeaderSet.CONNECTION_ID; System.arraycopy(mConnectionId, 0, head, 1, 4); } } HeaderSet returnHeaderSet = new HeaderSet(); - sendRequest(0x81, head, returnHeaderSet, null); + sendRequest(ObexHelper.OBEX_OPCODE_DISCONNECT, head, returnHeaderSet, null); /* * An OBEX DISCONNECT reply from the server: @@ -253,36 +251,36 @@ public final class ClientSession implements ObexSession { setRequestActive(); ensureOpen(); - + HeaderSet head; if (header == null) { - header = new HeaderSet(); + head = new HeaderSet(); } else { - // when auth is initated by client ,save the digest - if (header.nonce != null) { + head = header; + // when auth is initiated by client ,save the digest + if (head.nonce != null) { mChallengeDigest = new byte[16]; - System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16); + System.arraycopy(head.nonce, 0, mChallengeDigest, 0, 16); } } // Add the connection ID if one exists if (mConnectionId != null) { - header.connectionID = new byte[4]; - System.arraycopy(mConnectionId, 0, header.connectionID, 0, 4); + head.mConnectionID = new byte[4]; + System.arraycopy(mConnectionId, 0, head.mConnectionID, 0, 4); } - return new ClientOperation(mInput, maxPacketSize, this, header, false); + return new ClientOperation(maxPacketSize, this, head, false); } - public void setAuthenticator(Authenticator auth) { + public void setAuthenticator(Authenticator auth) throws IOException { if (auth == null) { - throw new NullPointerException("Authenticator may not be null"); + throw new IOException("Authenticator may not be null"); } mAuthenticator = auth; } - public HeaderSet setPath(HeaderSet header, boolean backup, boolean create) - throws IOException { + public HeaderSet setPath(HeaderSet header, boolean backup, boolean create) throws IOException { if (!mObexConnected) { throw new IOException("Not connected to the server"); } @@ -291,29 +289,30 @@ public final class ClientSession implements ObexSession { int totalLength = 2; byte[] head = null; - + HeaderSet headset; if (header == null) { - header = new HeaderSet(); + headset = new HeaderSet(); } else { - if (header.nonce != null) { + headset = header; + if (headset.nonce != null) { mChallengeDigest = new byte[16]; - System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16); + System.arraycopy(headset.nonce, 0, mChallengeDigest, 0, 16); } } // when auth is initiated by client ,save the digest - if (header.nonce != null) { + if (headset.nonce != null) { mChallengeDigest = new byte[16]; - System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16); + System.arraycopy(headset.nonce, 0, mChallengeDigest, 0, 16); } // Add the connection ID if one exists if (mConnectionId != null) { - header.connectionID = new byte[4]; - System.arraycopy(mConnectionId, 0, header.connectionID, 0, 4); + headset.mConnectionID = new byte[4]; + System.arraycopy(mConnectionId, 0, headset.mConnectionID, 0, 4); } - head = ObexHelper.createHeader(header, false); + head = ObexHelper.createHeader(headset, false); totalLength += head.length; if (totalLength > maxPacketSize) { @@ -345,12 +344,12 @@ public final class ClientSession implements ObexSession { byte[] packet = new byte[totalLength]; packet[0] = (byte)flags; packet[1] = (byte)0x00; - if (header != null) { + if (headset != null) { System.arraycopy(head, 0, packet, 2, head.length); } HeaderSet returnHeaderSet = new HeaderSet(); - sendRequest(0x85, packet, returnHeaderSet, null); + sendRequest(ObexHelper.OBEX_OPCODE_SETPATH, packet, returnHeaderSet, null); /* * An OBEX SETPATH reply from the server: @@ -380,7 +379,7 @@ public final class ClientSession implements ObexSession { * Allows Put and get operation objects to tell this object when they are * done. */ - /*package*/ synchronized void setRequestInactive() { + /*package*/synchronized void setRequestInactive() { mRequestActive = false; } @@ -401,7 +400,7 @@ public final class ClientSession implements ObexSession { * headers (i.e. authentication challenge or authentication response) are * received, they will be processed. * - * @param code the type of request to send to the client + * @param opCode the type of request to send to the client * * @param head the headers to send to the server * @@ -419,7 +418,7 @@ public final class ClientSession implements ObexSession { * * @throws IOException if an IO error occurs */ - public boolean sendRequest(int code, byte[] head, HeaderSet header, + public boolean sendRequest(int opCode, byte[] head, HeaderSet header, PrivateInputStream privateInput) throws IOException { //check header length with local max size if (head != null) { @@ -427,10 +426,10 @@ public final class ClientSession implements ObexSession { throw new IOException("header too large "); } } - //byte[] nonce; + int bytesReceived; ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write((byte)code); + out.write((byte)opCode); // Determine if there are any headers to send if (head == null) { @@ -453,10 +452,12 @@ public final class ClientSession implements ObexSession { if (length > ObexHelper.MAX_PACKET_SIZE_INT) { throw new IOException("Packet received exceeds packet size limit"); } - if (length > 3) { + if (length > ObexHelper.BASE_PACKET_LENGTH) { byte[] data = null; - if (code == 0x80) { + if (opCode == ObexHelper.OBEX_OPCODE_CONNECT) { + @SuppressWarnings("unused") int version = mInput.read(); + @SuppressWarnings("unused") int flags = mInput.read(); maxPacketSize = (mInput.read() << 8) + mInput.read(); @@ -483,7 +484,7 @@ public final class ClientSession implements ObexSession { while (bytesReceived != (length - 3)) { bytesReceived += mInput.read(data, bytesReceived, data.length - bytesReceived); } - if (code == 0xFF) { + if (opCode == ObexHelper.OBEX_OPCODE_ABORT) { return true; } } @@ -493,33 +494,33 @@ public final class ClientSession implements ObexSession { privateInput.writeBytes(body, 1); } - if (header.connectionID != null) { + if (header.mConnectionID != null) { mConnectionId = new byte[4]; - System.arraycopy(header.connectionID, 0, mConnectionId, 0, 4); + System.arraycopy(header.mConnectionID, 0, mConnectionId, 0, 4); } - if (header.authResp != null) { - if (!handleAuthResp(header.authResp)) { + if (header.mAuthResp != null) { + if (!handleAuthResp(header.mAuthResp)) { setRequestInactive(); throw new IOException("Authentication Failed"); } } if ((header.responseCode == ResponseCodes.OBEX_HTTP_UNAUTHORIZED) - && (header.authChall != null)) { + && (header.mAuthChall != null)) { if (handleAuthChall(header)) { - out.write((byte)0x4E); - out.write((byte)((header.authResp.length + 3) >> 8)); - out.write((byte)(header.authResp.length + 3)); - out.write(header.authResp); - header.authChall = null; - header.authResp = null; + out.write((byte)HeaderSet.AUTH_RESPONSE); + out.write((byte)((header.mAuthResp.length + 3) >> 8)); + out.write((byte)(header.mAuthResp.length + 3)); + out.write(header.mAuthResp); + header.mAuthChall = null; + header.mAuthResp = null; byte[] sendHeaders = new byte[out.size() - 3]; System.arraycopy(out.toByteArray(), 3, sendHeaders, 0, sendHeaders.length); - return sendRequest(code, sendHeaders, header, privateInput); + return sendRequest(opCode, sendHeaders, header, privateInput); } } } @@ -527,194 +528,6 @@ public final class ClientSession implements ObexSession { return true; } - /** - * Called when the client received an authentication challenge header. This - * will cause the authenticator to handle the authentication challenge. - * - * @param header the header with the authentication challenge - * - * @return <code>true</code> if the last request should be resent; - * <code>false</code> if the last request should not be resent - */ - protected boolean handleAuthChall(HeaderSet header) { - - if (mAuthenticator == null) { - return false; - } - - /* - * An authentication challenge is made up of one required and two - * optional tag length value triplets. The tag 0x00 is required to be - * in the authentication challenge and it represents the challenge - * digest that was received. The tag 0x01 is the options tag. This - * tag tracks if user ID is required and if full access will be - * granted. The tag 0x02 is the realm, which provides a description of - * which user name and password to use. - */ - byte[] challenge = ObexHelper.getTagValue((byte)0x00, header.authChall); - byte[] option = ObexHelper.getTagValue((byte)0x01, header.authChall); - byte[] description = ObexHelper.getTagValue((byte)0x02, header.authChall); - - String realm = ""; - if (description != null) { - byte[] realmString = new byte[description.length - 1]; - System.arraycopy(description, 1, realmString, 0, realmString.length); - - switch (description[0] & 0xFF) { - - case 0x00: - // ASCII encoding - // Fall through - case 0x01: - // ISO-8859-1 encoding - try { - realm = new String(realmString, "ISO8859_1"); - } catch (Exception e) { - throw new RuntimeException("Unsupported Encoding Scheme"); - } - break; - - case 0xFF: - // UNICODE Encoding - realm = ObexHelper.convertToUnicode(realmString, false); - break; - - case 0x02: - // ISO-8859-2 encoding - // Fall through - case 0x03: - // ISO-8859-3 encoding - // Fall through - case 0x04: - // ISO-8859-4 encoding - // Fall through - case 0x05: - // ISO-8859-5 encoding - // Fall through - case 0x06: - // ISO-8859-6 encoding - // Fall through - case 0x07: - // ISO-8859-7 encoding - // Fall through - case 0x08: - // ISO-8859-8 encoding - // Fall through - case 0x09: - // ISO-8859-9 encoding - // Fall through - default: - throw new RuntimeException("Unsupported Encoding Scheme"); - } - } - - boolean isUserIDRequired = false; - boolean isFullAccess = true; - if (option != null) { - if ((option[0] & 0x01) != 0) { - isUserIDRequired = true; - } - - if ((option[0] & 0x02) != 0) { - isFullAccess = false; - } - } - - PasswordAuthentication result = null; - header.authChall = null; - - try { - result = mAuthenticator.onAuthenticationChallenge(realm, isUserIDRequired, isFullAccess); - } catch (Exception e) { - return false; - } - - /* - * If no password was provided then do not resend the request - */ - if (result == null) { - return false; - } - - byte[] password = result.getPassword(); - if (password == null) { - return false; - } - - byte[] userName = result.getUserName(); - - /* - * Create the authentication response header. It includes 1 required - * and 2 option tag length value triples. The required triple has a - * tag of 0x00 and is the response digest. The first optional tag is - * 0x01 and represents the user ID. If no user ID is provided, then - * no user ID will be sent. The second optional tag is 0x02 and is the - * challenge that was received. This will always be sent - */ - if (userName != null) { - header.authResp = new byte[38 + userName.length]; - header.authResp[36] = (byte)0x01; - header.authResp[37] = (byte)userName.length; - System.arraycopy(userName, 0, header.authResp, 38, userName.length); - } else { - header.authResp = new byte[36]; - } - - // Create the secret String - byte[] digest = new byte[challenge.length + password.length]; - System.arraycopy(challenge, 0, digest, 0, challenge.length); - System.arraycopy(password, 0, digest, challenge.length, password.length); - - // Add the Response Digest - header.authResp[0] = (byte)0x00; - header.authResp[1] = (byte)0x10; - - byte[] responseDigest = ObexHelper.computeMd5Hash(digest); - System.arraycopy(responseDigest, 0, header.authResp, 2, 16); - - // Add the challenge - header.authResp[18] = (byte)0x02; - header.authResp[19] = (byte)0x10; - System.arraycopy(challenge, 0, header.authResp, 20, 16); - - return true; - } - - /** - * Called when the client received an authentication response header. This - * will cause the authenticator to handle the authentication response. - * - * @param authResp the authentication response - * - * @return <code>true</code> if the response passed; <code>false</code> if - * the response failed - */ - protected boolean handleAuthResp(byte[] authResp) { - if (mAuthenticator == null) { - return false; - } - - byte[] correctPassword = mAuthenticator.onAuthenticationResponse(ObexHelper.getTagValue( - (byte)0x01, authResp)); - if (correctPassword == null) { - return false; - } - - byte[] temp = new byte[correctPassword.length + 16]; - System.arraycopy(mChallengeDigest, 0, temp, 0, 16); - System.arraycopy(correctPassword, 0, temp, 16, correctPassword.length); - - byte[] correctResponse = ObexHelper.computeMd5Hash(temp); - byte[] actualResponse = ObexHelper.getTagValue((byte)0x00, authResp); - for (int i = 0; i < 16; i++) { - if (correctResponse[i] != actualResponse[i]) { - return false; - } - } - - return true; - } - public void close() throws IOException { mOpen = false; mInput.close(); diff --git a/obex/javax/obex/HeaderSet.java b/obex/javax/obex/HeaderSet.java index 5dddf8f..f777da6 100644 --- a/obex/javax/obex/HeaderSet.java +++ b/obex/javax/obex/HeaderSet.java @@ -118,6 +118,20 @@ public final class HeaderSet { public static final int HTTP = 0x47; /** + * Represents the OBEX BODY header. + * <P> + * The value of <code>BODY</code> is 0x48 (72). + */ + public static final int BODY = 0x48; + + /** + * Represents the OBEX End of BODY header. + * <P> + * The value of <code>BODY</code> is 0x49 (73). + */ + public static final int END_OF_BODY = 0x49; + + /** * Represents the OBEX Who header. Identifies the OBEX application to * determine if the two peers are talking to each other. * <P> @@ -126,12 +140,13 @@ public final class HeaderSet { public static final int WHO = 0x4A; /** - * Represents the OBEX Object Class header. This header specifies the - * OBEX object class of the object. + * Represents the OBEX Connection ID header. Identifies used for OBEX + * connection multiplexing. * <P> - * The value of <code>OBJECT_CLASS</code> is 0x4F (79). + * The value of <code>CONNECTION_ID</code> is 0xCB (203). */ - public static final int OBJECT_CLASS = 0x4F; + + public static final int CONNECTION_ID = 0xCB; /** * Represents the OBEX Application Parameter header. This header specifies @@ -141,49 +156,71 @@ public final class HeaderSet { */ public static final int APPLICATION_PARAMETER = 0x4C; - private Long count; // 4 byte unsigned integer + /** + * Represents the OBEX authentication digest-challenge. + * <P> + * The value of <code>AUTH_CHALLENGE</code> is 0x4D (77). + */ + public static final int AUTH_CHALLENGE = 0x4D; + + /** + * Represents the OBEX authentication digest-response. + * <P> + * The value of <code>AUTH_RESPONSE</code> is 0x4E (78). + */ + public static final int AUTH_RESPONSE = 0x4E; + + /** + * Represents the OBEX Object Class header. This header specifies the + * OBEX object class of the object. + * <P> + * The value of <code>OBJECT_CLASS</code> is 0x4F (79). + */ + public static final int OBJECT_CLASS = 0x4F; + + private Long mCount; // 4 byte unsigned integer - private String name; // null terminated Unicode text string + private String mName; // null terminated Unicode text string - private String type; // null terminated ASCII text string + private String mType; // null terminated ASCII text string - private Long length; // 4 byte unsigend integer + private Long mLength; // 4 byte unsigend integer - private Calendar isoTime; // String of the form YYYYMMDDTHHMMSSZ + private Calendar mIsoTime; // String of the form YYYYMMDDTHHMMSSZ - private Calendar byteTime; // 4 byte unsigned integer + private Calendar mByteTime; // 4 byte unsigned integer - private String description; // null terminated Unicode text String + private String mDescription; // null terminated Unicode text String - private byte[] target; // byte sequence + private byte[] mTarget; // byte sequence - private byte[] http; // byte sequence + private byte[] mHttpHeader; // byte sequence - private byte[] who; // length prefixed byte sequence + private byte[] mWho; // length prefixed byte sequence - private byte[] appParam; // byte sequence of the form tag length value + private byte[] mAppParam; // byte sequence of the form tag length value - public byte[] authChall; // The authentication challenge header + public byte[] mAuthChall; // The authentication challenge header - public byte[] authResp; // The authentication response header + public byte[] mAuthResp; // The authentication response header - public byte[] connectionID; // THe connection ID + public byte[] mConnectionID; // THe connection ID - private byte[] objectClass; // byte sequence + private byte[] mObjectClass; // byte sequence - private String[] unicodeUserDefined; //null terminated unicode string + private String[] mUnicodeUserDefined; //null terminated unicode string - private byte[][] sequenceUserDefined; // byte sequence user defined + private byte[][] mSequenceUserDefined; // byte sequence user defined - private Byte[] byteUserDefined; // 1 byte + private Byte[] mByteUserDefined; // 1 byte - private Long[] integerUserDefined; // 4 byte unsigned integer + private Long[] mIntegerUserDefined; // 4 byte unsigned integer - /*package*/ int responseCode; + /*package*/int responseCode; - /*package*/ byte[] nonce; + /*package*/byte[] nonce; - private final Random random; + private final Random mRandom; /** * Creates new <code>HeaderSet</code> object. @@ -191,12 +228,12 @@ public final class HeaderSet { * @param size the max packet size for this connection */ public HeaderSet() { - unicodeUserDefined = new String[16]; - sequenceUserDefined = new byte[16][]; - byteUserDefined = new Byte[16]; - integerUserDefined = new Long[16]; + mUnicodeUserDefined = new String[16]; + mSequenceUserDefined = new byte[16][]; + mByteUserDefined = new Byte[16]; + mIntegerUserDefined = new Long[16]; responseCode = -1; - random = new Random(); + mRandom = new Random(); } /** @@ -222,7 +259,7 @@ public final class HeaderSet { case COUNT: if (!(headerValue instanceof Long)) { if (headerValue == null) { - count = null; + mCount = null; break; } throw new IllegalArgumentException("Count must be a Long"); @@ -231,24 +268,24 @@ public final class HeaderSet { if ((temp < 0L) || (temp > 0xFFFFFFFFL)) { throw new IllegalArgumentException("Count must be between 0 and 0xFFFFFFFF"); } - count = (Long)headerValue; + mCount = (Long)headerValue; break; case NAME: if ((headerValue != null) && (!(headerValue instanceof String))) { throw new IllegalArgumentException("Name must be a String"); } - name = (String)headerValue; + mName = (String)headerValue; break; case TYPE: if ((headerValue != null) && (!(headerValue instanceof String))) { throw new IllegalArgumentException("Type must be a String"); } - type = (String)headerValue; + mType = (String)headerValue; break; case LENGTH: if (!(headerValue instanceof Long)) { if (headerValue == null) { - length = null; + mLength = null; break; } throw new IllegalArgumentException("Length must be a Long"); @@ -257,84 +294,84 @@ public final class HeaderSet { if ((temp < 0L) || (temp > 0xFFFFFFFFL)) { throw new IllegalArgumentException("Length must be between 0 and 0xFFFFFFFF"); } - length = (Long)headerValue; + mLength = (Long)headerValue; break; case TIME_ISO_8601: if ((headerValue != null) && (!(headerValue instanceof Calendar))) { throw new IllegalArgumentException("Time ISO 8601 must be a Calendar"); } - isoTime = (Calendar)headerValue; + mIsoTime = (Calendar)headerValue; break; case TIME_4_BYTE: if ((headerValue != null) && (!(headerValue instanceof Calendar))) { throw new IllegalArgumentException("Time 4 Byte must be a Calendar"); } - byteTime = (Calendar)headerValue; + mByteTime = (Calendar)headerValue; break; case DESCRIPTION: if ((headerValue != null) && (!(headerValue instanceof String))) { throw new IllegalArgumentException("Description must be a String"); } - description = (String)headerValue; + mDescription = (String)headerValue; break; case TARGET: if (headerValue == null) { - target = null; + mTarget = null; } else { if (!(headerValue instanceof byte[])) { throw new IllegalArgumentException("Target must be a byte array"); } else { - target = new byte[((byte[])headerValue).length]; - System.arraycopy(headerValue, 0, target, 0, target.length); + mTarget = new byte[((byte[])headerValue).length]; + System.arraycopy(headerValue, 0, mTarget, 0, mTarget.length); } } break; case HTTP: if (headerValue == null) { - http = null; + mHttpHeader = null; } else { if (!(headerValue instanceof byte[])) { throw new IllegalArgumentException("HTTP must be a byte array"); } else { - http = new byte[((byte[])headerValue).length]; - System.arraycopy(headerValue, 0, http, 0, http.length); + mHttpHeader = new byte[((byte[])headerValue).length]; + System.arraycopy(headerValue, 0, mHttpHeader, 0, mHttpHeader.length); } } break; case WHO: if (headerValue == null) { - who = null; + mWho = null; } else { if (!(headerValue instanceof byte[])) { throw new IllegalArgumentException("WHO must be a byte array"); } else { - who = new byte[((byte[])headerValue).length]; - System.arraycopy(headerValue, 0, who, 0, who.length); + mWho = new byte[((byte[])headerValue).length]; + System.arraycopy(headerValue, 0, mWho, 0, mWho.length); } } break; case OBJECT_CLASS: if (headerValue == null) { - objectClass = null; + mObjectClass = null; } else { if (!(headerValue instanceof byte[])) { throw new IllegalArgumentException("Object Class must be a byte array"); } else { - objectClass = new byte[((byte[])headerValue).length]; - System.arraycopy(headerValue, 0, objectClass, 0, objectClass.length); + mObjectClass = new byte[((byte[])headerValue).length]; + System.arraycopy(headerValue, 0, mObjectClass, 0, mObjectClass.length); } } break; case APPLICATION_PARAMETER: if (headerValue == null) { - appParam = null; + mAppParam = null; } else { if (!(headerValue instanceof byte[])) { throw new IllegalArgumentException( "Application Parameter must be a byte array"); } else { - appParam = new byte[((byte[])headerValue).length]; - System.arraycopy(headerValue, 0, appParam, 0, appParam.length); + mAppParam = new byte[((byte[])headerValue).length]; + System.arraycopy(headerValue, 0, mAppParam, 0, mAppParam.length); } } break; @@ -345,7 +382,7 @@ public final class HeaderSet { throw new IllegalArgumentException( "Unicode String User Defined must be a String"); } - unicodeUserDefined[headerID - 0x30] = (String)headerValue; + mUnicodeUserDefined[headerID - 0x30] = (String)headerValue; break; } @@ -353,15 +390,15 @@ public final class HeaderSet { if ((headerID >= 0x70) && (headerID <= 0x7F)) { if (headerValue == null) { - sequenceUserDefined[headerID - 0x70] = null; + mSequenceUserDefined[headerID - 0x70] = null; } else { if (!(headerValue instanceof byte[])) { throw new IllegalArgumentException( "Byte Sequence User Defined must be a byte array"); } else { - sequenceUserDefined[headerID - 0x70] = new byte[((byte[])headerValue).length]; - System.arraycopy(headerValue, 0, sequenceUserDefined[headerID - 0x70], - 0, sequenceUserDefined[headerID - 0x70].length); + mSequenceUserDefined[headerID - 0x70] = new byte[((byte[])headerValue).length]; + System.arraycopy(headerValue, 0, mSequenceUserDefined[headerID - 0x70], + 0, mSequenceUserDefined[headerID - 0x70].length); } } break; @@ -371,7 +408,7 @@ public final class HeaderSet { if ((headerValue != null) && (!(headerValue instanceof Byte))) { throw new IllegalArgumentException("ByteUser Defined must be a Byte"); } - byteUserDefined[headerID - 0xB0] = (Byte)headerValue; + mByteUserDefined[headerID - 0xB0] = (Byte)headerValue; break; } @@ -380,7 +417,7 @@ public final class HeaderSet { if ((headerID >= 0xF0) && (headerID <= 0xFF)) { if (!(headerValue instanceof Long)) { if (headerValue == null) { - integerUserDefined[headerID - 0xF0] = null; + mIntegerUserDefined[headerID - 0xF0] = null; break; } throw new IllegalArgumentException("Integer User Defined must be a Long"); @@ -390,7 +427,7 @@ public final class HeaderSet { throw new IllegalArgumentException( "Integer User Defined must be between 0 and 0xFFFFFFFF"); } - integerUserDefined[headerID - 0xF0] = (Long)headerValue; + mIntegerUserDefined[headerID - 0xF0] = (Long)headerValue; break; } throw new IllegalArgumentException("Invalid Header Identifier"); @@ -417,45 +454,45 @@ public final class HeaderSet { switch (headerID) { case COUNT: - return count; + return mCount; case NAME: - return name; + return mName; case TYPE: - return type; + return mType; case LENGTH: - return length; + return mLength; case TIME_ISO_8601: - return isoTime; + return mIsoTime; case TIME_4_BYTE: - return byteTime; + return mByteTime; case DESCRIPTION: - return description; + return mDescription; case TARGET: - return target; + return mTarget; case HTTP: - return http; + return mHttpHeader; case WHO: - return who; + return mWho; case OBJECT_CLASS: - return objectClass; + return mObjectClass; case APPLICATION_PARAMETER: - return appParam; + return mAppParam; default: // Verify that it was not a Unicode String user Defined if ((headerID >= 0x30) && (headerID <= 0x3F)) { - return unicodeUserDefined[headerID - 0x30]; + return mUnicodeUserDefined[headerID - 0x30]; } // Verify that it was not a byte sequence user defined header if ((headerID >= 0x70) && (headerID <= 0x7F)) { - return sequenceUserDefined[headerID - 0x70]; + return mSequenceUserDefined[headerID - 0x70]; } // Verify that it was not a byte user defined header if ((headerID >= 0xB0) && (headerID <= 0xBF)) { - return byteUserDefined[headerID - 0xB0]; + return mByteUserDefined[headerID - 0xB0]; } - // Verify that it was not a itneger user defined header + // Verify that it was not a integer user defined header if ((headerID >= 0xF0) && (headerID <= 0xFF)) { - return integerUserDefined[headerID - 0xF0]; + return mIntegerUserDefined[headerID - 0xF0]; } throw new IllegalArgumentException("Invalid Header Identifier"); } @@ -478,63 +515,63 @@ public final class HeaderSet { public int[] getHeaderList() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); - if (count != null) { + if (mCount != null) { out.write(COUNT); } - if (name != null) { + if (mName != null) { out.write(NAME); } - if (type != null) { + if (mType != null) { out.write(TYPE); } - if (length != null) { + if (mLength != null) { out.write(LENGTH); } - if (isoTime != null) { + if (mIsoTime != null) { out.write(TIME_ISO_8601); } - if (byteTime != null) { + if (mByteTime != null) { out.write(TIME_4_BYTE); } - if (description != null) { + if (mDescription != null) { out.write(DESCRIPTION); } - if (target != null) { + if (mTarget != null) { out.write(TARGET); } - if (http != null) { + if (mHttpHeader != null) { out.write(HTTP); } - if (who != null) { + if (mWho != null) { out.write(WHO); } - if (appParam != null) { + if (mAppParam != null) { out.write(APPLICATION_PARAMETER); } - if (objectClass != null) { + if (mObjectClass != null) { out.write(OBJECT_CLASS); } for (int i = 0x30; i < 0x40; i++) { - if (unicodeUserDefined[i - 0x30] != null) { + if (mUnicodeUserDefined[i - 0x30] != null) { out.write(i); } } for (int i = 0x70; i < 0x80; i++) { - if (sequenceUserDefined[i - 0x70] != null) { + if (mSequenceUserDefined[i - 0x70] != null) { out.write(i); } } for (int i = 0xB0; i < 0xC0; i++) { - if (byteUserDefined[i - 0xB0] != null) { + if (mByteUserDefined[i - 0xB0] != null) { out.write(i); } } for (int i = 0xF0; i < 0x100; i++) { - if (integerUserDefined[i - 0xF0] != null) { + if (mIntegerUserDefined[i - 0xF0] != null) { out.write(i); } } @@ -572,18 +609,20 @@ public final class HeaderSet { * @param access if <code>true</code> then full access will be granted if * successful; if <code>false</code> then read-only access will be granted * if successful + * @throws IOException */ - public void createAuthenticationChallenge(String realm, boolean userID, boolean access) { + public void createAuthenticationChallenge(String realm, boolean userID, boolean access) + throws IOException { try { nonce = new byte[16]; for (int i = 0; i < 16; i++) { - nonce[i] = (byte)random.nextInt(); + nonce[i] = (byte)mRandom.nextInt(); } - authChall = ObexHelper.computeAuthenticationChallenge(nonce, realm, access, userID); + mAuthChall = ObexHelper.computeAuthenticationChallenge(nonce, realm, access, userID); } catch (IOException e) { - throw new RuntimeException(e.getMessage()); + throw e; } } diff --git a/obex/javax/obex/ObexHelper.java b/obex/javax/obex/ObexHelper.java index 6bf5e3e..511b7c6 100644 --- a/obex/javax/obex/ObexHelper.java +++ b/obex/javax/obex/ObexHelper.java @@ -48,15 +48,17 @@ import java.util.TimeZone; */ public final class ObexHelper { - /** Prevent object construction of helper class */ - private ObexHelper() {} - /** - * Defines the OBEX CONTINUE response code. - * <P> - * The value of <code>OBEX_HTTP_CONTINUE</code> is 0x90 (144). + * Defines the basic packet length used by OBEX. Every OBEX packet has the + * same basic format:<BR> + * Byte 0: Request or Response Code + * Byte 1&2: Length of the packet. */ - public static final int OBEX_HTTP_CONTINUE = 0x90; + public static final int BASE_PACKET_LENGTH = 3; + + /** Prevent object construction of helper class */ + private ObexHelper() { + } /** * The maximum packet size for OBEX packets that this client can handle. @@ -73,6 +75,48 @@ public final class ObexHelper { */ public static final int MAX_PACKET_SIZE_INT = 0xFFFE; + public static final int OBEX_OPCODE_CONNECT = 0x80; + + public static final int OBEX_OPCODE_DISCONNECT = 0x81; + + public static final int OBEX_OPCODE_PUT = 0x02; + + public static final int OBEX_OPCODE_PUT_FINAL = 0x82; + + public static final int OBEX_OPCODE_GET = 0x03; + + public static final int OBEX_OPCODE_GET_FINAL = 0x83; + + public static final int OBEX_OPCODE_RESERVED = 0x04; + + public static final int OBEX_OPCODE_RESERVED_FINAL = 0x84; + + public static final int OBEX_OPCODE_SETPATH = 0x85; + + public static final int OBEX_OPCODE_ABORT = 0xFF; + + public static final int OBEX_AUTH_REALM_CHARSET_ASCII = 0x00; + + public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_1 = 0x01; + + public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_2 = 0x02; + + public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_3 = 0x03; + + public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_4 = 0x04; + + public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_5 = 0x05; + + public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_6 = 0x06; + + public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_7 = 0x07; + + public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_8 = 0x08; + + public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_9 = 0x09; + + public static final int OBEX_AUTH_REALM_CHARSET_UNICODE = 0xFF; + /** * Updates the HeaderSet with the headers received in the byte array * provided. Invalid headers are ignored. @@ -153,37 +197,25 @@ public final class ObexHelper { value.length - 1, "ISO8859_1")); } } catch (UnsupportedEncodingException e) { - throw new RuntimeException("ISO8859_1 is not supported" - + e.getMessage()); + throw e; } break; - // This is the constant for the authentication challenge header - // This header does not have a constant defined in the Java - // OBEX API - case 0x4D: - headerImpl.authChall = new byte[length]; - System.arraycopy(headerArray, index, headerImpl.authChall, 0, + case HeaderSet.AUTH_CHALLENGE: + headerImpl.mAuthChall = new byte[length]; + System.arraycopy(headerArray, index, headerImpl.mAuthChall, 0, length); break; - // This is the constant for the authentication response header - // This header does not have a constant defined in the Java - // OBEX API - case 0x4E: - headerImpl.authResp = new byte[length]; - System - .arraycopy(headerArray, index, headerImpl.authResp, 0, - length); + case HeaderSet.AUTH_RESPONSE: + headerImpl.mAuthResp = new byte[length]; + System.arraycopy(headerArray, index, headerImpl.mAuthResp, 0, + length); break; - /* - * These two case statements are for the body (0x48) - * and end of body (0x49) headers. - */ - case 0x48: + case HeaderSet.BODY: /* Fall Through */ - case 0x49: + case HeaderSet.END_OF_BODY: body = new byte[length + 1]; body[0] = (byte)headerID; System.arraycopy(headerArray, index, body, 1, length); @@ -211,24 +243,16 @@ public final class ObexHelper { .substring(13, 15))); headerImpl.setHeader(HeaderSet.TIME_ISO_8601, temp); } catch (UnsupportedEncodingException e) { - throw new RuntimeException("ISO8859_1 is not supported" - + e.getMessage()); - } catch (Exception e) { - throw new IOException( - "Time Header does not follow ISO 8601 standard"); + throw e; } break; default: - try { - if ((headerID & 0xC0) == 0x00) { - headerImpl.setHeader(headerID, ObexHelper.convertToUnicode( - value, true)); - } else { - headerImpl.setHeader(headerID, value); - } - } catch (Exception e) { - // Not a valid header so ignore + if ((headerID & 0xC0) == 0x00) { + headerImpl.setHeader(headerID, ObexHelper.convertToUnicode( + value, true)); + } else { + headerImpl.setHeader(headerID, value); } } @@ -262,9 +286,9 @@ public final class ObexHelper { if (headerID != HeaderSet.TIME_4_BYTE) { // Determine if it is a connection ID. These // need to be handled differently - if (headerID == 0xCB) { - headerImpl.connectionID = new byte[4]; - System.arraycopy(value, 0, headerImpl.connectionID, 0, 4); + if (headerID == HeaderSet.CONNECTION_ID) { + headerImpl.mConnectionID = new byte[4]; + System.arraycopy(value, 0, headerImpl.mConnectionID, 0, 4); } else { headerImpl.setHeader(headerID, Long .valueOf(convertToLong(value))); @@ -328,10 +352,10 @@ public final class ObexHelper { * Determine if there is a connection ID to send. If there is, * then it should be the first header in the packet. */ - if ((headImpl.connectionID != null) && (headImpl.getHeader(HeaderSet.TARGET) == null)) { + if ((headImpl.mConnectionID != null) && (headImpl.getHeader(HeaderSet.TARGET) == null)) { - out.write((byte)0xCB); - out.write(headImpl.connectionID); + out.write((byte)HeaderSet.CONNECTION_ID); + out.write(headImpl.mConnectionID); } // Count Header @@ -351,8 +375,8 @@ public final class ObexHelper { out.write((byte)HeaderSet.NAME); value = ObexHelper.convertToUnicodeByteArray(stringHeader); length = value.length + 3; - lengthArray[0] = (byte)(255 & (length >> 8)); - lengthArray[1] = (byte)(255 & length); + lengthArray[0] = (byte)(0xFF & (length >> 8)); + lengthArray[1] = (byte)(0xFF & length); out.write(lengthArray); out.write(value); if (nullOut) { @@ -367,7 +391,7 @@ public final class ObexHelper { try { value = stringHeader.getBytes("ISO8859_1"); } catch (UnsupportedEncodingException e) { - throw new RuntimeException("Unsupported Encoding Scheme: " + e.getMessage()); + throw e; } length = value.length + 4; @@ -440,7 +464,7 @@ public final class ObexHelper { try { value = buffer.toString().getBytes("ISO8859_1"); } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UnsupportedEncodingException: " + e.getMessage()); + throw e; } length = value.length + 3; @@ -612,28 +636,28 @@ public final class ObexHelper { } // Add the authentication challenge header - if (headImpl.authChall != null) { - out.write((byte)0x4D); - length = headImpl.authChall.length + 3; + if (headImpl.mAuthChall != null) { + out.write((byte)HeaderSet.AUTH_CHALLENGE); + length = headImpl.mAuthChall.length + 3; lengthArray[0] = (byte)(255 & (length >> 8)); lengthArray[1] = (byte)(255 & length); out.write(lengthArray); - out.write(headImpl.authChall); + out.write(headImpl.mAuthChall); if (nullOut) { - headImpl.authChall = null; + headImpl.mAuthChall = null; } } // Add the authentication response header - if (headImpl.authResp != null) { - out.write((byte)0x4E); - length = headImpl.authResp.length + 3; + if (headImpl.mAuthResp != null) { + out.write((byte)HeaderSet.AUTH_RESPONSE); + length = headImpl.mAuthResp.length + 3; lengthArray[0] = (byte)(255 & (length >> 8)); lengthArray[1] = (byte)(255 & length); out.write(lengthArray); - out.write(headImpl.authResp); + out.write(headImpl.mAuthResp); if (nullOut) { - headImpl.authResp = null; + headImpl.mAuthResp = null; } } diff --git a/obex/javax/obex/ObexSession.java b/obex/javax/obex/ObexSession.java index 1dc50c6..97d65e0 100644 --- a/obex/javax/obex/ObexSession.java +++ b/obex/javax/obex/ObexSession.java @@ -47,8 +47,180 @@ import java.io.IOException; * * @hide */ -public interface ObexSession { +public class ObexSession { - public void close() throws IOException; + protected Authenticator mAuthenticator; + protected byte[] mChallengeDigest; + + /** + * Called when the server received an authentication challenge header. This + * will cause the authenticator to handle the authentication challenge. + * + * @param header + * the header with the authentication challenge + * + * @return <code>true</code> if the last request should be resent; + * <code>false</code> if the last request should not be resent + * @throws IOException + */ + public boolean handleAuthChall(HeaderSet header) throws IOException { + if (mAuthenticator == null) { + return false; + } + + /* + * An authentication challenge is made up of one required and two + * optional tag length value triplets. The tag 0x00 is required to be in + * the authentication challenge and it represents the challenge digest + * that was received. The tag 0x01 is the options tag. This tag tracks + * if user ID is required and if full access will be granted. The tag + * 0x02 is the realm, which provides a description of which user name + * and password to use. + */ + byte[] challenge = ObexHelper.getTagValue((byte)0x00, header.mAuthChall); + byte[] option = ObexHelper.getTagValue((byte)0x01, header.mAuthChall); + byte[] description = ObexHelper.getTagValue((byte)0x02, header.mAuthChall); + + String realm = null; + if (description != null) { + byte[] realmString = new byte[description.length - 1]; + System.arraycopy(description, 1, realmString, 0, realmString.length); + + switch (description[0] & 0xFF) { + + case ObexHelper.OBEX_AUTH_REALM_CHARSET_ASCII: + // ASCII encoding + // Fall through + case ObexHelper.OBEX_AUTH_REALM_CHARSET_ISO_8859_1: + // ISO-8859-1 encoding + try { + realm = new String(realmString, "ISO8859_1"); + } catch (Exception e) { + throw new IOException("Unsupported Encoding Scheme"); + } + break; + + case ObexHelper.OBEX_AUTH_REALM_CHARSET_UNICODE: + // UNICODE Encoding + realm = ObexHelper.convertToUnicode(realmString, false); + break; + + default: + throw new IOException("Unsupported Encoding Scheme"); + } + } + + boolean isUserIDRequired = false; + boolean isFullAccess = true; + if (option != null) { + if ((option[0] & 0x01) != 0) { + isUserIDRequired = true; + } + + if ((option[0] & 0x02) != 0) { + isFullAccess = false; + } + } + + PasswordAuthentication result = null; + header.mAuthChall = null; + + try { + result = mAuthenticator + .onAuthenticationChallenge(realm, isUserIDRequired, isFullAccess); + } catch (Exception e) { + return false; + } + + /* + * If no password is provided then we not resent the request + */ + if (result == null) { + return false; + } + + byte[] password = result.getPassword(); + if (password == null) { + return false; + } + + byte[] userName = result.getUserName(); + + /* + * Create the authentication response header. It includes 1 required and + * 2 option tag length value triples. The required triple has a tag of + * 0x00 and is the response digest. The first optional tag is 0x01 and + * represents the user ID. If no user ID is provided, then no user ID + * will be sent. The second optional tag is 0x02 and is the challenge + * that was received. This will always be sent + */ + if (userName != null) { + header.mAuthResp = new byte[38 + userName.length]; + header.mAuthResp[36] = (byte)0x01; + header.mAuthResp[37] = (byte)userName.length; + System.arraycopy(userName, 0, header.mAuthResp, 38, userName.length); + } else { + header.mAuthResp = new byte[36]; + } + + // Create the secret String + byte[] digest = new byte[challenge.length + password.length + 1]; + System.arraycopy(challenge, 0, digest, 0, challenge.length); + // Insert colon between challenge and password + digest[challenge.length] = (byte)0x3A; + System.arraycopy(password, 0, digest, challenge.length + 1, password.length); + + // Add the Response Digest + header.mAuthResp[0] = (byte)0x00; + header.mAuthResp[1] = (byte)0x10; + + System.arraycopy(ObexHelper.computeMd5Hash(digest), 0, header.mAuthResp, 2, 16); + + // Add the challenge + header.mAuthResp[18] = (byte)0x02; + header.mAuthResp[19] = (byte)0x10; + System.arraycopy(challenge, 0, header.mAuthResp, 20, 16); + + return true; + } + + /** + * Called when the server received an authentication response header. This + * will cause the authenticator to handle the authentication response. + * + * @param authResp + * the authentication response + * + * @return <code>true</code> if the response passed; <code>false</code> if + * the response failed + */ + public boolean handleAuthResp(byte[] authResp) { + if (mAuthenticator == null) { + return false; + } + // get the correct password from the application + byte[] correctPassword = mAuthenticator.onAuthenticationResponse(ObexHelper.getTagValue( + (byte)0x01, authResp)); + if (correctPassword == null) { + return false; + } + + byte[] temp = new byte[correctPassword.length + 16]; + + System.arraycopy(mChallengeDigest, 0, temp, 0, 16); + System.arraycopy(correctPassword, 0, temp, 16, correctPassword.length); + + byte[] correctResponse = ObexHelper.computeMd5Hash(temp); + byte[] actualResponse = ObexHelper.getTagValue((byte)0x00, authResp); + + // compare the MD5 hash array . + for (int i = 0; i < 16; i++) { + if (correctResponse[i] != actualResponse[i]) { + return false; + } + } + + return true; + } } diff --git a/obex/javax/obex/Operation.java b/obex/javax/obex/Operation.java index 5a8bcec..f265f53 100644 --- a/obex/javax/obex/Operation.java +++ b/obex/javax/obex/Operation.java @@ -137,7 +137,7 @@ public interface Operation { * @throws IOException if the transaction has already ended or if an * OBEX server calls this method */ - public void abort() throws IOException; + void abort() throws IOException; /** * Returns the headers that have been received during the operation. @@ -148,7 +148,7 @@ public interface Operation { * * @throws IOException if this <code>Operation</code> has been closed */ - public HeaderSet getReceivedHeaders() throws IOException; + HeaderSet getReceivedHeader() throws IOException; /** * Specifies the headers that should be sent in the next OBEX message that @@ -165,7 +165,7 @@ public interface Operation { * * @throws NullPointerException if <code>headers</code> if <code>null</code> */ - public void sendHeaders(HeaderSet headers) throws IOException; + void sendHeaders(HeaderSet headers) throws IOException; /** * Returns the response code received from the server. Response codes @@ -178,23 +178,23 @@ public interface Operation { * @throws IOException if an error occurred in the transport layer during * the transaction; if this object was created by an OBEX server */ - public int getResponseCode() throws IOException; + int getResponseCode() throws IOException; - public String getEncoding(); + String getEncoding(); - public long getLength(); + long getLength(); - public String getType(); + String getType(); - public InputStream openInputStream() throws IOException; + InputStream openInputStream() throws IOException; - public DataInputStream openDataInputStream() throws IOException; + DataInputStream openDataInputStream() throws IOException; - public OutputStream openOutputStream() throws IOException; + OutputStream openOutputStream() throws IOException; - public DataOutputStream openDataOutputStream() throws IOException; + DataOutputStream openDataOutputStream() throws IOException; - public void close() throws IOException; + void close() throws IOException; - public int getMaxPacketSize(); + int getMaxPacketSize(); } diff --git a/obex/javax/obex/PasswordAuthentication.java b/obex/javax/obex/PasswordAuthentication.java index 49833fe..e81a861 100644 --- a/obex/javax/obex/PasswordAuthentication.java +++ b/obex/javax/obex/PasswordAuthentication.java @@ -37,11 +37,11 @@ package javax.obex; * * @hide */ -public class PasswordAuthentication { +public final class PasswordAuthentication { - private byte[] userName; + private byte[] mUserName; - private byte[] password; + private final byte[] mPassword; /** * Creates a new <code>PasswordAuthentication</code> with the user name @@ -51,17 +51,17 @@ public class PasswordAuthentication { * * @param password the password to include in the response * - * @exception NullPointerException if <code>password</code> is + * @throws NullPointerException if <code>password</code> is * <code>null</code> */ - public PasswordAuthentication(byte[] userName, byte[] password) { + public PasswordAuthentication(final byte[] userName, final byte[] password) { if (userName != null) { - this.userName = new byte[userName.length]; - System.arraycopy(userName, 0, this.userName, 0, userName.length); + mUserName = new byte[userName.length]; + System.arraycopy(userName, 0, mUserName, 0, userName.length); } - this.password = new byte[password.length]; - System.arraycopy(password, 0, this.password, 0, password.length); + mPassword = new byte[password.length]; + System.arraycopy(password, 0, mPassword, 0, password.length); } /** @@ -71,7 +71,7 @@ public class PasswordAuthentication { * @return the user name */ public byte[] getUserName() { - return this.userName; + return mUserName; } /** @@ -80,6 +80,6 @@ public class PasswordAuthentication { * @return the password */ public byte[] getPassword() { - return this.password; + return mPassword; } } diff --git a/obex/javax/obex/PrivateInputStream.java b/obex/javax/obex/PrivateInputStream.java index 9602649..2dc02da 100644 --- a/obex/javax/obex/PrivateInputStream.java +++ b/obex/javax/obex/PrivateInputStream.java @@ -39,23 +39,17 @@ import java.io.IOException; * This object provides an input stream to the Operation objects used in this * package. * - * TODO: Include the other read() methods defined in InputStream. - * * @hide */ -public class PrivateInputStream extends InputStream { - - private BaseStream parent; +public final class PrivateInputStream extends InputStream { - private byte[] data; + private BaseStream mParent; - private int index; + private byte[] mData; - private boolean isOpen; + private int mIndex; - public PrivateInputStream() { - - } + private boolean mOpen; /** * Creates an input stream for the <code>Operation</code> to read from @@ -63,10 +57,10 @@ public class PrivateInputStream extends InputStream { * @param p the connection this input stream is for */ public PrivateInputStream(BaseStream p) { - parent = p; - data = new byte[0]; - index = 0; - isOpen = true; + mParent = p; + mData = new byte[0]; + mIndex = 0; + mOpen = true; } /** @@ -83,7 +77,7 @@ public class PrivateInputStream extends InputStream { @Override public synchronized int available() throws IOException { ensureOpen(); - return data.length - index; + return mData.length - mIndex; } /** @@ -101,12 +95,12 @@ public class PrivateInputStream extends InputStream { @Override public synchronized int read() throws IOException { ensureOpen(); - while (data.length == index) { - if (!parent.continueOperation(true, true)) { + while (mData.length == mIndex) { + if (!mParent.continueOperation(true, true)) { return -1; } } - return (data[index++] & 0xFF); + return (mData[mIndex++] & 0xFF); } @Override @@ -118,33 +112,33 @@ public class PrivateInputStream extends InputStream { public synchronized int read(byte[] b, int offset, int length) throws IOException { if (b == null) { - throw new NullPointerException("buffer is null"); + throw new IOException("buffer is null"); } if ((offset | length) < 0 || length > b.length - offset) { throw new ArrayIndexOutOfBoundsException("index outof bound"); } ensureOpen(); - int currentDataLength = data.length - index; + int currentDataLength = mData.length - mIndex; int remainReadLength = length; int offset1 = offset; int result = 0; while (currentDataLength <= remainReadLength) { - System.arraycopy(data, index, b, offset1, currentDataLength); - index += currentDataLength; + System.arraycopy(mData, mIndex, b, offset1, currentDataLength); + mIndex += currentDataLength; offset1 += currentDataLength; result += currentDataLength; remainReadLength -= currentDataLength; - if (!parent.continueOperation(true, true)) { + if (!mParent.continueOperation(true, true)) { return result == 0 ? -1 : result; } - currentDataLength = data.length - index; + currentDataLength = mData.length - mIndex; } if (remainReadLength > 0) { - System.arraycopy(data, index, b, offset1, remainReadLength); - index += remainReadLength; + System.arraycopy(mData, mIndex, b, offset1, remainReadLength); + mIndex += remainReadLength; result += remainReadLength; } return result; @@ -160,14 +154,14 @@ public class PrivateInputStream extends InputStream { */ public synchronized void writeBytes(byte[] body, int start) { - int length = (body.length - start) + (data.length - index); + int length = (body.length - start) + (mData.length - mIndex); byte[] temp = new byte[length]; - System.arraycopy(data, index, temp, 0, data.length - index); - System.arraycopy(body, start, temp, data.length - index, body.length - start); + System.arraycopy(mData, mIndex, temp, 0, mData.length - mIndex); + System.arraycopy(body, start, temp, mData.length - mIndex, body.length - start); - data = temp; - index = 0; + mData = temp; + mIndex = 0; notifyAll(); } @@ -177,8 +171,8 @@ public class PrivateInputStream extends InputStream { * @throws IOException if the stream is not open */ private void ensureOpen() throws IOException { - parent.ensureOpen(); - if (!isOpen) { + mParent.ensureOpen(); + if (!mOpen) { throw new IOException("Input stream is closed"); } } @@ -191,7 +185,7 @@ public class PrivateInputStream extends InputStream { */ @Override public void close() throws IOException { - isOpen = false; - parent.streamClosed(true); + mOpen = false; + mParent.streamClosed(true); } } diff --git a/obex/javax/obex/PrivateOutputStream.java b/obex/javax/obex/PrivateOutputStream.java index 75220d6..d972f78 100644 --- a/obex/javax/obex/PrivateOutputStream.java +++ b/obex/javax/obex/PrivateOutputStream.java @@ -42,15 +42,15 @@ import java.io.ByteArrayOutputStream; * * @hide */ -class PrivateOutputStream extends OutputStream { +public final class PrivateOutputStream extends OutputStream { - private BaseStream parent; + private BaseStream mParent; - private ByteArrayOutputStream output; + private ByteArrayOutputStream mArray; - private boolean isClosed; + private boolean mOpen; - private int maxPacketSize; + private int mMaxPacketSize; /** * Creates an empty <code>PrivateOutputStream</code> to write to. @@ -58,9 +58,9 @@ class PrivateOutputStream extends OutputStream { * @param p the connection that this stream runs over */ public PrivateOutputStream(BaseStream p, int maxSize) { - parent = p; - output = new ByteArrayOutputStream(); - maxPacketSize = maxSize; + mParent = p; + mArray = new ByteArrayOutputStream(); + mMaxPacketSize = maxSize; } /** @@ -68,8 +68,8 @@ class PrivateOutputStream extends OutputStream { * * @return the number of bytes written to the output stream */ - protected int size() { - return output.size(); + public int size() { + return mArray.size(); } /** @@ -85,10 +85,10 @@ class PrivateOutputStream extends OutputStream { @Override public synchronized void write(int b) throws IOException { ensureOpen(); - parent.ensureNotDone(); - output.write(b); - if (output.size() == maxPacketSize) { - parent.continueOperation(true, false); + mParent.ensureNotDone(); + mArray.write(b); + if (mArray.size() == mMaxPacketSize) { + mParent.continueOperation(true, false); } } @@ -103,25 +103,25 @@ class PrivateOutputStream extends OutputStream { int remainLength = count; if (buffer == null) { - throw new NullPointerException("buffer is null"); + throw new IOException("buffer is null"); } if ((offset | count) < 0 || count > buffer.length - offset) { throw new IndexOutOfBoundsException("index outof bound"); } ensureOpen(); - parent.ensureNotDone(); - if (count < maxPacketSize) { - output.write(buffer, offset, count); + mParent.ensureNotDone(); + if (count < mMaxPacketSize) { + mArray.write(buffer, offset, count); } else { - while (remainLength >= maxPacketSize) { - output.write(buffer, offset1, maxPacketSize); - offset1 += maxPacketSize; + while (remainLength >= mMaxPacketSize) { + mArray.write(buffer, offset1, mMaxPacketSize); + offset1 += mMaxPacketSize; remainLength = count - offset1; - parent.continueOperation(true, false); + mParent.continueOperation(true, false); } if (remainLength > 0) { - output.write(buffer, offset1, remainLength); + mArray.write(buffer, offset1, remainLength); } } } @@ -129,33 +129,18 @@ class PrivateOutputStream extends OutputStream { /** * Reads the bytes that have been written to this stream. * - * @return the byte array that is written - */ - protected synchronized byte[] readBytes() { - if (output.size() > 0) { - byte[] result = output.toByteArray(); - output.reset(); - return result; - } else { - return null; - } - } - - /** - * Reads the bytes that have been written to this stream. - * * @param size the size of the array to return * * @return the byte array that is written */ - protected synchronized byte[] readBytes(int size) { - if (output.size() > 0) { - byte[] temp = output.toByteArray(); - output.reset(); + public synchronized byte[] readBytes(int size) { + if (mArray.size() > 0) { + byte[] temp = mArray.toByteArray(); + mArray.reset(); byte[] result = new byte[size]; System.arraycopy(temp, 0, result, 0, size); if (temp.length != size) { - output.write(temp, size, temp.length - size); + mArray.write(temp, size, temp.length - size); } return result; } else { @@ -169,8 +154,8 @@ class PrivateOutputStream extends OutputStream { * @throws IOException if the stream is not open */ private void ensureOpen() throws IOException { - parent.ensureOpen(); - if (isClosed) { + mParent.ensureOpen(); + if (!mOpen) { throw new IOException("Output stream is closed"); } } @@ -183,8 +168,8 @@ class PrivateOutputStream extends OutputStream { */ @Override public void close() throws IOException { - isClosed = true; - parent.streamClosed(false); + mOpen = false; + mParent.streamClosed(false); } /** @@ -193,7 +178,7 @@ class PrivateOutputStream extends OutputStream { * @return <code>true</code> if the connection is closed; * <code>false</code> if the connection is open */ - protected boolean isClosed() { - return isClosed; + public boolean isClosed() { + return !mOpen; } } diff --git a/obex/javax/obex/ResponseCodes.java b/obex/javax/obex/ResponseCodes.java index 2d7627b..f6cc9c1 100644 --- a/obex/javax/obex/ResponseCodes.java +++ b/obex/javax/obex/ResponseCodes.java @@ -38,11 +38,8 @@ package javax.obex; * <P> * <STRONG>IMPORTANT NOTE</STRONG> * <P> - * It is important to note that these values are different then those defined - * in <code>javax.microedition.io.HttpConnection</code>. The values in this - * interface represent the values defined in the IrOBEX specification. The - * values in <code>javax.microedition.io.HttpConnection</code> represent values - * defined in the HTTP specification. + * The values in this interface represent the values defined in the IrOBEX + * specification, which is different with the HTTP specification. * <P> * <code>OBEX_DATABASE_FULL</code> and <code>OBEX_DATABASE_LOCKED</code> require * further description since they are not defined in HTTP. The server will send @@ -54,7 +51,14 @@ package javax.obex; * * @hide */ -public class ResponseCodes { +public final class ResponseCodes { + + /** + * Defines the OBEX CONTINUE response code. + * <P> + * The value of <code>OBEX_HTTP_CONTINUE</code> is 0x90 (144). + */ + public static final int OBEX_HTTP_CONTINUE = 0x90; /** * Defines the OBEX SUCCESS response code. @@ -318,5 +322,6 @@ public class ResponseCodes { /** * Constructor does nothing. */ - private ResponseCodes() {} + private ResponseCodes() { + } } diff --git a/obex/javax/obex/ServerOperation.java b/obex/javax/obex/ServerOperation.java index 5dcbb93..6c3d9ba 100644 --- a/obex/javax/obex/ServerOperation.java +++ b/obex/javax/obex/ServerOperation.java @@ -48,7 +48,7 @@ import java.io.ByteArrayOutputStream; * additional OBEX packet. 0x82 is a PUT request that says that request is * complete. In this case, the server can begin sending the response. The * 0x03 is a GET request that signals that the request is not finished. When - * the server receives a 0x83, the client is signalling the server that it is + * the server receives a 0x83, the client is signaling the server that it is * done with its request. * * TODO: Extend the ClientOperation and reuse the methods defined @@ -56,52 +56,44 @@ import java.io.ByteArrayOutputStream; * * @hide */ -public class ServerOperation implements Operation, BaseStream { +public final class ServerOperation implements Operation, BaseStream { - private InputStream socketInput; + public boolean isAborted; - private ServerSession parent; + public HeaderSet requestHeader; - private int maxPacketLength; + public HeaderSet replyHeader; - private int responseSize; + public boolean finalBitSet; - private boolean isClosed; + private InputStream mInput; - boolean finalBitSet; + private ServerSession mParent; - // This variable defines when the end of body - // header has been received. When this header - // is received, no further body data will be - // received from the client - private boolean endOfBody; + private int mMaxPacketLength; - private boolean isGet; + private int mResponseSize; - boolean isAborted; + private boolean mClosed; - HeaderSet requestHeaders; + private boolean mGetOperation; - HeaderSet replyHeaders; + private PrivateInputStream mPrivateInput; - PrivateInputStream privateInput; + private PrivateOutputStream mPrivateOutput; - private PrivateOutputStream privateOutput; + private boolean mPrivateOutputOpen; - private String exceptionString; + private String mExceptionString; - private ServerRequestHandler listener; + private ServerRequestHandler mListener; - private boolean outputStreamOpened; + private boolean mRequestFinished; - private boolean requestFinished; - - private static final int BASE_PACKET_LENGTH = 3; - - private boolean isHasBody; + private boolean mHasBody; /** - * Creates new PutServerOperation + * Creates new ServerOperation * * @param p the parent that created this object * @@ -121,19 +113,18 @@ public class ServerOperation implements Operation, BaseStream { ServerRequestHandler listen) throws IOException { isAborted = false; - parent = p; - socketInput = in; - maxPacketLength = maxSize; - isClosed = false; - requestHeaders = new HeaderSet(); - replyHeaders = new HeaderSet(); - privateInput = new PrivateInputStream(this); - endOfBody = false; - responseSize = 3; - listener = listen; - requestFinished = false; - outputStreamOpened = false; - isHasBody = false; + mParent = p; + mInput = in; + mMaxPacketLength = maxSize; + mClosed = false; + requestHeader = new HeaderSet(); + replyHeader = new HeaderSet(); + mPrivateInput = new PrivateInputStream(this); + mResponseSize = 3; + mListener = listen; + mRequestFinished = false; + mPrivateOutputOpen = false; + mHasBody = false; int bytesReceived; /* @@ -143,12 +134,12 @@ public class ServerOperation implements Operation, BaseStream { /* * It is a PUT request. */ - isGet = false; + mGetOperation = false; } else { /* * It is a GET request. */ - isGet = true; + mGetOperation = true; } /* @@ -158,7 +149,7 @@ public class ServerOperation implements Operation, BaseStream { finalBitSet = false; } else { finalBitSet = true; - requestFinished = true; + mRequestFinished = true; } int length = in.read(); @@ -168,7 +159,7 @@ public class ServerOperation implements Operation, BaseStream { * Determine if the packet length is larger than this device can receive */ if (length > ObexHelper.MAX_PACKET_SIZE_INT) { - parent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); + mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); throw new IOException("Packet received was too large"); } @@ -183,81 +174,69 @@ public class ServerOperation implements Operation, BaseStream { bytesReceived += in.read(data, bytesReceived, data.length - bytesReceived); } - byte[] body = ObexHelper.updateHeaderSet(requestHeaders, data); + byte[] body = ObexHelper.updateHeaderSet(requestHeader, data); if (body != null) { - isHasBody = true; + mHasBody = true; } - if (requestHeaders.connectionID != null) { - listener.setConnectionID(ObexHelper.convertToLong(requestHeaders.connectionID)); + if (requestHeader.mConnectionID != null) { + mListener.setConnectionId(ObexHelper.convertToLong(requestHeader.mConnectionID)); } else { - listener.setConnectionID(0); + mListener.setConnectionId(0); } - if (requestHeaders.authResp != null) { - if (!parent.handleAuthResp(requestHeaders.authResp)) { - exceptionString = "Authentication Failed"; - parent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); - isClosed = true; - requestHeaders.authResp = null; + if (requestHeader.mAuthResp != null) { + if (!mParent.handleAuthResp(requestHeader.mAuthResp)) { + mExceptionString = "Authentication Failed"; + mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); + mClosed = true; + requestHeader.mAuthResp = null; return; } } - if (requestHeaders.authChall != null) { - parent.handleAuthChall(requestHeaders); + if (requestHeader.mAuthChall != null) { + mParent.handleAuthChall(requestHeader); // send the authResp to the client - replyHeaders.authResp = new byte[requestHeaders.authResp.length]; - System.arraycopy(requestHeaders.authResp, 0, replyHeaders.authResp, 0, - replyHeaders.authResp.length); - requestHeaders.authResp = null; - requestHeaders.authChall = null; + replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length]; + System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0, + replyHeader.mAuthResp.length); + requestHeader.mAuthResp = null; + requestHeader.mAuthChall = null; } if (body != null) { - /* - * 0x49 is the end of body header. This signifies that no more - * body data will be sent from the client - */ - if (body[0] == 0x49) { - endOfBody = true; - } - //privateInput.writeBytes(body, body.length); - //byte [] body_tmp = new byte[body.length-1]; - //System.arraycopy(body,1,body_tmp,0,body.length-1); - //privateInput.writeBytes(body_tmp, body.length-1); - privateInput.writeBytes(body, 1); + mPrivateInput.writeBytes(body, 1); } else { - while ((!isGet) && (!finalBitSet)) { - sendReply(ObexHelper.OBEX_HTTP_CONTINUE); - if (privateInput.available() > 0) { + while ((!mGetOperation) && (!finalBitSet)) { + sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); + if (mPrivateInput.available() > 0) { break; } } - }// if (body != null) - - }// if (length > 3) + } + } - while ((!isGet) && (!finalBitSet) && (privateInput.available() == 0)) { - sendReply(ObexHelper.OBEX_HTTP_CONTINUE); - if (privateInput.available() > 0) { + while ((!mGetOperation) && (!finalBitSet) && (mPrivateInput.available() == 0)) { + sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); + if (mPrivateInput.available() > 0) { break; } } // wait for get request finished !!!! - while (isGet && !finalBitSet) { - sendReply(ObexHelper.OBEX_HTTP_CONTINUE); + while (mGetOperation && !finalBitSet) { + sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); } - if (finalBitSet && isGet) { - requestFinished = true; + if (finalBitSet && mGetOperation) { + mRequestFinished = true; } } - public synchronized boolean isValidBody() { - return isHasBody; + public boolean isValidBody() { + return mHasBody; } /** @@ -268,21 +247,21 @@ public class ServerOperation implements Operation, BaseStream { * operation even if no headers will be sent; if <code>false</code> then * this method will only continue the operation if there are headers to * send - * @param isStream if<code>true</code> the stream is input stream or - * is outputstream + * @param isStream if<code>true</code> the stream is input stream, otherwise + * output stream * @return <code>true</code> if the operation was completed; * <code>false</code> if no operation took place */ public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream) throws IOException { - if (!isGet) { + if (!mGetOperation) { if (!finalBitSet) { if (sendEmpty) { - sendReply(ObexHelper.OBEX_HTTP_CONTINUE); + sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); return true; } else { - if ((responseSize > 3) || (privateOutput.size() > 0)) { - sendReply(ObexHelper.OBEX_HTTP_CONTINUE); + if ((mResponseSize > 3) || (mPrivateOutput.size() > 0)) { + sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); return true; } else { return false; @@ -292,7 +271,7 @@ public class ServerOperation implements Operation, BaseStream { return false; } } else { - sendReply(ObexHelper.OBEX_HTTP_CONTINUE); + sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); return true; } } @@ -309,52 +288,52 @@ public class ServerOperation implements Operation, BaseStream { * * @throws IOException if an IO error occurs */ - protected synchronized boolean sendReply(int type) throws IOException { + public synchronized boolean sendReply(int type) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); int bytesReceived; - long id = listener.getConnectionID(); + long id = mListener.getConnectionId(); if (id == -1) { - replyHeaders.connectionID = null; + replyHeader.mConnectionID = null; } else { - replyHeaders.connectionID = ObexHelper.convertToByteArray(id); + replyHeader.mConnectionID = ObexHelper.convertToByteArray(id); } - byte[] headerArray = ObexHelper.createHeader(replyHeaders, true); + byte[] headerArray = ObexHelper.createHeader(replyHeader, true); int bodyLength = -1; int orginalBodyLength = -1; - if (privateOutput != null) { - bodyLength = privateOutput.size(); + if (mPrivateOutput != null) { + bodyLength = mPrivateOutput.size(); orginalBodyLength = bodyLength; } - if ((BASE_PACKET_LENGTH + headerArray.length) > maxPacketLength) { + if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length) > mMaxPacketLength) { int end = 0; int start = 0; while (end != headerArray.length) { - end = ObexHelper.findHeaderEnd(headerArray, start, maxPacketLength - - BASE_PACKET_LENGTH); + end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketLength + - ObexHelper.BASE_PACKET_LENGTH); if (end == -1) { - isClosed = true; + mClosed = true; - if (privateInput != null) { - privateInput.close(); + if (mPrivateInput != null) { + mPrivateInput.close(); } - if (privateOutput != null) { - privateOutput.close(); + if (mPrivateOutput != null) { + mPrivateOutput.close(); } - parent.sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); + mParent.sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); throw new IOException("OBEX Packet exceeds max packet size"); } byte[] sendHeader = new byte[end - start]; System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length); - parent.sendResponse(type, sendHeader); + mParent.sendResponse(type, sendHeader); start = end; } @@ -368,48 +347,25 @@ public class ServerOperation implements Operation, BaseStream { out.write(headerArray); } - /* - * Determine if there is space to add a body reply. First, we need to - * verify that the client is finished sending the request. Next, there - * needs to be enough space to send the headers already defined along - * with the reply header (3 bytes) and the body header identifier - * (3 bytes). - */ - - /* if ((finalBitSet) && - ((bodyLength + 6 + headerArray.length) > maxPacketLength)) { - - exceptionString = "Header larger then can be sent in a packet"; - isClosed = true; - privateInput.close(); - if (privateOutput != null) { - privateOutput.close(); - } - parent.sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, - null); - throw new IOException("OBEX Packet exceeds max packet size"); - } - */ - - if ((finalBitSet) || (headerArray.length < (maxPacketLength - 20))) { + if ((finalBitSet) || (headerArray.length < (mMaxPacketLength - 20))) { if (bodyLength > 0) { /* * Determine if I can send the whole body or just part of * the body. Remember that there is the 3 bytes for the * response message and 3 bytes for the header ID and length */ - if (bodyLength > (maxPacketLength - headerArray.length - 6)) { - bodyLength = maxPacketLength - headerArray.length - 6; + if (bodyLength > (mMaxPacketLength - headerArray.length - 6)) { + bodyLength = mMaxPacketLength - headerArray.length - 6; } - byte[] body = privateOutput.readBytes(bodyLength); + byte[] body = mPrivateOutput.readBytes(bodyLength); /* * Since this is a put request if the final bit is set or * the output stream is closed we need to send the 0x49 * (End of Body) otherwise, we need to send 0x48 (Body) */ - if ((finalBitSet) || (privateOutput.isClosed())) { + if ((finalBitSet) || (mPrivateOutput.isClosed())) { out.write(0x49); } else { out.write(0x48); @@ -430,44 +386,46 @@ public class ServerOperation implements Operation, BaseStream { } - responseSize = 3; - parent.sendResponse(type, out.toByteArray()); + mResponseSize = 3; + mParent.sendResponse(type, out.toByteArray()); - if (type == ObexHelper.OBEX_HTTP_CONTINUE) { - int headerID = socketInput.read(); - int length = socketInput.read(); - length = (length << 8) + socketInput.read(); - if ((headerID != 0x02) && (headerID != 0x82) && (headerID != 0x03) - && (headerID != 0x83)) { + if (type == ResponseCodes.OBEX_HTTP_CONTINUE) { + int headerID = mInput.read(); + int length = mInput.read(); + length = (length << 8) + mInput.read(); + if ((headerID != ObexHelper.OBEX_OPCODE_PUT) + && (headerID != ObexHelper.OBEX_OPCODE_PUT_FINAL) + && (headerID != ObexHelper.OBEX_OPCODE_GET) + && (headerID != ObexHelper.OBEX_OPCODE_GET_FINAL)) { if (length > 3) { byte[] temp = new byte[length]; - bytesReceived = socketInput.read(temp); + bytesReceived = mInput.read(temp); while (bytesReceived != length) { - bytesReceived += socketInput.read(temp, bytesReceived, length - - bytesReceived); + bytesReceived += mInput.read(temp, bytesReceived, length - bytesReceived); } } /* * Determine if an ABORT was sent as the reply */ - if (headerID == 0xFF) { - parent.sendResponse(ResponseCodes.OBEX_HTTP_OK, null); - isClosed = true; + if (headerID == ObexHelper.OBEX_OPCODE_ABORT) { + mParent.sendResponse(ResponseCodes.OBEX_HTTP_OK, null); + mClosed = true; isAborted = true; - exceptionString = "Abort Received"; + mExceptionString = "Abort Received"; throw new IOException("Abort Received"); } else { - parent.sendResponse(ResponseCodes.OBEX_HTTP_BAD_REQUEST, null); - isClosed = true; - exceptionString = "Bad Request Received"; + mParent.sendResponse(ResponseCodes.OBEX_HTTP_BAD_REQUEST, null); + mClosed = true; + mExceptionString = "Bad Request Received"; throw new IOException("Bad Request Received"); } } else { - if ((headerID == 0x82) || (headerID == 0x83)) { + if ((headerID == ObexHelper.OBEX_OPCODE_PUT_FINAL) + || (headerID == ObexHelper.OBEX_OPCODE_GET_FINAL)) { finalBitSet = true; } @@ -475,7 +433,7 @@ public class ServerOperation implements Operation, BaseStream { * Determine if the packet length is larger then this device can receive */ if (length > ObexHelper.MAX_PACKET_SIZE_INT) { - parent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); + mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null); throw new IOException("Packet received was too large"); } @@ -484,54 +442,46 @@ public class ServerOperation implements Operation, BaseStream { */ if (length > 3) { byte[] data = new byte[length - 3]; - bytesReceived = socketInput.read(data); + bytesReceived = mInput.read(data); while (bytesReceived != data.length) { - bytesReceived += socketInput.read(data, bytesReceived, data.length + bytesReceived += mInput.read(data, bytesReceived, data.length - bytesReceived); } - byte[] body = ObexHelper.updateHeaderSet(requestHeaders, data); + byte[] body = ObexHelper.updateHeaderSet(requestHeader, data); if (body != null) { - isHasBody = true; + mHasBody = true; } - if (requestHeaders.connectionID != null) { - listener.setConnectionID(ObexHelper - .convertToLong(requestHeaders.connectionID)); + if (requestHeader.mConnectionID != null) { + mListener.setConnectionId(ObexHelper + .convertToLong(requestHeader.mConnectionID)); } else { - listener.setConnectionID(1); + mListener.setConnectionId(1); } - if (requestHeaders.authResp != null) { - if (!parent.handleAuthResp(requestHeaders.authResp)) { - exceptionString = "Authentication Failed"; - parent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); - isClosed = true; - requestHeaders.authResp = null; + if (requestHeader.mAuthResp != null) { + if (!mParent.handleAuthResp(requestHeader.mAuthResp)) { + mExceptionString = "Authentication Failed"; + mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null); + mClosed = true; + requestHeader.mAuthResp = null; return false; } - requestHeaders.authResp = null; + requestHeader.mAuthResp = null; } - if (requestHeaders.authChall != null) { - parent.handleAuthChall(requestHeaders); + if (requestHeader.mAuthChall != null) { + mParent.handleAuthChall(requestHeader); // send the auhtResp to the client - replyHeaders.authResp = new byte[requestHeaders.authResp.length]; - System.arraycopy(requestHeaders.authResp, 0, replyHeaders.authResp, 0, - replyHeaders.authResp.length); - requestHeaders.authResp = null; - requestHeaders.authChall = null; + replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length]; + System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0, + replyHeader.mAuthResp.length); + requestHeader.mAuthResp = null; + requestHeader.mAuthChall = null; } if (body != null) { - if (body[0] == 0x49) { - endOfBody = true; - } - - /*byte [] body_tmp = new byte[body.length-1]; - System.arraycopy(body,1,body_tmp,0,body.length-1); - privateInput.writeBytes(body_tmp, body.length-1);*/ - privateInput.writeBytes(body, 1); - + mPrivateInput.writeBytes(body, 1); } } } @@ -562,9 +512,9 @@ public class ServerOperation implements Operation, BaseStream { * * @throws IOException if this <code>Operation</code> has been closed */ - public HeaderSet getReceivedHeaders() throws IOException { + public HeaderSet getReceivedHeader() throws IOException { ensureOpen(); - return requestHeaders; + return requestHeader; } /** @@ -583,13 +533,13 @@ public class ServerOperation implements Operation, BaseStream { ensureOpen(); if (headers == null) { - throw new NullPointerException("Headers may not be null"); + throw new IOException("Headers may not be null"); } int[] headerList = headers.getHeaderList(); if (headerList != null) { for (int i = 0; i < headerList.length; i++) { - replyHeaders.setHeader(headerList[i], headers.getHeader(headerList[i])); + replyHeader.setHeader(headerList[i], headers.getHeader(headerList[i])); } } @@ -629,7 +579,7 @@ public class ServerOperation implements Operation, BaseStream { */ public String getType() { try { - return (String)requestHeaders.getHeader(HeaderSet.TYPE); + return (String)requestHeader.getHeader(HeaderSet.TYPE); } catch (IOException e) { return null; } @@ -645,7 +595,7 @@ public class ServerOperation implements Operation, BaseStream { */ public long getLength() { try { - Long temp = (Long)requestHeaders.getHeader(HeaderSet.LENGTH); + Long temp = (Long)requestHeader.getHeader(HeaderSet.LENGTH); if (temp == null) { return -1; @@ -658,7 +608,7 @@ public class ServerOperation implements Operation, BaseStream { } public int getMaxPacketSize() { - return maxPacketLength - 6; + return mMaxPacketLength - 6; } /** @@ -670,7 +620,7 @@ public class ServerOperation implements Operation, BaseStream { */ public InputStream openInputStream() throws IOException { ensureOpen(); - return privateInput; + return mPrivateInput; } /** @@ -694,17 +644,19 @@ public class ServerOperation implements Operation, BaseStream { public OutputStream openOutputStream() throws IOException { ensureOpen(); - if (outputStreamOpened) + if (mPrivateOutputOpen) { throw new IOException("no more input streams available, stream already opened"); + } - if (!requestFinished) + if (!mRequestFinished) { throw new IOException("no output streams available ,request not finished"); + } - if (privateOutput == null) { - privateOutput = new PrivateOutputStream(this, maxPacketLength - 6); + if (mPrivateOutput == null) { + mPrivateOutput = new PrivateOutputStream(this, mMaxPacketLength - 6); } - outputStreamOpened = true; - return privateOutput; + mPrivateOutputOpen = true; + return mPrivateOutput; } /** @@ -725,7 +677,7 @@ public class ServerOperation implements Operation, BaseStream { */ public void close() throws IOException { ensureOpen(); - isClosed = true; + mClosed = true; } /** @@ -734,10 +686,10 @@ public class ServerOperation implements Operation, BaseStream { * @throws IOException if an exception needs to be thrown */ public void ensureOpen() throws IOException { - if (exceptionString != null) { - throw new IOException(exceptionString); + if (mExceptionString != null) { + throw new IOException(mExceptionString); } - if (isClosed) { + if (mClosed) { throw new IOException("Operation has already ended"); } } diff --git a/obex/javax/obex/ServerRequestHandler.java b/obex/javax/obex/ServerRequestHandler.java index 955e916..e468b83 100644 --- a/obex/javax/obex/ServerRequestHandler.java +++ b/obex/javax/obex/ServerRequestHandler.java @@ -71,7 +71,7 @@ package javax.obex; */ public class ServerRequestHandler { - private long connectionID; + private long mConnectionId; /** * Creates a <code>ServerRequestHandler</code>. @@ -80,33 +80,23 @@ public class ServerRequestHandler { /* * A connection ID of -1 implies there is no conenction ID */ - connectionID = -1; - } - - /** - * Creates a <code>HeaderSet</code> object that may be used in put and get - * operations. - * - * @return the <code>HeaderSet</code> object to use in put and get operations - */ - public final HeaderSet createHeaderSet() { - return new HeaderSet(); + mConnectionId = -1; } /** * Sets the connection ID header to include in the reply packets. * - * @param id the connection ID to use; -1 if no connection ID should be + * @param connectionId the connection ID to use; -1 if no connection ID should be * sent * * @throws IllegalArgumentException if <code>id</code> is not in the * range -1 to 2<sup>32</sup>-1 */ - public void setConnectionID(long id) { - if ((id < -1) || (id > 0xFFFFFFFFL)) { + public void setConnectionId(final long connectionId) { + if ((connectionId < -1) || (connectionId > 0xFFFFFFFFL)) { throw new IllegalArgumentException("Illegal Connection ID"); } - connectionID = id; + mConnectionId = connectionId; } /** @@ -116,8 +106,8 @@ public class ServerRequestHandler { * @return the connection id being used or -1 if no connection ID is being * used */ - public long getConnectionID() { - return connectionID; + public long getConnectionId() { + return mConnectionId; } /** @@ -231,7 +221,7 @@ public class ServerRequestHandler { * If an ABORT request is received during the processing of a PUT request, * <code>op</code> will be closed by the implementation. * - * @param op contains the headers sent by the client and allows new + * @param operation contains the headers sent by the client and allows new * headers to be sent in the reply; <code>op</code> will never be * <code>null</code> * @@ -239,7 +229,7 @@ public class ServerRequestHandler { * returned to the client; if an invalid response code is provided, the * <code>OBEX_HTTP_INTERNAL_ERROR</code> response code will be used */ - public int onPut(Operation op) { + public int onPut(Operation operation) { return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; } @@ -253,7 +243,7 @@ public class ServerRequestHandler { * If an ABORT request is received during the processing of a GET request, * <code>op</code> will be closed by the implementation. * - * @param op contains the headers sent by the client and allows new + * @param operation contains the headers sent by the client and allows new * headers to be sent in the reply; <code>op</code> will never be * <code>null</code> * @@ -261,7 +251,7 @@ public class ServerRequestHandler { * returned to the client; if an invalid response code is provided, the * <code>OBEX_HTTP_INTERNAL_ERROR</code> response code will be used */ - public int onGet(Operation op) { + public int onGet(Operation operation) { return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; } @@ -279,10 +269,23 @@ public class ServerRequestHandler { public void onAuthenticationFailure(byte[] userName) { } - /**Called by ServerSession to update the status of current transaction */ + /** + * Called by ServerSession to update the status of current transaction + * <P> + * If this method is not implemented by the class that extends this class, + * this method will do nothing. + * + */ public void updateStatus(String message) { } + /** + * Called when session is closed. + * <P> + * If this method is not implemented by the class that extends this class, + * this method will do nothing. + * + */ public void onClose() { } } diff --git a/obex/javax/obex/ServerSession.java b/obex/javax/obex/ServerSession.java index 9daa6c0..3a0e8150 100644 --- a/obex/javax/obex/ServerSession.java +++ b/obex/javax/obex/ServerSession.java @@ -32,39 +32,39 @@ package javax.obex; +import android.util.Log; + import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; /** - * This class in an implementation of the ServerSession interface. + * This class in an implementation of the OBEX ServerSession. * * @hide */ -public class ServerSession implements Runnable, ObexSession { - - private ObexTransport client; +public final class ServerSession extends ObexSession implements Runnable { - private InputStream input; + private static final String TAG = "Obex ServerSession"; - private OutputStream output; + private ObexTransport mTransport; - private ServerRequestHandler listener; + private InputStream mInput; - private Thread processThread; + private OutputStream mOutput; - private int maxPacketLength; + private ServerRequestHandler mListener; - private Authenticator authenticator; + private Thread mProcessThread; - byte[] challengeDigest; + private int mMaxPacketLength; - private boolean isClosed; + private boolean mClosed; /** * Creates new ServerSession. * - * @param conn + * @param trans * the connection to the client * * @param handler @@ -77,50 +77,20 @@ public class ServerSession implements Runnable, ObexSession { * if an error occurred while opening the input and output * streams */ - public ServerSession(ObexTransport conn, ServerRequestHandler handler, Authenticator auth) + public ServerSession(ObexTransport trans, ServerRequestHandler handler, Authenticator auth) throws IOException { - authenticator = auth; - client = conn; - input = client.openInputStream(); - output = client.openOutputStream(); - listener = handler; - maxPacketLength = 256; - - isClosed = false; - processThread = new Thread(this); - processThread.start(); + mAuthenticator = auth; + mTransport = trans; + mInput = mTransport.openInputStream(); + mOutput = mTransport.openOutputStream(); + mListener = handler; + mMaxPacketLength = 256; + + mClosed = false; + mProcessThread = new Thread(this); + mProcessThread.start(); } - /* removed as they're provided to the API user. Not used internally. */ - /* - public boolean isCreatedServer() { - if (client instanceof BTConnection) - return ((BTConnection)client).isServerCreated(); - else - return false; - } - - public boolean isClosed() { - if (client instanceof BTConnection) - return ((BTConnection)client).isClosed(); - else - return false; - } - - public int getConnectionHandle() { - if (client instanceof BTConnection) - return ((BTConnection)client).getConnectionHandle(); - else - return -1; - } - - public RemoteDevice getRemoteDevice() { - if (client instanceof BTConnection) - return ((BTConnection)client).getRemoteDevice(); - else - return null; - }*/ - /** * Processes requests made to the server and forwards them to the * appropriate event listener. @@ -129,29 +99,29 @@ public class ServerSession implements Runnable, ObexSession { try { boolean done = false; - while (!done && !isClosed) { - int requestType = input.read(); + while (!done && !mClosed) { + int requestType = mInput.read(); switch (requestType) { - case 0x80: + case ObexHelper.OBEX_OPCODE_CONNECT: handleConnectRequest(); break; - case 0x81: + case ObexHelper.OBEX_OPCODE_DISCONNECT: handleDisconnectRequest(); done = true; break; - case 0x03: - case 0x83: + case ObexHelper.OBEX_OPCODE_GET: + case ObexHelper.OBEX_OPCODE_GET_FINAL: handleGetRequest(requestType); break; - case 0x02: - case 0x82: + case ObexHelper.OBEX_OPCODE_PUT: + case ObexHelper.OBEX_OPCODE_PUT_FINAL: handlePutRequest(requestType); break; - case 0x85: + case ObexHelper.OBEX_OPCODE_SETPATH: handleSetPathRequest(); break; @@ -166,19 +136,19 @@ public class ServerSession implements Runnable, ObexSession { * just going to read the packet and send a not implemented * to the client */ - int length = input.read(); - length = (length << 8) + input.read(); + int length = mInput.read(); + length = (length << 8) + mInput.read(); for (int i = 3; i < length; i++) { - input.read(); + mInput.read(); } sendResponse(ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED, null); - - // done = true; } } } catch (NullPointerException e) { + Log.d(TAG, e.toString()); } catch (Exception e) { + Log.d(TAG, e.toString()); } close(); } @@ -201,24 +171,24 @@ public class ServerSession implements Runnable, ObexSession { * if an error occurred at the transport layer */ private void handlePutRequest(int type) throws IOException { - ServerOperation client = new ServerOperation(this, input, type, maxPacketLength, listener); + ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener); try { int response = -1; - if ((client.finalBitSet) && !client.isValidBody()) { - response = validateResponseCode(listener.onDelete(client.requestHeaders, - client.replyHeaders)); + if ((op.finalBitSet) && !op.isValidBody()) { + response = validateResponseCode(mListener + .onDelete(op.requestHeader, op.replyHeader)); } else { - response = validateResponseCode(listener.onPut(client)); + response = validateResponseCode(mListener.onPut(op)); } if (response != ResponseCodes.OBEX_HTTP_OK) { - client.sendReply(response); - } else if (!client.isAborted) { + op.sendReply(response); + } else if (!op.isAborted) { // wait for the final bit - while (!client.finalBitSet) { - client.sendReply(ObexHelper.OBEX_HTTP_CONTINUE); + while (!op.finalBitSet) { + op.sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); } - client.sendReply(response); + op.sendReply(response); } } catch (Exception e) { sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); @@ -243,12 +213,12 @@ public class ServerSession implements Runnable, ObexSession { * if an error occurred at the transport layer */ private void handleGetRequest(int type) throws IOException { - ServerOperation client = new ServerOperation(this, input, type, maxPacketLength, listener); + ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener); try { - int response = validateResponseCode(listener.onGet(client)); + int response = validateResponseCode(mListener.onGet(op)); - if (!client.isAborted) { - client.sendReply(response); + if (!op.isAborted) { + op.sendReply(response); } } catch (Exception e) { sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); @@ -267,7 +237,7 @@ public class ServerSession implements Runnable, ObexSession { * @throws IOException * if an IO error occurs */ - protected void sendResponse(int code, byte[] header) throws IOException { + public void sendResponse(int code, byte[] header) throws IOException { int totalLength = 3; byte[] data = null; @@ -284,8 +254,8 @@ public class ServerSession implements Runnable, ObexSession { data[1] = (byte)0x00; data[2] = (byte)totalLength; } - output.write(data); - output.flush(); + mOutput.write(data); + mOutput.flush(); } /** @@ -302,6 +272,7 @@ public class ServerSession implements Runnable, ObexSession { private void handleSetPathRequest() throws IOException { int length; int flags; + @SuppressWarnings("unused") int constants; int totalLength = 3; byte[] head = null; @@ -310,10 +281,10 @@ public class ServerSession implements Runnable, ObexSession { HeaderSet request = new HeaderSet(); HeaderSet reply = new HeaderSet(); - length = input.read(); - length = (length << 8) + input.read(); - flags = input.read(); - constants = input.read(); + length = mInput.read(); + length = (length << 8) + mInput.read(); + flags = mInput.read(); + constants = mInput.read(); if (length > ObexHelper.MAX_PACKET_SIZE_INT) { code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE; @@ -321,41 +292,41 @@ public class ServerSession implements Runnable, ObexSession { } else { if (length > 5) { byte[] headers = new byte[length - 5]; - bytesReceived = input.read(headers); + bytesReceived = mInput.read(headers); while (bytesReceived != headers.length) { - bytesReceived += input.read(headers, bytesReceived, headers.length + bytesReceived += mInput.read(headers, bytesReceived, headers.length - bytesReceived); } ObexHelper.updateHeaderSet(request, headers); - if (request.connectionID != null) { - listener.setConnectionID(ObexHelper.convertToLong(request.connectionID)); + if (request.mConnectionID != null) { + mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID)); } else { - listener.setConnectionID(-1); + mListener.setConnectionId(-1); } - // the Auth chan is initiated by the server. - // client sent back the authResp . - if (request.authResp != null) { - if (!handleAuthResp(request.authResp)) { + // the Auth chan is initiated by the server, client sent back the authResp . + if (request.mAuthResp != null) { + if (!handleAuthResp(request.mAuthResp)) { code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED; - listener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01, - request.authResp)); + mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01, + request.mAuthResp)); } - request.authResp = null; + request.mAuthResp = null; } } if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) { - // the Auth chan is initiated by the client + // the Auth challenge is initiated by the client // the server will send back the authResp to the client - if (request.authChall != null) { + if (request.mAuthChall != null) { handleAuthChall(request); - reply.authResp = new byte[request.authResp.length]; - System.arraycopy(request.authResp, 0, reply.authResp, 0, reply.authResp.length); - request.authChall = null; - request.authResp = null; + reply.mAuthResp = new byte[request.mAuthResp.length]; + System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0, + reply.mAuthResp.length); + request.mAuthChall = null; + request.mAuthResp = null; } boolean backup = false; boolean create = true; @@ -367,7 +338,7 @@ public class ServerSession implements Runnable, ObexSession { } try { - code = listener.onSetPath(request, reply, backup, create); + code = mListener.onSetPath(request, reply, backup, create); } catch (Exception e) { sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); return; @@ -376,23 +347,23 @@ public class ServerSession implements Runnable, ObexSession { code = validateResponseCode(code); if (reply.nonce != null) { - challengeDigest = new byte[16]; - System.arraycopy(reply.nonce, 0, challengeDigest, 0, 16); + mChallengeDigest = new byte[16]; + System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16); } else { - challengeDigest = null; + mChallengeDigest = null; } - long id = listener.getConnectionID(); + long id = mListener.getConnectionId(); if (id == -1) { - reply.connectionID = null; + reply.mConnectionID = null; } else { - reply.connectionID = ObexHelper.convertToByteArray(id); + reply.mConnectionID = ObexHelper.convertToByteArray(id); } head = ObexHelper.createHeader(reply, false); totalLength += head.length; - if (totalLength > maxPacketLength) { + if (totalLength > mMaxPacketLength) { totalLength = 3; head = null; code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; @@ -412,8 +383,8 @@ public class ServerSession implements Runnable, ObexSession { * Write the OBEX SETPATH packet to the server. Byte 0: response code * Byte 1&2: Connect Packet Length Byte 3 to n: headers */ - output.write(replyData); - output.flush(); + mOutput.write(replyData); + mOutput.flush(); } /** @@ -435,8 +406,8 @@ public class ServerSession implements Runnable, ObexSession { HeaderSet request = new HeaderSet(); HeaderSet reply = new HeaderSet(); - length = input.read(); - length = (length << 8) + input.read(); + length = mInput.read(); + length = (length << 8) + mInput.read(); if (length > ObexHelper.MAX_PACKET_SIZE_INT) { code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE; @@ -444,66 +415,56 @@ public class ServerSession implements Runnable, ObexSession { } else { if (length > 3) { byte[] headers = new byte[length - 3]; - bytesReceived = input.read(headers); + bytesReceived = mInput.read(headers); while (bytesReceived != headers.length) { - bytesReceived += input.read(headers, bytesReceived, headers.length + bytesReceived += mInput.read(headers, bytesReceived, headers.length - bytesReceived); } ObexHelper.updateHeaderSet(request, headers); } - if (request.connectionID != null) { - listener.setConnectionID(ObexHelper.convertToLong(request.connectionID)); + if (request.mConnectionID != null) { + mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID)); } else { - listener.setConnectionID(1); + mListener.setConnectionId(1); } - if (request.authResp != null) { - if (!handleAuthResp(request.authResp)) { + if (request.mAuthResp != null) { + if (!handleAuthResp(request.mAuthResp)) { code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED; - listener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01, - request.authResp)); + mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01, + request.mAuthResp)); } - request.authResp = null; + request.mAuthResp = null; } if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) { - if (request.authChall != null) { + if (request.mAuthChall != null) { handleAuthChall(request); - request.authChall = null; + request.mAuthChall = null; } try { - listener.onDisconnect(request, reply); + mListener.onDisconnect(request, reply); } catch (Exception e) { sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); return; } - /* - * Since a client will never response to an authentication - * challenge on a DISCONNECT, there is no reason to keep track - * of the challenge. - * - * if (reply.nonce != null) { challengeDigest = new byte[16]; - * System.arraycopy(reply.nonce, 0, challengeDigest, 0, 16); } - * else { challengeDigest = null; } - */ - - long id = listener.getConnectionID(); + long id = mListener.getConnectionId(); if (id == -1) { - reply.connectionID = null; + reply.mConnectionID = null; } else { - reply.connectionID = ObexHelper.convertToByteArray(id); + reply.mConnectionID = ObexHelper.convertToByteArray(id); } head = ObexHelper.createHeader(reply, false); totalLength += head.length; - if (totalLength > maxPacketLength) { + if (totalLength > mMaxPacketLength) { totalLength = 3; head = null; code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; @@ -528,8 +489,8 @@ public class ServerSession implements Runnable, ObexSession { * Write the OBEX DISCONNECT packet to the server. Byte 0: response code * Byte 1&2: Connect Packet Length Byte 3 to n: headers */ - output.write(replyData); - output.flush(); + mOutput.write(replyData); + mOutput.flush(); } /** @@ -545,7 +506,9 @@ public class ServerSession implements Runnable, ObexSession { */ private void handleConnectRequest() throws IOException { int packetLength; + @SuppressWarnings("unused") int version; + @SuppressWarnings("unused") int flags; int totalLength = 7; byte[] head = null; @@ -558,16 +521,16 @@ public class ServerSession implements Runnable, ObexSession { * Read in the length of the OBEX packet, OBEX version, flags, and max * packet length */ - packetLength = input.read(); - packetLength = (packetLength << 8) + input.read(); - version = input.read(); - flags = input.read(); - maxPacketLength = input.read(); - maxPacketLength = (maxPacketLength << 8) + input.read(); + packetLength = mInput.read(); + packetLength = (packetLength << 8) + mInput.read(); + version = mInput.read(); + flags = mInput.read(); + mMaxPacketLength = mInput.read(); + mMaxPacketLength = (mMaxPacketLength << 8) + mInput.read(); // should we check it? - if (maxPacketLength > ObexHelper.MAX_PACKET_SIZE_INT) { - maxPacketLength = ObexHelper.MAX_PACKET_SIZE_INT; + if (mMaxPacketLength > ObexHelper.MAX_PACKET_SIZE_INT) { + mMaxPacketLength = ObexHelper.MAX_PACKET_SIZE_INT; } if (packetLength > ObexHelper.MAX_PACKET_SIZE_INT) { @@ -576,61 +539,62 @@ public class ServerSession implements Runnable, ObexSession { } else { if (packetLength > 7) { byte[] headers = new byte[packetLength - 7]; - bytesReceived = input.read(headers); + bytesReceived = mInput.read(headers); while (bytesReceived != headers.length) { - bytesReceived += input.read(headers, bytesReceived, headers.length + bytesReceived += mInput.read(headers, bytesReceived, headers.length - bytesReceived); } ObexHelper.updateHeaderSet(request, headers); } - if (request.connectionID != null) { - listener.setConnectionID(ObexHelper.convertToLong(request.connectionID)); + if (request.mConnectionID != null) { + mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID)); } else { - listener.setConnectionID(1); + mListener.setConnectionId(1); } - if (request.authResp != null) { - if (!handleAuthResp(request.authResp)) { + if (request.mAuthResp != null) { + if (!handleAuthResp(request.mAuthResp)) { code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED; - listener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01, - request.authResp)); + mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01, + request.mAuthResp)); } - request.authResp = null; + request.mAuthResp = null; } if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) { - if (request.authChall != null) { + if (request.mAuthChall != null) { handleAuthChall(request); - reply.authResp = new byte[request.authResp.length]; - System.arraycopy(request.authResp, 0, reply.authResp, 0, reply.authResp.length); - request.authChall = null; - request.authResp = null; + reply.mAuthResp = new byte[request.mAuthResp.length]; + System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0, + reply.mAuthResp.length); + request.mAuthChall = null; + request.mAuthResp = null; } try { - code = listener.onConnect(request, reply); + code = mListener.onConnect(request, reply); code = validateResponseCode(code); if (reply.nonce != null) { - challengeDigest = new byte[16]; - System.arraycopy(reply.nonce, 0, challengeDigest, 0, 16); + mChallengeDigest = new byte[16]; + System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16); } else { - challengeDigest = null; + mChallengeDigest = null; } - long id = listener.getConnectionID(); + long id = mListener.getConnectionId(); if (id == -1) { - reply.connectionID = null; + reply.mConnectionID = null; } else { - reply.connectionID = ObexHelper.convertToByteArray(id); + reply.mConnectionID = ObexHelper.convertToByteArray(id); } head = ObexHelper.createHeader(reply, false); totalLength += head.length; - if (totalLength > maxPacketLength) { + if (totalLength > mMaxPacketLength) { totalLength = 7; head = null; code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; @@ -667,8 +631,8 @@ public class ServerSession implements Runnable, ObexSession { System.arraycopy(head, 0, sendData, 7, head.length); } - output.write(sendData); - output.flush(); + mOutput.write(sendData); + mOutput.flush(); } /** @@ -677,20 +641,20 @@ public class ServerSession implements Runnable, ObexSession { * attempt to read/write will throw an exception. */ public synchronized void close() { - if (listener != null) { - listener.onClose(); + if (mListener != null) { + mListener.onClose(); } try { - input.close(); - output.close(); - client.close(); - isClosed = true; + mInput.close(); + mOutput.close(); + mTransport.close(); + mClosed = true; } catch (Exception e) { } - client = null; - input = null; - output = null; - listener = null; + mTransport = null; + mInput = null; + mOutput = null; + mListener = null; } /** @@ -727,196 +691,4 @@ public class ServerSession implements Runnable, ObexSession { return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } - /** - * Called when the server received an authentication challenge header. This - * will cause the authenticator to handle the authentication challenge. - * - * @param header - * the header with the authentication challenge - * - * @return <code>true</code> if the last request should be resent; - * <code>false</code> if the last request should not be resent - */ - protected boolean handleAuthChall(HeaderSet header) { - if (authenticator == null) { - return false; - } - - /* - * An authentication challenge is made up of one required and two - * optional tag length value triplets. The tag 0x00 is required to be in - * the authentication challenge and it represents the challenge digest - * that was received. The tag 0x01 is the options tag. This tag tracks - * if user ID is required and if full access will be granted. The tag - * 0x02 is the realm, which provides a description of which user name - * and password to use. - */ - byte[] challenge = ObexHelper.getTagValue((byte)0x00, header.authChall); - byte[] option = ObexHelper.getTagValue((byte)0x01, header.authChall); - byte[] description = ObexHelper.getTagValue((byte)0x02, header.authChall); - - String realm = ""; - if (description != null) { - byte[] realmString = new byte[description.length - 1]; - System.arraycopy(description, 1, realmString, 0, realmString.length); - - switch (description[0] & 0xFF) { - - case 0x00: - // ASCII encoding - // Fall through - case 0x01: - // ISO-8859-1 encoding - try { - realm = new String(realmString, "ISO8859_1"); - } catch (Exception e) { - throw new RuntimeException("Unsupported Encoding Scheme"); - } - break; - - case 0xFF: - // UNICODE Encoding - realm = ObexHelper.convertToUnicode(realmString, false); - break; - - case 0x02: - // ISO-8859-2 encoding - // Fall through - case 0x03: - // ISO-8859-3 encoding - // Fall through - case 0x04: - // ISO-8859-4 encoding - // Fall through - case 0x05: - // ISO-8859-5 encoding - // Fall through - case 0x06: - // ISO-8859-6 encoding - // Fall through - case 0x07: - // ISO-8859-7 encoding - // Fall through - case 0x08: - // ISO-8859-8 encoding - // Fall through - case 0x09: - // ISO-8859-9 encoding - // Fall through - default: - throw new RuntimeException("Unsupported Encoding Scheme"); - } - } - - boolean isUserIDRequired = false; - boolean isFullAccess = true; - if (option != null) { - if ((option[0] & 0x01) != 0) { - isUserIDRequired = true; - } - - if ((option[0] & 0x02) != 0) { - isFullAccess = false; - } - } - - PasswordAuthentication result = null; - header.authChall = null; - - try { - result = authenticator.onAuthenticationChallenge(realm, isUserIDRequired, isFullAccess); - } catch (Exception e) { - return false; - } - - /* - * If no password is provided then we not resent the request - */ - if (result == null) { - return false; - } - - byte[] password = result.getPassword(); - if (password == null) { - return false; - } - - byte[] userName = result.getUserName(); - - /* - * Create the authentication response header. It includes 1 required and - * 2 option tag length value triples. The required triple has a tag of - * 0x00 and is the response digest. The first optional tag is 0x01 and - * represents the user ID. If no user ID is provided, then no user ID - * will be sent. The second optional tag is 0x02 and is the challenge - * that was received. This will always be sent - */ - if (userName != null) { - header.authResp = new byte[38 + userName.length]; - header.authResp[36] = (byte)0x01; - header.authResp[37] = (byte)userName.length; - System.arraycopy(userName, 0, header.authResp, 38, userName.length); - } else { - header.authResp = new byte[36]; - } - - // Create the secret String - byte[] digest = new byte[challenge.length + password.length + 1]; - System.arraycopy(challenge, 0, digest, 0, challenge.length); - // Insert colon between challenge and password - digest[challenge.length] = (byte)0x3A; - System.arraycopy(password, 0, digest, challenge.length + 1, password.length); - - // Add the Response Digest - header.authResp[0] = (byte)0x00; - header.authResp[1] = (byte)0x10; - - System.arraycopy(ObexHelper.computeMd5Hash(digest), 0, header.authResp, 2, 16); - - // Add the challenge - header.authResp[18] = (byte)0x02; - header.authResp[19] = (byte)0x10; - System.arraycopy(challenge, 0, header.authResp, 20, 16); - - return true; - } - - /** - * Called when the server received an authentication response header. This - * will cause the authenticator to handle the authentication response. - * - * @param authResp - * the authentication response - * - * @return <code>true</code> if the response passed; <code>false</code> if - * the response failed - */ - protected boolean handleAuthResp(byte[] authResp) { - if (authenticator == null) { - return false; - } - // get the correct password from the application - byte[] correctPassword = authenticator.onAuthenticationResponse(ObexHelper.getTagValue( - (byte)0x01, authResp)); - if (correctPassword == null) { - return false; - } - - byte[] temp = new byte[correctPassword.length + 16]; - - System.arraycopy(challengeDigest, 0, temp, 0, 16); - System.arraycopy(correctPassword, 0, temp, 16, correctPassword.length); - - byte[] correctResponse = ObexHelper.computeMd5Hash(temp); - byte[] actualResponse = ObexHelper.getTagValue((byte)0x00, authResp); - - // compare the MD5 hash array . - for (int i = 0; i < 16; i++) { - if (correctResponse[i] != actualResponse[i]) { - return false; - } - } - - return true; - } } diff --git a/obex/javax/obex/SessionNotifier.java b/obex/javax/obex/SessionNotifier.java index fd574c0..36e0ebf 100644 --- a/obex/javax/obex/SessionNotifier.java +++ b/obex/javax/obex/SessionNotifier.java @@ -61,7 +61,7 @@ public interface SessionNotifier { * does not have a <code>ServiceRecord</code> in the SDDB, the * <code>ServiceRecord</code> for this object will be added to the SDDB. * This method requests the BCC to put the - * local device in connectable mode so that it will respond to + * local device in connectible mode so that it will respond to * connection attempts by clients. * <P> * The following checks are done to verify that the service record @@ -101,10 +101,10 @@ public interface SessionNotifier { * be due to insufficient disk space, database locks, etc. * * @throws BluetoothStateException if the server device could - * not be placed in connectable mode because the device user has - * configured the device to be non-connectable + * not be placed in connectible mode because the device user has + * configured the device to be non-connectible */ - public ObexSession acceptAndOpen(ServerRequestHandler handler) throws IOException; + ObexSession acceptAndOpen(ServerRequestHandler handler) throws IOException; /** * Waits for a transport layer connection to be established and specifies @@ -117,7 +117,7 @@ public interface SessionNotifier { * does not have a <code>ServiceRecord</code> in the SDDB, the * <code>ServiceRecord</code> for this object will be added to the SDDB. * This method requests the BCC to put the - * local device in connectable mode so that it will respond to + * local device in connectible mode so that it will respond to * connection attempts by clients. * <P> * The following checks are done to verify that the service record @@ -160,9 +160,8 @@ public interface SessionNotifier { * be due to insufficient disk space, database locks, etc. * * @throws BluetoothStateException if the server device could - * not be placed in connectable mode because the device user has - * configured the device to be non-connectable + * not be placed in connectible mode because the device user has + * configured the device to be non-connectible */ - public ObexSession acceptAndOpen(ServerRequestHandler handler, Authenticator auth) - throws IOException; + ObexSession acceptAndOpen(ServerRequestHandler handler, Authenticator auth) throws IOException; } |