// process CPBR command after permission check
  private AtCommandResult processCpbrCommand() {
    // Shortcut SM phonebook
    if ("SM".equals(mCurrentPhonebook)) {
      return new AtCommandResult(AtCommandResult.OK);
    }

    // Check phonebook
    PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, false);
    if (pbr == null) {
      return mHandsfree.reportCmeError(BluetoothCmeError.OPERATION_NOT_ALLOWED);
    }

    // More sanity checks
    // Send OK instead of ERROR if these checks fail.
    // When we send error, certain kits like BMW disconnect the
    // Handsfree connection.
    if (SystemProperties.BLUETI_ENHANCEMENT) {
      if (pbr.cursor.getCount() == 0
          || mCpbrIndex1 <= 0
          || mCpbrIndex2 < mCpbrIndex1
          || mCpbrIndex1 > pbr.cursor.getCount()) {
        return new AtCommandResult(AtCommandResult.OK);
      }
    } else {
      if (pbr.cursor.getCount() == 0
          || mCpbrIndex1 <= 0
          || mCpbrIndex2 < mCpbrIndex1
          || mCpbrIndex2 > pbr.cursor.getCount()
          || mCpbrIndex1 > pbr.cursor.getCount()) {
        return new AtCommandResult(AtCommandResult.OK);
      }
    }

    if (SystemProperties.BLUETI_ENHANCEMENT) {
      /* If index2 is more then what we currentely have in our device
       * We will return only the ones that we have and not just AT->OK
       */
      if (mCpbrIndex2 > pbr.cursor.getCount()) {
        Log.d(
            TAG,
            "mCpbrIndex2 is: "
                + mCpbrIndex2
                + " its more then we actually got : "
                + pbr.cursor.getCount());
        Log.d(TAG, "Returning only what we got : " + pbr.cursor.getCount());
        mCpbrIndex2 = pbr.cursor.getCount();
      }
    }

    // Process
    AtCommandResult result = new AtCommandResult(AtCommandResult.OK);
    int errorDetected = -1; // no error
    pbr.cursor.moveToPosition(mCpbrIndex1 - 1);
    for (int index = mCpbrIndex1; index <= mCpbrIndex2; index++) {
      String number = pbr.cursor.getString(pbr.numberColumn);
      String name = null;
      int type = -1;
      if (pbr.nameColumn == -1) {
        // try caller id lookup
        // TODO: This code is horribly inefficient. I saw it
        // take 7 seconds to process 100 missed calls.
        Cursor c =
            mContext
                .getContentResolver()
                .query(
                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number),
                    new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup.TYPE},
                    null,
                    null,
                    null);
        if (c != null) {
          if (c.moveToFirst()) {
            name = c.getString(0);
            type = c.getInt(1);
          }
          c.close();
        }
        if (DBG && name == null) log("Caller ID lookup failed for " + number);

      } else {
        name = pbr.cursor.getString(pbr.nameColumn);
      }
      if (name == null) name = "";
      name = name.trim();
      if (name.length() > 28) name = name.substring(0, 28);

      if (pbr.typeColumn != -1) {
        type = pbr.cursor.getInt(pbr.typeColumn);
        name = name + "/" + getPhoneType(type);
      }

      if (number == null) number = "";
      int regionType = PhoneNumberUtils.toaFromString(number);

      number = number.trim();
      number = PhoneNumberUtils.stripSeparators(number);
      if (number.length() > 30) number = number.substring(0, 30);
      if (number.equals("-1")) {
        // unknown numbers are stored as -1 in our database
        number = "";
        name = mContext.getString(R.string.unknown);
      }

      // TODO(): Handle IRA commands. It's basically
      // a 7 bit ASCII character set.
      if (!name.equals("") && mCharacterSet.equals("GSM")) {
        byte[] nameByte = GsmAlphabet.stringToGsm8BitPacked(name);
        if (nameByte == null) {
          name = mContext.getString(R.string.unknown);
        } else {
          name = new String(nameByte);
        }
      }

      result.addResponse(
          "+CPBR: " + index + ",\"" + number + "\"," + regionType + ",\"" + name + "\"");
      if (!pbr.cursor.moveToNext()) {
        break;
      }
    }
    return result;
  }
  // process CPBR command after permission check
  /*package*/ int processCpbrCommand() {
    log("processCpbrCommand");
    int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR;
    int atCommandErrorCode = -1;
    String atCommandResponse = null;
    StringBuilder response = new StringBuilder();
    String record;

    // Shortcut SM phonebook
    if ("SM".equals(mCurrentPhonebook)) {
      atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK;
      return atCommandResult;
    }

    // Check phonebook
    PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, true); // false);
    if (pbr == null) {
      atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_ALLOWED;
      return atCommandResult;
    }

    // More sanity checks
    // Send OK instead of ERROR if these checks fail.
    // When we send error, certain kits like BMW disconnect the
    // Handsfree connection.
    if (pbr.cursor.getCount() == 0
        || mCpbrIndex1 <= 0
        || mCpbrIndex2 < mCpbrIndex1
        || mCpbrIndex2 > pbr.cursor.getCount()
        || mCpbrIndex1 > pbr.cursor.getCount()) {
      atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK;
      return atCommandResult;
    }

    // Process
    atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK;
    int errorDetected = -1; // no error
    pbr.cursor.moveToPosition(mCpbrIndex1 - 1);
    log("mCpbrIndex1 = " + mCpbrIndex1 + " and mCpbrIndex2 = " + mCpbrIndex2);
    for (int index = mCpbrIndex1; index <= mCpbrIndex2; index++) {
      String number = pbr.cursor.getString(pbr.numberColumn);
      String name = null;
      int type = -1;
      if (pbr.nameColumn == -1 && number != null && number.length() > 0) {
        // try caller id lookup
        // TODO: This code is horribly inefficient. I saw it
        // take 7 seconds to process 100 missed calls.
        Cursor c =
            mContentResolver.query(
                Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number),
                new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup.TYPE},
                null,
                null,
                null);
        if (c != null) {
          if (c.moveToFirst()) {
            name = c.getString(0);
            type = c.getInt(1);
          }
          c.close();
        }
        if (DBG && name == null) log("Caller ID lookup failed for " + number);

      } else if (pbr.nameColumn != -1) {
        name = pbr.cursor.getString(pbr.nameColumn);
      } else {
        log("processCpbrCommand: empty name and number");
      }
      if (name == null) name = "";
      name = name.trim();
      if (name.length() > 28) name = name.substring(0, 28);

      if (pbr.typeColumn != -1) {
        type = pbr.cursor.getInt(pbr.typeColumn);
        name = name + "/" + getPhoneType(type);
      }

      if (number == null) number = "";
      int regionType = PhoneNumberUtils.toaFromString(number);

      number = number.trim();
      number = PhoneNumberUtils.stripSeparators(number);
      if (number.length() > 30) number = number.substring(0, 30);
      int numberPresentation = Calls.PRESENTATION_ALLOWED;
      if (pbr.numberPresentationColumn != -1) {
        numberPresentation = pbr.cursor.getInt(pbr.numberPresentationColumn);
      }
      if (numberPresentation != Calls.PRESENTATION_ALLOWED) {
        number = "";
        // TODO: there are 3 types of numbers should have resource
        // strings for: unknown, private, and payphone
        name = mContext.getString(R.string.unknownNumber);
      }

      // TODO(): Handle IRA commands. It's basically
      // a 7 bit ASCII character set.
      if (!name.equals("") && mCharacterSet.equals("GSM")) {
        byte[] nameByte = GsmAlphabet.stringToGsm8BitPacked(name);
        if (nameByte == null) {
          name = mContext.getString(R.string.unknownNumber);
        } else {
          name = new String(nameByte);
        }
      }

      record = "+CPBR: " + index + ",\"" + number + "\"," + regionType + ",\"" + name + "\"";
      record = record + "\r\n\r\n";
      atCommandResponse = record;
      log("processCpbrCommand - atCommandResponse = " + atCommandResponse);
      mStateMachine.atResponseStringNative(atCommandResponse);
      if (!pbr.cursor.moveToNext()) {
        break;
      }
    }
    if (pbr != null && pbr.cursor != null) {
      pbr.cursor.close();
      pbr.cursor = null;
    }
    return atCommandResult;
  }