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);
    }
  }