private final int pullVcardEntry( byte[] appParam, AppParamValue appParamValue, Operation op, final String name, final String current_path) { if (name == null || name.length() < VCARD_NAME_SUFFIX_LENGTH) { if (D) Log.d(TAG, "Name is Null, or the length of name < 5 !"); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } String strIndex = name.substring(0, name.length() - VCARD_NAME_SUFFIX_LENGTH + 1); int intIndex = 0; if (strIndex.trim().length() != 0) { try { intIndex = Integer.parseInt(strIndex); } catch (NumberFormatException e) { Log.e(TAG, "catch number format exception " + e.toString()); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } } int size = mVcardManager.getPhonebookSize(appParamValue.needTag); if (size == 0) { if (V) Log.v(TAG, "PhonebookSize is 0, return."); return ResponseCodes.OBEX_HTTP_OK; } boolean vcard21 = appParamValue.vcard21; if (appParamValue.needTag == 0) { Log.w(TAG, "wrong path!"); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } else if (appParamValue.needTag == ContentType.PHONEBOOK) { if (intIndex < 0 || intIndex >= size) { Log.w(TAG, "The requested vcard is not acceptable! name= " + name); return ResponseCodes.OBEX_HTTP_OK; } else if (intIndex == 0) { // For PB_PATH, 0.vcf is the phone number of this phone. String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21); return pushBytes(op, ownerVcard); } else { return mVcardManager.composeAndSendPhonebookOneVcard(op, intIndex, vcard21, null, mOrderBy); } } else { if (intIndex <= 0 || intIndex > size) { Log.w(TAG, "The requested vcard is not acceptable! name= " + name); return ResponseCodes.OBEX_HTTP_OK; } // For others (ich/och/cch/mch), 0.vcf is meaningless, and must // begin from 1.vcf if (intIndex >= 1) { return mVcardManager.composeAndSendCallLogVcards( appParamValue.needTag, op, intIndex, intIndex, vcard21); } } return ResponseCodes.OBEX_HTTP_OK; }
public BluetoothPbapObexServer(Handler callback, Context context) { super(); mConnectionId = -1; mCallback = callback; mContext = context; mVcardManager = new BluetoothPbapVcardManager(mContext); // set initial value when ObexServer created mMissedCallSize = mVcardManager.getPhonebookSize(ContentType.MISSED_CALL_HISTORY); if (D) Log.d(TAG, "Initialize mMissedCallSize=" + mMissedCallSize); }
/** Form and Send an XML format String to client for Phone book listing */ private final int sendVcardListingXml( final int type, Operation op, final int maxListCount, final int listStartOffset, final String searchValue, String searchAttr) { StringBuilder result = new StringBuilder(); int itemsFound = 0; result.append("<?xml version=\"1.0\"?>"); result.append("<!DOCTYPE vcard-listing SYSTEM \"vcard-listing.dtd\">"); result.append("<vCard-listing version=\"1.0\">"); // Phonebook listing request if (type == ContentType.PHONEBOOK) { if (searchAttr.equals("0")) { // search by name itemsFound = createList(maxListCount, listStartOffset, searchValue, result, "name"); } else if (searchAttr.equals("1")) { // search by number itemsFound = createList(maxListCount, listStartOffset, searchValue, result, "number"); } // end of search by number else { return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } } // Call history listing request else { ArrayList<String> nameList = mVcardManager.loadCallHistoryList(type); int requestSize = nameList.size() >= maxListCount ? maxListCount : nameList.size(); int startPoint = listStartOffset; int endPoint = startPoint + requestSize; if (endPoint > nameList.size()) { endPoint = nameList.size(); } if (D) Log.d(TAG, "call log list, size=" + requestSize + " offset=" + listStartOffset); for (int j = startPoint; j < endPoint; j++) { // listing object begin with 1.vcf result.append( "<card handle=\"" + (j + 1) + ".vcf\" name=\"" + nameList.get(j) + "\"" + "/>"); itemsFound++; } } result.append("</vCard-listing>"); if (V) Log.v(TAG, "itemsFound =" + itemsFound); return pushBytes(op, result.toString()); }
private final int pullPhonebook( byte[] appParam, AppParamValue appParamValue, HeaderSet reply, Operation op, final String name) { // code start for passing PTS3.2 TC_PSE_PBD_BI_01_C if (name != null) { int dotIndex = name.indexOf("."); String vcf = "vcf"; if (dotIndex >= 0 && dotIndex <= name.length()) { if (name.regionMatches(dotIndex + 1, vcf, 0, vcf.length()) == false) { Log.w(TAG, "name is not .vcf"); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } } } // code end for passing PTS3.2 TC_PSE_PBD_BI_01_C int pbSize = mVcardManager.getPhonebookSize(appParamValue.needTag); int needSendBody = handleAppParaForResponse(appParamValue, pbSize, reply, op); if (needSendBody != NEED_SEND_BODY) { return needSendBody; } if (pbSize == 0) { if (V) Log.v(TAG, "PhonebookSize is 0, return."); return ResponseCodes.OBEX_HTTP_OK; } int requestSize = pbSize >= appParamValue.maxListCount ? appParamValue.maxListCount : pbSize; int startPoint = appParamValue.listStartOffset; if (startPoint < 0 || startPoint >= pbSize) { Log.w(TAG, "listStartOffset is not correct! " + startPoint); return ResponseCodes.OBEX_HTTP_OK; } // Limit the number of call log to CALLLOG_NUM_LIMIT if (appParamValue.needTag != BluetoothPbapObexServer.ContentType.PHONEBOOK) { if (requestSize > CALLLOG_NUM_LIMIT) { requestSize = CALLLOG_NUM_LIMIT; } } int endPoint = startPoint + requestSize - 1; if (endPoint > pbSize - 1) { endPoint = pbSize - 1; } if (D) Log.d( TAG, "pullPhonebook(): requestSize=" + requestSize + " startPoint=" + startPoint + " endPoint=" + endPoint); String result = null; boolean vcard21 = appParamValue.vcard21; if (appParamValue.needTag == BluetoothPbapObexServer.ContentType.PHONEBOOK) { if (startPoint == 0) { String ownerVcard = mVcardManager.getOwnerPhoneNumberVcard(vcard21); if (endPoint == 0) { return pushBytes(op, ownerVcard); } else { return mVcardManager.composeAndSendPhonebookVcards(op, 1, endPoint, vcard21, ownerVcard); } } else { return mVcardManager.composeAndSendPhonebookVcards(op, startPoint, endPoint, vcard21, null); } } else { return mVcardManager.composeAndSendCallLogVcards( appParamValue.needTag, op, startPoint + 1, endPoint + 1, vcard21); } }
private final int pullVcardListing( byte[] appParam, AppParamValue appParamValue, HeaderSet reply, Operation op) { String searchAttr = appParamValue.searchAttr.trim(); if (searchAttr == null || searchAttr.length() == 0) { // If searchAttr is not set by PCE, set default value per spec. appParamValue.searchAttr = "0"; if (D) Log.d(TAG, "searchAttr is not set by PCE, assume search by name by default"); } else if (!searchAttr.equals("0") && !searchAttr.equals("1")) { Log.w(TAG, "search attr not supported"); if (searchAttr.equals("2")) { // search by sound is not supported currently Log.w(TAG, "do not support search by sound"); return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; } return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } else { Log.i(TAG, "searchAttr is valid: " + searchAttr); } int size = mVcardManager.getPhonebookSize(appParamValue.needTag); int needSendBody = handleAppParaForResponse(appParamValue, size, reply, op); if (needSendBody != NEED_SEND_BODY) { return needSendBody; } if (size == 0) { if (V) Log.v(TAG, "PhonebookSize is 0, return."); return ResponseCodes.OBEX_HTTP_OK; } String orderPara = appParamValue.order.trim(); if (TextUtils.isEmpty(orderPara)) { // If order parameter is not set by PCE, set default value per spec. orderPara = "0"; if (D) Log.d(TAG, "Order parameter is not set by PCE. " + "Assume order by 'Indexed' by default"); } else if (!orderPara.equals("0") && !orderPara.equals("1")) { if (V) Log.v(TAG, "Order parameter is not supported: " + appParamValue.order); if (orderPara.equals("2")) { // Order by sound is not supported currently Log.w(TAG, "Do not support order by sound"); return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; } return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } else { Log.i(TAG, "Order parameter is valid: " + orderPara); } if (orderPara.equals("0")) { mOrderBy = ORDER_BY_INDEXED; } else if (orderPara.equals("1")) { mOrderBy = ORDER_BY_ALPHABETICAL; } int sendResult = sendVcardListingXml( appParamValue.needTag, op, appParamValue.maxListCount, appParamValue.listStartOffset, appParamValue.searchValue, appParamValue.searchAttr); return sendResult; }
private int createList( final int maxListCount, final int listStartOffset, final String searchValue, StringBuilder result, String type) { int itemsFound = 0; ArrayList<String> nameList = mVcardManager.getPhonebookNameList(mOrderBy); final int requestSize = nameList.size() >= maxListCount ? maxListCount : nameList.size(); final int listSize = nameList.size(); String compareValue = "", currentValue, tmpCurrentValue; if (D) Log.d( TAG, "search by " + type + ", requestSize=" + requestSize + " offset=" + listStartOffset + " searchValue=" + searchValue); if (type.equals("number")) { // query the number, to get the names ArrayList<String> names = mVcardManager.getContactNamesByNumber(searchValue); for (int i = 0; i < names.size(); i++) { compareValue = names.get(i).trim(); if (D) Log.d(TAG, "compareValue=" + compareValue); for (int pos = listStartOffset; pos < listSize && itemsFound < requestSize; pos++) { currentValue = nameList.get(pos); if (D) Log.d(TAG, "currentValue=" + currentValue); if (currentValue.startsWith(compareValue)) { itemsFound++; result.append("<card handle=\"" + pos + ".vcf\" name=\"" + currentValue + "\"" + "/>"); } } if (itemsFound >= requestSize) { break; } } } else { if (searchValue != null) { compareValue = searchValue.trim(); compareValue = compareValue.toLowerCase(); } for (int pos = listStartOffset; pos < listSize && itemsFound < requestSize; pos++) { currentValue = nameList.get(pos); tmpCurrentValue = currentValue.toLowerCase(); if (D) Log.d(TAG, "currentValue=" + currentValue); if (searchValue == null) { itemsFound++; result.append("<card handle=\"" + pos + ".vcf\" name=\"" + currentValue + "\"" + "/>"); } else { int sIndex = -1; do { tmpCurrentValue = tmpCurrentValue.substring(sIndex + 1); if (tmpCurrentValue.startsWith(compareValue)) { itemsFound++; result.append( "<card handle=\"" + pos + ".vcf\" name=\"" + currentValue + "\"" + "/>"); break; } sIndex = tmpCurrentValue.indexOf(' '); } while (sIndex > 0); } } } return itemsFound; }