19439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/* 2238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde * Copyright (C) 2015 The Android Open Source Project 3238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde * Copyright (c) 2015 Samsung LSI 49439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc. 59439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 69439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * All rights reserved. 79439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 89439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Redistribution and use in source and binary forms, with or without 99439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * modification, are permitted provided that the following conditions are met: 109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions of source code must retain the above copyright notice, 129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer. 139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice, 159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer in the documentation 169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * and/or other materials provided with the distribution. 179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors 199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * may be used to endorse or promote products derived from this software 209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * without specific prior written permission. 219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * POSSIBILITY OF SUCH DAMAGE. 339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellypackage javax.obex; 369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 373998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejunimport android.util.Log; 383998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun 392e0da96e757a977154063f980d3f4e1abd41cf09Nick Pellyimport java.io.InputStream; 402e0da96e757a977154063f980d3f4e1abd41cf09Nick Pellyimport java.io.IOException; 412e0da96e757a977154063f980d3f4e1abd41cf09Nick Pellyimport java.io.OutputStream; 429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/** 443998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun * This class in an implementation of the OBEX ServerSession. 452e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @hide 469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejunpublic final class ServerSession extends ObexSession implements Runnable { 489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 493998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private static final String TAG = "Obex ServerSession"; 50238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde private static final boolean V = ObexHelper.VDBG; 519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private ObexTransport mTransport; 539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private InputStream mInput; 559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private OutputStream mOutput; 579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private ServerRequestHandler mListener; 599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private Thread mProcessThread; 619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 623998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private int mMaxPacketLength; 639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 643998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mClosed; 659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Creates new ServerSession. 6805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param trans the connection to the client 6905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param handler the event listener that will process requests 7005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param auth the authenticator to use with this connection 7105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if an error occurred while opening the input and 7205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * output streams 739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 743998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public ServerSession(ObexTransport trans, ServerRequestHandler handler, Authenticator auth) 759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throws IOException { 763998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mAuthenticator = auth; 773998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mTransport = trans; 783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mInput = mTransport.openInputStream(); 793998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOutput = mTransport.openOutputStream(); 803998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener = handler; 813998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mMaxPacketLength = 256; 823998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun 833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = false; 843998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mProcessThread = new Thread(this); 853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mProcessThread.start(); 869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Processes requests made to the server and forwards them to the 909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * appropriate event listener. 919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void run() { 939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly boolean done = false; 963998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while (!done && !mClosed) { 97238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.v(TAG, "Waiting for incoming request..."); 983998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int requestType = mInput.read(); 99238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.v(TAG, "Read request: " + requestType); 1009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly switch (requestType) { 1013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun case ObexHelper.OBEX_OPCODE_CONNECT: 1029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly handleConnectRequest(); 1039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 1049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun case ObexHelper.OBEX_OPCODE_DISCONNECT: 1069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly handleDisconnectRequest(); 1079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 1089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun case ObexHelper.OBEX_OPCODE_GET: 1103998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun case ObexHelper.OBEX_OPCODE_GET_FINAL: 1119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly handleGetRequest(requestType); 1129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 1139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun case ObexHelper.OBEX_OPCODE_PUT: 1153998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun case ObexHelper.OBEX_OPCODE_PUT_FINAL: 1169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly handlePutRequest(requestType); 1179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 1189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1193998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun case ObexHelper.OBEX_OPCODE_SETPATH: 1209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly handleSetPathRequest(); 1219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 1228258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue case ObexHelper.OBEX_OPCODE_ABORT: 1238258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue handleAbortRequest(); 1248258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue break; 1259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly case -1: 1279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly done = true; 1289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 1299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly default: 1319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Received a request type that is not recognized so I am 1349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * just going to read the packet and send a not implemented 1359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * to the client 1369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1373998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int length = mInput.read(); 1383998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun length = (length << 8) + mInput.read(); 1399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly for (int i = 3; i < length; i++) { 1403998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mInput.read(); 1419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendResponse(ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED, null); 1439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (NullPointerException e) { 147238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde Log.d(TAG, "Exception occured - ignoring", e); 1489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (Exception e) { 149238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde Log.d(TAG, "Exception occured - ignoring", e); 1509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly close(); 1529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 1558258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue * Handles a ABORT request from a client. This method will read the rest of 1568258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue * the request from the client. Assuming the request is valid, it will 1578258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue * create a <code>HeaderSet</code> object to pass to the 1588258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue * <code>ServerRequestHandler</code> object. After the handler processes the 1598258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue * request, this method will create a reply message to send to the server. 1608258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue * 1618258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue * @throws IOException if an error occurred at the transport layer 1628258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue */ 1638258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue private void handleAbortRequest() throws IOException { 1648258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue int code = ResponseCodes.OBEX_HTTP_OK; 1658258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue HeaderSet request = new HeaderSet(); 1668258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue HeaderSet reply = new HeaderSet(); 1678258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue 1688258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue int length = mInput.read(); 1698258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue length = (length << 8) + mInput.read(); 170238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if (length > ObexHelper.getMaxRxPacketSize(mTransport)) { 1718258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE; 1728258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue } else { 1738258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue for (int i = 3; i < length; i++) { 1748258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue mInput.read(); 1758258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue } 1768258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue code = mListener.onAbort(request, reply); 1778258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue Log.v(TAG, "onAbort request handler return value- " + code); 1788258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue code = validateResponseCode(code); 1798258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue } 1808258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue sendResponse(code, null); 1818258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue } 1828258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue 1838258ebdf128ef70a96fcaaa294167e39f1b5e94eLixin Yue /** 1849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Handles a PUT request from a client. This method will provide a 1859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <code>ServerOperation</code> object to the request handler. The 1869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <code>ServerOperation</code> object will handle the rest of the request. 1879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * It will also send replies and receive requests until the final reply 1889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * should be sent. When the final reply should be sent, this method will get 1899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the response code to use and send the reply. The 1909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <code>ServerOperation</code> object will always reply with a 1919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * OBEX_HTTP_CONTINUE reply. It will only reply if further information is 1929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * needed. 19305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param type the type of request received; either 0x02 or 0x82 19405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if an error occurred at the transport layer 1959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private void handlePutRequest(int type) throws IOException { 1973998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener); 1989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 1999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int response = -1; 2009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((op.finalBitSet) && !op.isValidBody()) { 2023998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun response = validateResponseCode(mListener 2033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun .onDelete(op.requestHeader, op.replyHeader)); 2049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun response = validateResponseCode(mListener.onPut(op)); 2069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2070b309d6ee433d55b7499d7bbd447494366ef1316Jackson Fan if (response != ResponseCodes.OBEX_HTTP_OK && !op.isAborted) { 2083998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun op.sendReply(response); 2093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } else if (!op.isAborted) { 2109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // wait for the final bit 2113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while (!op.finalBitSet) { 2123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun op.sendReply(ResponseCodes.OBEX_HTTP_CONTINUE); 2139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun op.sendReply(response); 2159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (Exception e) { 21705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun /*To fix bugs in aborted cases, 21805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun *(client abort file transfer prior to the last packet which has the end of body header, 21905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun *internal error should not be sent because server has already replied with 22005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun *OK response in "sendReply") 22105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun */ 222238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e); 22305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun if (!op.isAborted) { 22405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); 22505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun } 2269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 2309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Handles a GET request from a client. This method will provide a 2319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <code>ServerOperation</code> object to the request handler. The 2329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <code>ServerOperation</code> object will handle the rest of the request. 2339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * It will also send replies and receive requests until the final reply 2349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * should be sent. When the final reply should be sent, this method will get 2359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the response code to use and send the reply. The 2369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <code>ServerOperation</code> object will always reply with a 2379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * OBEX_HTTP_CONTINUE reply. It will only reply if further information is 2389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * needed. 23905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param type the type of request received; either 0x03 or 0x83 24005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if an error occurred at the transport layer 2419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private void handleGetRequest(int type) throws IOException { 2433998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener); 2449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 2453998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun int response = validateResponseCode(mListener.onGet(op)); 2469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!op.isAborted) { 2483998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun op.sendReply(response); 2499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (Exception e) { 251238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e); 2529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); 2539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 2579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Send standard response. 25805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param code the response code to send 25905ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param header the headers to include in the response 26005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if an IO error occurs 2619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2623998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public void sendResponse(int code, byte[] header) throws IOException { 2639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int totalLength = 3; 2649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] data = null; 2650d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz OutputStream op = mOutput; 2660d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz if (op == null) { 2670d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz return; 2680d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz } 2699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (header != null) { 2719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength += header.length; 2729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data = new byte[totalLength]; 2739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data[0] = (byte)code; 2749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data[1] = (byte)(totalLength >> 8); 2759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data[2] = (byte)totalLength; 2769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(header, 0, data, 3, header.length); 2779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data = new byte[totalLength]; 2799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data[0] = (byte)code; 2809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data[1] = (byte)0x00; 2819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data[2] = (byte)totalLength; 2829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2830d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz op.write(data); 284238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde op.flush(); // TODO: Do we need to flush? 2859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 2889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Handles a SETPATH request from a client. This method will read the rest 2899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * of the request from the client. Assuming the request is valid, it will 2909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * create a <code>HeaderSet</code> object to pass to the 2919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <code>ServerRequestHandler</code> object. After the handler processes the 2929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * request, this method will create a reply message to send to the server 2939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * with the response code provided. 29405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if an error occurred at the transport layer 2959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private void handleSetPathRequest() throws IOException { 2979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int length; 2989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int flags; 2993998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun @SuppressWarnings("unused") 3009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int constants; 3019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int totalLength = 3; 3029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] head = null; 3039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int code = -1; 3049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bytesReceived; 3059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly HeaderSet request = new HeaderSet(); 3069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly HeaderSet reply = new HeaderSet(); 3079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3083998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun length = mInput.read(); 3093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun length = (length << 8) + mInput.read(); 3103998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun flags = mInput.read(); 3113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun constants = mInput.read(); 3129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 313238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if (length > ObexHelper.getMaxRxPacketSize(mTransport)) { 3149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE; 3159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength = 3; 3169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 5) { 3189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] headers = new byte[length - 5]; 3193998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived = mInput.read(headers); 3209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != headers.length) { 3223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived += mInput.read(headers, bytesReceived, headers.length 3239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly - bytesReceived); 3249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3262e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly ObexHelper.updateHeaderSet(request, headers); 3279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 328e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun if (mListener.getConnectionId() != -1 && request.mConnectionID != null) { 3293998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID)); 3309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 331e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun mListener.setConnectionId(1); 3329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3333998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun // the Auth chan is initiated by the server, client sent back the authResp . 3343998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (request.mAuthResp != null) { 3353998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!handleAuthResp(request.mAuthResp)) { 3369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED; 3373998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01, 3383998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthResp)); 3399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3403998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthResp = null; 3419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) { 3453998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun // the Auth challenge is initiated by the client 3469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // the server will send back the authResp to the client 3473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (request.mAuthChall != null) { 3489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly handleAuthChall(request); 3493998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mAuthResp = new byte[request.mAuthResp.length]; 3503998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0, 3513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mAuthResp.length); 3523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthChall = null; 3533998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthResp = null; 3549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly boolean backup = false; 3569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly boolean create = true; 3579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (!((flags & 1) == 0)) { 3589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly backup = true; 3599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 36069f72c00a12933f0fde049e8465257745f373d21Lixin Yue if (!((flags & 2) == 0)) { 3619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly create = false; 3629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 3653998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun code = mListener.onSetPath(request, reply, backup, create); 3669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (Exception e) { 367238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e); 3689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); 3699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return; 3709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = validateResponseCode(code); 3739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (reply.nonce != null) { 3753998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mChallengeDigest = new byte[16]; 3763998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16); 3779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mChallengeDigest = null; 3799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3813998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun long id = mListener.getConnectionId(); 3829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (id == -1) { 3833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mConnectionID = null; 3849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 3853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mConnectionID = ObexHelper.convertToByteArray(id); 3869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3882e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly head = ObexHelper.createHeader(reply, false); 3899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength += head.length; 3909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (totalLength > mMaxPacketLength) { 3929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength = 3; 3939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly head = null; 3949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 3959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Compute Length of OBEX SETPATH packet 4009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] replyData = new byte[totalLength]; 4019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly replyData[0] = (byte)code; 4029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly replyData[1] = (byte)(totalLength >> 8); 4039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly replyData[2] = (byte)totalLength; 4049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (head != null) { 4059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(head, 0, replyData, 3, head.length); 4069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Write the OBEX SETPATH packet to the server. Byte 0: response code 4099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 1&2: Connect Packet Length Byte 3 to n: headers 4109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOutput.write(replyData); 4123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOutput.flush(); 4139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 4169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Handles a disconnect request from a client. This method will read the 4179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * rest of the request from the client. Assuming the request is valid, it 4189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * will create a <code>HeaderSet</code> object to pass to the 4199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <code>ServerRequestHandler</code> object. After the handler processes the 4209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * request, this method will create a reply message to send to the server. 42105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if an error occurred at the transport layer 4229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private void handleDisconnectRequest() throws IOException { 4249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int length; 4259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int code = ResponseCodes.OBEX_HTTP_OK; 4269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int totalLength = 3; 4279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] head = null; 4289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bytesReceived; 4299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly HeaderSet request = new HeaderSet(); 4309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly HeaderSet reply = new HeaderSet(); 4319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4323998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun length = mInput.read(); 4333998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun length = (length << 8) + mInput.read(); 4349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 435238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if (length > ObexHelper.getMaxRxPacketSize(mTransport)) { 4369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE; 4379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength = 3; 4389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 3) { 4409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] headers = new byte[length - 3]; 4413998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived = mInput.read(headers); 4429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != headers.length) { 4443998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived += mInput.read(headers, bytesReceived, headers.length 4459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly - bytesReceived); 4469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4482e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly ObexHelper.updateHeaderSet(request, headers); 4499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 451e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun if (mListener.getConnectionId() != -1 && request.mConnectionID != null) { 4523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID)); 4539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(1); 4559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4573998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (request.mAuthResp != null) { 4583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!handleAuthResp(request.mAuthResp)) { 4599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED; 4603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01, 4613998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthResp)); 4629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4633998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthResp = null; 4649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) { 4679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4683998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (request.mAuthChall != null) { 4699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly handleAuthChall(request); 4703998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthChall = null; 4719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 4743998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.onDisconnect(request, reply); 4759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (Exception e) { 476238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e); 4779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null); 4789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return; 4799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4813998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun long id = mListener.getConnectionId(); 4829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (id == -1) { 4833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mConnectionID = null; 4849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4853998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mConnectionID = ObexHelper.convertToByteArray(id); 4869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4882e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly head = ObexHelper.createHeader(reply, false); 4899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength += head.length; 4909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (totalLength > mMaxPacketLength) { 4929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength = 3; 4939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly head = null; 4949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 4959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Compute Length of OBEX CONNECT packet 5009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] replyData; 5019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (head != null) { 5029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly replyData = new byte[3 + head.length]; 5039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 5049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly replyData = new byte[3]; 5059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly replyData[0] = (byte)code; 5079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly replyData[1] = (byte)(totalLength >> 8); 5089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly replyData[2] = (byte)totalLength; 5099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (head != null) { 5109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(head, 0, replyData, 3, head.length); 5119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 5139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Write the OBEX DISCONNECT packet to the server. Byte 0: response code 5149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 1&2: Connect Packet Length Byte 3 to n: headers 5159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOutput.write(replyData); 5173998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOutput.flush(); 5189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 5219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Handles a connect request from a client. This method will read the rest 5229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * of the request from the client. Assuming the request is valid, it will 5239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * create a <code>HeaderSet</code> object to pass to the 5249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * <code>ServerRequestHandler</code> object. After the handler processes the 5259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * request, this method will create a reply message to send to the server 5269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * with the response code provided. 52705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if an error occurred at the transport layer 5289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private void handleConnectRequest() throws IOException { 5309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int packetLength; 5313998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun @SuppressWarnings("unused") 5329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int version; 5333998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun @SuppressWarnings("unused") 5349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int flags; 5359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int totalLength = 7; 5369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] head = null; 5379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int code = -1; 5389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly HeaderSet request = new HeaderSet(); 5399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly HeaderSet reply = new HeaderSet(); 5409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bytesReceived; 5419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 542238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.v(TAG,"handleConnectRequest()"); 543238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde 5449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 5459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Read in the length of the OBEX packet, OBEX version, flags, and max 5469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * packet length 5479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5483998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun packetLength = mInput.read(); 5493998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun packetLength = (packetLength << 8) + mInput.read(); 550238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.v(TAG,"handleConnectRequest() - packetLength: " + packetLength); 551238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde 5523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun version = mInput.read(); 5533998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun flags = mInput.read(); 5543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mMaxPacketLength = mInput.read(); 5553998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mMaxPacketLength = (mMaxPacketLength << 8) + mInput.read(); 5569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 557238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.v(TAG,"handleConnectRequest() - version: " + version 558238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde + " MaxLength: " + mMaxPacketLength + " flags: " + flags); 559238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde 5609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // should we check it? 5613998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mMaxPacketLength > ObexHelper.MAX_PACKET_SIZE_INT) { 5623998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mMaxPacketLength = ObexHelper.MAX_PACKET_SIZE_INT; 5639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 565238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(mMaxPacketLength > ObexHelper.getMaxTxPacketSize(mTransport)) { 566238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde Log.w(TAG, "Requested MaxObexPacketSize " + mMaxPacketLength 567238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde + " is larger than the max size supported by the transport: " 568238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde + ObexHelper.getMaxTxPacketSize(mTransport) 569238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde + " Reducing to this size."); 570238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde mMaxPacketLength = ObexHelper.getMaxTxPacketSize(mTransport); 571238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 572238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde 573238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if (packetLength > ObexHelper.getMaxRxPacketSize(mTransport)) { 5749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE; 5759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength = 7; 5769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 5779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (packetLength > 7) { 5789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] headers = new byte[packetLength - 7]; 5793998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived = mInput.read(headers); 5809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != headers.length) { 5823998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bytesReceived += mInput.read(headers, bytesReceived, headers.length 5839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly - bytesReceived); 5849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5862e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly ObexHelper.updateHeaderSet(request, headers); 5879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 589e80534ff59b2e62a0ddf4359147b81f5ba10de86Tao Liejun if (mListener.getConnectionId() != -1 && request.mConnectionID != null) { 5903998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID)); 5919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 5923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.setConnectionId(1); 5939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5953998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (request.mAuthResp != null) { 5963998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!handleAuthResp(request.mAuthResp)) { 5979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED; 5983998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01, 5993998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthResp)); 6009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthResp = null; 6029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) { 6053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (request.mAuthChall != null) { 6069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly handleAuthChall(request); 6073998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mAuthResp = new byte[request.mAuthResp.length]; 6083998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0, 6093998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mAuthResp.length); 6103998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthChall = null; 6113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun request.mAuthResp = null; 6129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 6153998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun code = mListener.onConnect(request, reply); 6169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = validateResponseCode(code); 6179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (reply.nonce != null) { 6193998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mChallengeDigest = new byte[16]; 6203998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16); 6219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 6223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mChallengeDigest = null; 6239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6243998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun long id = mListener.getConnectionId(); 6259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (id == -1) { 6263998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mConnectionID = null; 6279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 6283998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun reply.mConnectionID = ObexHelper.convertToByteArray(id); 6299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6312e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly head = ObexHelper.createHeader(reply, false); 6329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength += head.length; 6339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6343998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (totalLength > mMaxPacketLength) { 6359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength = 7; 6369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly head = null; 6379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 6389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (Exception e) { 640238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e); 6419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength = 7; 6429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly head = null; 6439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 6449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Compute Length of OBEX CONNECT packet 6502e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly byte[] length = ObexHelper.convertToByteArray(totalLength); 6519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 6539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Write the OBEX CONNECT packet to the server. Byte 0: response code 6549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 1&2: Connect Packet Length Byte 3: OBEX Version Number 6559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * (Presently, 0x10) Byte 4: Flags (For TCP 0x00) Byte 5&6: Max OBEX 6569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Packet Length (Defined in MAX_PACKET_SIZE) Byte 7 to n: headers 6579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] sendData = new byte[totalLength]; 659238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde int maxRxLength = ObexHelper.getMaxRxPacketSize(mTransport); 6603fba4935a7d2353f6f3ec1091729e3509ba73d41Hemant Gupta if (maxRxLength > mMaxPacketLength) { 6613fba4935a7d2353f6f3ec1091729e3509ba73d41Hemant Gupta if(V) Log.v(TAG,"Set maxRxLength to min of maxRxServrLen:" + maxRxLength + 6623fba4935a7d2353f6f3ec1091729e3509ba73d41Hemant Gupta " and MaxNegotiated from Client: " + mMaxPacketLength); 6633fba4935a7d2353f6f3ec1091729e3509ba73d41Hemant Gupta maxRxLength = mMaxPacketLength; 6643fba4935a7d2353f6f3ec1091729e3509ba73d41Hemant Gupta } 6659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendData[0] = (byte)code; 6669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendData[1] = length[2]; 6679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendData[2] = length[3]; 6689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendData[3] = (byte)0x10; 6699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendData[4] = (byte)0x00; 670238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde sendData[5] = (byte)(maxRxLength >> 8); 671238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde sendData[6] = (byte)(maxRxLength & 0xFF); 6729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (head != null) { 6749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(head, 0, sendData, 7, head.length); 6759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6773998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOutput.write(sendData); 6783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOutput.flush(); 6799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Closes the server session - in detail close I/O streams and the 6839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * underlying transport layer. Internal flag is also set so that later 6849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * attempt to read/write will throw an exception. 6859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized void close() { 6873998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mListener != null) { 6883998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener.onClose(); 6899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 691238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde /* Set state to closed before interrupting the thread by closing the streams */ 6923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mClosed = true; 693238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(mInput != null) 694238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde mInput.close(); 695238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(mOutput != null) 696238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde mOutput.close(); 697238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(mTransport != null) 698238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde mTransport.close(); 6999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (Exception e) { 700238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde if(V) Log.d(TAG,"Exception occured during close() - ignore",e); 7019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7023998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mTransport = null; 7033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mInput = null; 7043998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOutput = null; 7053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mListener = null; 7069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 7099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Verifies that the response code is valid. If it is not valid, it will 7109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * return the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code. 71105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param code the response code to check 7129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the valid response code or <code>OBEX_HTTP_INTERNAL_ERROR</code> 7139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * if <code>code</code> is not valid 7149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 7159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private int validateResponseCode(int code) { 7169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((code >= ResponseCodes.OBEX_HTTP_OK) && (code <= ResponseCodes.OBEX_HTTP_PARTIAL)) { 7189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return code; 7199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((code >= ResponseCodes.OBEX_HTTP_MULT_CHOICE) 7219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly && (code <= ResponseCodes.OBEX_HTTP_USE_PROXY)) { 7229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return code; 7239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((code >= ResponseCodes.OBEX_HTTP_BAD_REQUEST) 7259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly && (code <= ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE)) { 7269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return code; 7279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((code >= ResponseCodes.OBEX_HTTP_INTERNAL_ERROR) 7299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly && (code <= ResponseCodes.OBEX_HTTP_VERSION)) { 7309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return code; 7319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((code >= ResponseCodes.OBEX_DATABASE_FULL) 7339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly && (code <= ResponseCodes.OBEX_DATABASE_LOCKED)) { 7349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return code; 7359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 7379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 739238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde public ObexTransport getTransport() { 740238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde return mTransport; 741238e0f934f1f47263b384bc745ae0678c777130dCasper Bonde } 7429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly} 743