19439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/* 29439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc. 39439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 49439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * All rights reserved. 59439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 69439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Redistribution and use in source and binary forms, with or without 79439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * modification, are permitted provided that the following conditions are met: 89439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 99439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions of source code must retain the above copyright notice, 109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer. 119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice, 139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * this list of conditions and the following disclaimer in the documentation 149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * and/or other materials provided with the distribution. 159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors 179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * may be used to endorse or promote products derived from this software 189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * without specific prior written permission. 199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * 209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * POSSIBILITY OF SUCH DAMAGE. 319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellypackage javax.obex; 349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.ByteArrayOutputStream; 369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.IOException; 379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.InputStream; 389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pellyimport java.io.OutputStream; 399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly/** 413998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun * This class in an implementation of the OBEX ClientSession. 422e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @hide 439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 443998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejunpublic final class ClientSession extends ObexSession { 459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly private boolean mOpen; 479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 482e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly // Determines if an OBEX layer connection has been established 4941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly private boolean mObexConnected; 509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly private byte[] mConnectionId = null; 529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 5441557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly * The max Packet size must be at least 256 according to the OBEX 5541557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly * specification. 5641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly */ 579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly private int maxPacketSize = 256; 589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly private boolean mRequestActive; 609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly private final InputStream mInput; 629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 6341557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly private final OutputStream mOutput; 649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 653998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public ClientSession(final ObexTransport trans) throws IOException { 6641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mInput = trans.openInputStream(); 6741557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mOutput = trans.openOutputStream(); 6841557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mOpen = true; 6941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mRequestActive = false; 709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 723998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public HeaderSet connect(final HeaderSet header) throws IOException { 739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 7441557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (mObexConnected) { 759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Already connected to server"); 769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 7741557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly setRequestActive(); 7841557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly 799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int totalLength = 4; 809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] head = null; 819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Determine the header byte array 839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (header != null) { 8441557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (header.nonce != null) { 8541557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mChallengeDigest = new byte[16]; 8641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16); 879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 882e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly head = ObexHelper.createHeader(header, false); 899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength += head.length; 909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Write the OBEX CONNECT packet to the server. 939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 0: 0x80 949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 1&2: Connect Packet Length 959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 3: OBEX Version Number (Presently, 0x10) 969439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 4: Flags (For TCP 0x00) 979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 5&6: Max OBEX Packet Length (Defined in MAX_PACKET_SIZE) 989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 7 to n: headers 999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] requestPacket = new byte[totalLength]; 1019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // We just need to start at byte 3 since the sendRequest() method will 1029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // handle the length and 0x80. 1039439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly requestPacket[0] = (byte)0x10; 1049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly requestPacket[1] = (byte)0x00; 1052e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly requestPacket[2] = (byte)(ObexHelper.MAX_PACKET_SIZE_INT >> 8); 1062e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly requestPacket[3] = (byte)(ObexHelper.MAX_PACKET_SIZE_INT & 0xFF); 1079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (head != null) { 1089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(head, 0, requestPacket, 4, head.length); 1099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // check with local max packet size 1122e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly if ((requestPacket.length + 3) > ObexHelper.MAX_PACKET_SIZE_INT) { 1139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet size exceeds max packet size"); 1149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly HeaderSet returnHeaderSet = new HeaderSet(); 1173998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendRequest(ObexHelper.OBEX_OPCODE_CONNECT, requestPacket, returnHeaderSet, null); 1189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 1209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Read the response from the OBEX server. 1219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 0: Response Code (If successful then OBEX_HTTP_OK) 1229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 1&2: Packet Length 1239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 3: OBEX Version Number 1249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 4: Flags3 1259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 5&6: Max OBEX packet Length 1269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 7 to n: Optional HeaderSet 1279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 1289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (returnHeaderSet.responseCode == ResponseCodes.OBEX_HTTP_OK) { 12941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mObexConnected = true; 1309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 13141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly setRequestInactive(); 1329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return returnHeaderSet; 1349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 13641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly public Operation get(HeaderSet header) throws IOException { 1379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 13841557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (!mObexConnected) { 1399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Not connected to the server"); 1409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 14141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly setRequestActive(); 14241557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly 1439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 1449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1453998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun HeaderSet head; 1469439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (header == null) { 1473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun head = new HeaderSet(); 1489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 1493998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun head = header; 1503998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (head.nonce != null) { 15141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mChallengeDigest = new byte[16]; 1523998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(head.nonce, 0, mChallengeDigest, 0, 16); 1539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Add the connection ID if one exists 15641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (mConnectionId != null) { 1573998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun head.mConnectionID = new byte[4]; 1583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(mConnectionId, 0, head.mConnectionID, 0, 4); 1599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1613998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return new ClientOperation(maxPacketSize, this, head, true); 1629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 16505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * 0xCB Connection Id an identifier used for OBEX connection multiplexing 16641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly */ 1679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void setConnectionID(long id) { 1689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((id < 0) || (id > 0xFFFFFFFFL)) { 1699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IllegalArgumentException("Connection ID is not in a valid range"); 1709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 17141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mConnectionId = ObexHelper.convertToByteArray(id); 1729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 17441557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly public HeaderSet delete(HeaderSet header) throws IOException { 1759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 17641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly Operation op = put(header); 1779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly op.getResponseCode(); 1783998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun HeaderSet returnValue = op.getReceivedHeader(); 1799439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly op.close(); 1809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 1819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return returnValue; 1829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 18441557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly public HeaderSet disconnect(HeaderSet header) throws IOException { 18541557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (!mObexConnected) { 1869439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Not connected to the server"); 1879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 18841557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly setRequestActive(); 18941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly 1909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 1919439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Determine the header byte array 1929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] head = null; 1939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (header != null) { 19441557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (header.nonce != null) { 19541557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mChallengeDigest = new byte[16]; 19641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16); 1979439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 1989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Add the connection ID if one exists 19941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (mConnectionId != null) { 2003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun header.mConnectionID = new byte[4]; 2013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(mConnectionId, 0, header.mConnectionID, 0, 4); 2029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2032e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly head = ObexHelper.createHeader(header, false); 2049439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2059439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((head.length + 3) > maxPacketSize) { 2069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet size exceeds max packet size"); 2079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Add the connection ID if one exists 21041557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (mConnectionId != null) { 2119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly head = new byte[5]; 2123998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun head[0] = (byte)HeaderSet.CONNECTION_ID; 21341557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly System.arraycopy(mConnectionId, 0, head, 1, 4); 2149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly HeaderSet returnHeaderSet = new HeaderSet(); 2183998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendRequest(ObexHelper.OBEX_OPCODE_DISCONNECT, head, returnHeaderSet, null); 2199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 22141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly * An OBEX DISCONNECT reply from the server: 22241557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly * Byte 1: Response code 22341557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly * Bytes 2 & 3: packet size 22441557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly * Bytes 4 & up: headers 22541557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly */ 2269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* response code , and header are ignored 2289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * */ 2299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly synchronized (this) { 23141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mObexConnected = false; 23241557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly setRequestInactive(); 2339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return returnHeaderSet; 2369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public long getConnectionID() { 2399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 24041557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (mConnectionId == null) { 2419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return -1; 2429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 24341557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly return ObexHelper.convertToLong(mConnectionId); 2449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 24641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly public Operation put(HeaderSet header) throws IOException { 24741557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (!mObexConnected) { 2489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Not connected to the server"); 2499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 25041557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly setRequestActive(); 2519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 2533998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun HeaderSet head; 2549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (header == null) { 2553998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun head = new HeaderSet(); 2569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2573998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun head = header; 2583998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun // when auth is initiated by client ,save the digest 2593998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (head.nonce != null) { 26041557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mChallengeDigest = new byte[16]; 2613998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(head.nonce, 0, mChallengeDigest, 0, 16); 2629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Add the connection ID if one exists 26641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (mConnectionId != null) { 2679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2683998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun head.mConnectionID = new byte[4]; 2693998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(mConnectionId, 0, head.mConnectionID, 0, 4); 2709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2723998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return new ClientOperation(maxPacketSize, this, head, false); 2739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2753998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public void setAuthenticator(Authenticator auth) throws IOException { 2769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (auth == null) { 2773998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun throw new IOException("Authenticator may not be null"); 2789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 27941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mAuthenticator = auth; 2809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 2819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2823998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public HeaderSet setPath(HeaderSet header, boolean backup, boolean create) throws IOException { 28341557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (!mObexConnected) { 2849439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Not connected to the server"); 2859439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 28641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly setRequestActive(); 2879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ensureOpen(); 2889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 2899439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int totalLength = 2; 2909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] head = null; 2913998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun HeaderSet headset; 2929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (header == null) { 2933998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun headset = new HeaderSet(); 2949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 2953998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun headset = header; 2963998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (headset.nonce != null) { 29741557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mChallengeDigest = new byte[16]; 2983998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(headset.nonce, 0, mChallengeDigest, 0, 16); 2999439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3009439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3019439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3029439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // when auth is initiated by client ,save the digest 3033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (headset.nonce != null) { 30441557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mChallengeDigest = new byte[16]; 3053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(headset.nonce, 0, mChallengeDigest, 0, 16); 3069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Add the connection ID if one exists 30941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (mConnectionId != null) { 3103998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun headset.mConnectionID = new byte[4]; 3113998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(mConnectionId, 0, headset.mConnectionID, 0, 4); 3129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3143998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun head = ObexHelper.createHeader(headset, false); 3159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly totalLength += head.length; 3169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (totalLength > maxPacketSize) { 3189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet size exceeds max packet size"); 3199439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int flags = 0; 3229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * The backup flag bit is bit 0 so if we add 1, this will set that bit 3249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (backup) { 3269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly flags++; 3279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * The create bit is bit 1 so if we or with 2 the bit will be set. 3309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (!create) { 3329439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly flags |= 2; 3339439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3359439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * An OBEX SETPATH packet to the server: 3379439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 1: 0x85 3389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 2 & 3: packet size 3399439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 4: flags 3409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 5: constants 3419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 6 & up: headers 3429439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] packet = new byte[totalLength]; 3449439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly packet[0] = (byte)flags; 3459439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly packet[1] = (byte)0x00; 3463998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (headset != null) { 3479439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(head, 0, packet, 2, head.length); 3489439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3499439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly HeaderSet returnHeaderSet = new HeaderSet(); 3513998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun sendRequest(ObexHelper.OBEX_OPCODE_SETPATH, packet, returnHeaderSet, null); 3529439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3539439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /* 3549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * An OBEX SETPATH reply from the server: 3559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Byte 1: Response code 3569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Bytes 2 & 3: packet size 3579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Bytes 4 & up: headers 3589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3599439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 36041557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly setRequestInactive(); 3619439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return returnHeaderSet; 3639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 3669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly * Verifies that the connection is open. 3672e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if the connection is closed 3689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3699439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public synchronized void ensureOpen() throws IOException { 37041557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (!mOpen) { 3719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Connection closed"); 3729439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3749439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 37605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Set request inactive. Allows Put and get operation objects to tell this 37705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * object when they are done. 3789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 3793998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun /*package*/synchronized void setRequestInactive() { 38041557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mRequestActive = false; 38141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly } 38241557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly 38341557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly /** 38441557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly * Set request to active. 38541557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly * @throws IOException if already active 38641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly */ 38741557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly private synchronized void setRequestActive() throws IOException { 38841557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (mRequestActive) { 38941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly throw new IOException("OBEX request is already being performed"); 3909439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 39141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mRequestActive = true; 3929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 3939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 3949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly /** 39505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * Sends a standard request to the client. It will then wait for the reply 39605ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * and update the header set object provided. If any authentication headers 39705ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * (i.e. authentication challenge or authentication response) are received, 39805ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * they will be processed. 3993998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun * @param opCode the type of request to send to the client 40005ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param head the headers to send to the client 40141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly * @param header the header object to update with the response 40205ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * @param privateInput the input stream used by the Operation object; null 40305ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * if this is called on a CONNECT, SETPATH or DISCONNECT return 40405ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>true</code> if the operation completed successfully; 40505ff98bbefda39b9ff26f8bca132cfd0248745c6Tao Liejun * <code>false</code> if an authentication response failed to pass 4062e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly * @throws IOException if an IO error occurs 4079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly */ 4083998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun public boolean sendRequest(int opCode, byte[] head, HeaderSet header, 4099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly PrivateInputStream privateInput) throws IOException { 4109439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly //check header length with local max size 4119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (head != null) { 4122e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly if ((head.length + 3) > ObexHelper.MAX_PACKET_SIZE_INT) { 4139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("header too large "); 4149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4163998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun 4179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly int bytesReceived; 4189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly ByteArrayOutputStream out = new ByteArrayOutputStream(); 4193998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun out.write((byte)opCode); 4209439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4219439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Determine if there are any headers to send 4229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (head == null) { 4239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x00); 4249439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(0x03); 4259439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4269439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)((head.length + 3) >> 8)); 4279439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write((byte)(head.length + 3)); 4289439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly out.write(head); 4299439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4309439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4319439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly // Write the request to the output stream and flush the stream 43241557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mOutput.write(out.toByteArray()); 43341557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mOutput.flush(); 4349439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 43541557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly header.responseCode = mInput.read(); 4369439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 43741557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly int length = ((mInput.read() << 8) | (mInput.read())); 4389439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4392e0da96e757a977154063f980d3f4e1abd41cf09Nick Pelly if (length > ObexHelper.MAX_PACKET_SIZE_INT) { 4409439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Packet received exceeds packet size limit"); 4419439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4423998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (length > ObexHelper.BASE_PACKET_LENGTH) { 4439439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] data = null; 4443998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (opCode == ObexHelper.OBEX_OPCODE_CONNECT) { 4453998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun @SuppressWarnings("unused") 44641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly int version = mInput.read(); 4473998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun @SuppressWarnings("unused") 44841557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly int flags = mInput.read(); 44941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly maxPacketSize = (mInput.read() << 8) + mInput.read(); 4509439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4519439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly //check with local max size 452e83b744d7d0b3caaf8f5456b795331d5db2495a3Erik Ljungberg if (maxPacketSize > ObexHelper.MAX_CLIENT_PACKET_SIZE) { 453e83b744d7d0b3caaf8f5456b795331d5db2495a3Erik Ljungberg maxPacketSize = ObexHelper.MAX_CLIENT_PACKET_SIZE; 4549439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4559439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4569439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if (length > 7) { 4579439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data = new byte[length - 7]; 4589439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 45941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly bytesReceived = mInput.read(data); 4609439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != (length - 7)) { 46141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly bytesReceived += mInput.read(data, bytesReceived, data.length 4629439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly - bytesReceived); 4639439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4649439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4659439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 4669439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4679439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } else { 4689439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly data = new byte[length - 3]; 46941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly bytesReceived = mInput.read(data); 4709439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4719439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly while (bytesReceived != (length - 3)) { 47241557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly bytesReceived += mInput.read(data, bytesReceived, data.length - bytesReceived); 4739439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4743998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (opCode == ObexHelper.OBEX_OPCODE_ABORT) { 4759439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 4769439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4779439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4789439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 47941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly byte[] body = ObexHelper.updateHeaderSet(header, data); 4809439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly if ((privateInput != null) && (body != null)) { 4819439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly privateInput.writeBytes(body, 1); 4829439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4839439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4843998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (header.mConnectionID != null) { 48541557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mConnectionId = new byte[4]; 4863998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun System.arraycopy(header.mConnectionID, 0, mConnectionId, 0, 4); 4879439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4889439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 4893998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (header.mAuthResp != null) { 4903998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun if (!handleAuthResp(header.mAuthResp)) { 49141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly setRequestInactive(); 4929439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly throw new IOException("Authentication Failed"); 4939439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4949439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 4959439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 49641557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if ((header.responseCode == ResponseCodes.OBEX_HTTP_UNAUTHORIZED) 4973998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun && (header.mAuthChall != null)) { 4989439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 49941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly if (handleAuthChall(header)) { 5003998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun out.write((byte)HeaderSet.AUTH_RESPONSE); 5013998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun out.write((byte)((header.mAuthResp.length + 3) >> 8)); 5023998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun out.write((byte)(header.mAuthResp.length + 3)); 5033998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun out.write(header.mAuthResp); 5043998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun header.mAuthChall = null; 5053998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun header.mAuthResp = null; 5069439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5079439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly byte[] sendHeaders = new byte[out.size() - 3]; 5089439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly System.arraycopy(out.toByteArray(), 3, sendHeaders, 0, sendHeaders.length); 5099439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5103998bf009acaf8cde4d7f837f8b8e41ae0a65141Tao Liejun return sendRequest(opCode, sendHeaders, header, privateInput); 5119439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5129439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5139439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5149439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5159439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly return true; 5169439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5179439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly 5189439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly public void close() throws IOException { 51941557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mOpen = false; 52041557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mInput.close(); 52141557e18fa3fc5791a5a1c7f0051ae3385608bc4Nick Pelly mOutput.close(); 5229439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly } 5239439a7fe517b858bc5e5c654b459315e4722feb2Nick Pelly} 524