Пример #1
0
 public void handleCpbsCommand(String atString, int type) {
   // Select PhoneBook memory Storage
   log("handleCpbsCommand - atString = " + atString);
   int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR;
   int atCommandErrorCode = -1;
   String atCommandResponse = null;
   switch (type) {
     case TYPE_READ: // Read
       log("handleCpbsCommand - read command");
       // Return current size and max size
       if ("SM".equals(mCurrentPhonebook)) {
         atCommandResponse = "+CPBS: \"SM\",0," + getMaxPhoneBookSize(0);
         atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK;
         break;
       }
       PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, true);
       if (pbr == null) {
         atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_SUPPORTED;
         break;
       }
       int size = pbr.cursor.getCount();
       atCommandResponse =
           "+CPBS: \"" + mCurrentPhonebook + "\"," + size + "," + getMaxPhoneBookSize(size);
       pbr.cursor.close();
       pbr.cursor = null;
       atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK;
       break;
     case TYPE_TEST: // Test
       log("handleCpbsCommand - test command");
       atCommandResponse = ("+CPBS: (\"ME\",\"SM\",\"DC\",\"RC\",\"MC\")");
       atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK;
       break;
     case TYPE_SET: // Set
       log("handleCpbsCommand - set command");
       String[] args = atString.split("=");
       // Select phonebook memory
       if (args.length < 2 || !(args[1] instanceof String)) {
         atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_SUPPORTED;
         break;
       }
       String pb = ((String) args[1]).trim();
       while (pb.endsWith("\"")) pb = pb.substring(0, pb.length() - 1);
       while (pb.startsWith("\"")) pb = pb.substring(1, pb.length());
       if (getPhonebookResult(pb, false) == null && !"SM".equals(pb)) {
         if (DBG) log("Dont know phonebook: '" + pb + "'");
         atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_ALLOWED;
         break;
       }
       mCurrentPhonebook = pb;
       atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK;
       break;
     case TYPE_UNKNOWN:
     default:
       log("handleCpbsCommand - invalid chars");
       atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS;
   }
   if (atCommandResponse != null) mStateMachine.atResponseStringNative(atCommandResponse);
   mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode);
 }
Пример #2
0
  private synchronized boolean queryPhonebook(String pb, PhonebookResult pbr) {
    String where;
    boolean ancillaryPhonebook = true;

    if (pb.equals("ME")) {
      ancillaryPhonebook = false;
      where = VISIBLE_PHONEBOOK_WHERE;
    } else if (pb.equals("DC")) {
      where = OUTGOING_CALL_WHERE;
    } else if (pb.equals("RC")) {
      where = INCOMING_CALL_WHERE;
    } else if (pb.equals("MC")) {
      where = MISSED_CALL_WHERE;
    } else {
      return false;
    }

    if (pbr.cursor != null) {
      pbr.cursor.close();
      pbr.cursor = null;
    }

    if (ancillaryPhonebook) {
      pbr.cursor =
          mContext
              .getContentResolver()
              .query(
                  Calls.CONTENT_URI,
                  CALLS_PROJECTION,
                  where,
                  null,
                  Calls.DEFAULT_SORT_ORDER + " LIMIT " + MAX_PHONEBOOK_SIZE);
      if (pbr.cursor == null) return false;

      pbr.numberColumn = pbr.cursor.getColumnIndexOrThrow(Calls.NUMBER);
      pbr.typeColumn = -1;
      pbr.nameColumn = -1;
    } else {
      pbr.cursor =
          mContext
              .getContentResolver()
              .query(
                  Phone.CONTENT_URI,
                  PHONES_PROJECTION,
                  where,
                  null,
                  Phone.NUMBER + " LIMIT " + MAX_PHONEBOOK_SIZE);
      if (pbr.cursor == null) return false;

      pbr.numberColumn = pbr.cursor.getColumnIndex(Phone.NUMBER);
      pbr.typeColumn = pbr.cursor.getColumnIndex(Phone.TYPE);
      pbr.nameColumn = pbr.cursor.getColumnIndex(Phone.DISPLAY_NAME);
    }
    Log.i(TAG, "Refreshed phonebook " + pb + " with " + pbr.cursor.getCount() + " results");
    return true;
  }
Пример #3
0
  // 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;
  }
Пример #4
0
  public void handleCpbrCommand(String atString, int type, BluetoothDevice remoteDevice) {
    log("handleCpbrCommand - atString = " + atString);
    int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR;
    int atCommandErrorCode = -1;
    String atCommandResponse = null;
    switch (type) {
      case TYPE_TEST: // Test
        /* Ideally we should return the maximum range of valid index's
         * for the selected phone book, but this causes problems for the
         * Parrot CK3300. So instead send just the range of currently
         * valid index's.
         */
        log("handleCpbrCommand - test command");
        int size;
        if ("SM".equals(mCurrentPhonebook)) {
          size = 0;
        } else {
          PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, true); // false);
          if (pbr == null) {
            atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_ALLOWED;
            break;
          }
          size = pbr.cursor.getCount();
          log("handleCpbrCommand - size = " + size);
          pbr.cursor.close();
          pbr.cursor = null;
        }
        if (size == 0) {
          /* Sending "+CPBR: (1-0)" can confused some carkits, send "1-1" * instead */
          size = 1;
        }
        atCommandResponse = "+CPBR: (1-" + size + "),30,30";
        atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK;
        break;
        // Read PhoneBook Entries
      case TYPE_READ:
      case TYPE_SET: // Set & read
        // Phone Book Read Request
        // AT+CPBR=<index1>[,<index2>]
        log("handleCpbrCommand - set/read command");
        if (mCpbrIndex1 != -1) {
          /* handling a CPBR at the moment, reject this CPBR command */
          atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_ALLOWED;
          break;
        }
        // Parse indexes
        int index1;
        int index2;
        if ((atString.split("=")).length < 2) {
          mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode);
          break;
        }
        String atCommand = (atString.split("="))[1];
        String[] indices = atCommand.split(",");
        for (int i = 0; i < indices.length; i++)
          // replace AT command separator ';' from the index if any
          indices[i] = indices[i].replace(';', ' ').trim();
        try {
          index1 = Integer.parseInt(indices[0]);
          if (indices.length == 1) index2 = index1;
          else index2 = Integer.parseInt(indices[1]);
        } catch (Exception e) {
          log("handleCpbrCommand - exception - invalid chars: " + e.toString());
          atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS;
          mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode);
          break;
        }
        mCpbrIndex1 = index1;
        mCpbrIndex2 = index2;
        mCheckingAccessPermission = true;

        if (checkAccessPermission(remoteDevice)) {
          mCheckingAccessPermission = false;
          atCommandResult = processCpbrCommand();
          mCpbrIndex1 = mCpbrIndex2 = -1;
          break;
        }
        // no reponse here, will continue the process in handleAccessPermissionResult
        break;
      case TYPE_UNKNOWN:
      default:
        log("handleCpbrCommand - invalid chars");
        atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS;
    }
    if (atCommandResponse != null) mStateMachine.atResponseStringNative(atCommandResponse);
    mStateMachine.atResponseCodeNative(atCommandResult, atCommandErrorCode);
  }