Esempio n. 1
0
  /**
   * Disconnect from IMS network interface
   *
   * @throws PayloadException
   * @throws NetworkException
   * @throws ContactManagerException
   */
  private void disconnectFromIms()
      throws PayloadException, NetworkException, ContactManagerException {
    // Stop the IMS connection
    stopImsConnection(TerminationReason.TERMINATION_BY_CONNECTION_LOST);

    // Registration terminated
    mCurrentNetworkInterface.registrationTerminated();

    // Disconnect from the network access
    mCurrentNetworkInterface.getNetworkAccess().disconnect();
  }
Esempio n. 2
0
  /**
   * Connect to IMS network interface
   *
   * @param ipAddr IP address
   * @throws CertificateException
   * @throws IOException
   */
  private void connectToIms(String ipAddr) throws CertificateException, IOException {
    // Connected to the network access
    mCurrentNetworkInterface.getNetworkAccess().connect(ipAddr);

    // Start the IMS connection
    startImsConnection();
  }
Esempio n. 3
0
 /** Load the user profile associated to the network interface */
 private void loadUserProfile() {
   ImsModule.setImsUserProfile(mCurrentNetworkInterface.getUserProfile());
   RtpSource.setCname(ImsModule.getImsUserProfile().getPublicUri());
   if (sLogger.isActivated()) {
     sLogger.debug("User profile has been reloaded");
   }
 }
Esempio n. 4
0
 /**
  * Terminate the connection manager
  *
  * @throws PayloadException
  * @throws NetworkException
  * @throws ContactManagerException
  */
 public void terminate() throws PayloadException, NetworkException, ContactManagerException {
   if (sLogger.isActivated()) {
     sLogger.info("Terminate the IMS connection manager");
   }
   if (mBatteryLevelListener != null) {
     mCtx.unregisterReceiver(mBatteryLevelListener);
     mBatteryLevelListener = null;
   }
   if (mNetworkStateListener != null) {
     mCtx.unregisterReceiver(mNetworkStateListener);
     mNetworkStateListener = null;
   }
   stopImsConnection(TerminationReason.TERMINATION_BY_SYSTEM);
   mCurrentNetworkInterface.unregister();
   if (sLogger.isActivated()) {
     sLogger.info("IMS connection manager has been terminated");
   }
 }
