Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d526789d authored by Thomas Nguyen's avatar Thomas Nguyen
Browse files

Support NB-IOT NTN modem states

Bug: 297943030
Test: SMS, MMS, call with live network.
atest android.telephony.satellite.cts.SatelliteManagerTestOnMockService
atest com.android.internal.telephony.satellite.SatelliteSessionControllerTest
atest com.android.internal.telephony.satellite.SatelliteControllerTest

Change-Id: I56adee884c6eb1ff70896d557fa5845c11f14fad
parent fc632839
Loading
Loading
Loading
Loading
+40 −4
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.internal.telephony.satellite;

import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING;

import android.annotation.NonNull;
import android.content.Context;
import android.os.Build;
@@ -46,6 +49,8 @@ public class DatagramController {
    public static final long MAX_DATAGRAM_ID = (long) Math.pow(2, 16);
    public static final int ROUNDING_UNIT = 10;
    public static final long SATELLITE_ALIGN_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
    public static final long DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMEOUT =
            TimeUnit.SECONDS.toMillis(60);
    private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
    private static final boolean DEBUG = !"user".equals(Build.TYPE);

@@ -74,6 +79,10 @@ public class DatagramController {
    private SatelliteDatagram mDemoModeDatagram;
    private boolean mIsDemoMode = false;
    private long mAlignTimeoutDuration = SATELLITE_ALIGN_TIMEOUT;
    private long mDatagramWaitTimeForConnectedState = DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMEOUT;
    @GuardedBy("mLock")
    @SatelliteManager.SatelliteModemState
    private int mSatelltieModemState = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;

    /**
     * @return The singleton instance of DatagramController.
@@ -267,6 +276,9 @@ public class DatagramController {
     * @param state Current satellite modem state.
     */
    public void onSatelliteModemStateChanged(@SatelliteManager.SatelliteModemState int state) {
        synchronized (mLock) {
            mSatelltieModemState = state;
        }
        mDatagramDispatcher.onSatelliteModemStateChanged(state);
        mDatagramReceiver.onSatelliteModemStateChanged(state);
    }
@@ -284,17 +296,35 @@ public class DatagramController {
        }
    }

    /**
     * Check if Telephony needs to wait for the modem satellite connected to a satellite network
     * before transferring datagrams via satellite.
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public boolean needsWaitingForSatelliteConnected() {
        synchronized (mLock) {
            if (SatelliteController.getInstance().isSatelliteAttachRequired()
                    && mSatelltieModemState != SATELLITE_MODEM_STATE_CONNECTED
                    && mSatelltieModemState != SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING) {
                return true;
            }
            return false;
        }
    }

    public boolean isSendingInIdleState() {
        synchronized (mLock) {
            return mSendDatagramTransferState ==
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
            return (mSendDatagramTransferState
                    == SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE)
                    && (mDatagramDispatcher.getPendingDatagramCount() == 0);
        }
    }

    public boolean isPollingInIdleState() {
        synchronized (mLock) {
            return mReceiveDatagramTransferState ==
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
            return (mReceiveDatagramTransferState
                    == SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE)
                    && !mDatagramReceiver.isPollingPending();
        }
    }

@@ -336,6 +366,11 @@ public class DatagramController {
        return mAlignTimeoutDuration;
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public long getDatagramWaitTimeForConnectedState() {
        return mDatagramWaitTimeForConnectedState;
    }

    /**
     * This API can be used by only CTS to update the timeout duration in milliseconds whether
     * the device is aligned with the satellite for demo mode
@@ -351,6 +386,7 @@ public class DatagramController {

        logd("setSatelliteDeviceAlignedTimeoutDuration: timeoutMillis=" + timeoutMillis);
        mAlignTimeoutDuration = timeoutMillis;
        mDatagramWaitTimeForConnectedState = timeoutMillis;
        return true;
    }

+53 −5
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.telephony.satellite;

import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;

import static com.android.internal.telephony.satellite.DatagramController.ROUNDING_UNIT;

import android.annotation.NonNull;
@@ -51,6 +53,7 @@ public class DatagramDispatcher extends Handler {
    private static final int CMD_SEND_SATELLITE_DATAGRAM = 1;
    private static final int EVENT_SEND_SATELLITE_DATAGRAM_DONE = 2;
    private static final int EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT = 3;
    private static final int EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT = 4;

    @NonNull private static DatagramDispatcher sInstance;
    @NonNull private final Context mContext;
@@ -308,6 +311,10 @@ public class DatagramDispatcher extends Handler {
                break;
            }

            case EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT:
                handleEventDatagramWaitForConnectedStateTimedOut();
                break;

            default:
                logw("DatagramDispatcherHandler: unexpected message code: " + msg.what);
                break;
@@ -350,8 +357,13 @@ public class DatagramDispatcher extends Handler {
                mPendingNonEmergencyDatagramsMap.put(datagramId, datagramArgs);
            }

            // Modem can be busy receiving datagrams, so send datagram only when modem is not busy.
            if (!mSendingDatagramInProgress && mDatagramController.isPollingInIdleState()) {
            if (mDatagramController.needsWaitingForSatelliteConnected()) {
                logd("sendSatelliteDatagram: wait for satellite connected");
                SatelliteSessionController.getInstance().onSatelliteDatagramsTransferRequested();
                startDatagramWaitForConnectedStateTimer();
            } else if (!mSendingDatagramInProgress && mDatagramController.isPollingInIdleState()) {
                // Modem can be busy receiving datagrams, so send datagram only when modem is
                // not busy.
                mSendingDatagramInProgress = true;
                datagramArgs.setDatagramStartTime();
                mDatagramController.updateSendStatus(subId,
@@ -525,10 +537,11 @@ public class DatagramDispatcher extends Handler {
     * Return pending datagram count
     * @return pending datagram count
     */
    @GuardedBy("mLock")
    private int getPendingDatagramCount() {
    public int getPendingDatagramCount() {
        synchronized (mLock) {
            return mPendingEmergencyDatagramsMap.size() + mPendingNonEmergencyDatagramsMap.size();
        }
    }

    /**
     * Posts the specified command to be executed on the main thread and returns immediately.
@@ -579,6 +592,12 @@ public class DatagramDispatcher extends Handler {
            } else if (state == SatelliteManager.SATELLITE_MODEM_STATE_IDLE) {
                sendPendingDatagrams();
            }

            if (state == SATELLITE_MODEM_STATE_CONNECTED
                    && isDatagramWaitForConnectedStateTimerStarted()) {
                stopDatagramWaitForConnectedStateTimer();
                sendPendingDatagrams();
            }
        }
    }

@@ -598,11 +617,40 @@ public class DatagramDispatcher extends Handler {
                SatelliteManager.SATELLITE_RESULT_REQUEST_ABORTED);

        stopSatelliteAlignedTimer();
        stopDatagramWaitForConnectedStateTimer();
        mIsDemoMode = false;
        mSendSatelliteDatagramRequest = null;
        mIsAligned = false;
    }

    private void startDatagramWaitForConnectedStateTimer() {
        if (isDatagramWaitForConnectedStateTimerStarted()) {
            logd("DatagramWaitForConnectedStateTimer is already started");
            return;
        }
        sendMessageDelayed(obtainMessage(
                        EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT),
                mDatagramController.getDatagramWaitTimeForConnectedState());
    }

    private void stopDatagramWaitForConnectedStateTimer() {
        removeMessages(EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT);
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public boolean isDatagramWaitForConnectedStateTimerStarted() {
        return hasMessages(EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT);
    }

    private void handleEventDatagramWaitForConnectedStateTimedOut() {
        logw("Timed out to wait for satellite connected before sending datagrams");
        synchronized (mLock) {
            abortSendingPendingDatagrams(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
                    SatelliteManager.SATELLITE_RESULT_NOT_REACHABLE);
            SatelliteSessionController.getInstance().onDatagramWaitForConnectedStateTimerTimedOut();
        }
    }

    private static void logd(@NonNull String log) {
        Rlog.d(TAG, log);
    }
+116 −11
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.telephony.satellite;

import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;

import static com.android.internal.telephony.satellite.DatagramController.ROUNDING_UNIT;

import android.annotation.NonNull;
@@ -65,6 +67,7 @@ public class DatagramReceiver extends Handler {
    private static final int CMD_POLL_PENDING_SATELLITE_DATAGRAMS = 1;
    private static final int EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE = 2;
    private static final int EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT = 3;
    private static final int EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT = 4;

    /** Key used to read/write satellite datagramId in shared preferences. */
    private static final String SATELLITE_DATAGRAM_ID_KEY = "satellite_datagram_id_key";
@@ -82,7 +85,10 @@ public class DatagramReceiver extends Handler {
    private boolean mIsDemoMode = false;
    @GuardedBy("mLock")
    private boolean mIsAligned = false;
    private DatagramReceiverHandlerRequest mPollPendingSatelliteDatagramsRequest = null;
    @Nullable
    private DatagramReceiverHandlerRequest mDemoPollPendingSatelliteDatagramsRequest = null;
    @Nullable
    private DatagramReceiverHandlerRequest mPendingPollSatelliteDatagramsRequest = null;
    private final Object mLock = new Object();

    /**
@@ -497,6 +503,14 @@ public class DatagramReceiver extends Handler {
                handleEventSatelliteAlignedTimeout((DatagramReceiverHandlerRequest) msg.obj);
                break;
            }

            case EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT:
                handleEventDatagramWaitForConnectedStateTimedOut();
                break;

            default:
                logw("DatagramDispatcherHandler: unexpected message code: " + msg.what);
                break;
        }
    }

@@ -585,10 +599,38 @@ public class DatagramReceiver extends Handler {
            callback.accept(SatelliteManager.SATELLITE_RESULT_MODEM_BUSY);
            return;
        }

        pollPendingSatelliteDatagramsInternal(subId, callback);
    }

    /**
     * Check if DatagramReceiver is waiting for satellite modem connected to a satellite network
     * before pushing down the poll request to modem.
     */
    public boolean isPollingPending() {
        synchronized (mLock) {
            return (mPendingPollSatelliteDatagramsRequest != null);
        }
    }

    private void handleSatelliteConnectedEvent() {
        synchronized (mLock) {
            if (isDatagramWaitForConnectedStateTimerStarted()) {
                stopDatagramWaitForConnectedStateTimer();
                if (mPendingPollSatelliteDatagramsRequest == null) {
                    loge("handleSatelliteConnectedEvent: mPendingPollSatelliteDatagramsRequest is"
                            + " null");
                    return;
                }

                Consumer<Integer> callback =
                        (Consumer<Integer>) mPendingPollSatelliteDatagramsRequest.argument;
                pollPendingSatelliteDatagramsInternal(
                        mPendingPollSatelliteDatagramsRequest.subId, callback);
                mPendingPollSatelliteDatagramsRequest = null;
            }
        }
    }

    private void pollPendingSatelliteDatagramsInternal(int subId,
            @NonNull Consumer<Integer> callback) {
        if (!mDatagramController.isSendingInIdleState()) {
@@ -598,6 +640,17 @@ public class DatagramReceiver extends Handler {
            return;
        }

        if (mDatagramController.needsWaitingForSatelliteConnected()) {
            logd("pollPendingSatelliteDatagrams: wait for satellite connected");
            synchronized (mLock) {
                mPendingPollSatelliteDatagramsRequest = new DatagramReceiverHandlerRequest(
                        callback, SatelliteServiceUtils.getPhone(), subId);
                SatelliteSessionController.getInstance().onSatelliteDatagramsTransferRequested();
                startDatagramWaitForConnectedStateTimer();
            }
            return;
        }

        mDatagramController.updateReceiveStatus(subId,
                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING,
                mDatagramController.getReceivePendingCount(),
@@ -635,6 +688,8 @@ public class DatagramReceiver extends Handler {
                    || state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE) {
                logd("onSatelliteModemStateChanged: cleaning up resources");
                cleanUpResources();
            } else if (state == SATELLITE_MODEM_STATE_CONNECTED) {
                handleSatelliteConnectedEvent();
            }
        }
    }
@@ -643,22 +698,31 @@ public class DatagramReceiver extends Handler {
    private void cleanupDemoModeResources() {
        if (isSatelliteAlignedTimerStarted()) {
            stopSatelliteAlignedTimer();
            if (mPollPendingSatelliteDatagramsRequest == null) {
            if (mDemoPollPendingSatelliteDatagramsRequest == null) {
                loge("Satellite aligned timer was started "
                        + "but mPollPendingSatelliteDatagramsRequest is null");
                        + "but mDemoPollPendingSatelliteDatagramsRequest is null");
            } else {
                Consumer<Integer> callback =
                        (Consumer<Integer>) mPollPendingSatelliteDatagramsRequest.argument;
                        (Consumer<Integer>) mDemoPollPendingSatelliteDatagramsRequest.argument;
                callback.accept(SatelliteManager.SATELLITE_RESULT_REQUEST_ABORTED);
            }
        }
        mIsDemoMode = false;
        mPollPendingSatelliteDatagramsRequest = null;
        mDemoPollPendingSatelliteDatagramsRequest = null;
        mIsAligned = false;
    }

    @GuardedBy("mLock")
    private void cleanUpResources() {
        synchronized (mLock) {
            if (mPendingPollSatelliteDatagramsRequest != null) {
                Consumer<Integer> callback =
                        (Consumer<Integer>) mPendingPollSatelliteDatagramsRequest.argument;
                callback.accept(SatelliteManager.SATELLITE_RESULT_REQUEST_ABORTED);
                mPendingPollSatelliteDatagramsRequest = null;
            }
            stopDatagramWaitForConnectedStateTimer();
        }
        if (mDatagramController.isReceivingDatagrams()) {
            mDatagramController.updateReceiveStatus(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED,
@@ -736,7 +800,7 @@ public class DatagramReceiver extends Handler {
            logd("Satellite aligned timer was already started");
            return;
        }
        mPollPendingSatelliteDatagramsRequest = request;
        mDemoPollPendingSatelliteDatagramsRequest = request;
        sendMessageDelayed(
                obtainMessage(EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT, request),
                getSatelliteAlignedTimeoutDuration());
@@ -751,13 +815,14 @@ public class DatagramReceiver extends Handler {
        if (isSatelliteAlignedTimerStarted()) {
            stopSatelliteAlignedTimer();

            if (mPollPendingSatelliteDatagramsRequest == null) {
                loge("handleSatelliteAlignedTimer: mPollPendingSatelliteDatagramsRequest is null");
            if (mDemoPollPendingSatelliteDatagramsRequest == null) {
                loge("handleSatelliteAlignedTimer: mDemoPollPendingSatelliteDatagramsRequest "
                        + "is null");
            } else {
                Message message = obtainMessage(
                        EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE,
                        mPollPendingSatelliteDatagramsRequest);
                mPollPendingSatelliteDatagramsRequest = null;
                        mDemoPollPendingSatelliteDatagramsRequest);
                mDemoPollPendingSatelliteDatagramsRequest = null;
                AsyncResult.forMessage(message, null, null);
                message.sendToTarget();
            }
@@ -781,6 +846,42 @@ public class DatagramReceiver extends Handler {
        removeMessages(EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT);
    }

    private void startDatagramWaitForConnectedStateTimer() {
        if (isDatagramWaitForConnectedStateTimerStarted()) {
            logd("DatagramWaitForConnectedStateTimer is already started");
            return;
        }
        sendMessageDelayed(obtainMessage(
                        EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT),
                mDatagramController.getDatagramWaitTimeForConnectedState());
    }

    private void stopDatagramWaitForConnectedStateTimer() {
        removeMessages(EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT);
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public boolean isDatagramWaitForConnectedStateTimerStarted() {
        return hasMessages(EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT);
    }

    private void handleEventDatagramWaitForConnectedStateTimedOut() {
        synchronized (mLock) {
            if (mPendingPollSatelliteDatagramsRequest == null) {
                logw("handleEventDatagramWaitForConnectedStateTimedOut: "
                        + "mPendingPollSatelliteDatagramsRequest is null");
                return;
            }

            logw("Timed out to wait for satellite connected before polling datagrams");
            Consumer<Integer> callback =
                    (Consumer<Integer>) mPendingPollSatelliteDatagramsRequest.argument;
            callback.accept(SatelliteManager.SATELLITE_RESULT_NOT_REACHABLE);
            mPendingPollSatelliteDatagramsRequest = null;
            SatelliteSessionController.getInstance().onDatagramWaitForConnectedStateTimerTimedOut();
        }
    }

    /**
     * Destroys this DatagramDispatcher. Used for tearing down static resources during testing.
     */
@@ -796,4 +897,8 @@ public class DatagramReceiver extends Handler {
    private static void loge(@NonNull String log) {
        Rlog.e(TAG, log);
    }

    private static void logw(@NonNull String log) {
        Rlog.w(TAG, log);
    }
}
+39 −3
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.satellite.metrics.ControllerMetricsStats;
import com.android.internal.telephony.satellite.metrics.ProvisionMetricsStats;
import com.android.internal.telephony.satellite.metrics.SessionMetricsStats;
@@ -242,6 +243,7 @@ public class SatelliteController extends Handler {
     * {@code true} for enabled and {@code false} for disabled. */
    @NonNull private final Map<Integer, Boolean> mIsSatelliteAttachEnabledForCarrierArrayPerSub =
            new HashMap<>();
    @NonNull private final FeatureFlags mFeatureFlags;
    /**
     * @return The singleton instance of SatelliteController.
     */
@@ -255,12 +257,13 @@ public class SatelliteController extends Handler {
    /**
     * Create the SatelliteController singleton instance.
     * @param context The Context to use to create the SatelliteController.
     * @param featureFlags The feature flag.
     */
    public static void make(@NonNull Context context) {
    public static void make(@NonNull Context context, @NonNull FeatureFlags featureFlags) {
        if (sInstance == null) {
            HandlerThread satelliteThread = new HandlerThread(TAG);
            satelliteThread.start();
            sInstance = new SatelliteController(context, satelliteThread.getLooper());
            sInstance = new SatelliteController(context, satelliteThread.getLooper(), featureFlags);
        }
    }

@@ -270,12 +273,15 @@ public class SatelliteController extends Handler {
     *
     * @param context The Context for the SatelliteController.
     * @param looper The looper for the handler. It does not run on main thread.
     * @param featureFlags The feature flag.
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public SatelliteController(@NonNull Context context, @NonNull Looper looper) {
    public SatelliteController(
            @NonNull Context context, @NonNull Looper looper, @NonNull FeatureFlags featureFlags) {
        super(looper);

        mContext = context;
        mFeatureFlags = featureFlags;
        Phone phone = SatelliteServiceUtils.getPhone();
        mCi = phone.mCi;
        // Create the SatelliteModemInterface singleton, which is used to manage connections
@@ -2128,6 +2134,30 @@ public class SatelliteController extends Handler {
        }
    }

    /**
     * Check whether satellite modem has to attach to a satellite network before sending/receiving
     * datagrams.
     *
     * @return {@code true} if satellite attach is required, {@code false} otherwise.
     */
    public boolean isSatelliteAttachRequired() {
        if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
            return false;
        }

        synchronized (mSatelliteCapabilitiesLock) {
            if (mSatelliteCapabilities == null) {
                loge("isSatelliteAttachRequired: mSatelliteCapabilities is null");
                return false;
            }
            if (mSatelliteCapabilities.getSupportedRadioTechnologies().contains(
                    SatelliteManager.NT_RADIO_TECHNOLOGY_NB_IOT_NTN)) {
                return true;
            }
            return false;
        }
    }

    /**
     * If we have not successfully queried the satellite modem for its satellite service support,
     * we will retry the query one more time. Otherwise, we will return the cached result.
@@ -2477,6 +2507,12 @@ public class SatelliteController extends Handler {
                }
                mWaitingForSatelliteModemOff = false;
            }
        } else {
            if (mSatelliteSessionController != null) {
                mSatelliteSessionController.onSatelliteModemStateChanged(state);
            } else {
                loge("handleEventSatelliteModemStateChanged: mSatelliteSessionController is null");
            }
        }
        mDatagramController.onSatelliteModemStateChanged(state);
    }
+4 −0
Original line number Diff line number Diff line
@@ -150,6 +150,10 @@ public class SatelliteServiceUtils {
                return SatelliteManager.SATELLITE_MODEM_STATE_OFF;
            case SatelliteModemState.SATELLITE_MODEM_STATE_UNAVAILABLE:
                return SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE;
            case SatelliteModemState.SATELLITE_MODEM_STATE_NOT_CONNECTED:
                return SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED;
            case SatelliteModemState.SATELLITE_MODEM_STATE_CONNECTED:
                return SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
            default:
                loge("Received invalid modem state: " + modemState);
                return SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
Loading