protected void handleBroadcastSms(AsyncResult ar) {
    try {
      byte[][] pdus = null;
      byte[] receivedPdu = (byte[]) ar.result;

      if (Config.LOGD) {
        for (int i = 0; i < receivedPdu.length; i += 8) {
          StringBuilder sb = new StringBuilder("SMS CB pdu data: ");
          for (int j = i; j < i + 8 && j < receivedPdu.length; j++) {
            int b = receivedPdu[j] & 0xff;
            if (b < 0x10) {
              sb.append("0");
            }
            sb.append(Integer.toHexString(b)).append(" ");
          }
          Log.d(TAG, sb.toString());
        }
      }

      SmsCbHeader header = new SmsCbHeader(receivedPdu);
      String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
      GsmCellLocation cellLocation = (GsmCellLocation) mGsmPhone.getCellLocation();
      int lac = cellLocation.getLac();
      int cid = cellLocation.getCid();

      if (header.nrOfPages > 1) {
        // Multi-page message
        SmsCbConcatInfo concatInfo = new SmsCbConcatInfo(header, plmn, lac, cid);

        // Try to find other pages of the same message
        pdus = mSmsCbPageMap.get(concatInfo);

        if (pdus == null) {
          // This it the first page of this message, make room for all
          // pages and keep until complete
          pdus = new byte[header.nrOfPages][];

          mSmsCbPageMap.put(concatInfo, pdus);
        }

        // Page parameter is one-based
        pdus[header.pageIndex - 1] = receivedPdu;

        for (int i = 0; i < pdus.length; i++) {
          if (pdus[i] == null) {
            // Still missing pages, exit
            return;
          }
        }

        // Message complete, remove and dispatch
        mSmsCbPageMap.remove(concatInfo);
      } else {
        // Single page message
        pdus = new byte[1][];
        pdus[0] = receivedPdu;
      }

      dispatchBroadcastPdus(pdus);

      // Remove messages that are out of scope to prevent the map from
      // growing indefinitely, containing incomplete messages that were
      // never assembled
      Iterator<SmsCbConcatInfo> iter = mSmsCbPageMap.keySet().iterator();

      while (iter.hasNext()) {
        SmsCbConcatInfo info = iter.next();

        if (!info.matchesLocation(plmn, lac, cid)) {
          iter.remove();
        }
      }
    } catch (RuntimeException e) {
      Log.e(TAG, "Error in decoding SMS CB pdu", e);
    }
  }
  public void handleMessage(Message msg) {
    AsyncResult ar;

    switch (msg.what) {
      case EVENT_POLL_CALLS_RESULT:
        ar = (AsyncResult) msg.obj;

        if (msg == lastRelevantPoll) {
          if (DBG_POLL) log("handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
          needsPoll = false;
          lastRelevantPoll = null;
          handlePollCalls((AsyncResult) msg.obj);
        }
        break;

      case EVENT_OPERATION_COMPLETE:
        ar = (AsyncResult) msg.obj;
        operationComplete();
        break;

      case EVENT_SWITCH_RESULT:
      case EVENT_CONFERENCE_RESULT:
      case EVENT_SEPARATE_RESULT:
      case EVENT_ECT_RESULT:
        ar = (AsyncResult) msg.obj;
        if (ar.exception != null) {
          phone.notifySuppServiceFailed(getFailedService(msg.what));
        }
        operationComplete();
        break;

      case EVENT_GET_LAST_CALL_FAIL_CAUSE:
        int causeCode;
        ar = (AsyncResult) msg.obj;

        operationComplete();

        if (ar.exception != null) {
          // An exception occurred...just treat the disconnect
          // cause as "normal"
          causeCode = CallFailCause.NORMAL_CLEARING;
          Rlog.i(LOG_TAG, "Exception during getLastCallFailCause, assuming normal disconnect");
        } else {
          causeCode = ((int[]) ar.result)[0];
        }
        // Log the causeCode if its not normal
        if (causeCode == CallFailCause.NO_CIRCUIT_AVAIL
            || causeCode == CallFailCause.TEMPORARY_FAILURE
            || causeCode == CallFailCause.SWITCHING_CONGESTION
            || causeCode == CallFailCause.CHANNEL_NOT_AVAIL
            || causeCode == CallFailCause.QOS_NOT_AVAIL
            || causeCode == CallFailCause.BEARER_NOT_AVAIL
            || causeCode == CallFailCause.ERROR_UNSPECIFIED) {
          GsmCellLocation loc = ((GsmCellLocation) phone.getCellLocation());
          EventLog.writeEvent(
              EventLogTags.CALL_DROP,
              causeCode,
              loc != null ? loc.getCid() : -1,
              TelephonyManager.getDefault().getNetworkType());
        }

        for (int i = 0, s = droppedDuringPoll.size(); i < s; i++) {
          GsmConnection conn = droppedDuringPoll.get(i);

          conn.onRemoteDisconnect(causeCode);
        }

        updatePhoneState();

        phone.notifyPreciseCallStateChanged();
        droppedDuringPoll.clear();
        break;

      case EVENT_REPOLL_AFTER_DELAY:
      case EVENT_CALL_STATE_CHANGE:
        pollCallsWhenSafe();
        break;

      case EVENT_RADIO_AVAILABLE:
        handleRadioAvailable();
        break;

      case EVENT_RADIO_NOT_AVAILABLE:
        handleRadioNotAvailable();
        break;
    }
  }