19439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/* 28949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta * Copyright (c) 2014 The Android Open Source Project 39439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc. 49439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 59439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * All rights reserved. 69439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 79439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Redistribution and use in source and binary forms, with or without 89439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * modification, are permitted provided that the following conditions are met: 99439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions of source code must retain the above copyright notice, 119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer. 129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice, 149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer in the documentation 159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * and/or other materials provided with the distribution. 169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors 189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * may be used to endorse or promote products derived from this software 199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * without specific prior written permission. 209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * POSSIBILITY OF SUCH DAMAGE. 329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellypackage javax.obex; 359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.IOException; 379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.InputStream; 389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.OutputStream; 399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.DataInputStream; 409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.DataOutputStream; 419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.ByteArrayOutputStream; 429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/** 4405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * This class implements the <code>Operation</code> interface. It will read and 4505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * write data via puts and gets. 462e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @hide 479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 482e0da96e757a977154063f980d3f4e1abd41cf09Nick Pellypublic final class ClientOperation implements Operation, BaseStream { 499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 503998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private ClientSession mParent; 519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mInputOpen; 539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private PrivateInputStream mPrivateInput; 559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mPrivateInputOpen; 579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private PrivateOutputStream mPrivateOutput; 599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mPrivateOutputOpen; 619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 623998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private String mExceptionMessage; 639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 643998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private int mMaxPacketSize; 659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 663998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mOperationDone; 679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 683998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mGetOperation; 699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 708949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta private boolean mGetFinalFlag; 718949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta 723998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private HeaderSet mRequestHeader; 739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 743998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private HeaderSet mReplyHeader; 759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 763998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun private boolean mEndOfBodySent; 779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun /** 799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Creates new OperationImpl to read and write data to a server 809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param maxSize the maximum packet size 819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param p the parent to this object 829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param type <code>true</code> if this is a get request; 8305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code. if this is a put request 8405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param header the header to set in the initial request 8505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if the an IO error occurred 869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 873998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public ClientOperation(int maxSize, ClientSession p, HeaderSet header, boolean type) 883998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throws IOException { 899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 903998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent = p; 913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mEndOfBodySent = false; 923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mInputOpen = true; 933998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = false; 943998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mMaxPacketSize = maxSize; 953998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mGetOperation = type; 968949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta mGetFinalFlag = false; 979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 983998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInputOpen = false; 993998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutputOpen = false; 1003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput = null; 1013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutput = null; 1029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mReplyHeader = new HeaderSet(); 1049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mRequestHeader = new HeaderSet(); 1069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int[] headerList = header.getHeaderList(); 1089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headerList != null) { 1109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly for (int i = 0; i < headerList.length; i++) { 1123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mRequestHeader.setHeader(headerList[i], header.getHeader(headerList[i])); 1139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((header).mAuthChall != null) { 1173998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mRequestHeader.mAuthChall = new byte[(header).mAuthChall.length]; 1183998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy((header).mAuthChall, 0, mRequestHeader.mAuthChall, 0, 1193998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun (header).mAuthChall.length); 1209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((header).mAuthResp != null) { 1233998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mRequestHeader.mAuthResp = new byte[(header).mAuthResp.length]; 1243998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy((header).mAuthResp, 0, mRequestHeader.mAuthResp, 0, 1253998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun (header).mAuthResp.length); 1269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1280d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz 1290d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz if ((header).mConnectionID != null) { 1300d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz mRequestHeader.mConnectionID = new byte[4]; 1310d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz System.arraycopy((header).mConnectionID, 0, mRequestHeader.mConnectionID, 0, 1320d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz 4); 1330d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz 1340d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz } 1359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 1388949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta * Allows to set flag which will force GET to be always sent as single packet request with 1398949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta * final flag set. This is to improve compatibility with some profiles, i.e. PBAP which 1408949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta * require requests to be sent this way. 1418949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta */ 1428949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta public void setGetFinalFlag(boolean flag) { 1438949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta mGetFinalFlag = flag; 1448949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta } 1458949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta 1468949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta /** 14705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Sends an ABORT message to the server. By calling this method, the 1489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * corresponding input and output streams will be closed along with this 1499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * object. 15005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if the transaction has already ended or if an OBEX 15105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * server called this method 1529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized void abort() throws IOException { 1549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 1559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly //no compatible with sun-ri 1563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mOperationDone) && (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE)) { 1579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Operation has already ended"); 1589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionMessage = "Operation aborted"; 1613998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((!mOperationDone) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { 1623998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = true; 1639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Since we are not sending any headers or returning any headers then 1659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * we just need to write and read the same bytes 1669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1673998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendRequest(ObexHelper.OBEX_OPCODE_ABORT, null, mReplyHeader, null); 1689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1693998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_OK) { 1709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Invalid response code from server"); 1719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1733998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionMessage = null; 1749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly close(); 1779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 18005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Retrieves the response code retrieved from the server. Response codes are 18105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * defined in the <code>ResponseCodes</code> interface. 1829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the response code retrieved from the server 1832e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an error occurred in the transport layer during 18405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * the transaction; if this method is called on a 18505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>HeaderSet</code> object created by calling 18605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>createHeaderSet</code> in a <code>ClientSession</code> 18705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * object 1889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized int getResponseCode() throws IOException { 1909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly //avoid dup validateConnection 1913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mReplyHeader.responseCode == -1) 1923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun || (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { 1939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly validateConnection(); 1949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1963998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mReplyHeader.responseCode; 1979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 2009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * This method will always return <code>null</code> 2019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>null</code> 2029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public String getEncoding() { 2049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return null; 2059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 2089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the type of content that the resource connected to is providing. 2099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * E.g. if the connection is via HTTP, then the value of the content-type 2109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * header field is returned. 2119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the content type of the resource that the URL references, or 21205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>null</code> if not known 2139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public String getType() { 2159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 2163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return (String)mReplyHeader.getHeader(HeaderSet.TYPE); 2179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (IOException e) { 2189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return null; 2199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 2239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the length of the content which is being provided. E.g. if the 22405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * connection is via HTTP, then the value of the content-length header field 22505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * is returned. 2269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the content length of the resource that this connection's URL 22705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * references, or -1 if the content length is not known 2289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public long getLength() { 2309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly try { 2313998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun Long temp = (Long)mReplyHeader.getHeader(HeaderSet.LENGTH); 2329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (temp == null) { 2349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 2359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return temp.longValue(); 2379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } catch (IOException e) { 2399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 2409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 2449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return an input stream for a connection. 2459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an input stream 2462e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 2479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public InputStream openInputStream() throws IOException { 2499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 2519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInputOpen) 2539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("no more input streams available"); 2543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mGetOperation) { 2559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // send the GET request here 2569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly validateConnection(); 2579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput == null) { 2593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput = new PrivateInputStream(this); 2609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2633998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInputOpen = true; 2649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2653998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mPrivateInput; 2669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 26805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun /** 2699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return a data input stream for a connection. 2709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an input stream 2712e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 2729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public DataInputStream openDataInputStream() throws IOException { 2749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return new DataInputStream(openInputStream()); 2759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 2789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return an output stream for a connection. 2799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an output stream 2802e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 2819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 2829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public OutputStream openOutputStream() throws IOException { 2833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun 2849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 2859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureNotDone(); 2869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2873998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutputOpen) 2889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("no more output streams available"); 2899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2903998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput == null) { 2919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // there are 3 bytes operation headers and 3 bytes body headers // 29265208317ba9d16486b47ebcaa868c596d424c87fLixin Yue mPrivateOutput = new PrivateOutputStream(this, getMaxPacketSize()); 2939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2953998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutputOpen = true; 2969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2973998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mPrivateOutput; 2989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public int getMaxPacketSize() { 30165208317ba9d16486b47ebcaa868c596d424c87fLixin Yue return mMaxPacketSize - 6 - getHeaderLength(); 30265208317ba9d16486b47ebcaa868c596d424c87fLixin Yue } 30365208317ba9d16486b47ebcaa868c596d424c87fLixin Yue 30465208317ba9d16486b47ebcaa868c596d424c87fLixin Yue public int getHeaderLength() { 30565208317ba9d16486b47ebcaa868c596d424c87fLixin Yue // OPP may need it 30665208317ba9d16486b47ebcaa868c596d424c87fLixin Yue byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false); 30765208317ba9d16486b47ebcaa868c596d424c87fLixin Yue return headerArray.length; 3089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 3119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Open and return a data output stream for a connection. 3129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return an output stream 3132e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an I/O error occurs 3149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public DataOutputStream openDataOutputStream() throws IOException { 3169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return new DataOutputStream(openOutputStream()); 3179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 3209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Closes the connection and ends the transaction 3212e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the operation has already ended or is closed 3229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void close() throws IOException { 3243998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mInputOpen = false; 3253998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInputOpen = false; 3263998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutputOpen = false; 3273998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.setRequestInactive(); 3289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 3319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Returns the headers that have been received during the operation. 33205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Modifying the object returned has no effect on the headers that are sent 33305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * or retrieved. 3349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return the headers received during this <code>Operation</code> 3352e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if this <code>Operation</code> has been closed 3369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3373998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public HeaderSet getReceivedHeader() throws IOException { 3389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 3399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3403998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return mReplyHeader; 3419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 3449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Specifies the headers that should be sent in the next OBEX message that 3459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * is sent. 3469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param headers the headers to send in the next message 34705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @throws IOException if this <code>Operation</code> has been closed or the 34805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * transaction has ended and no further messages will be exchanged 3492e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IllegalArgumentException if <code>headers</code> was not created 35005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * by a call to <code>ServerRequestHandler.createHeaderSet()</code> 3512e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws NullPointerException if <code>headers</code> is <code>null</code> 3529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void sendHeaders(HeaderSet headers) throws IOException { 3549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 3553998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mOperationDone) { 3569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Operation has already exchanged all data"); 3579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headers == null) { 3603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException("Headers may not be null"); 3619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int[] headerList = headers.getHeaderList(); 3649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headerList != null) { 3659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly for (int i = 0; i < headerList.length; i++) { 3663998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mRequestHeader.setHeader(headerList[i], headers.getHeader(headerList[i])); 3679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 37205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Verifies that additional information may be sent. In other words, the 3739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * operation is not done. 3742e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the operation is completed 3759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void ensureNotDone() throws IOException { 3773998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mOperationDone) { 3789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Operation has completed"); 3799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 3839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Verifies that the connection is open and no exceptions should be thrown. 3842e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an exception needs to be thrown 3859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void ensureOpen() throws IOException { 3873998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.ensureOpen(); 3889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mExceptionMessage != null) { 3903998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException(mExceptionMessage); 3919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mInputOpen) { 3939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Operation has already ended"); 3949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 3989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Verifies that the connection is open and the proper data has been read. 3992e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 4009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private void validateConnection() throws IOException { 4029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 4039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // to sure only one privateInput object exist. 4053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput == null) { 4069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly startProcessing(); 4079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 4119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Sends a request to the client of the specified type 41205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param opCode the request code to send to the client 4139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @return <code>true</code> if there is more data to send; 41405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if there is no more data to send 4152e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 4169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 41705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun private boolean sendRequest(int opCode) throws IOException { 4189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly boolean returnValue = false; 4199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ByteArrayOutputStream out = new ByteArrayOutputStream(); 4209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bodyLength = -1; 4213998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] headerArray = ObexHelper.createHeader(mRequestHeader, true); 4223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput != null) { 4233998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bodyLength = mPrivateOutput.size(); 4249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if there is space to add a body request. At present 4289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this method checks to see if there is room for at least a 17 4299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * byte body header. This number needs to be at least 6 so that 4309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * there is room for the header ID and length and the reply ID and 4319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * length, but it is a waste of resources if we can't send much of 4329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the body. 4339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4343998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length) > mMaxPacketSize) { 4359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int end = 0; 4369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int start = 0; 4379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // split & send the headerArray in multiple packets. 4389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (end != headerArray.length) { 4409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly //split the headerArray 4413998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketSize 4423998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun - ObexHelper.BASE_PACKET_LENGTH); 4430d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz // can not split 4449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (end == -1) { 4453998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = true; 4469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly abort(); 4473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mExceptionMessage = "Header larger then can be sent in a packet"; 4483998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mInputOpen = false; 4499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4503998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput != null) { 4513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput.close(); 4529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutput != null) { 4553998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateOutput.close(); 4569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("OBEX Packet exceeds max packet size"); 4589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] sendHeader = new byte[end - start]; 4619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length); 46205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun if (!mParent.sendRequest(opCode, sendHeader, mReplyHeader, mPrivateInput)) { 4639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 4649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4663998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { 4679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 4689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly start = end; 4719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (bodyLength > 0) { 4749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 4759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 4779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(headerArray); 4809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (bodyLength > 0) { 4839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4843998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun * Determine if we can send the whole body or just part of 4859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the body. Remember that there is the 3 bytes for the 4869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * response message and 3 bytes for the header ID and length 4879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4883998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (bodyLength > (mMaxPacketSize - headerArray.length - 6)) { 4899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly returnValue = true; 4909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun bodyLength = mMaxPacketSize - headerArray.length - 6; 4929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4943998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] body = mPrivateOutput.readBytes(bodyLength); 4959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 4979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Since this is a put request if the final bit is set or 4989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * the output stream is closed we need to send the 0x49 4999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * (End of Body) otherwise, we need to send 0x48 (Body) 5009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mPrivateOutput.isClosed()) && (!returnValue) && (!mEndOfBodySent) 50205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun && ((opCode & 0x80) != 0)) { 5039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x49); 5043998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mEndOfBodySent = true; 5059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 5069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x48); 5079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bodyLength += 3; 5109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)(bodyLength >> 8)); 5119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)bodyLength); 5129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (body != null) { 5149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(body); 5159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5183998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateOutputOpen && bodyLength <= 0 && !mEndOfBodySent) { 5199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // only 0x82 or 0x83 can send 0x49 52005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun if ((opCode & 0x80) == 0) { 5219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x48); 5229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 5239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x49); 5243998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mEndOfBodySent = true; 5259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly bodyLength = 3; 5299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)(bodyLength >> 8)); 5309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)bodyLength); 5319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (out.size() == 0) { 53405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun if (!mParent.sendRequest(opCode, null, mReplyHeader, mPrivateInput)) { 5359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 5369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return returnValue; 5389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((out.size() > 0) 54005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun && (!mParent.sendRequest(opCode, out.toByteArray(), mReplyHeader, mPrivateInput))) { 5419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 5429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5440d376053747615ac7c4b45ab7810329ffbdf80d1Kim Schulz // send all of the output data in 0x48, 5459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // send 0x49 with empty body 5463998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mPrivateOutput != null) && (mPrivateOutput.size() > 0)) 5479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly returnValue = true; 5489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return returnValue; 5509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 55305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * This method starts the processing thread results. It will send the 55405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * initial request. If the response takes more then one packet, a thread 5559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * will be started to handle additional requests 5562e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 5579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 5589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private synchronized void startProcessing() throws IOException { 5599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput == null) { 5613998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput = new PrivateInputStream(this); 5629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly boolean more = true; 5649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5653998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mGetOperation) { 5663998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mOperationDone) { 5678949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta if (!mGetFinalFlag) { 5688949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; 5698949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { 5708949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta more = sendRequest(0x03); 5718949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta } 5728949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta 5738949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { 5748949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta mParent.sendRequest(0x83, null, mReplyHeader, mPrivateInput); 5758949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta } 5768949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { 5778949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta mOperationDone = true; 5788949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta } 5798949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta } else { 5808949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta more = sendRequest(0x83); 5818949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta 5828949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta if (more) { 5838949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta throw new IOException("FINAL_GET forced but data did not fit into single packet!"); 5848949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta } 5859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5863998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = true; 5879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 5909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mOperationDone) { 5923998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; 5933998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { 5949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly more = sendRequest(0x02); 5959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5993998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { 6003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendRequest(0x82, null, mReplyHeader, mPrivateInput); 6019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { 6043998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = true; 6059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Continues the operation since there is no data to read. 61105ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param sendEmpty <code>true</code> if the operation should send an empty 61205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * packet or not send anything if there is no data to send 61305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param inStream <code>true</code> if the stream is input stream or is 61405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * output stream 6152e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 6169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream) 6189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throws IOException { 6199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6203998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mGetOperation) { 6213998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((inStream) && (!mOperationDone)) { 6229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // to deal with inputstream in get operation 6233998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendRequest(0x83, null, mReplyHeader, mPrivateInput); 6249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 6259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Determine if that was not the last packet in the operation 6269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6273998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { 6283998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = true; 6299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 6329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6333998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } else if ((!inStream) && (!mOperationDone)) { 6349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // to deal with outputstream in get operation 6359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6363998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput == null) { 6373998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput = new PrivateInputStream(this); 6389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6398949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta 6408949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta if (!mGetFinalFlag) { 6418949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta sendRequest(0x03); 6428949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta } else { 6438949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta sendRequest(0x83); 6448949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta 6458949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { 6468949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta mOperationDone = true; 6478949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta } 6488949bfb90c415629dbd0e30d25003fb3e0375fb5Hemant Gupta } 6499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 6509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } else if (mOperationDone) { 6529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 6539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 6563998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((!inStream) && (!mOperationDone)) { 6579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // to deal with outputstream in put operation 6583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mReplyHeader.responseCode == -1) { 6593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; 6609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendRequest(0x02); 6629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 6633998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } else if ((inStream) && (!mOperationDone)) { 6649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // How to deal with inputstream in put operation ? 6659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 6669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6673998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } else if (mOperationDone) { 6689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 6699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return false; 6739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 6769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Called when the output or input stream is closed. 6779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * @param inStream <code>true</code> if the input stream is closed; 67805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if the output stream is closed 6792e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 6809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 6819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void streamClosed(boolean inStream) throws IOException { 6823998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!mGetOperation) { 6833998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((!inStream) && (!mOperationDone)) { 6849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // to deal with outputstream in put operation 6859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly boolean more = true; 6879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6883998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) { 6893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false); 6909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headerArray.length <= 0) 6919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly more = false; 6929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // If have not sent any data so send all now 6943998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mReplyHeader.responseCode == -1) { 6953998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; 6969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 6979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6983998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { 6999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly more = sendRequest(0x02); 7009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 7039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * According to the IrOBEX specification, after the final put, you 7049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * only have a single reply to send. so we don't need the while 7059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * loop. 7069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 7073998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { 7089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendRequest(0x82); 7109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = true; 7123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } else if ((inStream) && (mOperationDone)) { 7139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // how to deal with input stream in put stream ? 7143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = true; 7159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 7173998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((inStream) && (!mOperationDone)) { 7189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // to deal with inputstream in get operation 7209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Have not sent any data so send it all now 7219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7223998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mReplyHeader.responseCode == -1) { 7233998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; 7249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7263998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { 7279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (!sendRequest(0x83)) { 7289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly break; 7299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7313998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { 7323998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mParent.sendRequest(0x83, null, mReplyHeader, mPrivateInput); 7339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7343998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = true; 7353998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun } else if ((!inStream) && (!mOperationDone)) { 7369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // to deal with outputstream in get operation 7379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // part of the data may have been sent in continueOperation. 7389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly boolean more = true; 7409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7413998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) { 7423998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false); 7439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (headerArray.length <= 0) 7449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly more = false; 7459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mPrivateInput == null) { 7483998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mPrivateInput = new PrivateInputStream(this); 7499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7503998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) 7519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly more = false; 7529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 7533998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; 7543998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) { 7559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly more = sendRequest(0x03); 7569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly sendRequest(0x83); 7589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // parent.sendRequest(0x83, null, replyHeaders, privateInput); 7593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) { 7603998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun mOperationDone = true; 7619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 765fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie 766fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie public void noBodyHeader(){ 767fe3807a5b23f54f6539436d71aa0cd931a2b76f0Matthew Xie } 7689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly} 769