Esempio n. 5
0
  @Override
  // @FIXME: This run method needs to be refactored as the current logic of polling is bit too
  // complex and can be made much more simpler.
  public void run() {
    try {
      if (sLogger.isActivated()) {
        sLogger.debug("Start polling of the IMS connection");
      }

      long servicePollingPeriod = mRcsSettings.getImsServicePollingPeriod();
      long regBaseTime = mRcsSettings.getRegisterRetryBaseTime();
      long regMaxTime = mRcsSettings.getRegisterRetryMaxTime();
      Random random = new Random();
      int nbFailures = 0;

      while (mImsPollingThreadId == Thread.currentThread().getId()) {
        if (sLogger.isActivated()) {
          sLogger.debug("Polling: check IMS connection");
        }

        // Connection management
        try {
          // Test IMS registration
          if (!mCurrentNetworkInterface.isRegistered()) {
            if (sLogger.isActivated()) {
              sLogger.debug("Not yet registered to IMS: try registration");
            }

            // Try to register to IMS
            mCurrentNetworkInterface.register(mDnsResolvedFields);

            // InterruptedException thrown by stopImsConnection() may be caught by one
            // of the methods used in currentNetworkInterface.register() above
            if (mImsPollingThreadId != Thread.currentThread().getId()) {
              if (sLogger.isActivated()) {
                sLogger.debug("IMS connection polling thread race condition");
              }
              break;
            }

            if (mImsModule.isInitializationFinished() && !mImsServicesStarted) {
              if (sLogger.isActivated()) {
                sLogger.debug("Registered to the IMS with success: start IMS services");
              }
              mImsModule.startImsServices();
              mImsServicesStarted = true;
            }

            // Reset number of failures
            nbFailures = 0;
          } else {
            if (mImsModule.isInitializationFinished()) {
              if (!mImsServicesStarted) {
                if (sLogger.isActivated()) {
                  sLogger.debug("Already registered to IMS: start IMS services");
                }
                mImsModule.startImsServices();
                mImsServicesStarted = true;
              } else {
                if (sLogger.isActivated()) {
                  sLogger.debug("Already registered to IMS: check IMS services");
                }
                mImsModule.checkImsServices();
              }
            } else {
              if (sLogger.isActivated()) {
                sLogger.debug("Already registered to IMS: IMS services not yet started");
              }
            }
          }
        } catch (ContactManagerException e) {
          sLogger.error("Can't register to the IMS!", e);
          mCurrentNetworkInterface.getSipManager().closeStack();
          /* Increment number of failures */
          nbFailures++;
          /* Force to perform a new DNS lookup */
          mDnsResolvedFields = null;
        } catch (PayloadException e) {
          sLogger.error("Can't register to the IMS!", e);
          mCurrentNetworkInterface.getSipManager().closeStack();
          /* Increment number of failures */
          nbFailures++;
          /* Force to perform a new DNS lookup */
          mDnsResolvedFields = null;
        } catch (NetworkException e) {
          if (sLogger.isActivated()) {
            sLogger.debug(e.getMessage());
          }
          mCurrentNetworkInterface.getSipManager().closeStack();
          /* Increment number of failures */
          nbFailures++;
          /* Force to perform a new DNS lookup */
          mDnsResolvedFields = null;
        }

        // InterruptedException thrown by stopImsConnection() may be caught by one
        // of the methods used in currentNetworkInterface.register() above
        if (mImsPollingThreadId != Thread.currentThread().getId()) {
          sLogger.debug("IMS connection polling thread race condition");
          break;
        }

        // Make a pause before the next polling
        try {
          if (!mCurrentNetworkInterface.isRegistered()) {
            final long retryAfterHeaderDuration =
                mCurrentNetworkInterface.getRetryAfterHeaderDuration();
            if (retryAfterHeaderDuration > 0) {
              Thread.sleep(retryAfterHeaderDuration);
            } else {
              // Pause before the next register attempt
              double w = Math.min(regMaxTime, (regBaseTime * Math.pow(2, nbFailures)));
              double coeff = (random.nextInt(51) + 50) / 100.0; // Coeff between 50%
              // and
              // 100%
              long retryPeriod = (long) (coeff * w);
              if (sLogger.isActivated()) {
                sLogger.debug(
                    new StringBuilder("Wait ")
                        .append(retryPeriod)
                        .append("ms before retry registration (failures=")
                        .append(nbFailures)
                        .append(", coeff=")
                        .append(coeff)
                        .append(')')
                        .toString());
              }
              Thread.sleep(retryPeriod);
            }
          } else if (!mImsServicesStarted) {
            if (sLogger.isActivated()) {
              sLogger.debug(
                  new StringBuilder("Wait ")
                      .append(DEFAULT_RETRY_PERIOD)
                      .append("ms before retry to start services")
                      .toString());
            }
            Thread.sleep(DEFAULT_RETRY_PERIOD);
          } else {
            // Pause before the next service check
            Thread.sleep(servicePollingPeriod);
          }
        } catch (InterruptedException e) {
          if (sLogger.isActivated()) {
            sLogger.warn("IMS connection polling is interrupted", e);
          }
          break;
        }
      }
      if (sLogger.isActivated()) {
        sLogger.debug("IMS connection polling is terminated");
      }
    } catch (RuntimeException e) {
      /*
       * Normally we are not allowed to catch runtime exceptions as these are genuine bugs
       * which should be handled/fixed within the code. However the cases when we are
       * executing operations on a thread unhandling such exceptions will eventually lead to
       * exit the system and thus can bring the whole system down, which is not intended.
       */
      sLogger.error("Failed to poll for ims connection!", e);
    }
  }
Esempio n. 6
0
  // @FIXME: This method is doing so many things at this moment and has become too complex thus
  // needs a complete refactor, However at this moment due to other prior tasks the refactoring
  // task has been kept in backlog.
  private void connectionEvent(Intent intent)
      throws PayloadException, CertificateException, NetworkException, ContactManagerException {
    try {
      if (mDisconnectedByBattery) {
        return;
      }

      if (!intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
        return;
      }

      boolean connectivity =
          intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
      String reason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
      boolean failover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
      if (sLogger.isActivated()) {
        sLogger.debug(
            "Connectivity event change: failover="
                + failover
                + ", connectivity="
                + !connectivity
                + ", reason="
                + reason);
      }
      NetworkInfo networkInfo = mCnxManager.getActiveNetworkInfo();
      if (networkInfo == null) {
        if (sLogger.isActivated()) {
          sLogger.debug("Disconnect from IMS: no network (e.g. air plane mode)");
        }
        disconnectFromIms();
        return;
      }
      if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
        String lastUserAccount = LauncherUtils.getLastUserAccount(mCtx);
        String currentUserAccount = LauncherUtils.getCurrentUserAccount(mCtx);
        if (lastUserAccount != null) {
          if ((currentUserAccount == null)
              || !currentUserAccount.equalsIgnoreCase(lastUserAccount)) {
            mImsModule.getCoreListener().onSimChangeDetected();
            return;
          }
        }
      }
      String localIpAddr = null;
      if (networkInfo.getType() != mCurrentNetworkInterface.getType()) {
        if (sLogger.isActivated()) {
          sLogger.info("Data connection state: NETWORK ACCESS CHANGED");
        }
        if (sLogger.isActivated()) {
          sLogger.debug("Disconnect from IMS: network access has changed");
        }
        disconnectFromIms();

        if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
          if (sLogger.isActivated()) {
            sLogger.debug("Change the network interface to mobile");
          }
          mCurrentNetworkInterface = getMobileNetworkInterface();
        } else if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
          if (sLogger.isActivated()) {
            sLogger.debug("Change the network interface to Wi-Fi");
          }
          mCurrentNetworkInterface = getWifiNetworkInterface();
        }

        loadUserProfile();

        try {
          mDnsResolvedFields = mCurrentNetworkInterface.getDnsResolvedFields();
        } catch (UnknownHostException e) {
          /*
           * Even if we are not able to resolve host name , we should still continue to
           * get local IP as this is a very obvious case, Specially for networks
           * supporting IPV4 protocol.
           */
          if (sLogger.isActivated()) {
            sLogger.debug(e.getMessage());
          }
        }
        localIpAddr =
            NetworkFactory.getFactory()
                .getLocalIpAddress(mDnsResolvedFields, networkInfo.getType());
      } else {
        /* Check if the IP address has changed */
        try {
          if (mDnsResolvedFields == null) {
            mDnsResolvedFields = mCurrentNetworkInterface.getDnsResolvedFields();
          }
        } catch (UnknownHostException e) {
          /*
           * Even if we are not able to resolve host name , we should still continue to
           * get local IP as this is a very obvious case, Specially for networks
           * supporting IPV4 protocol.
           */
          if (sLogger.isActivated()) {
            sLogger.debug(e.getMessage());
          }
        }
        localIpAddr =
            NetworkFactory.getFactory()
                .getLocalIpAddress(mDnsResolvedFields, networkInfo.getType());
        String lastIpAddr = mCurrentNetworkInterface.getNetworkAccess().getIpAddress();
        if (!localIpAddr.equals(lastIpAddr)) {
          // Changed by Deutsche Telekom
          if (lastIpAddr != null) {
            if (sLogger.isActivated()) {
              sLogger.debug("Disconnect from IMS: IP address has changed");
            }
            disconnectFromIms();
          } else {
            if (sLogger.isActivated()) {
              sLogger.debug("IP address available (again)");
            }
          }
        } else {
          // Changed by Deutsche Telekom
          if (sLogger.isActivated()) {
            sLogger.debug("Neither interface nor IP address has changed; nothing to do.");
          }
          return;
        }
      }
      if (networkInfo.isConnected()) {
        String remoteAddress;
        if (mDnsResolvedFields != null) {
          remoteAddress = mDnsResolvedFields.mIpAddress;
        } else {
          remoteAddress = new String("unresolved");
        }

        if (sLogger.isActivated()) {
          sLogger.info(
              "Data connection state: CONNECTED to "
                  + networkInfo.getTypeName()
                  + " with local IP "
                  + localIpAddr
                  + " valid for "
                  + remoteAddress);
        }

        if (!NetworkAccessType.ANY.equals(mNetwork)
            && (mNetwork.toInt() != networkInfo.getType())) {
          if (sLogger.isActivated()) {
            sLogger.warn("Network access " + networkInfo.getTypeName() + " is not authorized");
          }
          return;
        }

        TelephonyManager tm = (TelephonyManager) mCtx.getSystemService(Context.TELEPHONY_SERVICE);
        String currentOpe = tm.getSimOperatorName();
        if (mOperator != null && !currentOpe.equalsIgnoreCase(mOperator)) {
          if (sLogger.isActivated()) {
            sLogger.warn(
                "Operator not authorized current=" + currentOpe + " authorized=" + mOperator);
          }
          return;
        }

        if (!mCurrentNetworkInterface.isInterfaceConfigured()) {
          if (sLogger.isActivated()) {
            sLogger.warn("IMS network interface not well configured");
          }
          return;
        }

        if (sLogger.isActivated()) {
          sLogger.debug("Connect to IMS");
        }
        connectToIms(localIpAddr);
      }
    } catch (SocketException e) {
      if (sLogger.isActivated()) {
        sLogger.debug(e.getMessage());
      }
      disconnectFromIms();
    } catch (IOException e) {
      if (sLogger.isActivated()) {
        sLogger.debug(e.getMessage());
      }
      disconnectFromIms();
    }
  }