/** To parse obex application parameter */ private final boolean parseApplicationParameter( final byte[] appParam, AppParamValue appParamValue) { int i = 0; boolean parseOk = true; while ((i < appParam.length) && (parseOk == true)) { switch (appParam[i]) { case ApplicationParameter.TRIPLET_TAGID.FILTER_TAGID: i += 2; // length and tag field in triplet i += ApplicationParameter.TRIPLET_LENGTH.FILTER_LENGTH; break; case ApplicationParameter.TRIPLET_TAGID.ORDER_TAGID: i += 2; // length and tag field in triplet appParamValue.order = Byte.toString(appParam[i]); i += ApplicationParameter.TRIPLET_LENGTH.ORDER_LENGTH; break; case ApplicationParameter.TRIPLET_TAGID.SEARCH_VALUE_TAGID: i += 1; // length field in triplet // length of search value is variable int length = appParam[i]; if (length == 0) { // If parse is not OK return false parseOk = false; break; } if (appParam[i + length] == 0x0) { appParamValue.searchValue = new String(appParam, i + 1, length - 1); } else { appParamValue.searchValue = new String(appParam, i + 1, length); } i += length; i += 1; break; case ApplicationParameter.TRIPLET_TAGID.SEARCH_ATTRIBUTE_TAGID: i += 2; appParamValue.searchAttr = Byte.toString(appParam[i]); i += ApplicationParameter.TRIPLET_LENGTH.SEARCH_ATTRIBUTE_LENGTH; break; case ApplicationParameter.TRIPLET_TAGID.MAXLISTCOUNT_TAGID: i += 2; if (appParam[i] == 0 && appParam[i + 1] == 0) { mNeedPhonebookSize = true; } else { int highValue = appParam[i] & 0xff; int lowValue = appParam[i + 1] & 0xff; appParamValue.maxListCount = highValue * 256 + lowValue; } i += ApplicationParameter.TRIPLET_LENGTH.MAXLISTCOUNT_LENGTH; break; case ApplicationParameter.TRIPLET_TAGID.LISTSTARTOFFSET_TAGID: i += 2; int highValue = appParam[i] & 0xff; int lowValue = appParam[i + 1] & 0xff; appParamValue.listStartOffset = highValue * 256 + lowValue; i += ApplicationParameter.TRIPLET_LENGTH.LISTSTARTOFFSET_LENGTH; break; case ApplicationParameter.TRIPLET_TAGID.FORMAT_TAGID: i += 2; // length field in triplet if (appParam[i] != 0) { appParamValue.vcard21 = false; } i += ApplicationParameter.TRIPLET_LENGTH.FORMAT_LENGTH; break; default: parseOk = false; Log.e(TAG, "Parse Application Parameter error"); break; } } if (D) appParamValue.dump(); return parseOk; }
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; }
@Override public int onGet(Operation op) { sIsAborted = false; HeaderSet request = null; HeaderSet reply = new HeaderSet(); String type = ""; String name = ""; byte[] appParam = null; AppParamValue appParamValue = new AppParamValue(); try { request = op.getReceivedHeader(); type = (String) request.getHeader(HeaderSet.TYPE); name = (String) request.getHeader(HeaderSet.NAME); appParam = (byte[]) request.getHeader(HeaderSet.APPLICATION_PARAMETER); } catch (IOException e) { Log.e(TAG, "request headers error"); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } if (V) logHeader(request); if (D) Log.d(TAG, "OnGet type is " + type + "; name is " + name); if (type == null) { return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } // Accroding to specification,the name header could be omitted such as // sony erriccsonHBH-DS980 // For "x-bt/phonebook" and "x-bt/vcard-listing": // if name == null, guess what carkit actually want from current path // For "x-bt/vcard": // We decide which kind of content client would like per current path boolean validName = true; if (TextUtils.isEmpty(name)) { validName = false; } if (!validName || (validName && type.equals(TYPE_VCARD))) { if (D) Log.d(TAG, "Guess what carkit actually want from current path (" + mCurrentPath + ")"); if (mCurrentPath.equals(PB_PATH)) { appParamValue.needTag = ContentType.PHONEBOOK; } else if (mCurrentPath.equals(ICH_PATH)) { appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; } else if (mCurrentPath.equals(OCH_PATH)) { appParamValue.needTag = ContentType.OUTGOING_CALL_HISTORY; } else if (mCurrentPath.equals(MCH_PATH)) { appParamValue.needTag = ContentType.MISSED_CALL_HISTORY; mNeedNewMissedCallsNum = true; } else if (mCurrentPath.equals(CCH_PATH)) { appParamValue.needTag = ContentType.COMBINED_CALL_HISTORY; } else { Log.w(TAG, "mCurrentpath is not valid path!!!"); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } if (D) Log.v(TAG, "onGet(): appParamValue.needTag=" + appParamValue.needTag); } else { // Not support SIM card currently if (name.contains(SIM1.subSequence(0, SIM1.length()))) { Log.w(TAG, "Not support access SIM card info!"); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } // we have weak name checking here to provide better // compatibility with other devices,although unique name such as // "pb.vcf" is required by SIG spec. if (name.contains(PB.subSequence(0, PB.length()))) { appParamValue.needTag = ContentType.PHONEBOOK; if (D) Log.v(TAG, "download phonebook request"); } else if (name.contains(ICH.subSequence(0, ICH.length()))) { appParamValue.needTag = ContentType.INCOMING_CALL_HISTORY; if (D) Log.v(TAG, "download incoming calls request"); } else if (name.contains(OCH.subSequence(0, OCH.length()))) { appParamValue.needTag = ContentType.OUTGOING_CALL_HISTORY; if (D) Log.v(TAG, "download outgoing calls request"); } else if (name.contains(MCH.subSequence(0, MCH.length()))) { appParamValue.needTag = ContentType.MISSED_CALL_HISTORY; mNeedNewMissedCallsNum = true; if (D) Log.v(TAG, "download missed calls request"); } else if (name.contains(CCH.subSequence(0, CCH.length()))) { appParamValue.needTag = ContentType.COMBINED_CALL_HISTORY; if (D) Log.v(TAG, "download combined calls request"); } else { Log.w(TAG, "Input name doesn't contain valid info!!!"); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } } if ((appParam != null) && !parseApplicationParameter(appParam, appParamValue)) { return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } // listing request if (type.equals(TYPE_LISTING)) { return pullVcardListing(appParam, appParamValue, reply, op); } // pull vcard entry request else if (type.equals(TYPE_VCARD)) { return pullVcardEntry(appParam, appParamValue, op, name, mCurrentPath); } // down load phone book request else if (type.equals(TYPE_PB)) { return pullPhonebook(appParam, appParamValue, reply, op, name); } else { Log.w(TAG, "unknown type request!!!"); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } }