1b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh/* 2b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * Copyright (c) 2008-2009, Motorola, Inc. 3b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 4b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * All rights reserved. 5b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 6b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * Redistribution and use in source and binary forms, with or without 7b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * modification, are permitted provided that the following conditions are met: 8b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 9b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * - Redistributions of source code must retain the above copyright notice, 10b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * this list of conditions and the following disclaimer. 11b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 12b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * - Redistributions in binary form must reproduce the above copyright notice, 13b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * this list of conditions and the following disclaimer in the documentation 14b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * and/or other materials provided with the distribution. 15b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 16b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * - Neither the name of the Motorola, Inc. nor the names of its contributors 17b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * may be used to endorse or promote products derived from this software 18b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * without specific prior written permission. 19b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 20b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * POSSIBILITY OF SUCH DAMAGE. 31b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh */ 322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpackage com.android.bluetooth.pbap; 342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 352f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.content.Context; 36ff33061e763656438daea7249e45e38b8a174288kschulzimport android.content.ContentResolver; 37ff33061e763656438daea7249e45e38b8a174288kschulzimport android.database.Cursor; 382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.Message; 392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport android.os.Handler; 402f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.provider.CallLog.Calls; 412f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.provider.CallLog; 42ff33061e763656438daea7249e45e38b8a174288kschulzimport android.text.TextUtils; 43ff33061e763656438daea7249e45e38b8a174288kschulzimport android.util.Log; 442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport java.io.IOException; 462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport java.io.OutputStream; 47e479e18951a375a548e617e86e3b1b7d121351a1Fredimport java.text.CharacterIterator; 48e479e18951a375a548e617e86e3b1b7d121351a1Fredimport java.text.StringCharacterIterator; 492c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport java.util.ArrayList; 504446eaa935994bc91d6d308303e8d27526b4590dLixin Yueimport java.util.Arrays; 512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport javax.obex.ServerRequestHandler; 532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport javax.obex.ResponseCodes; 542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport javax.obex.ApplicationParameter; 550b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yueimport javax.obex.ServerOperation; 562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport javax.obex.Operation; 572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport javax.obex.HeaderSet; 582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpublic class BluetoothPbapObexServer extends ServerRequestHandler { 602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String TAG = "BluetoothPbapObexServer"; 622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 634446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final boolean D = BluetoothPbapService.DEBUG; 644446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 654446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final boolean V = BluetoothPbapService.VERBOSE; 662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 674446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final int UUID_LENGTH = 16; 682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 69d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // The length of suffix of vcard name - ".vcf" is 5 70d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue private static final int VCARD_NAME_SUFFIX_LENGTH = 5; 712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // 128 bit UUID for PBAP 732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final byte[] PBAP_TARGET = new byte[] { 742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 0x79, 0x61, 0x35, (byte)0xf0, (byte)0xf0, (byte)0xc5, 0x11, (byte)0xd8, 0x09, 0x66, 752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 0x08, 0x00, 0x20, 0x0c, (byte)0x9a, 0x66 762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan }; 772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 784446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // Currently not support SIM card 79d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue private static final String[] LEGAL_PATH = { 802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan "/telecom", "/telecom/pb", "/telecom/ich", "/telecom/och", "/telecom/mch", 814446eaa935994bc91d6d308303e8d27526b4590dLixin Yue "/telecom/cch" 824446eaa935994bc91d6d308303e8d27526b4590dLixin Yue }; 834446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 844446eaa935994bc91d6d308303e8d27526b4590dLixin Yue @SuppressWarnings("unused") 854446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final String[] LEGAL_PATH_WITH_SIM = { 864446eaa935994bc91d6d308303e8d27526b4590dLixin Yue "/telecom", "/telecom/pb", "/telecom/ich", "/telecom/och", "/telecom/mch", 872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan "/telecom/cch", "/SIM1", "/SIM1/telecom", "/SIM1/telecom/ich", "/SIM1/telecom/och", 882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan "/SIM1/telecom/mch", "/SIM1/telecom/cch", "/SIM1/telecom/pb" 894446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan }; 912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 924446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // SIM card 934446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final String SIM1 = "SIM1"; 944446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // missed call history 962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String MCH = "mch"; 972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // incoming call history 992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String ICH = "ich"; 1002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // outgoing call history 1022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String OCH = "och"; 1032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // combined call history 1052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String CCH = "cch"; 1062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // phone book 1082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String PB = "pb"; 1092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 110b99a8af5a27318bb5ae3745531d5a2175370b892Hemant Gupta private static final String TELECOM_PATH = "/telecom"; 111b99a8af5a27318bb5ae3745531d5a2175370b892Hemant Gupta 1122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String ICH_PATH = "/telecom/ich"; 1132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String OCH_PATH = "/telecom/och"; 1152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String MCH_PATH = "/telecom/mch"; 1172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String CCH_PATH = "/telecom/cch"; 1192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String PB_PATH = "/telecom/pb"; 1212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // type for list vcard objects 1232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String TYPE_LISTING = "x-bt/vcard-listing"; 1242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // type for get single vcard object 1262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String TYPE_VCARD = "x-bt/vcard"; 1272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1284446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // to indicate if need send body besides headers 129d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue private static final int NEED_SEND_BODY = -1; 130d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 1312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // type for download all vcard objects 1322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private static final String TYPE_PB = "x-bt/phonebook"; 1332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 134d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // The number of indexes in the phone book. 135d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue private boolean mNeedPhonebookSize = false; 1362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 137d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // The number of missed calls that have not been checked on the PSE at the 138d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // point of the request. Only apply to "mch" case. 139d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue private boolean mNeedNewMissedCallsNum = false; 1402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 141d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue private int mMissedCallSize = 0; 1422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 143d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // record current path the client are browsing 144d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue private String mCurrentPath = ""; 1452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 146d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue private Handler mCallback = null; 1472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1482f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private Context mContext; 1492f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 1502f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private BluetoothPbapVcardManager mVcardManager; 1512f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 1522b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh private int mOrderBy = ORDER_BY_INDEXED; 1532b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 15477b122f551ae37811c75ae76fa2029f7b3f2f404a private static int CALLLOG_NUM_LIMIT = 50; 15577b122f551ae37811c75ae76fa2029f7b3f2f404a 1562b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh public static int ORDER_BY_INDEXED = 0; 1572b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 1582b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh public static int ORDER_BY_ALPHABETICAL = 1; 1592b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 1600b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public static boolean sIsAborted = false; 1610b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue 162d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static class ContentType { 163d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final int PHONEBOOK = 1; 1642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 165d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final int INCOMING_CALL_HISTORY = 2; 1662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 167d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final int OUTGOING_CALL_HISTORY = 3; 1682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 169d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final int MISSED_CALL_HISTORY = 4; 1702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 171d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue public static final int COMBINED_CALL_HISTORY = 5; 172d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 1732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1742f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public BluetoothPbapObexServer(Handler callback, Context context) { 1752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan super(); 1762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mCallback = callback; 1772f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue mContext = context; 1782f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue mVcardManager = new BluetoothPbapVcardManager(mContext); 1792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 182c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue public int onConnect(final HeaderSet request, HeaderSet reply) { 183c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (V) logHeader(request); 1848fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu notifyUpdateWakeLock(); 1852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 186c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue byte[] uuid = (byte[])request.getHeader(HeaderSet.TARGET); 187c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (uuid == null) { 188c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 189c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue } 190c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (D) Log.d(TAG, "onConnect(): uuid=" + Arrays.toString(uuid)); 1914446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 192c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (uuid.length != UUID_LENGTH) { 1932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.w(TAG, "Wrong UUID length"); 1942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 1952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan for (int i = 0; i < UUID_LENGTH; i++) { 197c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (uuid[i] != PBAP_TARGET[i]) { 1982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.w(TAG, "Wrong UUID"); 1992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 2002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 202c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue reply.setHeader(HeaderSet.WHO, uuid); 2032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } catch (IOException e) { 2042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.e(TAG, e.toString()); 2052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 2062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 208c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue try { 209c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue byte[] remote = (byte[])request.getHeader(HeaderSet.WHO); 210c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (remote != null) { 211c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (D) Log.d(TAG, "onConnect(): remote=" + Arrays.toString(remote)); 212c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue reply.setHeader(HeaderSet.TARGET, remote); 213c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue } 214c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue } catch (IOException e) { 215c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.e(TAG, e.toString()); 216c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 217c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue } 218c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue 219c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (V) Log.v(TAG, "onConnect(): uuid is ok, will send out " + 2204446eaa935994bc91d6d308303e8d27526b4590dLixin Yue "MSG_SESSION_ESTABLISHED msg."); 2214446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Message msg = Message.obtain(mCallback); 2232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan msg.what = BluetoothPbapService.MSG_SESSION_ESTABLISHED; 2242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan msg.sendToTarget(); 2252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_OK; 2272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 2302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public void onDisconnect(final HeaderSet req, final HeaderSet resp) { 2314446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "onDisconnect(): enter"); 232c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (V) logHeader(req); 2338fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu notifyUpdateWakeLock(); 2342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan resp.responseCode = ResponseCodes.OBEX_HTTP_OK; 2352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (mCallback != null) { 2362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Message msg = Message.obtain(mCallback); 2372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan msg.what = BluetoothPbapService.MSG_SESSION_DISCONNECTED; 2382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan msg.sendToTarget(); 2394446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (V) Log.v(TAG, "onDisconnect(): msg MSG_SESSION_DISCONNECTED sent out."); 2402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 2440b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public int onAbort(HeaderSet request, HeaderSet reply) { 2450b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue if (D) Log.d(TAG, "onAbort(): enter."); 2468fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu notifyUpdateWakeLock(); 2470b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue sIsAborted = true; 2480b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue return ResponseCodes.OBEX_HTTP_OK; 2490b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue } 2500b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue 2510b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue @Override 2522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public int onPut(final Operation op) { 2534446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "onPut(): not support PUT request."); 2548fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu notifyUpdateWakeLock(); 2552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_BAD_REQUEST; 2562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 25976dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin public int onDelete(final HeaderSet request, final HeaderSet reply) { 26076dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin if (D) Log.d(TAG, "onDelete(): not support PUT request."); 26176dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin notifyUpdateWakeLock(); 26276dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin return ResponseCodes.OBEX_HTTP_BAD_REQUEST; 26376dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin } 26476dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin 26576dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin @Override 2662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public int onSetPath(final HeaderSet request, final HeaderSet reply, final boolean backup, 2672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan final boolean create) { 268c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (V) logHeader(request); 2694446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "before setPath, mCurrentPath == " + mCurrentPath); 2708fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu notifyUpdateWakeLock(); 2712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan String current_path_tmp = mCurrentPath; 2722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan String tmp_path = null; 2732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 2742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan tmp_path = (String)request.getHeader(HeaderSet.NAME); 2752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } catch (IOException e) { 2762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.e(TAG, "Get name header fail"); 2772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 2782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2794446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "backup=" + backup + " create=" + create + " name=" + tmp_path); 280d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 281d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (backup) { 282d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (current_path_tmp.length() != 0) { 283d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue current_path_tmp = current_path_tmp.substring(0, 284d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue current_path_tmp.lastIndexOf("/")); 285d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 286d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } else { 2872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (tmp_path == null) { 2882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan current_path_tmp = ""; 2892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } else { 2902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan current_path_tmp = current_path_tmp + "/" + tmp_path; 2912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if ((current_path_tmp.length() != 0) && (!isLegalPath(current_path_tmp))) { 295d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (create) { 296d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue Log.w(TAG, "path create is forbidden!"); 297d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue return ResponseCodes.OBEX_HTTP_FORBIDDEN; 298d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } else { 299d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue Log.w(TAG, "path is not legal"); 300a4508589f298c67fda54c344760ae39f0f375c11Lixin Yue return ResponseCodes.OBEX_HTTP_NOT_FOUND; 301d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 3022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mCurrentPath = current_path_tmp; 3044446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (V) Log.v(TAG, "after setPath, mCurrentPath == " + mCurrentPath); 3054446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_OK; 3072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 3102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public void onClose() { 3112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (mCallback != null) { 3122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Message msg = Message.obtain(mCallback); 3132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan msg.what = BluetoothPbapService.MSG_SERVERSESSION_CLOSE; 3142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan msg.sendToTarget(); 3154446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "onClose(): msg MSG_SERVERSESSION_CLOSE sent out."); 3162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan @Override 3200b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public int onGet(Operation op) { 3218fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu notifyUpdateWakeLock(); 32220b5a93b6e18cd441065edfdf676ad612affc507Jaikumar Ganesh sIsAborted = false; 3232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan HeaderSet request = null; 3242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan HeaderSet reply = new HeaderSet(); 3252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan String type = ""; 3262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan String name = ""; 3272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan byte[] appParam = null; 3282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan AppParamValue appParamValue = new AppParamValue(); 3292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 3302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan request = op.getReceivedHeader(); 3312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan type = (String)request.getHeader(HeaderSet.TYPE); 3322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan name = (String)request.getHeader(HeaderSet.NAME); 3332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan appParam = (byte[])request.getHeader(HeaderSet.APPLICATION_PARAMETER); 3342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } catch (IOException e) { 3352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.e(TAG, "request headers error"); 3362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 3372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 338d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 339c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue if (V) logHeader(request); 3404446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "OnGet type is " + type + "; name is " + name); 341d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 34218bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue if (type == null) { 343a4508589f298c67fda54c344760ae39f0f375c11Lixin Yue return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 34418bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue } 345d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // Accroding to specification,the name header could be omitted such as 346d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // sony erriccsonHBH-DS980 347d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 348d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // For "x-bt/phonebook" and "x-bt/vcard-listing": 349d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // if name == null, guess what carkit actually want from current path 350d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // For "x-bt/vcard": 351d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // We decide which kind of content client would like per current path 352d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 353d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue boolean validName = true; 35418bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue if (TextUtils.isEmpty(name)) { 355d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue validName = false; 356d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 357d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 358d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (!validName || (validName && type.equals(TYPE_VCARD))) { 3594446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "Guess what carkit actually want from current path (" + 3604446eaa935994bc91d6d308303e8d27526b4590dLixin Yue mCurrentPath + ")"); 3614446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3622b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (mCurrentPath.equals(PB_PATH)) { 363d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.PHONEBOOK; 3642b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else if (mCurrentPath.equals(ICH_PATH)) { 365d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; 3662b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else if (mCurrentPath.equals(OCH_PATH)) { 367d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.OUTGOING_CALL_HISTORY; 3682b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else if (mCurrentPath.equals(MCH_PATH)) { 369d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.MISSED_CALL_HISTORY; 370d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue mNeedNewMissedCallsNum = true; 3712b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else if (mCurrentPath.equals(CCH_PATH)) { 372d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.COMBINED_CALL_HISTORY; 373b99a8af5a27318bb5ae3745531d5a2175370b892Hemant Gupta } else if (mCurrentPath.equals(TELECOM_PATH)) { 374b99a8af5a27318bb5ae3745531d5a2175370b892Hemant Gupta /* PBAP 1.1.1 change */ 375b99a8af5a27318bb5ae3745531d5a2175370b892Hemant Gupta if (!validName && type.equals(TYPE_LISTING)) { 376b99a8af5a27318bb5ae3745531d5a2175370b892Hemant Gupta Log.e(TAG, "invalid vcard listing request in default folder"); 377b99a8af5a27318bb5ae3745531d5a2175370b892Hemant Gupta return ResponseCodes.OBEX_HTTP_NOT_FOUND; 378b99a8af5a27318bb5ae3745531d5a2175370b892Hemant Gupta } 379d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } else { 380d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue Log.w(TAG, "mCurrentpath is not valid path!!!"); 381a4508589f298c67fda54c344760ae39f0f375c11Lixin Yue return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 3822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3834446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.v(TAG, "onGet(): appParamValue.needTag=" + appParamValue.needTag); 3844446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } else { 3854446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // Not support SIM card currently 3864446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (name.contains(SIM1.subSequence(0, SIM1.length()))) { 3874446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Log.w(TAG, "Not support access SIM card info!"); 3884446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 3894446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 3904446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3914446eaa935994bc91d6d308303e8d27526b4590dLixin Yue // we have weak name checking here to provide better 3922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // compatibility with other devices,although unique name such as 3932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // "pb.vcf" is required by SIG spec. 39476dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin if (isNameMatchTarget(name, PB)) { 395d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.PHONEBOOK; 3964446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.v(TAG, "download phonebook request"); 39776dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin } else if (isNameMatchTarget(name, ICH)) { 398d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; 3994446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.v(TAG, "download incoming calls request"); 40076dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin } else if (isNameMatchTarget(name, OCH)) { 401d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.OUTGOING_CALL_HISTORY; 4024446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.v(TAG, "download outgoing calls request"); 40376dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin } else if (isNameMatchTarget(name, MCH)) { 404d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.MISSED_CALL_HISTORY; 405d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue mNeedNewMissedCallsNum = true; 4064446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.v(TAG, "download missed calls request"); 40776dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin } else if (isNameMatchTarget(name, CCH)) { 408d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.needTag = ContentType.COMBINED_CALL_HISTORY; 4094446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.v(TAG, "download combined calls request"); 410d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } else { 411d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue Log.w(TAG, "Input name doesn't contain valid info!!!"); 41276dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin return ResponseCodes.OBEX_HTTP_NOT_FOUND; 4132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 415d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 4164ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson if ((appParam != null) && !parseApplicationParameter(appParam, appParamValue)) { 417d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue return ResponseCodes.OBEX_HTTP_BAD_REQUEST; 418d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 419d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 4202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // listing request 4212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (type.equals(TYPE_LISTING)) { 4222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return pullVcardListing(appParam, appParamValue, reply, op); 4232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // pull vcard entry request 4252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan else if (type.equals(TYPE_VCARD)) { 4262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return pullVcardEntry(appParam, appParamValue, op, name, mCurrentPath); 4272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // down load phone book request 4292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan else if (type.equals(TYPE_PB)) { 4302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return pullPhonebook(appParam, appParamValue, reply, op, name); 4312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } else { 4322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.w(TAG, "unknown type request!!!"); 433a4508589f298c67fda54c344760ae39f0f375c11Lixin Yue return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 4342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 435d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 4362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 43776dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin private boolean isNameMatchTarget(String name, String target) { 43876dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin String contentTypeName = name; 43976dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin if (contentTypeName.endsWith(".vcf")) { 44076dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin contentTypeName = contentTypeName 44176dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin .substring(0, contentTypeName.length() - ".vcf".length()); 44276dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin } 44376dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin // There is a test case: Client will send a wrong name "/telecom/pbpb". 44476dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin // So we must use the String between '/' and '/' as a indivisible part 44576dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin // for comparing. 44676dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin String[] nameList = contentTypeName.split("/"); 44776dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin for (String subName : nameList) { 44876dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin if (subName.equals(target)) { 44976dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin return true; 45076dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin } 45176dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin } 45276dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin return false; 45376dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin } 45476dc9e2d09ea7f2655e557462c149a0c6b6dd771Mick Lin 4552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** check whether path is legal */ 4562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private final boolean isLegalPath(final String str) { 4572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (str.length() == 0) { 4582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return true; 4592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4604446eaa935994bc91d6d308303e8d27526b4590dLixin Yue for (int i = 0; i < LEGAL_PATH.length; i++) { 461d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (str.equals(LEGAL_PATH[i])) { 4622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return true; 4632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return false; 4662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private class AppParamValue { 4692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public int maxListCount; 4702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public int listStartOffset; 4722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public String searchValue; 4742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4752b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // Indicate which vCard parameter the search operation shall be carried 4762b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // out on. Can be "Name | Number | Sound", default value is "Name". 4772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public String searchAttr; 4782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4792b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // Indicate which sorting order shall be used for the 4802b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // <x-bt/vcard-listing> listing object. 4812b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // Can be "Alphabetical | Indexed | Phonetical", default value is 4822b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // "Indexed". 4832b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh public String order; 4842b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 4852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public int needTag; 4862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public boolean vcard21; 4882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4896db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta public byte[] filter; 4906db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 4916db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta public boolean ignorefilter; 4926db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 4932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public AppParamValue() { 4944ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson maxListCount = 0xFFFF; 4952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan listStartOffset = 0; 4962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan searchValue = ""; 4972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan searchAttr = ""; 4982b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh order = ""; 4992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan needTag = 0x00; 5002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan vcard21 = true; 5016db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta //Filter is not set by default 5026db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta ignorefilter = true; 5036db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta filter = new byte[] {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} ; 5042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public void dump() { 5072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.i(TAG, "maxListCount=" + maxListCount + " listStartOffset=" + listStartOffset 5082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan + " searchValue=" + searchValue + " searchAttr=" + searchAttr + " needTag=" 5092b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh + needTag + " vcard21=" + vcard21 + " order=" + order); 5102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** To parse obex application parameter */ 5142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private final boolean parseApplicationParameter(final byte[] appParam, 5152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan AppParamValue appParamValue) { 5162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan int i = 0; 517d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue boolean parseOk = true; 5186db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta while ((i < appParam.length) && (parseOk == true)) { 5192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan switch (appParam[i]) { 5202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan case ApplicationParameter.TRIPLET_TAGID.FILTER_TAGID: 5212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += 2; // length and tag field in triplet 5226db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta for (int index=0; index < ApplicationParameter.TRIPLET_LENGTH.FILTER_LENGTH; 5236db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta index++) { 5246db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta if (appParam[i+index] != 0){ 5256db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta appParamValue.ignorefilter = false; 5266db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta appParamValue.filter[index] = appParam[i+index]; 5276db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 5286db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 5292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += ApplicationParameter.TRIPLET_LENGTH.FILTER_LENGTH; 5302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan break; 5312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan case ApplicationParameter.TRIPLET_TAGID.ORDER_TAGID: 5322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += 2; // length and tag field in triplet 5332b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh appParamValue.order = Byte.toString(appParam[i]); 5342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += ApplicationParameter.TRIPLET_LENGTH.ORDER_LENGTH; 5352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan break; 5362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan case ApplicationParameter.TRIPLET_TAGID.SEARCH_VALUE_TAGID: 5372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += 1; // length field in triplet 5382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // length of search value is variable 5394ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson int length = appParam[i]; 5400dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (length == 0) { 5410dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao parseOk = false; 5420dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao break; 5430dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } 5440dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (appParam[i+length] == 0x0) { 5450dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao appParamValue.searchValue = new String(appParam, i + 1, length-1); 5460dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } else { 5470dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao appParamValue.searchValue = new String(appParam, i + 1, length); 5480dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } 5494ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson i += length; 5502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += 1; 5512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan break; 5522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan case ApplicationParameter.TRIPLET_TAGID.SEARCH_ATTRIBUTE_TAGID: 5532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += 2; 5542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan appParamValue.searchAttr = Byte.toString(appParam[i]); 5552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += ApplicationParameter.TRIPLET_LENGTH.SEARCH_ATTRIBUTE_LENGTH; 5562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan break; 5572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan case ApplicationParameter.TRIPLET_TAGID.MAXLISTCOUNT_TAGID: 5582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += 2; 5592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (appParam[i] == 0 && appParam[i + 1] == 0) { 560d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue mNeedPhonebookSize = true; 5612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } else { 5622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan int highValue = appParam[i] & 0xff; 5632c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan int lowValue = appParam[i + 1] & 0xff; 5642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan appParamValue.maxListCount = highValue * 256 + lowValue; 5652c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += ApplicationParameter.TRIPLET_LENGTH.MAXLISTCOUNT_LENGTH; 5672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan break; 5682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan case ApplicationParameter.TRIPLET_TAGID.LISTSTARTOFFSET_TAGID: 5692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += 2; 570d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue int highValue = appParam[i] & 0xff; 571d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue int lowValue = appParam[i + 1] & 0xff; 572d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.listStartOffset = highValue * 256 + lowValue; 5732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += ApplicationParameter.TRIPLET_LENGTH.LISTSTARTOFFSET_LENGTH; 5742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan break; 5752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan case ApplicationParameter.TRIPLET_TAGID.FORMAT_TAGID: 5762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += 2;// length field in triplet 5772b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (appParam[i] != 0) { 5782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan appParamValue.vcard21 = false; 5792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan i += ApplicationParameter.TRIPLET_LENGTH.FORMAT_LENGTH; 5812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan break; 5822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan default: 583d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue parseOk = false; 5844446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Log.e(TAG, "Parse Application Parameter error"); 5852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan break; 5862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 588d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 5894446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) appParamValue.dump(); 5904446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 591d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue return parseOk; 5922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 5932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 5942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** Form and Send an XML format String to client for Phone book listing */ 5950b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue private final int sendVcardListingXml(final int type, Operation op, 5962c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan final int maxListCount, final int listStartOffset, final String searchValue, 5972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan String searchAttr) { 5982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan StringBuilder result = new StringBuilder(); 5992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan int itemsFound = 0; 6002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan result.append("<?xml version=\"1.0\"?>"); 6012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan result.append("<!DOCTYPE vcard-listing SYSTEM \"vcard-listing.dtd\">"); 6022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan result.append("<vCard-listing version=\"1.0\">"); 6032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 6042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // Phonebook listing request 605d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (type == ContentType.PHONEBOOK) { 6064ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson if (searchAttr.equals("0")) { // search by name 6074ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson itemsFound = createList(maxListCount, listStartOffset, searchValue, result, 6080dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao "name"); 6094ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson } else if (searchAttr.equals("1")) { // search by number 6104ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson itemsFound = createList(maxListCount, listStartOffset, searchValue, result, 6110dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao "number"); 6122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan }// end of search by number 6132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan else { 614d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue return ResponseCodes.OBEX_HTTP_PRECON_FAILED; 6152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // Call history listing request 6182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan else { 6192f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue ArrayList<String> nameList = mVcardManager.loadCallHistoryList(type); 620d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue int requestSize = nameList.size() >= maxListCount ? maxListCount : nameList.size(); 621d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue int startPoint = listStartOffset; 622d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue int endPoint = startPoint + requestSize; 623d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (endPoint > nameList.size()) { 624d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue endPoint = nameList.size(); 625d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 6264446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "call log list, size=" + requestSize + " offset=" + listStartOffset); 6274446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 628d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue for (int j = startPoint; j < endPoint; j++) { 629e479e18951a375a548e617e86e3b1b7d121351a1Fred writeVCardEntry(j+1, nameList.get(j),result); 6302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan result.append("</vCard-listing>"); 6332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 6344446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (V) Log.v(TAG, "itemsFound =" + itemsFound); 635d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 636d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue return pushBytes(op, result.toString()); 6372c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 6394ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson private int createList(final int maxListCount, final int listStartOffset, 6400dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao final String searchValue, StringBuilder result, String type) { 6414ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson int itemsFound = 0; 6420dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao ArrayList<String> nameList = mVcardManager.getPhonebookNameList(mOrderBy); 6430dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao final int requestSize = nameList.size() >= maxListCount ? maxListCount : nameList.size(); 6440dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao final int listSize = nameList.size(); 6450dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao String compareValue = "", currentValue; 6464ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson 6470dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (D) Log.d(TAG, "search by " + type + ", requestSize=" + requestSize + " offset=" 6484ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson + listStartOffset + " searchValue=" + searchValue); 6494ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson 6500dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (type.equals("number")) { 6510dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao // query the number, to get the names 6520dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao ArrayList<String> names = mVcardManager.getContactNamesByNumber(searchValue); 6530dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao for (int i = 0; i < names.size(); i++) { 6540dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao compareValue = names.get(i).trim(); 6550dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (D) Log.d(TAG, "compareValue=" + compareValue); 6560dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao for (int pos = listStartOffset; pos < listSize && 6570dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao itemsFound < requestSize; pos++) { 6580dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao currentValue = nameList.get(pos); 6590dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (D) Log.d(TAG, "currentValue=" + currentValue); 6601321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta if (currentValue.equals(compareValue)) { 6610dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao itemsFound++; 66290d9ea96c0b0f3209dc03667e21d14a13ca1f614Hemant Gupta if (currentValue.contains(",")) 66390d9ea96c0b0f3209dc03667e21d14a13ca1f614Hemant Gupta currentValue = currentValue.substring(0, currentValue.lastIndexOf(',')); 664e479e18951a375a548e617e86e3b1b7d121351a1Fred writeVCardEntry(pos, currentValue,result); 6650dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } 6660dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } 6670dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (itemsFound >= requestSize) { 6680dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao break; 6690dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } 6700dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } 6710dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } else { 6720dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (searchValue != null) { 673c3a43ae7d1f54495fb4d830d08386aee75e0e997Hemant Gupta compareValue = searchValue.trim().toLowerCase(); 6740dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } 6750dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao for (int pos = listStartOffset; pos < listSize && 6760dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao itemsFound < requestSize; pos++) { 6770dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao currentValue = nameList.get(pos); 678130969d18eadbd94361fe95bf16b8131cdea6168Hemant Gupta if (currentValue.contains(",")) 679130969d18eadbd94361fe95bf16b8131cdea6168Hemant Gupta currentValue = currentValue.substring(0, currentValue.lastIndexOf(',')); 680130969d18eadbd94361fe95bf16b8131cdea6168Hemant Gupta 681c3a43ae7d1f54495fb4d830d08386aee75e0e997Hemant Gupta if (searchValue.isEmpty() || ((currentValue.toLowerCase()).startsWith(compareValue))) { 6820dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao itemsFound++; 683e479e18951a375a548e617e86e3b1b7d121351a1Fred writeVCardEntry(pos, currentValue,result); 6840dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao } 6854ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson } 6864ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson } 6874ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson return itemsFound; 6884ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson } 6894ce32fccf381a3b448f0d5ff56665201c0e0e6d3Ola Johnsson 6902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** 6912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * Function to send obex header back to client such as get phonebook size 6922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan * request 6932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan */ 6942c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private final int pushHeader(final Operation op, final HeaderSet reply) { 6952c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan OutputStream outputStream = null; 696d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 6974446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "Push Header"); 6984446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, reply.toString()); 699d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 7004446eaa935994bc91d6d308303e8d27526b4590dLixin Yue int pushResult = ResponseCodes.OBEX_HTTP_OK; 7012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 7022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan op.sendHeaders(reply); 7032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan outputStream = op.openOutputStream(); 7042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan outputStream.flush(); 7052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } catch (IOException e) { 7062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.e(TAG, e.toString()); 7074446eaa935994bc91d6d308303e8d27526b4590dLixin Yue pushResult = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 7082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } finally { 7092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (!closeStream(outputStream, op)) { 7104446eaa935994bc91d6d308303e8d27526b4590dLixin Yue pushResult = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 7112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7134446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return pushResult; 7142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 7162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan /** Function to send vcard data to client */ 7170b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue private final int pushBytes(Operation op, final String vcardString) { 7182f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (vcardString == null) { 7192f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Log.w(TAG, "vcardString is null!"); 7202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_OK; 7212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7224446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 7232f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue OutputStream outputStream = null; 7242f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int pushResult = ResponseCodes.OBEX_HTTP_OK; 7252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 7262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan outputStream = op.openOutputStream(); 727ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita outputStream.write(vcardString.getBytes()); 728ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita if (V) Log.v(TAG, "Send Data complete!"); 7292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } catch (IOException e) { 730ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita Log.e(TAG, "open/write outputstrem failed" + e.toString()); 731ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita pushResult = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 7322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7332f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 7342f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (!closeStream(outputStream, op)) { 7352f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue pushResult = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 7362f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 7372f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 7384446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return pushResult; 7392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 7414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private final int handleAppParaForResponse(AppParamValue appParamValue, int size, 7420b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue HeaderSet reply, Operation op) { 743d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue byte[] misnum = new byte[1]; 7442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan ApplicationParameter ap = new ApplicationParameter(); 745d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 746d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // In such case, PCE only want the number of index. 747d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // So response not contain any Body header. 748d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (mNeedPhonebookSize) { 7492f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "Need Phonebook size in response header."); 750d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue mNeedPhonebookSize = false; 751d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 7522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan byte[] pbsize = new byte[2]; 753d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 7542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan pbsize[0] = (byte)((size / 256) & 0xff);// HIGH VALUE 7552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan pbsize[1] = (byte)((size % 256) & 0xff);// LOW VALUE 7562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan ap.addAPPHeader(ApplicationParameter.TRIPLET_TAGID.PHONEBOOKSIZE_TAGID, 7572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan ApplicationParameter.TRIPLET_LENGTH.PHONEBOOKSIZE_LENGTH, pbsize); 758d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 759d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (mNeedNewMissedCallsNum) { 7609522370104410f24602ac98172bfbda27f89780dYoshiharu Kurita mNeedNewMissedCallsNum = false; 761ff33061e763656438daea7249e45e38b8a174288kschulz int nmnum = 0; 762ff33061e763656438daea7249e45e38b8a174288kschulz ContentResolver contentResolver; 763ff33061e763656438daea7249e45e38b8a174288kschulz contentResolver = mContext.getContentResolver(); 764ff33061e763656438daea7249e45e38b8a174288kschulz 765ff33061e763656438daea7249e45e38b8a174288kschulz Cursor c = contentResolver.query( 766ff33061e763656438daea7249e45e38b8a174288kschulz Calls.CONTENT_URI, 767ff33061e763656438daea7249e45e38b8a174288kschulz null, 768ff33061e763656438daea7249e45e38b8a174288kschulz Calls.TYPE + " = " + Calls.MISSED_TYPE + " AND " + android.provider.CallLog.Calls.NEW + " = 1", 769ff33061e763656438daea7249e45e38b8a174288kschulz null, 770ff33061e763656438daea7249e45e38b8a174288kschulz Calls.DEFAULT_SORT_ORDER); 771ff33061e763656438daea7249e45e38b8a174288kschulz 772ff33061e763656438daea7249e45e38b8a174288kschulz if (c != null) { 773ff33061e763656438daea7249e45e38b8a174288kschulz nmnum = c.getCount(); 774ff33061e763656438daea7249e45e38b8a174288kschulz c.close(); 775ff33061e763656438daea7249e45e38b8a174288kschulz } 776d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 777d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue nmnum = nmnum > 0 ? nmnum : 0; 778d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue misnum[0] = (byte)nmnum; 779ff33061e763656438daea7249e45e38b8a174288kschulz if (D) Log.d(TAG, "handleAppParaForResponse(): mNeedNewMissedCallsNum=true, num= " + nmnum); 780d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 7812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan reply.setHeader(HeaderSet.APPLICATION_PARAMETER, ap.getAPPparam()); 782ff33061e763656438daea7249e45e38b8a174288kschulz 7834446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "Send back Phonebook size only, without body info! Size= " + size); 784d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 7852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return pushHeader(op, reply); 7862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 788d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // Only apply to "mch" download/listing. 789d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // NewMissedCalls is used only in the response, together with Body 790d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // header. 791d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (mNeedNewMissedCallsNum) { 7922f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "Need new missed call num in response header."); 793d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue mNeedNewMissedCallsNum = false; 794ff33061e763656438daea7249e45e38b8a174288kschulz int nmnum = 0; 795ff33061e763656438daea7249e45e38b8a174288kschulz ContentResolver contentResolver; 796ff33061e763656438daea7249e45e38b8a174288kschulz contentResolver = mContext.getContentResolver(); 797ff33061e763656438daea7249e45e38b8a174288kschulz 798ff33061e763656438daea7249e45e38b8a174288kschulz Cursor c = contentResolver.query( 799ff33061e763656438daea7249e45e38b8a174288kschulz Calls.CONTENT_URI, 800ff33061e763656438daea7249e45e38b8a174288kschulz null, 801ff33061e763656438daea7249e45e38b8a174288kschulz Calls.TYPE + " = " + Calls.MISSED_TYPE + " AND " + android.provider.CallLog.Calls.NEW + " = 1", 802ff33061e763656438daea7249e45e38b8a174288kschulz null, 803ff33061e763656438daea7249e45e38b8a174288kschulz Calls.DEFAULT_SORT_ORDER); 804ff33061e763656438daea7249e45e38b8a174288kschulz 805ff33061e763656438daea7249e45e38b8a174288kschulz if (c != null) { 806ff33061e763656438daea7249e45e38b8a174288kschulz nmnum = c.getCount(); 807ff33061e763656438daea7249e45e38b8a174288kschulz c.close(); 808ff33061e763656438daea7249e45e38b8a174288kschulz } 809d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 8102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan nmnum = nmnum > 0 ? nmnum : 0; 8112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan misnum[0] = (byte)nmnum; 812ff33061e763656438daea7249e45e38b8a174288kschulz if (D) Log.d(TAG, "handleAppParaForResponse(): mNeedNewMissedCallsNum=true, num= " + nmnum); 813ff33061e763656438daea7249e45e38b8a174288kschulz 8142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan ap.addAPPHeader(ApplicationParameter.TRIPLET_TAGID.NEWMISSEDCALLS_TAGID, 8152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan ApplicationParameter.TRIPLET_LENGTH.NEWMISSEDCALLS_LENGTH, misnum); 8162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan reply.setHeader(HeaderSet.APPLICATION_PARAMETER, ap.getAPPparam()); 8174446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "handleAppParaForResponse(): mNeedNewMissedCallsNum=true, num= " 8184446eaa935994bc91d6d308303e8d27526b4590dLixin Yue + nmnum); 8192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 820d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // Only Specifies the headers, not write for now, will write to PCE 821d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // together with Body 822d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue try { 823d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue op.sendHeaders(reply); 824d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } catch (IOException e) { 825d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue Log.e(TAG, e.toString()); 826d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 8272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 8282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 829d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue return NEED_SEND_BODY; 830d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 8312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 832d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue private final int pullVcardListing(byte[] appParam, AppParamValue appParamValue, 8330b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue HeaderSet reply, Operation op) { 834d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue String searchAttr = appParamValue.searchAttr.trim(); 8352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 836d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (searchAttr == null || searchAttr.length() == 0) { 837d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // If searchAttr is not set by PCE, set default value per spec. 838d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue appParamValue.searchAttr = "0"; 8394446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "searchAttr is not set by PCE, assume search by name by default"); 8402b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else if (!searchAttr.equals("0") && !searchAttr.equals("1")) { 841d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue Log.w(TAG, "search attr not supported"); 8422b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (searchAttr.equals("2")) { 843d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // search by sound is not supported currently 844d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue Log.w(TAG, "do not support search by sound"); 845d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; 846d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 847d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue return ResponseCodes.OBEX_HTTP_PRECON_FAILED; 848d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } else { 8494446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Log.i(TAG, "searchAttr is valid: " + searchAttr); 8502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 8512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 8522f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int size = mVcardManager.getPhonebookSize(appParamValue.needTag); 8534446eaa935994bc91d6d308303e8d27526b4590dLixin Yue int needSendBody = handleAppParaForResponse(appParamValue, size, reply, op); 8544446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (needSendBody != NEED_SEND_BODY) { 8554446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return needSendBody; 8562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 857d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 8582f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (size == 0) { 8592f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "PhonebookSize is 0, return."); 8602f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return ResponseCodes.OBEX_HTTP_OK; 8612f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 8622f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 8632b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh String orderPara = appParamValue.order.trim(); 8642b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (TextUtils.isEmpty(orderPara)) { 8652b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // If order parameter is not set by PCE, set default value per spec. 8660dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao orderPara = "0"; 8672b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (D) Log.d(TAG, "Order parameter is not set by PCE. " + 8682b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh "Assume order by 'Indexed' by default"); 8692b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else if (!orderPara.equals("0") && !orderPara.equals("1")) { 8702b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (V) Log.v(TAG, "Order parameter is not supported: " + appParamValue.order); 8712b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (orderPara.equals("2")) { 8722b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // Order by sound is not supported currently 8732b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Log.w(TAG, "Do not support order by sound"); 8742b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; 8752b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 8762b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh return ResponseCodes.OBEX_HTTP_PRECON_FAILED; 8772b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else { 8782b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Log.i(TAG, "Order parameter is valid: " + orderPara); 8792b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 8802b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 8812b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (orderPara.equals("0")) { 8822b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh mOrderBy = ORDER_BY_INDEXED; 8832b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else if (orderPara.equals("1")) { 8842b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh mOrderBy = ORDER_BY_ALPHABETICAL; 8852b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 8862b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 8874446eaa935994bc91d6d308303e8d27526b4590dLixin Yue int sendResult = sendVcardListingXml(appParamValue.needTag, op, appParamValue.maxListCount, 8884446eaa935994bc91d6d308303e8d27526b4590dLixin Yue appParamValue.listStartOffset, appParamValue.searchValue, 8894446eaa935994bc91d6d308303e8d27526b4590dLixin Yue appParamValue.searchAttr); 8904446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return sendResult; 8912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 8922c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 8932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private final int pullVcardEntry(byte[] appParam, AppParamValue appParamValue, 8940b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue Operation op, final String name, final String current_path) { 895d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (name == null || name.length() < VCARD_NAME_SUFFIX_LENGTH) { 8964446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "Name is Null, or the length of name < 5 !"); 897a4508589f298c67fda54c344760ae39f0f375c11Lixin Yue return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 8982c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 899d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue String strIndex = name.substring(0, name.length() - VCARD_NAME_SUFFIX_LENGTH + 1); 9002f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int intIndex = 0; 9012c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (strIndex.trim().length() != 0) { 9022c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 9032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan intIndex = Integer.parseInt(strIndex); 9042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } catch (NumberFormatException e) { 9052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.e(TAG, "catch number format exception " + e.toString()); 906a4508589f298c67fda54c344760ae39f0f375c11Lixin Yue return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 9072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 909d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue 9102f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int size = mVcardManager.getPhonebookSize(appParamValue.needTag); 9112f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (size == 0) { 9122f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "PhonebookSize is 0, return."); 9136f02f510e5dc3fb994516128f2de1d78bc7f9b1eStaffan Lindvall return ResponseCodes.OBEX_HTTP_NOT_FOUND; 9144446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 9154446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 9162f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue boolean vcard21 = appParamValue.vcard21; 917d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (appParamValue.needTag == 0) { 918d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue Log.w(TAG, "wrong path!"); 919a4508589f298c67fda54c344760ae39f0f375c11Lixin Yue return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 920d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } else if (appParamValue.needTag == ContentType.PHONEBOOK) { 9214446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (intIndex < 0 || intIndex >= size) { 9224446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Log.w(TAG, "The requested vcard is not acceptable! name= " + name); 9236f02f510e5dc3fb994516128f2de1d78bc7f9b1eStaffan Lindvall return ResponseCodes.OBEX_HTTP_NOT_FOUND; 9242f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else if (intIndex == 0) { 925d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // For PB_PATH, 0.vcf is the phone number of this phone. 926c7a57f31515107366589bd6875c3cc4af1fc806efredc String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21,null); 9272f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return pushBytes(op, ownerVcard); 9282f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 9292b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh return mVcardManager.composeAndSendPhonebookOneVcard(op, intIndex, vcard21, null, 9306db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta mOrderBy, appParamValue.ignorefilter, appParamValue.filter); 931d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 932d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } else { 9334446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (intIndex <= 0 || intIndex > size) { 934d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue Log.w(TAG, "The requested vcard is not acceptable! name= " + name); 9356f02f510e5dc3fb994516128f2de1d78bc7f9b1eStaffan Lindvall return ResponseCodes.OBEX_HTTP_NOT_FOUND; 936d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 937d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // For others (ich/och/cch/mch), 0.vcf is meaningless, and must 938d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // begin from 1.vcf 939d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue if (intIndex >= 1) { 9402f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return mVcardManager.composeAndSendCallLogVcards(appParamValue.needTag, op, 9416db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta intIndex, intIndex, vcard21, appParamValue.ignorefilter, 9426db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta appParamValue.filter); 943d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } 9442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9452f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return ResponseCodes.OBEX_HTTP_OK; 9462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 9482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private final int pullPhonebook(byte[] appParam, AppParamValue appParamValue, HeaderSet reply, 9490b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue Operation op, final String name) { 9502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // code start for passing PTS3.2 TC_PSE_PBD_BI_01_C 9512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (name != null) { 9522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan int dotIndex = name.indexOf("."); 9532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan String vcf = "vcf"; 9542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (dotIndex >= 0 && dotIndex <= name.length()) { 9552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (name.regionMatches(dotIndex + 1, vcf, 0, vcf.length()) == false) { 9562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.w(TAG, "name is not .vcf"); 9572c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 9582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 960d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue } // code end for passing PTS3.2 TC_PSE_PBD_BI_01_C 9612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 9622f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int pbSize = mVcardManager.getPhonebookSize(appParamValue.needTag); 9634446eaa935994bc91d6d308303e8d27526b4590dLixin Yue int needSendBody = handleAppParaForResponse(appParamValue, pbSize, reply, op); 9644446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (needSendBody != NEED_SEND_BODY) { 9654446eaa935994bc91d6d308303e8d27526b4590dLixin Yue return needSendBody; 9662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 9682f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (pbSize == 0) { 9692f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "PhonebookSize is 0, return."); 9702f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return ResponseCodes.OBEX_HTTP_OK; 9712f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 9722f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 973d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue int requestSize = pbSize >= appParamValue.maxListCount ? appParamValue.maxListCount 974d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue : pbSize; 975d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue int startPoint = appParamValue.listStartOffset; 97618bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue if (startPoint < 0 || startPoint >= pbSize) { 97718bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue Log.w(TAG, "listStartOffset is not correct! " + startPoint); 97818bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue return ResponseCodes.OBEX_HTTP_OK; 97918bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue } 98018bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue 98177b122f551ae37811c75ae76fa2029f7b3f2f404a // Limit the number of call log to CALLLOG_NUM_LIMIT 98277b122f551ae37811c75ae76fa2029f7b3f2f404a if (appParamValue.needTag != BluetoothPbapObexServer.ContentType.PHONEBOOK) { 98377b122f551ae37811c75ae76fa2029f7b3f2f404a if (requestSize > CALLLOG_NUM_LIMIT) { 98477b122f551ae37811c75ae76fa2029f7b3f2f404a requestSize = CALLLOG_NUM_LIMIT; 98577b122f551ae37811c75ae76fa2029f7b3f2f404a } 98677b122f551ae37811c75ae76fa2029f7b3f2f404a } 98777b122f551ae37811c75ae76fa2029f7b3f2f404a 98818bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue int endPoint = startPoint + requestSize - 1; 98918bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue if (endPoint > pbSize - 1) { 99018bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue endPoint = pbSize - 1; 9912c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9924446eaa935994bc91d6d308303e8d27526b4590dLixin Yue if (D) Log.d(TAG, "pullPhonebook(): requestSize=" + requestSize + " startPoint=" + 9934446eaa935994bc91d6d308303e8d27526b4590dLixin Yue startPoint + " endPoint=" + endPoint); 9944446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 9952f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue boolean vcard21 = appParamValue.vcard21; 9962f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) { 99718bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue if (startPoint == 0) { 998c7a57f31515107366589bd6875c3cc4af1fc806efredc String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21,null); 99918bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue if (endPoint == 0) { 100018bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue return pushBytes(op, ownerVcard); 100118bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue } else { 100218bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue return mVcardManager.composeAndSendPhonebookVcards(op, 1, endPoint, vcard21, 10036db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta ownerVcard, appParamValue.ignorefilter, appParamValue.filter); 100418bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue } 10052f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 100618bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue return mVcardManager.composeAndSendPhonebookVcards(op, startPoint, endPoint, 10076db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta vcard21, null, appParamValue.ignorefilter, appParamValue.filter); 10082f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 10092f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 101018bde766b20c899310ebdd5ca823e30ff27d407fLixin Yue return mVcardManager.composeAndSendCallLogVcards(appParamValue.needTag, op, 10116db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta startPoint + 1, endPoint + 1, vcard21, appParamValue.ignorefilter, 10126db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta appParamValue.filter); 10132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10142c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 10162f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public static boolean closeStream(final OutputStream out, final Operation op) { 10172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan boolean returnvalue = true; 10182c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 10192c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (out != null) { 10202c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan out.close(); 10212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } catch (IOException e) { 10232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan Log.e(TAG, "outputStream close failed" + e.toString()); 10242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan returnvalue = false; 10252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10262c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan try { 10272c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan if (op != null) { 10282c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan op.close(); 10292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10302c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } catch (IOException e) { 10314446eaa935994bc91d6d308303e8d27526b4590dLixin Yue Log.e(TAG, "operation close failed" + e.toString()); 10322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan returnvalue = false; 10332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan return returnvalue; 10352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10362c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1037d896162ef022a5607b13bae5177637ff3f18b737Lixin Yue // Reserved for future use. In case PSE challenge PCE and PCE input wrong 10382c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan // session key. 10392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public final void onAuthenticationFailure(final byte[] userName) { 10402c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1041c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue 10422f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public static final String createSelectionPara(final int type) { 10432f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection = null; 10442f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue switch (type) { 10452f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue case ContentType.INCOMING_CALL_HISTORY: 10462f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue selection = Calls.TYPE + "=" + CallLog.Calls.INCOMING_TYPE; 10472f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 10482f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue case ContentType.OUTGOING_CALL_HISTORY: 10492f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue selection = Calls.TYPE + "=" + CallLog.Calls.OUTGOING_TYPE; 10502f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 10512f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue case ContentType.MISSED_CALL_HISTORY: 10522f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue selection = Calls.TYPE + "=" + CallLog.Calls.MISSED_TYPE; 10532f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 10542f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue default: 10552f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 10562f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 10572f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "Call log selection: " + selection); 10582f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return selection; 10592f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 10602f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 1061e479e18951a375a548e617e86e3b1b7d121351a1Fred /** 1062e479e18951a375a548e617e86e3b1b7d121351a1Fred * XML encode special characters in the name field 1063e479e18951a375a548e617e86e3b1b7d121351a1Fred */ 1064e479e18951a375a548e617e86e3b1b7d121351a1Fred private void xmlEncode(String name, StringBuilder result) { 1065e479e18951a375a548e617e86e3b1b7d121351a1Fred if (name == null) { 1066e479e18951a375a548e617e86e3b1b7d121351a1Fred return; 1067e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1068e479e18951a375a548e617e86e3b1b7d121351a1Fred 1069e479e18951a375a548e617e86e3b1b7d121351a1Fred final StringCharacterIterator iterator = new StringCharacterIterator(name); 1070e479e18951a375a548e617e86e3b1b7d121351a1Fred char character = iterator.current(); 1071e479e18951a375a548e617e86e3b1b7d121351a1Fred while (character != CharacterIterator.DONE ){ 1072e479e18951a375a548e617e86e3b1b7d121351a1Fred if (character == '<') { 1073e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append("<"); 1074e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1075e479e18951a375a548e617e86e3b1b7d121351a1Fred else if (character == '>') { 1076e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append(">"); 1077e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1078e479e18951a375a548e617e86e3b1b7d121351a1Fred else if (character == '\"') { 1079e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append("""); 1080e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1081e479e18951a375a548e617e86e3b1b7d121351a1Fred else if (character == '\'') { 1082e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append("'"); 1083e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1084e479e18951a375a548e617e86e3b1b7d121351a1Fred else if (character == '&') { 1085e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append("&"); 1086e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1087e479e18951a375a548e617e86e3b1b7d121351a1Fred else { 1088e479e18951a375a548e617e86e3b1b7d121351a1Fred // The char is not a special one, add it to the result as is 1089e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append(character); 1090e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1091e479e18951a375a548e617e86e3b1b7d121351a1Fred character = iterator.next(); 1092e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1093e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1094e479e18951a375a548e617e86e3b1b7d121351a1Fred 1095e479e18951a375a548e617e86e3b1b7d121351a1Fred private void writeVCardEntry(int vcfIndex, String name, StringBuilder result) { 1096e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append("<card handle=\""); 1097e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append(vcfIndex); 1098e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append(".vcf\" name=\""); 1099e479e18951a375a548e617e86e3b1b7d121351a1Fred xmlEncode(name, result); 1100e479e18951a375a548e617e86e3b1b7d121351a1Fred result.append("\"/>"); 1101e479e18951a375a548e617e86e3b1b7d121351a1Fred } 1102e479e18951a375a548e617e86e3b1b7d121351a1Fred 11038fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu private void notifyUpdateWakeLock() { 11048fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu Message msg = Message.obtain(mCallback); 11058fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu msg.what = BluetoothPbapService.MSG_ACQUIRE_WAKE_LOCK; 11068fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu msg.sendToTarget(); 11078fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu } 11088fa8d120e86c7488616cc7f7310843f15278b5d9Zhihai Xu 11092f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public static final void logHeader(HeaderSet hs) { 1110c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "Dumping HeaderSet " + hs.toString()); 1111c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue try { 1112c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue 1113c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "COUNT : " + hs.getHeader(HeaderSet.COUNT)); 1114c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "NAME : " + hs.getHeader(HeaderSet.NAME)); 1115c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "TYPE : " + hs.getHeader(HeaderSet.TYPE)); 1116c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "LENGTH : " + hs.getHeader(HeaderSet.LENGTH)); 1117c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "TIME_ISO_8601 : " + hs.getHeader(HeaderSet.TIME_ISO_8601)); 1118c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "TIME_4_BYTE : " + hs.getHeader(HeaderSet.TIME_4_BYTE)); 1119c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "DESCRIPTION : " + hs.getHeader(HeaderSet.DESCRIPTION)); 1120c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "TARGET : " + hs.getHeader(HeaderSet.TARGET)); 1121c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "HTTP : " + hs.getHeader(HeaderSet.HTTP)); 1122c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "WHO : " + hs.getHeader(HeaderSet.WHO)); 1123c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "OBJECT_CLASS : " + hs.getHeader(HeaderSet.OBJECT_CLASS)); 1124c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.v(TAG, "APPLICATION_PARAMETER : " + hs.getHeader(HeaderSet.APPLICATION_PARAMETER)); 1125c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue } catch (IOException e) { 1126c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue Log.e(TAG, "dump HeaderSet error " + e); 1127c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue } 1128c5495c585c0d19cdd20963e5a2144e5f984a306eLixin Yue } 11292c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan} 1130