/** {@inheritDoc} */
  protected void sendSms(SmsTracker tracker) {
    HashMap map = tracker.mData;

    byte smsc[] = (byte[]) map.get("smsc");
    byte pdu[] = (byte[]) map.get("pdu");

    Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
    mCm.sendSMS(IccUtils.bytesToHexString(smsc), IccUtils.bytesToHexString(pdu), reply);
  }
  /**
   * Called when a status report is received. This should correspond to a previously successful
   * SEND.
   *
   * @param ar AsyncResult passed into the message handler. ar.result should be a String
   *     representing the status report PDU, as ASCII hex.
   */
  protected void handleStatusReport(AsyncResult ar) {
    String pduString = (String) ar.result;
    SmsMessage sms = SmsMessage.newFromCDS(pduString);

    if (sms != null) {
      int tpStatus = sms.getStatus();
      int messageRef = sms.messageRef;
      for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
        SmsTracker tracker = deliveryPendingList.get(i);
        if (tracker.mMessageRef == messageRef) {
          // Found it.  Remove from list and broadcast.
          if (tpStatus >= Sms.STATUS_FAILED || tpStatus < Sms.STATUS_PENDING) {
            deliveryPendingList.remove(i);
          }
          PendingIntent intent = tracker.mDeliveryIntent;
          Intent fillIn = new Intent();
          fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString));
          try {
            intent.send(mContext, Activity.RESULT_OK, fillIn);
          } catch (CanceledException ex) {
          }

          // Only expect to see one tracker matching this messageref
          break;
        }
      }
    }
    acknowledgeLastIncomingSms(true, Intents.RESULT_SMS_HANDLED, null);
  }
 private byte[] buildAnrData(int length, int adnRecIndex, String anr) {
   byte[] data = new byte[length];
   for (int i = 0; i < length; i++) {
     data[i] = (byte) 0xff;
   }
   if (TextUtils.isEmpty(anr)) {
     Log.w(LOG_TAG, "[buildAnrData] Empty anr record");
     return data; // return the empty record (for delete)
   }
   data[ANR_DESCRIPTION_ID] = (byte) (0x0);
   byte[] byteAnr = PhoneNumberUtils.numberToCalledPartyBCD(anr);
   int maxlength = ANR_ADDITIONAL_NUMBER_END_ID - ANR_ADDITIONAL_NUMBER_START_ID + 1;
   if (byteAnr.length > maxlength) {
     System.arraycopy(byteAnr, 0, data, ANR_TON_NPI_ID, maxlength);
     data[ANR_BCD_NUMBER_LENGTH] = (byte) (maxlength);
   } else {
     System.arraycopy(byteAnr, 0, data, ANR_TON_NPI_ID, byteAnr.length);
     data[ANR_BCD_NUMBER_LENGTH] = (byte) (byteAnr.length);
   }
   data[ANR_CAPABILITY_ID] = (byte) 0xFF;
   data[ANR_EXTENSION_ID] = (byte) 0xFF;
   if (length == 17) {
     // TODO: should update the SFI at the same time???
     int pbrIndex = getPbrIndexBy(adnRecIndex);
     int recordIndex = adnRecIndex - getInitIndexBy(pbrIndex);
     data[ANR_ADN_RECORD_IDENTIFIER_ID] = (byte) (recordIndex + 1);
   }
   Log.w(LOG_TAG, " buildAnrData: data is" + IccUtils.bytesToHexString(data));
   return data;
 }
  private String readEmailRecord(int recNum, int pbrIndex) {
    byte[] emailRec = null;
    if (!hasRecordIn(mEmailFileRecord, pbrIndex)) return null;
    try {
      emailRec = mEmailFileRecord.get(pbrIndex).get(recNum);
    } catch (IndexOutOfBoundsException e) {
      return null;
    }

    // The length of the record is X+2 byte, where X bytes is the email address
    String email = IccUtils.adnStringFieldToString(emailRec, 0, emailRec.length - 2);
    return email;
  }
 private byte[] buildEmailData(int length, int adnRecIndex, String email) {
   byte[] data = new byte[length];
   for (int i = 0; i < length; i++) {
     data[i] = (byte) 0xff;
   }
   if (TextUtils.isEmpty(email)) {
     Log.w(LOG_TAG, "[buildEmailData] Empty email record");
     return data; // return the empty record (for delete)
   }
   byte[] byteEmail = GsmAlphabet.stringToGsm8BitPacked(email);
   System.arraycopy(byteEmail, 0, data, 0, byteEmail.length);
   int pbrIndex = getPbrIndexBy(adnRecIndex);
   int recordIndex = adnRecIndex - getInitIndexBy(pbrIndex);
   if (mEmailPresentInIap) {
     data[length - 1] = (byte) (recordIndex + 1);
   }
   Log.w(LOG_TAG, " buildEmailData: data is" + IccUtils.bytesToHexString(data));
   return data;
 }
  @Override
  protected Object responseCallList(Parcel p) {
    int num;
    int voiceSettings;
    ArrayList<DriverCall> response;
    DriverCall dc;
    int dataAvail = p.dataAvail();
    int pos = p.dataPosition();
    int size = p.dataSize();

    Log.d(LOG_TAG, "Parcel size = " + size);
    Log.d(LOG_TAG, "Parcel pos = " + pos);
    Log.d(LOG_TAG, "Parcel dataAvail = " + dataAvail);

    // Samsung f****d up here

    num = p.readInt();

    Log.d(LOG_TAG, "num = " + num);
    response = new ArrayList<DriverCall>(num);

    for (int i = 0; i < num; i++) {
      if (mIsSamsungCdma) dc = new SamsungDriverCall();
      else dc = new DriverCall();

      dc.state = DriverCall.stateFromCLCC(p.readInt());
      Log.d(LOG_TAG, "state = " + dc.state);
      dc.index = p.readInt();
      Log.d(LOG_TAG, "index = " + dc.index);
      dc.TOA = p.readInt();
      Log.d(LOG_TAG, "state = " + dc.TOA);
      dc.isMpty = (0 != p.readInt());
      Log.d(LOG_TAG, "isMpty = " + dc.isMpty);
      dc.isMT = (0 != p.readInt());
      Log.d(LOG_TAG, "isMT = " + dc.isMT);
      dc.als = p.readInt();
      Log.d(LOG_TAG, "als = " + dc.als);
      voiceSettings = p.readInt();
      dc.isVoice = (0 == voiceSettings) ? false : true;
      Log.d(LOG_TAG, "isVoice = " + dc.isVoice);
      dc.isVoicePrivacy = (0 != p.readInt());
      // Some Samsung magic data for Videocalls
      voiceSettings = p.readInt();
      // printing it to cosole for later investigation
      Log.d(LOG_TAG, "Samsung magic = " + voiceSettings);
      dc.number = p.readString();
      Log.d(LOG_TAG, "number = " + dc.number);
      int np = p.readInt();
      Log.d(LOG_TAG, "np = " + np);
      dc.numberPresentation = DriverCall.presentationFromCLIP(np);
      dc.name = p.readString();
      Log.d(LOG_TAG, "name = " + dc.name);
      dc.namePresentation = p.readInt();
      Log.d(LOG_TAG, "namePresentation = " + dc.namePresentation);
      int uusInfoPresent = p.readInt();
      Log.d(LOG_TAG, "uusInfoPresent = " + uusInfoPresent);

      if (uusInfoPresent == 1) {
        dc.uusInfo = new UUSInfo();
        dc.uusInfo.setType(p.readInt());
        dc.uusInfo.setDcs(p.readInt());
        byte[] userData = p.createByteArray();
        dc.uusInfo.setUserData(userData);
        Log.v(
            LOG_TAG,
            String.format(
                "Incoming UUS : type=%d, dcs=%d, length=%d",
                dc.uusInfo.getType(), dc.uusInfo.getDcs(), dc.uusInfo.getUserData().length));
        Log.v(LOG_TAG, "Incoming UUS : data (string)=" + new String(dc.uusInfo.getUserData()));
        Log.v(
            LOG_TAG,
            "Incoming UUS : data (hex): " + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
      } else {
        Log.v(LOG_TAG, "Incoming UUS : NOT present!");
      }

      // Make sure there's a leading + on addresses with a TOA of 145
      dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);

      response.add(dc);

      if (dc.isVoicePrivacy) {
        mVoicePrivacyOnRegistrants.notifyRegistrants();
        Log.d(LOG_TAG, "InCall VoicePrivacy is enabled");
      } else {
        mVoicePrivacyOffRegistrants.notifyRegistrants();
        Log.d(LOG_TAG, "InCall VoicePrivacy is disabled");
      }
    }

    Collections.sort(response);

    return response;
  }
  @Override
  protected void processUnsolicited(Parcel p) {
    int response;
    Object ret;

    response = p.readInt();

    try {
      switch (response) {
          /*
          cat libs/telephony/ril_unsol_commands.h \
          | egrep "^ *{RIL_" \
          | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
               */

        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_RESPONSE_NEW_SMS:
          ret = responseString(p);
          break;
        case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
          ret = responseString(p);
          break;
        case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
          ret = responseInts(p);
          break;
        case RIL_UNSOL_ON_USSD:
          ret = responseStrings(p);
          break;
        case RIL_UNSOL_NITZ_TIME_RECEIVED:
          ret = responseString(p);
          break;
        case RIL_UNSOL_SIGNAL_STRENGTH:
          ret = responseSignalStrength(p);
          break;
        case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
          ret = responseDataCallList(p);
          break;
        case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
          ret = responseSuppServiceNotification(p);
          break;
        case RIL_UNSOL_STK_SESSION_END:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_STK_PROACTIVE_COMMAND:
          ret = responseString(p);
          break;
        case RIL_UNSOL_STK_EVENT_NOTIFY:
          ret = responseString(p);
          break;
        case RIL_UNSOL_STK_CALL_SETUP:
          ret = responseInts(p);
          break;
        case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_SIM_REFRESH:
          ret = responseInts(p);
          break;
        case RIL_UNSOL_CALL_RING:
          ret = responseCallRing(p);
          break;
        case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
          ret = responseInts(p);
          break;
        case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
          ret = responseCdmaSms(p);
          break;
        case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
          ret = responseString(p);
          break;
        case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_CDMA_CALL_WAITING:
          ret = responseCdmaCallWaiting(p);
          break;
        case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
          ret = responseInts(p);
          break;
        case RIL_UNSOL_CDMA_INFO_REC:
          ret = responseCdmaInformationRecord(p);
          break;
        case RIL_UNSOL_OEM_HOOK_RAW:
          ret = responseRaw(p);
          break;
        case RIL_UNSOL_RINGBACK_TONE:
          ret = responseInts(p);
          break;
        case RIL_UNSOL_RESEND_INCALL_MUTE:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_HSDPA_STATE_CHANGED:
          ret = responseVoid(p);
          break;

          // fixing anoying Exceptions caused by the new Samsung states
          // FIXME figure out what the states mean an what data is in the parcel

        case RIL_UNSOL_O2_HOME_ZONE_INFO:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_STK_SEND_SMS_RESULT:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_DEVICE_READY_NOTI:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_2:
          ret = responseVoid(p);
          break;
        case RIL_UNSOL_SAMSUNG_UNKNOWN_MAGIC_REQUEST_3:
          ret = responseVoid(p);
          break;

        default:
          throw new RuntimeException("Unrecognized unsol response: " + response);
          // break; (implied)
      }
    } catch (Throwable tr) {
      Log.e(
          LOG_TAG,
          "Exception processing unsol response: " + response + "Exception:" + tr.toString());
      return;
    }

    switch (response) {
      case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
        /* has bonus radio state int */
        RadioState newState = getRadioStateFromInt(p.readInt());
        if (RILJ_LOGD) unsljLogMore(response, newState.toString());

        switchToRadioState(newState);
        break;
      case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
        if (RILJ_LOGD) unsljLog(response);

        mCallStateRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
        break;
      case RIL_UNSOL_HSDPA_STATE_CHANGED:
        if (RILJ_LOGD) unsljLog(response);

        mVoiceNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
        break;

      case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
        if (RILJ_LOGD) unsljLog(response);

        mVoiceNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
        break;
      case RIL_UNSOL_RESPONSE_NEW_SMS:
        {
          if (RILJ_LOGD) unsljLog(response);

          // FIXME this should move up a layer
          String a[] = new String[2];

          a[1] = (String) ret;

          SmsMessage sms;

          sms = SmsMessage.newFromCMT(a);
          if (mGsmSmsRegistrant != null) {
            mGsmSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
          }
          break;
        }
      case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mSmsStatusRegistrant != null) {
          mSmsStatusRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;
      case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        int[] smsIndex = (int[]) ret;

        if (smsIndex.length == 1) {
          if (mSmsOnSimRegistrant != null) {
            mSmsOnSimRegistrant.notifyRegistrant(new AsyncResult(null, smsIndex, null));
          }
        } else {
          if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length " + smsIndex.length);
        }
        break;
      case RIL_UNSOL_ON_USSD:
        String[] resp = (String[]) ret;

        if (resp.length < 2) {
          resp = new String[2];
          resp[0] = ((String[]) ret)[0];
          resp[1] = null;
        }
        if (RILJ_LOGD) unsljLogMore(response, resp[0]);
        if (mUSSDRegistrant != null) {
          mUSSDRegistrant.notifyRegistrant(new AsyncResult(null, resp, null));
        }
        break;
      case RIL_UNSOL_NITZ_TIME_RECEIVED:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        // has bonus long containing milliseconds since boot that the NITZ
        // time was received
        long nitzReceiveTime = p.readLong();

        Object[] result = new Object[2];

        String nitz = (String) ret;
        if (RILJ_LOGD)
          riljLog(" RIL_UNSOL_NITZ_TIME_RECEIVED length = " + nitz.split("[/:,+-]").length);
        // remove the tailing information that samsung added to the string
        // it will screw the NITZ parser
        if (nitz.split("[/:,+-]").length >= 9) nitz = nitz.substring(0, (nitz.lastIndexOf(",")));
        if (RILJ_LOGD) riljLog(" RIL_UNSOL_NITZ_TIME_RECEIVED striped nitz = " + nitz);
        result[0] = nitz;
        result[1] = Long.valueOf(nitzReceiveTime);

        if (mNITZTimeRegistrant != null) {

          mNITZTimeRegistrant.notifyRegistrant(new AsyncResult(null, result, null));
        } else {
          // in case NITZ time registrant isnt registered yet
          mLastNITZTimeInfo = nitz;
        }
        break;

      case RIL_UNSOL_SIGNAL_STRENGTH:
        // Note this is set to "verbose" because it happens
        // frequently
        if (RILJ_LOGV) unsljLogvRet(response, ret);

        if (mSignalStrengthRegistrant != null) {
          mSignalStrengthRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;
      case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
        break;

      case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mSsnRegistrant != null) {
          mSsnRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_STK_SESSION_END:
        if (RILJ_LOGD) unsljLog(response);

        if (mCatSessionEndRegistrant != null) {
          mCatSessionEndRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_STK_PROACTIVE_COMMAND:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mCatProCmdRegistrant != null) {
          mCatProCmdRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_STK_EVENT_NOTIFY:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mCatEventRegistrant != null) {
          mCatEventRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_STK_CALL_SETUP:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mCatCallSetUpRegistrant != null) {
          mCatCallSetUpRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
        if (RILJ_LOGD) unsljLog(response);

        if (mIccSmsFullRegistrant != null) {
          mIccSmsFullRegistrant.notifyRegistrant();
        }
        break;

      case RIL_UNSOL_SIM_REFRESH:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mIccRefreshRegistrants != null) {
          mIccRefreshRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_CALL_RING:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mRingRegistrant != null) {
          mRingRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
        if (RILJ_LOGD) unsljLogvRet(response, ret);
        if (mRestrictedStateRegistrant != null) {
          mRestrictedStateRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
        if (RILJ_LOGD) unsljLog(response);

        if (mIccStatusChangedRegistrants != null) {
          mIccStatusChangedRegistrants.notifyRegistrants();
        }
        break;

      case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
        if (RILJ_LOGD) unsljLog(response);

        SmsMessage sms = (SmsMessage) ret;

        if (mCdmaSmsRegistrant != null) {
          mCdmaSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
        }
        break;

      case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
        if (RILJ_LOGD) unsljLog(response);

        if (mGsmBroadcastSmsRegistrant != null) {
          mGsmBroadcastSmsRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
        if (RILJ_LOGD) unsljLog(response);

        if (mIccSmsFullRegistrant != null) {
          mIccSmsFullRegistrant.notifyRegistrant();
        }
        break;

      case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
        if (RILJ_LOGD) unsljLog(response);

        if (mEmergencyCallbackModeRegistrant != null) {
          mEmergencyCallbackModeRegistrant.notifyRegistrant();
        }
        break;

      case RIL_UNSOL_CDMA_CALL_WAITING:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mCallWaitingInfoRegistrants != null) {
          mCallWaitingInfoRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mOtaProvisionRegistrants != null) {
          mOtaProvisionRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_CDMA_INFO_REC:
        ArrayList<CdmaInformationRecords> listInfoRecs;

        try {
          listInfoRecs = (ArrayList<CdmaInformationRecords>) ret;
        } catch (ClassCastException e) {
          Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
          break;
        }

        for (CdmaInformationRecords rec : listInfoRecs) {
          if (RILJ_LOGD) unsljLogRet(response, rec);
          notifyRegistrantsCdmaInfoRec(rec);
        }
        break;

      case RIL_UNSOL_OEM_HOOK_RAW:
        if (RILJ_LOGD) unsljLogvRet(response, IccUtils.bytesToHexString((byte[]) ret));
        if (mUnsolOemHookRawRegistrant != null) {
          mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
        }
        break;

      case RIL_UNSOL_RINGBACK_TONE:
        if (RILJ_LOGD) unsljLogvRet(response, ret);
        if (mRingbackToneRegistrants != null) {
          boolean playtone = (((int[]) ret)[0] == 1);
          mRingbackToneRegistrants.notifyRegistrants(new AsyncResult(null, playtone, null));
        }
        break;

      case RIL_UNSOL_RESEND_INCALL_MUTE:
        if (RILJ_LOGD) unsljLogRet(response, ret);

        if (mResendIncallMuteRegistrants != null) {
          mResendIncallMuteRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
        }
    }
  }
  @DSSafe(DSCat.IPC_CALLBACK)
  @DSGenerator(
      tool_name = "Doppelganger",
      tool_version = "2.0",
      generated_on = "2013-12-30 12:58:54.915 -0500",
      hash_original_method = "584E0C361321C2DCD1B11D8CE97AF6DF",
      hash_generated_method = "CAF5DAE398870082803BAF9A29AA061A")
  @Override
  public void handleMessage(Message msg) {
    AsyncResult ar;

    byte data[];

    boolean isRecordLoadResponse = false;

    try {
      switch (msg.what) {
        case EVENT_RUIM_READY:
          onRuimReady();
          break;

        case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
          onRadioOffOrNotAvailable();
          break;

        case EVENT_GET_DEVICE_IDENTITY_DONE:
          Log.d(LOG_TAG, "Event EVENT_GET_DEVICE_IDENTITY_DONE Received");
          break;

          /* IO events */
        case EVENT_GET_IMSI_DONE:
          isRecordLoadResponse = true;

          ar = (AsyncResult) msg.obj;
          if (ar.exception != null) {
            Log.e(LOG_TAG, "Exception querying IMSI, Exception:" + ar.exception);
            break;
          }

          mImsi = (String) ar.result;

          // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
          // than 15 (and usually 15).
          if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
            Log.e(LOG_TAG, "invalid IMSI " + mImsi);
            mImsi = null;
          }

          Log.d(LOG_TAG, "IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx");

          String operatorNumeric = getRUIMOperatorNumeric();
          if (operatorNumeric != null) {
            if (operatorNumeric.length() <= 6) {
              MccTable.updateMccMncConfiguration(phone, operatorNumeric);
            }
          }
          break;

        case EVENT_GET_CDMA_SUBSCRIPTION_DONE:
          ar = (AsyncResult) msg.obj;
          String localTemp[] = (String[]) ar.result;
          if (ar.exception != null) {
            break;
          }

          mMyMobileNumber = localTemp[0];
          mMin2Min1 = localTemp[3];
          mPrlVersion = localTemp[4];

          Log.d(LOG_TAG, "MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1);

          break;

        case EVENT_GET_ICCID_DONE:
          isRecordLoadResponse = true;

          ar = (AsyncResult) msg.obj;
          data = (byte[]) ar.result;

          if (ar.exception != null) {
            break;
          }

          iccid = IccUtils.bcdToString(data, 0, data.length);

          Log.d(LOG_TAG, "iccid: " + iccid);

          break;

        case EVENT_UPDATE_DONE:
          ar = (AsyncResult) msg.obj;
          if (ar.exception != null) {
            Log.i(LOG_TAG, "RuimRecords update failed", ar.exception);
          }
          break;

        case EVENT_GET_ALL_SMS_DONE:
        case EVENT_MARK_SMS_READ_DONE:
        case EVENT_SMS_ON_RUIM:
        case EVENT_GET_SMS_DONE:
          Log.w(LOG_TAG, "Event not supported: " + msg.what);
          break;

          // TODO: probably EF_CST should be read instead
        case EVENT_GET_SST_DONE:
          Log.d(LOG_TAG, "Event EVENT_GET_SST_DONE Received");
          break;

        case EVENT_RUIM_REFRESH:
          isRecordLoadResponse = false;
          ar = (AsyncResult) msg.obj;
          if (ar.exception == null) {
            handleRuimRefresh((int[]) (ar.result));
          }
          break;
      }
    } catch (RuntimeException exc) {
      // I don't want these exceptions to be fatal
      Log.w(LOG_TAG, "Exception parsing RUIM record", exc);
    } finally {
      // Count up record load responses even if they are fails
      if (isRecordLoadResponse) {
        onRecordLoaded();
      }
    }
  }
 @Override
 public void handleMessage(Message msg) {
   AsyncResult ar = (AsyncResult) msg.obj;
   switch (msg.what) {
     case ADDLOCK_ICC_SML_COMPLETE:
       if (ar.exception != null) {
         showDialog(DIALOG_ADDLOCKFAIL);
       } else {
         showDialog(DIALOG_ADDLOCKSUCCEED);
       }
       break;
     case EVENT_GET_SIM_GID1:
       if (ar.exception != null) {
         log("fail to get SIM GID1");
         mSimGid1Valid = false;
       } else {
         log("succeed to get SIM GID1");
         byte[] data = (byte[]) (ar.result);
         log("SIM GID :" + data);
         String hexSIMGID1 = IccUtils.bytesToHexString(data);
         if ((data[0] & 0xff) == 0xff) {
           log("SIM GID1 not initialized");
           mSimGid1Valid = false;
         } else {
           mSimGid1Valid = true;
           if (hexSIMGID1.length() >= 2) {
             mSimGid1 = String.valueOf(Integer.parseInt(hexSIMGID1.substring(0, 2)));
           } else {
             mSimGid1 = String.valueOf(Integer.parseInt(hexSIMGID1));
           }
           log("Normal SIM GID1 :" + mSimGid1);
         }
       }
       break;
     case EVENT_GET_SIM_GID2:
       if (ar.exception != null) {
         log("fail to get SIM GID2");
         mSimGid2Valid = false;
       } else {
         log("succeed to get SIM GID2");
         byte[] data = (byte[]) (ar.result);
         log("SIM GID2 :" + data);
         String hexSIMGID2 = IccUtils.bytesToHexString(data);
         if ((data[0] & 0xff) == 0xff) {
           log("SIM GID2 not initialized");
           mSimGid2Valid = false;
         } else {
           mSimGid2Valid = true;
           if (hexSIMGID2.length() >= 2) {
             mSimGid2 = String.valueOf(Integer.parseInt(hexSIMGID2.substring(0, 2)));
           } else {
             mSimGid2 = String.valueOf(Integer.parseInt(hexSIMGID2));
           }
           log("Normal SIM GID2 :" + mSimGid2);
         }
       }
       break;
     default:
       break;
   }
 }
  @Override
  public void handleMessage(Message msg) {
    AsyncResult ar;
    byte data[];
    int efid;
    int adnRecIndex;
    int recordIndex;
    int[] recordSize;
    int recordNumber;
    String oldAnr = null;
    String newAnr = null;
    String oldEmail = null;
    String newEmail = null;
    Message response = null;
    int pbrIndex;

    switch (msg.what) {
      case EVENT_PBR_LOAD_DONE:
        ar = (AsyncResult) msg.obj;
        if (ar.exception == null) {
          createPbrFile((ArrayList<byte[]>) ar.result);
        }
        synchronized (mLock) {
          mLock.notify();
        }
        break;
      case EVENT_USIM_ADN_LOAD_DONE:
        log("Loading USIM ADN records done");
        ar = (AsyncResult) msg.obj;
        pbrIndex = (Integer) ar.userObj;
        if (ar.exception == null) {
          mPhoneBookRecords.addAll((ArrayList<AdnRecord>) ar.result);
          mAdnLengthList.add(pbrIndex, ((ArrayList<AdnRecord>) ar.result).size());
          putValidRecNums(pbrIndex);
        }
        synchronized (mLock) {
          mLock.notify();
        }
        break;
      case EVENT_IAP_LOAD_DONE:
        log("Loading USIM IAP records done");
        ar = (AsyncResult) msg.obj;
        pbrIndex = (Integer) ar.userObj;
        if (ar.exception == null) {
          mIapFileRecord.put(pbrIndex, (ArrayList<byte[]>) ar.result);
        }
        synchronized (mLock) {
          mLock.notify();
        }
        break;
      case EVENT_EMAIL_LOAD_DONE:
        log("Loading USIM Email records done");
        ar = (AsyncResult) msg.obj;
        pbrIndex = (Integer) ar.userObj;
        if (ar.exception == null) {
          mEmailFileRecord.put(pbrIndex, (ArrayList<byte[]>) ar.result);
        }

        synchronized (mLock) {
          mLock.notify();
        }
        break;
      case EVENT_ANR_LOAD_DONE:
        log("Loading USIM Anr records done");
        ar = (AsyncResult) msg.obj;
        pbrIndex = (Integer) ar.userObj;
        if (ar.exception == null) {
          mAnrFileRecord.put(pbrIndex, (ArrayList<byte[]>) ar.result);
        }
        synchronized (mLock) {
          mLock.notify();
        }
        break;
      case EVENT_EF_EMAIL_RECORD_SIZE_DONE:
        ar = (AsyncResult) (msg.obj);
        String emails = (String) (ar.userObj);
        adnRecIndex = ((int) msg.arg1) - 1;
        efid = (int) msg.arg2;
        String email[] = emails.split(",");
        if (email.length == 1) {
          oldEmail = email[0];
          newEmail = "";
        } else if (email.length > 1) {
          oldEmail = email[0];
          newEmail = email[1];
        }
        if (ar.exception != null) {
          success = false;
          synchronized (mLock) {
            mLock.notify();
          }
          return;
        }
        recordSize = (int[]) ar.result;
        recordNumber = getEmailRecNumber(adnRecIndex, mPhoneBookRecords.size(), oldEmail);
        if (recordSize.length != 3 || recordNumber > recordSize[2] || recordNumber <= 0) {
          success = false;
          synchronized (mLock) {
            mLock.notify();
          }
          return;
        }
        data = buildEmailData(recordSize[0], adnRecIndex, newEmail);
        mFh.updateEFLinearFixed(
            efid,
            recordNumber,
            data,
            null,
            obtainMessage(EVENT_UPDATE_EMAIL_RECORD_DONE, recordNumber, adnRecIndex, data));
        pendingExtLoads = 1;
        break;
      case EVENT_EF_ANR_RECORD_SIZE_DONE:
        ar = (AsyncResult) (msg.obj);
        String anrs = (String) (ar.userObj);
        adnRecIndex = ((int) msg.arg1) - 1;
        efid = (int) msg.arg2;
        String[] anr = anrs.split(",");
        if (anr.length == 1) {
          oldAnr = anr[0];
          newAnr = "";
        } else if (anr.length > 1) {
          oldAnr = anr[0];
          newAnr = anr[1];
        }
        if (ar.exception != null) {
          success = false;
          synchronized (mLock) {
            mLock.notify();
          }
          return;
        }
        recordSize = (int[]) ar.result;
        recordNumber = getAnrRecNumber(adnRecIndex, mPhoneBookRecords.size(), oldAnr);
        if (recordSize.length != 3 || recordNumber > recordSize[2] || recordNumber <= 0) {
          success = false;
          synchronized (mLock) {
            mLock.notify();
          }
          return;
        }
        data = buildAnrData(recordSize[0], adnRecIndex, newAnr);
        mFh.updateEFLinearFixed(
            efid,
            recordNumber,
            data,
            null,
            obtainMessage(EVENT_UPDATE_ANR_RECORD_DONE, recordNumber, adnRecIndex, data));
        pendingExtLoads = 1;
        break;
      case EVENT_UPDATE_EMAIL_RECORD_DONE:
        ar = (AsyncResult) (msg.obj);
        if (ar.exception != null) {
          success = false;
        }
        data = (byte[]) (ar.userObj);
        recordNumber = (int) msg.arg1;
        adnRecIndex = (int) msg.arg2;
        pbrIndex = getPbrIndexBy(adnRecIndex);
        log("EVENT_UPDATE_EMAIL_RECORD_DONE");
        pendingExtLoads = 0;
        success = true;
        mEmailFileRecord.get(pbrIndex).set(recordNumber - 1, data);
        synchronized (mLock) {
          mLock.notify();
        }
        break;
      case EVENT_UPDATE_ANR_RECORD_DONE:
        ar = (AsyncResult) (msg.obj);
        data = (byte[]) (ar.userObj);
        recordNumber = (int) msg.arg1;
        adnRecIndex = (int) msg.arg2;
        pbrIndex = getPbrIndexBy(adnRecIndex);
        if (ar.exception != null) {
          success = false;
        }
        log("EVENT_UPDATE_ANR_RECORD_DONE");
        pendingExtLoads = 0;
        success = true;
        mAnrFileRecord.get(pbrIndex).set(recordNumber - 1, data);
        synchronized (mLock) {
          mLock.notify();
        }
        break;
      case EVENT_EF_IAP_RECORD_SIZE_DONE:
        log("EVENT_EF_IAP_RECORD_SIZE_DONE");
        ar = (AsyncResult) (msg.obj);
        recordNumber = (int) msg.arg2;
        adnRecIndex = ((int) msg.arg1) - 1;
        pbrIndex = getPbrIndexBy(adnRecIndex);
        efid = getEfidByTag(pbrIndex, USIM_EFIAP_TAG);
        int tag = (Integer) ar.userObj;
        if (ar.exception != null) {
          success = false;
          synchronized (mLock) {
            mLock.notify();
          }
          return;
        }
        recordSize = (int[]) ar.result;
        data = null;
        recordIndex = adnRecIndex - getInitIndexBy(pbrIndex);
        if (recordSize.length != 3 || recordIndex + 1 > recordSize[2] || recordNumber == 0) {
          success = false;
          synchronized (mLock) {
            mLock.notify();
          }
          return;
        }
        if (hasRecordIn(mIapFileRecord, pbrIndex)) {
          data = mIapFileRecord.get(pbrIndex).get(recordIndex);
          switch (tag) {
            case USIM_EFEMAIL_TAG:
              data[mEmailTagNumberInIap] = (byte) recordNumber;
              break;
            case USIM_EFANR_TAG:
              data[mAnrTagNumberInIap] = (byte) recordNumber;
              break;
          }
          pendingExtLoads = 1;
          Log.d(
              LOG_TAG,
              " IAP  efid= "
                  + efid
                  + ", update IAP index= "
                  + (recordIndex)
                  + " with value= "
                  + IccUtils.bytesToHexString(data));
          mFh.updateEFLinearFixed(
              efid,
              recordIndex + 1,
              data,
              null,
              obtainMessage(EVENT_UPDATE_IAP_RECORD_DONE, adnRecIndex, recordNumber, data));
        }
        break;
      case EVENT_UPDATE_IAP_RECORD_DONE:
        ar = (AsyncResult) (msg.obj);
        if (ar.exception != null) {
          success = false;
        }
        data = (byte[]) (ar.userObj);
        adnRecIndex = (int) msg.arg1;
        pbrIndex = getPbrIndexBy(adnRecIndex);
        recordIndex = adnRecIndex - getInitIndexBy(pbrIndex);
        log("EVENT_UPDATE_IAP_RECORD_DONE");
        pendingExtLoads = 0;
        success = true;
        mIapFileRecord.get(pbrIndex).set(recordIndex, data);
        synchronized (mLock) {
          mLock.notify();
        }
        break;
    }
  }