diff --git a/Android.bp b/Android.bp
index 7ab0990..ffd2292 100644
--- a/Android.bp
+++ b/Android.bp
@@ -47,6 +47,8 @@
         "service-entitlement",
         "telephony_flags_core_java_lib",
         "android.permission.flags-aconfig-java",
+        "satellite-s2storage-ro",
+        "s2-geometry-library-java",
     ],
 
     srcs: [
@@ -90,7 +92,19 @@
     libs: [
         "telephony-common",
         "service-entitlement"
-        ],
+    ],
+}
+
+// Used by satellite unit tests temporarily during the development phase.
+// TODO: Remove this once the satellite code is wired into Telephony code.
+java_library {
+    name: "telephony-satellite",
+    srcs: ["src/com/android/phone/satellite/**/*.java"],
+    libs: [
+        "satellite-s2storage-ro",
+        "s2-geometry-library-java",
+        "telephony-common",
+    ],
 }
 
 platform_compat_config {
diff --git a/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessController.java b/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessController.java
new file mode 100644
index 0000000..62fbd18
--- /dev/null
+++ b/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessController.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.phone.satellite.accesscontrol;
+
+import android.annotation.NonNull;
+import android.telephony.Rlog;
+
+import com.android.storage.s2.S2LevelRange;
+import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+
+import com.google.common.geometry.S2CellId;
+import com.google.common.geometry.S2LatLng;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * An implementation of {@link SatelliteOnDeviceAccessController} that uses
+ * {@link SatS2RangeFileReader}.
+ */
+final class S2RangeSatelliteOnDeviceAccessController extends SatelliteOnDeviceAccessController {
+    private static final String TAG = "S2RangeSatelliteOnDeviceAccessController";
+    private static final boolean DBG = false;
+
+    @NonNull private final SatS2RangeFileReader mSatS2RangeFileReader;
+
+    private final int mS2Level;
+
+    private S2RangeSatelliteOnDeviceAccessController(
+            @NonNull SatS2RangeFileReader satS2RangeFileReader, int s2Level) {
+        mSatS2RangeFileReader = Objects.requireNonNull(satS2RangeFileReader);
+        mS2Level = s2Level;
+    }
+
+    /**
+     * Returns a new {@link S2RangeSatelliteOnDeviceAccessController} using the specified data file.
+     *
+     * @param file The input file that contains the S2-range-based access restriction information.
+     * @throws IOException in the event of a problem while reading the underlying file.
+     * @throws IllegalArgumentException if either the S2 level defined by
+     * {@code config_oem_enabled_satellite_s2cell_level} or the satellite access allow defined by
+     * {@code config_oem_enabled_satellite_access_allow} does not match the values included in the
+     * header of the input file.
+     */
+    public static S2RangeSatelliteOnDeviceAccessController create(
+            @NonNull File file) throws IOException, IllegalArgumentException {
+        SatS2RangeFileReader reader = SatS2RangeFileReader.open(file);
+        int s2Level = reader.getS2Level();
+        return new S2RangeSatelliteOnDeviceAccessController(reader, s2Level);
+    }
+
+    @Override
+    public LocationToken createLocationTokenForLatLng(double latDegrees, double lngDegrees) {
+        return new LocationTokenImpl(getS2CellId(latDegrees, lngDegrees).id());
+    }
+
+    @Override
+    public boolean isSatCommunicationAllowedAtLocation(LocationToken locationToken)
+            throws IOException {
+        if (!(locationToken instanceof LocationTokenImpl)) {
+            throw new IllegalArgumentException("Unknown locationToken=" + locationToken);
+        }
+        LocationTokenImpl locationTokenImpl = (LocationTokenImpl) locationToken;
+        return isSatCommunicationAllowedAtLocation(locationTokenImpl.getS2CellId());
+    }
+
+    private boolean isSatCommunicationAllowedAtLocation(long s2CellId) throws IOException {
+        S2LevelRange entry = mSatS2RangeFileReader.findEntryByCellId(s2CellId);
+        if (mSatS2RangeFileReader.isAllowedList()) {
+            // The file contains an allowed list of S2 cells. Thus, satellite is allowed if an
+            // entry is found
+            return (entry != null);
+        } else {
+            // The file contains a disallowed list of S2 cells. Thus, satellite is allowed if an
+            // entry is not found
+            return (entry == null);
+        }
+    }
+
+    private S2CellId getS2CellId(double latDegrees, double lngDegrees) {
+        // Create the leaf S2 cell containing the given S2LatLng
+        S2CellId cellId = S2CellId.fromLatLng(S2LatLng.fromDegrees(latDegrees, lngDegrees));
+
+        // Return the S2 cell at the expected S2 level
+        return cellId.parent(mS2Level);
+    }
+
+    @Override
+    public void close() throws IOException {
+        mSatS2RangeFileReader.close();
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+
+    private static class LocationTokenImpl extends LocationToken {
+
+        private final long mS2CellId;
+
+        private LocationTokenImpl(long s2CellId) {
+            this.mS2CellId = s2CellId;
+        }
+
+        long getS2CellId() {
+            return mS2CellId;
+        }
+
+        @Override
+        public String toString() {
+            return DBG ? toPiiString() : "LocationToken{<redacted>}";
+        }
+
+        @Override
+        public String toPiiString() {
+            return "LocationToken{"
+                    + "mS2CellId=" + mS2CellId
+                    + '}';
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof LocationTokenImpl)) {
+                return false;
+            }
+            LocationTokenImpl that = (LocationTokenImpl) o;
+            return mS2CellId == that.mS2CellId;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mS2CellId);
+        }
+    }
+}
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
new file mode 100644
index 0000000..7f9c1aa
--- /dev/null
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.satellite.accesscontrol;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ResultReceiver;
+import android.telephony.Rlog;
+import android.telephony.satellite.SatelliteManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.flags.FeatureFlags;
+
+/**
+ * This module is responsible for making sure that satellite communication can be used by devices
+ * in only regions allowed by OEMs.
+ */
+public class SatelliteAccessController extends Handler {
+    private static final String TAG = "SatelliteAccessController";
+
+    private static final int CMD_IS_SATELLITE_COMMUNICATION_ALLOWED = 1;
+
+    /** Feature flags to control behavior and errors. */
+    @NonNull private final FeatureFlags mFeatureFlags;
+    @Nullable private final SatelliteOnDeviceAccessController mSatelliteOnDeviceAccessController;
+
+    /**
+     * Create a SatelliteAccessController instance.
+     *
+     * @param featureFlags The FeatureFlags that are supported.
+     * @param looper The Looper to run the SatelliteAccessController on.
+     * @param satelliteOnDeviceAccessController The location-based satellite restriction lookup.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public SatelliteAccessController(@NonNull FeatureFlags featureFlags, @NonNull Looper looper,
+            @Nullable SatelliteOnDeviceAccessController satelliteOnDeviceAccessController) {
+        super(looper);
+        mFeatureFlags = featureFlags;
+        mSatelliteOnDeviceAccessController = satelliteOnDeviceAccessController;
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case CMD_IS_SATELLITE_COMMUNICATION_ALLOWED:
+                handleRequestIsSatelliteCommunicationAllowedForCurrentLocation(
+                        (ResultReceiver) msg.obj);
+                break;
+            default:
+                logw("SatelliteAccessControllerHandler: unexpected message code: " + msg.what);
+                break;
+        }
+    }
+
+    /**
+     * Request to get whether satellite communication is allowed for the current location.
+     *
+     * @param result The result receiver that returns whether satellite communication is allowed
+     *               for the current location if the request is successful or an error code
+     *               if the request failed.
+     */
+    public void requestIsSatelliteCommunicationAllowedForCurrentLocation(
+            @NonNull ResultReceiver result) {
+        if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+            logd("oemEnabledSatelliteFlag is disabled");
+            result.send(SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
+            return;
+        }
+        sendRequestAsync(CMD_IS_SATELLITE_COMMUNICATION_ALLOWED, result);
+    }
+
+    private void handleRequestIsSatelliteCommunicationAllowedForCurrentLocation(
+            @NonNull ResultReceiver result) {
+        // To be implemented
+    }
+
+    /**
+     * Posts the specified command to be executed on the main thread and returns immediately.
+     *
+     * @param command command to be executed on the main thread
+     * @param argument additional parameters required to perform of the operation
+     */
+    private void sendRequestAsync(int command, @NonNull Object argument) {
+        Message msg = this.obtainMessage(command, argument);
+        msg.sendToTarget();
+    }
+
+    private static void logd(@NonNull String log) {
+        Rlog.d(TAG, log);
+    }
+
+    private static void logw(@NonNull String log) {
+        Rlog.w(TAG, log);
+    }
+
+    private static void loge(@NonNull String log) {
+        Rlog.e(TAG, log);
+    }
+}
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteOnDeviceAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteOnDeviceAccessController.java
new file mode 100644
index 0000000..9292f33
--- /dev/null
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteOnDeviceAccessController.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.phone.satellite.accesscontrol;
+
+import android.annotation.NonNull;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * A class that performs location-based access control for satellite communication synchronously
+ * without exposing implementation details.
+ */
+public abstract class SatelliteOnDeviceAccessController implements Closeable {
+
+    /**
+     * Returns the default {@link SatelliteOnDeviceAccessController}. This method will open the
+     * underlying storage and may carry some CPU and I/O expense; callers may want to hold the
+     * {@link SatelliteOnDeviceAccessController} object for multiple lookups to amortize that cost
+     * but at the cost of some memory, or close it immediately after a single use.
+     *
+     * @param file The input file that contains the location-based access restriction information.
+     * @throws IOException in the unlikely event of errors when reading underlying file(s)
+     * @throws IllegalArgumentException if the input file format does not match the format defined
+     * by the device overlay configs.
+     */
+    public static SatelliteOnDeviceAccessController create(
+            @NonNull File file) throws IOException, IllegalArgumentException {
+        return S2RangeSatelliteOnDeviceAccessController.create(file);
+    }
+
+    /**
+     * Returns a token for a given location. See {@link LocationToken} for details.
+     *
+     * @throws IOException in the unlikely event of errors when reading the underlying file
+     */
+    public abstract LocationToken createLocationTokenForLatLng(double latDegrees, double lngDegrees)
+            throws IOException;
+
+    /**
+     * Returns {@code true} if the satellite communication is allowed at the provided location,
+     * {@code false} otherwise.
+     *
+     * @throws IOException in the unlikely event of errors when reading the underlying file
+     */
+    public abstract boolean isSatCommunicationAllowedAtLocation(LocationToken locationToken)
+            throws IOException;
+
+    /**
+     * A class that represents an area with the same value. Two locations with tokens that
+     * {@link #equals(Object) equal each other} will definitely return the same value.
+     *
+     * <p>Depending on the implementation, it may be cheaper to obtain a {@link LocationToken} than
+     * doing a full lookup.
+     */
+    public abstract static class LocationToken {
+        @Override
+        public abstract boolean equals(Object other);
+
+        @Override
+        public abstract int hashCode();
+
+        /** This will print out the location information */
+        public abstract String toPiiString();
+    }
+}
diff --git a/tests/Android.bp b/tests/Android.bp
index d2288d0..3015f76 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -50,6 +50,10 @@
         "testables",
         "platform-compat-test-rules",
         "flag-junit",
+        "satellite-s2storage-rw",
+        "satellite-s2storage-testutils",
+        "s2-geometry-library-java",
+        "telephony-satellite",
     ],
 
     test_suites: [
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessControllerTest.java
new file mode 100644
index 0000000..84c233a
--- /dev/null
+++ b/tests/src/com/android/phone/satellite/accesscontrol/S2RangeSatelliteOnDeviceAccessControllerTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.satellite.accesscontrol;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.storage.s2.S2LevelRange;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.utils.TestUtils;
+import com.android.telephony.sats2range.write.SatS2RangeFileWriter;
+
+import com.google.common.geometry.S2CellId;
+import com.google.common.geometry.S2LatLng;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class S2RangeSatelliteOnDeviceAccessControllerTest {
+    private File mFile;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mFile = File.createTempFile("test", ".data");
+        assertTrue(mFile.exists());
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        if (mFile != null && mFile.exists()) {
+            assertTrue(mFile.delete());
+        }
+    }
+
+    @Test
+    public void testSatelliteAccessControl_AllowedList() throws Exception {
+        testSatelliteAccessControl(true);
+    }
+
+    @Test
+    public void testSatelliteAccessControl_DisallowedList() throws Exception {
+        testSatelliteAccessControl(false);
+    }
+
+    private void testSatelliteAccessControl(boolean isAllowedList) throws Exception {
+        SatS2RangeFileFormat fileFormat = null;
+        try {
+            fileFormat = createSatS2File(mFile, isAllowedList);
+        } catch (Exception ex) {
+            fail("Got unexpected exception in createSatS2File, ex=" + ex);
+        }
+
+        // Validate the output block file
+        SatelliteOnDeviceAccessController accessController = null;
+        try {
+            accessController = SatelliteOnDeviceAccessController.create(mFile);
+
+            // Verify an edge cell of range 1 not in the output file
+            S2CellId s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, 999));
+            S2LatLng s2LatLng = s2CellId.toLatLng();
+            SatelliteOnDeviceAccessController.LocationToken locationToken =
+                    accessController.createLocationTokenForLatLng(
+                            s2LatLng.latDegrees(), s2LatLng.lngDegrees());
+            boolean isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
+            assertTrue(isAllowed != isAllowedList);
+
+            // Verify cells in range1 present in the output file
+            for (int suffix = 1000; suffix < 2000; suffix++) {
+                s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, suffix));
+                s2LatLng = s2CellId.toLatLng();
+
+                // Lookup using location token
+                locationToken = accessController.createLocationTokenForLatLng(
+                                s2LatLng.latDegrees(), s2LatLng.lngDegrees());
+                isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
+                assertTrue(isAllowed == isAllowedList);
+            }
+
+            // Verify the middle cell not in the output file
+            s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, 2000));
+            s2LatLng = s2CellId.toLatLng();
+            locationToken = accessController.createLocationTokenForLatLng(
+                    s2LatLng.latDegrees(), s2LatLng.lngDegrees());
+            isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
+            assertTrue(isAllowed != isAllowedList);
+
+            // Verify cells in range2 present in the output file
+            for (int suffix = 2001; suffix < 3000; suffix++) {
+                s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, suffix));
+                s2LatLng = s2CellId.toLatLng();
+                locationToken = accessController.createLocationTokenForLatLng(
+                        s2LatLng.latDegrees(), s2LatLng.lngDegrees());
+                isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
+                assertTrue(isAllowed == isAllowedList);
+            }
+
+            // Verify an edge cell of range 2 not in the output file
+            s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1000, 3000));
+            s2LatLng = s2CellId.toLatLng();
+            locationToken = accessController.createLocationTokenForLatLng(
+                    s2LatLng.latDegrees(), s2LatLng.lngDegrees());
+            isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
+            assertTrue(isAllowed != isAllowedList);
+
+            // Verify an edge cell of range 3 not in the output file
+            s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1001, 999));
+            s2LatLng = s2CellId.toLatLng();
+            locationToken = accessController.createLocationTokenForLatLng(
+                    s2LatLng.latDegrees(), s2LatLng.lngDegrees());
+            isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
+            assertTrue(isAllowed != isAllowedList);
+
+            // Verify cells in range1 present in the output file
+            for (int suffix = 1000; suffix < 2000; suffix++) {
+                s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1001, suffix));
+                s2LatLng = s2CellId.toLatLng();
+                locationToken = accessController.createLocationTokenForLatLng(
+                        s2LatLng.latDegrees(), s2LatLng.lngDegrees());
+                isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
+                assertTrue(isAllowed == isAllowedList);
+            }
+
+            // Verify an edge cell of range 3 not in the output file
+            s2CellId = new S2CellId(TestUtils.createCellId(fileFormat, 1, 1001, 2000));
+            s2LatLng = s2CellId.toLatLng();
+            locationToken = accessController.createLocationTokenForLatLng(
+                    s2LatLng.latDegrees(), s2LatLng.lngDegrees());
+            isAllowed = accessController.isSatCommunicationAllowedAtLocation(locationToken);
+            assertTrue(isAllowed != isAllowedList);
+        } catch (Exception ex) {
+            fail("Unexpected exception when validating the output ex=" + ex);
+        } finally {
+            if (accessController != null) {
+                accessController.close();
+            }
+        }
+    }
+
+    private SatS2RangeFileFormat createSatS2File(
+            File file, boolean isAllowedList) throws Exception {
+        SatS2RangeFileFormat fileFormat;
+        S2LevelRange range1, range2, range3;
+        try (SatS2RangeFileWriter satS2RangeFileWriter = SatS2RangeFileWriter.open(
+                file, TestUtils.createS2RangeFileFormat(isAllowedList))) {
+            fileFormat = satS2RangeFileWriter.getFileFormat();
+
+            // Two ranges that share a prefix.
+            range1 = new S2LevelRange(
+                    TestUtils.createCellId(fileFormat, 1, 1000, 1000),
+                    TestUtils.createCellId(fileFormat, 1, 1000, 2000));
+            range2 = new S2LevelRange(
+                    TestUtils.createCellId(fileFormat, 1, 1000, 2001),
+                    TestUtils.createCellId(fileFormat, 1, 1000, 3000));
+            // This range has a different prefix, so will be in a different suffix table.
+            range3 = new S2LevelRange(
+                    TestUtils.createCellId(fileFormat, 1, 1001, 1000),
+                    TestUtils.createCellId(fileFormat, 1, 1001, 2000));
+
+            List<S2LevelRange> ranges = new ArrayList<>();
+            ranges.add(range1);
+            ranges.add(range2);
+            ranges.add(range3);
+            satS2RangeFileWriter.createSortedSuffixBlocks(ranges.iterator());
+        }
+        assertTrue(file.length() > 0);
+        return fileFormat;
+    }
+}
diff --git a/utils/satellite/README.md b/utils/satellite/README.md
new file mode 100644
index 0000000..e219823
--- /dev/null
+++ b/utils/satellite/README.md
@@ -0,0 +1,62 @@
+This directory contains code and tools for generating and debugging binary
+satellite s2 file.
+
+Directory structure
+=
+
+`s2storage`
+- `src/write` S2 write code used by tools to write the s2 cells into a
+  binary file. This code is also used by `TeleServiceTests`.
+- `src/readonly` S2 read-only code used by the above read-write code and the class
+ `S2RangeFileBasedSatelliteLocationLookup`.
+
+`tools`
+- `src/main` Contains the tools for generating binary satellite s2 file, and tools
+  for dumping the binary file into human-readable format.
+- `src/test` Contains the test code for the tools.
+
+Run unit tests
+=
+- Build the tools and test code: Go to the tool directory (`packages/services/Telephony/tools/
+  satellite`) in the local workspace and run `mm`, e.g.,
+- Run unit tests: `$atest SatelliteToolsTests`
+
+Data file generate tools
+=
+
+`satellite_createsats2file`
+- Runs the `satellite_createsats2file` to create a binary satellite S2 file from a
+  list of S2 cells ID.
+- Command: `$satellite_createsats2file --input-file <s2cells.txt> --s2-level <12>
+  --is-allowed-list <true> --output-file <sats2.dat>`
+  - `--input-file` Each line in the file contains a `signed-64bit` number which represents
+    the ID of a S2 cell.
+  - `--s2-level` The S2 level of all the cells in the input file.
+  - `--is-allowed-list` Should be either `trrue` or `false`
+    - `true` The input file contains a list of S2 cells where satellite services are allowed.
+    - `false` The input file contains a list of S2 cells where satellite services are disallowed.
+  - `--output-file` The created binary satellite S2 file, which will be used by
+  the `SatelliteAccessController` module in determining if satellite communication
+  is allowed at a location.
+- Build the tools: Go to the tool directory (`packages/services/Telephony/tools/satellite`)
+  in the local workspace and run `mm`.
+- Example run command: `$satellite_createsats2file --input-file s2cells.txt --s2-level 12
+  --is-allowed-list true --output-file sats2.dat`
+
+Debug tools
+=
+
+`satellite_createsats2file_test`
+- Create a test binary satellite S2 file with the following ranges:
+  - [(prefix=0b100_11111111, suffix=1000), (prefix=0b100_11111111, suffix=2000))
+  - [(prefix=0b100_11111111, suffix=2000), (prefix=0b100_11111111, suffix=3000))
+  - [(prefix=0b101_11111111, suffix=1000), (prefix=0b101_11111111, suffix=2000))
+- Run the test tool: `$satellite_createtestsats2file /tmp/foo.dat`
+  - This command will generate the binary satellite S2 cell file `/tmp/foo.dat` with
+  the above S2 ranges.
+
+`satellite_dumpsats2file`
+- Dump the input binary satellite S2 cell file into human-readable text format.
+- Run the tool: `$satellite_dumpsats2file /tmp/foo.dat /tmp/foo`
+  - `/tmp/foo.dat` Input binary satellite S2 cell file.
+  - `/tmp/foo` Output directory which contains the output text files.
\ No newline at end of file
diff --git a/utils/satellite/s2storage/Android.bp b/utils/satellite/s2storage/Android.bp
new file mode 100644
index 0000000..64882ee
--- /dev/null
+++ b/utils/satellite/s2storage/Android.bp
@@ -0,0 +1,77 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Library for read-only access to Sat S2 data files.
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// Library for read-only access to satellite S2 data files.
+java_library {
+    name: "satellite-s2storage-ro",
+    host_supported: true,
+    srcs: [
+        "src/readonly/java/**/*.java",
+    ],
+    static_libs: [
+        "s2storage_ro",
+    ],
+}
+
+// Library for read/write access to satellite S2 data files.
+// This can be a java_library_host since it is used by satellite tools, which runs on host. However,
+//  it is also used by the unit test S2RangeFileBasedSatelliteLocationLookupTest, which runs on
+// device. Thus, we need to make it a java_library to support the device-side usage,
+// `host_supported: true` to support the host-side usage.
+java_library {
+    name: "satellite-s2storage-rw",
+    host_supported: true,
+    srcs: [
+        "src/write/java/**/*.java",
+    ],
+    static_libs: [
+        "satellite-s2storage-ro",
+        "s2storage_rw",
+    ],
+}
+
+// Library for access to satellite S2 utils.
+java_library {
+    name: "satellite-s2storage-testutils",
+    host_supported: true,
+    srcs: [
+        "src/testutils/java/**/*.java",
+    ],
+    static_libs: [
+        "junit",
+        "satellite-s2storage-ro",
+    ],
+}
+
+// Tests for the satellite S2 storage code.
+java_test_host {
+    name: "SatelliteS2StorageTests",
+    srcs: ["src/test/java/**/*.java"],
+    static_libs: [
+        "junit",
+        "mockito",
+        "objenesis",
+        "satellite-s2storage-rw",
+        "satellite-s2storage-testutils",
+    ],
+    test_options: {
+        unit_test: true,
+    },
+    test_suites: ["general-tests"],
+}
\ No newline at end of file
diff --git a/utils/satellite/s2storage/TEST_MAPPING b/utils/satellite/s2storage/TEST_MAPPING
new file mode 100644
index 0000000..7d0fba8
--- /dev/null
+++ b/utils/satellite/s2storage/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+    "postsubmit": [
+        {
+            "name": "SatelliteS2StorageTests"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/HeaderBlock.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/HeaderBlock.java
new file mode 100644
index 0000000..9895d1a
--- /dev/null
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/HeaderBlock.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.read;
+
+import com.android.storage.block.read.BlockData;
+import com.android.storage.util.Visitor;
+
+/**
+ * Wraps a {@link BlockData}, interpreting it as a satellite S2 data file header (block 0). This
+ * class provides typed access to the information held in the header for use when reading a
+ * satellite S2 data file.
+ */
+public final class HeaderBlock {
+    /** Used for converting from bool type to int type */
+    public static final int TRUE = 1;
+    public static final int FALSE = 0;
+
+    private final SatS2RangeFileFormat mFileFormat;
+
+    private HeaderBlock(BlockData blockData) {
+        int offset = 0;
+
+        // Read the format information.
+        int dataS2Level = blockData.getUnsignedByte(offset++);
+        int prefixBitCount = blockData.getUnsignedByte(offset++);
+        int suffixBitCount = blockData.getUnsignedByte(offset++);
+        int suffixRecordBitCount = blockData.getUnsignedByte(offset++);
+        int suffixTableBlockIdOffset = blockData.getUnsignedByte(offset++);
+        boolean isAllowedList = (blockData.getUnsignedByte(offset) == TRUE);
+        mFileFormat = new SatS2RangeFileFormat(
+                dataS2Level, prefixBitCount, suffixBitCount, suffixTableBlockIdOffset,
+                suffixRecordBitCount, isAllowedList);
+    }
+
+    /** Creates a {@link HeaderBlock} from low-level block data from a block file. */
+    public static HeaderBlock wrap(BlockData blockData) {
+        return new HeaderBlock(blockData);
+    }
+
+    /** Returns the {@link SatS2RangeFileFormat} for the file. */
+    public SatS2RangeFileFormat getFileFormat() {
+        return mFileFormat;
+    }
+
+    /** A {@link Visitor} for the {@link HeaderBlock}. See {@link #visit} */
+    public interface HeaderBlockVisitor extends Visitor {
+
+        /** Called after {@link #begin()}, once. */
+        void visitFileFormat(SatS2RangeFileFormat fileFormat);
+    }
+
+    /**
+     * Issues callbacks to the supplied {@link HeaderBlockVisitor} containing information from the
+     * header block.
+     */
+    public void visit(HeaderBlockVisitor visitor) throws Visitor.VisitException {
+        try {
+            visitor.begin();
+            visitor.visitFileFormat(mFileFormat);
+        } finally {
+            visitor.end();
+        }
+    }
+}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/PopulatedSuffixTableBlock.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/PopulatedSuffixTableBlock.java
new file mode 100644
index 0000000..9aa56b2
--- /dev/null
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/PopulatedSuffixTableBlock.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.read;
+
+import static com.android.storage.s2.S2Support.MAX_FACE_ID;
+import static com.android.storage.s2.S2Support.cellIdToString;
+import static com.android.storage.util.Conditions.checkStateInRange;
+
+import com.android.storage.s2.S2LevelRange;
+import com.android.storage.table.packed.read.IntValueTypedPackedTable;
+import com.android.storage.table.reader.IntValueTable;
+
+import java.util.Objects;
+
+/**
+ * An implementation of {@link SuffixTableBlock.SuffixTableBlockDelegate} for tables that are backed
+ * by real block data, i.e. have one or more entries.
+ *
+ * <p>Logically, each populated suffix table block holds one or more entries for S2 ranges, e.g.:
+ * <pre>
+ *     startCellId=X, endCellId=Y
+ * </pre>
+ *
+ * <p>The storage of the range entries is as follows:
+ * <ul>
+ *     <li>The prefix bits are all the same so need not be stored in the individual entries. Only
+ *     the suffix bits of X are stored. The prefix determines the block ID when first locating the
+ *     suffix table, but it is also (redundantly) stored in the table's header for simplicity /
+ *     easy debugging.</li>
+ *     <li>Each range is expected to be relatively short, so Y is stored as a offset adjustment to
+ *     X, i.e. Y is calculated by advancing X by {length of range} cell IDs.</li>
+ * </ul>
+ */
+final class PopulatedSuffixTableBlock implements SuffixTableBlock.SuffixTableBlockDelegate {
+
+    private final SatS2RangeFileFormat mFileFormat;
+
+    private final IntValueTypedPackedTable mPackedTable;
+
+    private final SuffixTableSharedData mSuffixTableSharedData;
+
+    private final int mPrefix;
+
+    PopulatedSuffixTableBlock(
+            SatS2RangeFileFormat fileFormat, IntValueTypedPackedTable packedTable) {
+        mFileFormat = Objects.requireNonNull(fileFormat);
+        mPackedTable = Objects.requireNonNull(packedTable);
+        mSuffixTableSharedData = SuffixTableSharedData.fromBytes(packedTable.getSharedData());
+
+        // Obtain the prefix. All cellIds in this table will share the same prefix except for end
+        // range values (which are exclusive so can be for mPrefix + 1 with a suffix value of 0).
+        mPrefix = mSuffixTableSharedData.getTablePrefix();
+    }
+
+    @Override
+    public int getPrefix() {
+        return mPrefix;
+    }
+
+    @Override
+    public SuffixTableBlock.Entry findEntryByCellId(long cellId) {
+        int suffixValue = mFileFormat.extractSuffixValueFromCellId(cellId);
+        S2CellMatcher matcher = new S2CellMatcher(mFileFormat, suffixValue);
+        return findEntryWithMatcher(matcher);
+    }
+
+    @Override
+    public SuffixTableBlock.Entry findEntryByIndex(int i) {
+        return new Entry(mPackedTable.getEntryByIndex(i));
+    }
+
+    @Override
+    public int getEntryCount() {
+        return mPackedTable.getEntryCount();
+    }
+
+    /**
+     * Returns an entry that matches the supplied matcher. If multiple entries match, an arbitrary
+     * matching entry is returned. If no entries match then {@code null} is returned.
+     */
+    private SuffixTableBlock.Entry findEntryWithMatcher(
+            IntValueTable.IntValueEntryMatcher matcher) {
+        IntValueTable.TableEntry suffixTableEntry = mPackedTable.findEntry(matcher);
+        if (suffixTableEntry == null) {
+            return null;
+        }
+        return new Entry(suffixTableEntry);
+    }
+
+    /**
+     * An {@link IntValueTable.IntValueEntryMatcher} capable of interpreting and matching the
+     * key/value from the underlying table against a search suffix value.
+     */
+    private static final class S2CellMatcher implements IntValueTable.IntValueEntryMatcher {
+
+        private final SatS2RangeFileFormat mFileFormat;
+
+        private final int mSuffixSearchValue;
+
+        S2CellMatcher(SatS2RangeFileFormat fileFormat, int suffixSearchValue) {
+            mFileFormat = Objects.requireNonNull(fileFormat);
+            mSuffixSearchValue = suffixSearchValue;
+        }
+
+        @Override
+        public int compare(int key, int value) {
+            int rangeStartCellIdOffset = key;
+            if (mSuffixSearchValue < rangeStartCellIdOffset) {
+                return -1;
+            } else {
+                int rangeLength = mFileFormat.extractRangeLengthFromTableEntryValue(value);
+                int rangeEndCellIdOffset = rangeStartCellIdOffset + rangeLength;
+                if (mSuffixSearchValue >= rangeEndCellIdOffset) {
+                    return 1;
+                } else {
+                    return 0;
+                }
+            }
+        }
+    }
+
+    /**
+     * An entry from the {@link SuffixTableBlock}. Use {@link #getSuffixTableRange()} to get the
+     * full, interpreted entry data.
+     */
+    public final class Entry extends SuffixTableBlock.Entry {
+
+        private final IntValueTable.TableEntry mSuffixTableEntry;
+
+        private S2LevelRange mSuffixTableRange;
+
+        Entry(IntValueTable.TableEntry suffixTableEntry) {
+            mSuffixTableEntry = Objects.requireNonNull(suffixTableEntry);
+        }
+
+        @Override
+        public int getIndex() {
+            return mSuffixTableEntry.getIndex();
+        }
+
+        /** Returns the data for this entry. */
+        @Override
+        public S2LevelRange getSuffixTableRange() {
+            // Creating SuffixTableRange is relatively expensive so it is created lazily and
+            // memoized.
+            if (mSuffixTableRange == null) {
+                // Create the range to return.
+                int startCellIdSuffix = mSuffixTableEntry.getKey();
+                checkStateInRange("startCellIdSuffixBits", startCellIdSuffix,
+                        "minSuffixValue", 0, "maxSuffixValue", mFileFormat.getMaxSuffixValue());
+                long startCellId = mFileFormat.createCellId(mPrefix, startCellIdSuffix);
+
+                int tableEntryValue = mSuffixTableEntry.getValue();
+                int rangeLength =
+                        mFileFormat.extractRangeLengthFromTableEntryValue(tableEntryValue);
+                checkStateInRange("rangeLength", rangeLength, "minRangeLength", 0, "maxRangeLength",
+                        mFileFormat.getTableEntryMaxRangeLengthValue());
+                int endCellIdSuffix = startCellIdSuffix + rangeLength;
+
+                int endCellPrefixValue = mPrefix;
+                if (endCellIdSuffix > mFileFormat.getMaxSuffixValue()) {
+                    // Handle the special case where the range ends in the next prefix. This is
+                    // because the range end is exclusive, so the end value is allowed to be first
+                    // cell ID from the next prefix.
+                    if (endCellIdSuffix != mFileFormat.getMaxSuffixValue() + 1) {
+                        throw new IllegalStateException("Range exceeds allowable cell IDs:"
+                                + " startCellId=" + cellIdToString(startCellId)
+                                + ", rangeLength=" + rangeLength);
+                    }
+                    endCellPrefixValue += 1;
+
+                    // Check to see if the face ID has overflowed, and wrap to face zero if it has.
+                    if (mFileFormat.extractFaceIdFromPrefix(endCellPrefixValue) > MAX_FACE_ID) {
+                        endCellPrefixValue = 0;
+                    }
+                    endCellIdSuffix = 0;
+                }
+                long endCellId = mFileFormat.createCellId(endCellPrefixValue, endCellIdSuffix);
+                mSuffixTableRange = new S2LevelRange(startCellId, endCellId);
+            }
+            return mSuffixTableRange;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            Entry entry = (Entry) o;
+            return mSuffixTableEntry.equals(entry.mSuffixTableEntry);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mSuffixTableEntry);
+        }
+
+        @Override
+        public String toString() {
+            return "Entry{"
+                    + "mSuffixTableEntry=" + mSuffixTableEntry
+                    + '}';
+        }
+    }
+}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileFormat.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileFormat.java
new file mode 100644
index 0000000..39507aa
--- /dev/null
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileFormat.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.read;
+
+import static com.android.storage.s2.S2Support.FACE_BIT_COUNT;
+import static com.android.storage.s2.S2Support.MAX_FACE_ID;
+import static com.android.storage.s2.S2Support.MAX_S2_LEVEL;
+
+import com.android.storage.s2.S2Support;
+import com.android.storage.util.BitwiseUtils;
+import com.android.storage.util.Conditions;
+
+import java.util.Objects;
+
+/**
+ * Holds information about the format of a satellite S2 data file, which is a type of block file
+ * (see {@link com.android.storage.block.read.BlockFileReader}).
+ * Some information is hardcoded and some is parameterized using information read from the file's
+ * header block. This class contains useful methods for validation, interpretation and storage of
+ * data in a file with the specified format.
+ */
+public final class SatS2RangeFileFormat {
+
+    /** The block type of the satellite S2 data file header (held in block 0). */
+    public static final int BLOCK_TYPE_HEADER = 1;
+
+    /**
+     * The block type used for padding between the header and suffix tables that allows for future
+     * expansion. See {@link #getSuffixTableBlockIdOffset()}.
+     */
+    public static final int BLOCK_TYPE_PADDING = 20;
+
+    /** The block type of a populated suffix table. */
+    public static final int BLOCK_TYPE_SUFFIX_TABLE = 10;
+
+    /** The expected magic value of a satellite S2 data file. */
+    public static final char MAGIC = 0xCFAF;
+
+    /** The format version of the satellite S2 data file, read and written. */
+    public static final int VERSION = 1;
+
+    private final int mDataS2Level;
+
+    private final int mPrefixBitCount;
+
+    private final int mMaxPrefixValue;
+
+    private final int mSuffixTableBlockIdOffset;
+
+    private final int mSuffixBitCount;
+
+    private final int mMaxSuffixValue;
+
+    private final int mTableEntryByteCount;
+
+    private final int mTableEntryBitCount;
+
+    private final int mTableEntryRangeLengthBitCount;
+
+    private final int mTableEntryMaxRangeLengthValue;
+
+    /**
+     * The number of bits in a cell ID of the data storage level that have fixed values, i.e. the
+     * final "1" followed by all zeros.
+     */
+    private final int mUnusedCellIdBitCount;
+
+    /**
+     * Whether the satellite S2 file contains an allowed list of S2 cells.
+     * {@code true} means allowed list.
+     * {@code false} means disallowed list.
+     */
+    private final boolean mIsAllowedList;
+
+    /**
+     * Creates a new file format. This constructor validates the values against various hard-coded
+     * constraints and will throw an {@link IllegalArgumentException} if they are not satisfied.
+     */
+    public SatS2RangeFileFormat(int s2Level, int prefixBitCount, int suffixBitCount,
+            int suffixTableBlockIdOffset, int tableEntryBitCount, boolean isAllowedList) {
+
+        Conditions.checkArgInRange("s2Level", s2Level, 0, MAX_S2_LEVEL);
+
+        // prefixBitCount must include at least the face bits and one more, it makes the logic
+        // for mMaxPrefixValue easier below. We also assume that prefix and suffix will be 31-bits
+        // as that makes sure they can be represented, unsigned in a Java int. A prefix / suffix
+        // of 31-bits (each) should be enough for anyone(TM). 31-bits = ~15 S2 levels.
+        // Anything more than level 18 for geo data (i.e. prefix PLUS suffix) will be very
+        // detailed, so it's unlikely this constraint will be a problem.
+        Conditions.checkArgInRange("prefixBitCount", prefixBitCount, 4, Integer.SIZE - 1);
+
+        // The suffix table uses fixed length records that are broken into a key and a value. The
+        // implementation requires the key is an unsigned int value, i.e. 31-bits, and the value can
+        // be held in an int value.
+
+        // The key of a suffix table entry is used to store the suffix for the cell ID at the start
+        // of a range of S2 cells (the prefix for that cell ID is implicit and the same for every
+        // entry in the table, see prefixBitCount).
+        int tableEntryKeyBitCount = suffixBitCount;
+        Conditions.checkArgInRange(
+                "tableEntryKeyBitCount", tableEntryKeyBitCount, 1, Integer.SIZE - 1);
+
+        // The value of a suffix table entry is used to hold both the range length and the entry
+        // value. See methods below that extract these components from an int. Hence, we check they
+        // will fit.
+        int tableEntryValueBitCount = tableEntryBitCount - tableEntryKeyBitCount;
+        Conditions.checkArgInRange(
+                "tableEntryValueBitCount", tableEntryValueBitCount, 1, Integer.SIZE);
+
+        if (S2Support.storageBitCountForLevel(s2Level) != prefixBitCount + suffixBitCount) {
+            // s2Level implies cellIds have a certain number of "storage bits", the prefix and
+            // suffix must consume all the bits.
+            throw new IllegalArgumentException("prefixBitCount=" + prefixBitCount
+                    + " + suffixBitCount=" + suffixBitCount + " must be correct for the s2Level ("
+                    + S2Support.storageBitCountForLevel(s2Level) + ")");
+        }
+        if (suffixTableBlockIdOffset < 1) {
+            // The format includes a header block, so there will always be an adjustment for at
+            // least that one block.
+            throw new IllegalArgumentException(
+                    "suffixTableBlockIdOffset=" + suffixTableBlockIdOffset + " must be >= 1");
+        }
+        if (tableEntryBitCount < 0 || tableEntryBitCount % Byte.SIZE != 0
+                || tableEntryBitCount > Long.SIZE) {
+            // The classes used to read suffix tables only support entries that are a multiples of
+            // a byte. They also restrict to up a maximum of 8-bytes per table entry.
+            throw new IllegalArgumentException(
+                    "suffixTableEntryBitCount=" + tableEntryBitCount
+                            + " must be >= 0, be divisible by 8, and be no more than 64 bits");
+        }
+
+        // Everything in a suffix table entry that isn't the suffix is the range length, so we can
+        // calculate it from the information given.
+        int entryRangeLengthBitCount = tableEntryBitCount - suffixBitCount;
+        // For simplicity below we ensure we can hold the maximum range length value in an unsigned
+        // Java int, so up to 31-bits.
+        Conditions.checkArgInRange(
+                "entryRangeLengthBitCount", entryRangeLengthBitCount, 2, Integer.SIZE - 1);
+
+        // Set all the fields. The fields are either set directly from parameters or derived from
+        // the values given.
+
+        mDataS2Level = s2Level;
+        mPrefixBitCount = prefixBitCount;
+
+        // Prefix value: contains the face ID plus one or more bits for the index.
+        int cellIdIndexBitCount = prefixBitCount - FACE_BIT_COUNT;
+        mMaxPrefixValue = (int)
+                ((((long) MAX_FACE_ID) << cellIdIndexBitCount)
+                        | BitwiseUtils.maxUnsignedValue(cellIdIndexBitCount));
+
+        mSuffixBitCount = suffixBitCount;
+        mMaxSuffixValue = (int) BitwiseUtils.maxUnsignedValue(suffixBitCount);
+
+        // prefixBitCount + suffixBitCount are all the "useful" bits. The remaining bits in a 64-bit
+        // cell ID are the trailing "1" (which we don't need to store) and the rest are zeros.
+        mUnusedCellIdBitCount = Long.SIZE - (prefixBitCount + suffixBitCount);
+
+        mTableEntryBitCount = tableEntryBitCount;
+        mTableEntryByteCount = tableEntryBitCount / 8;
+
+        mTableEntryRangeLengthBitCount = entryRangeLengthBitCount;
+        mTableEntryMaxRangeLengthValue =
+                (int) BitwiseUtils.maxUnsignedValue(entryRangeLengthBitCount);
+
+        mSuffixTableBlockIdOffset = suffixTableBlockIdOffset;
+
+        mIsAllowedList = isAllowedList;
+    }
+
+    /** Returns the S2 level of all geo data stored in the file. */
+    public int getS2Level() {
+        return mDataS2Level;
+    }
+
+    /**
+     * Returns the number of prefix bits from an S2 cell ID used to identify the block containing
+     * ranges.
+     */
+    public int getPrefixBitCount() {
+        return mPrefixBitCount;
+    }
+
+    /**
+     * Returns the maximum valid value that {@link #getPrefixBitCount()} can represent. Note: This
+     * is not just the number of bits: the prefix contains the face ID which can only be 0 - 5
+     * (inclusive).
+     */
+    public int getMaxPrefixValue() {
+        return mMaxPrefixValue;
+    }
+
+    /**
+     * Returns the number of "useful" bits of an S2 cell ID in the data after
+     * {@link #getPrefixBitCount()}, i.e. not including the trailing "1".
+     * Dependent on the {@link #getS2Level()}, which dictates the number of storage bits in every
+     * cell ID in a file, and {@link #getPrefixBitCount()}.
+     */
+    public int getSuffixBitCount() {
+        return mSuffixBitCount;
+    }
+
+    /**
+     * Returns the maximum value that {@link #getSuffixBitCount()} can represent.
+     */
+    public int getMaxSuffixValue() {
+        return mMaxSuffixValue;
+    }
+
+    /**
+     * Returns the number of bits in each suffix table entry. i.e.
+     * {@link #getTableEntryByteCount()} * 8
+     */
+    public int getTableEntryBitCount() {
+        return mTableEntryBitCount;
+    }
+
+    /** Returns the number of bytes in each suffix table entry. */
+    public int getTableEntryByteCount() {
+        return mTableEntryByteCount;
+    }
+
+    /** Return the number of bits in each suffix table entry used to store the length of a range. */
+    public int getTableEntryRangeLengthBitCount() {
+        return mTableEntryRangeLengthBitCount;
+    }
+
+    /** Returns the maximum value that {@link #getTableEntryRangeLengthBitCount()} can represent. */
+    public int getTableEntryMaxRangeLengthValue() {
+        return mTableEntryMaxRangeLengthValue;
+    }
+
+    /**
+     * Returns the offset to apply to the prefix value to compute the block ID holding the data for
+     * that prefix. Always &gt;= 1 to account for the header block.
+     */
+    public int getSuffixTableBlockIdOffset() {
+        return mSuffixTableBlockIdOffset;
+    }
+
+    /**
+     * @return {@code true} if the satellite S2 file contains an allowed list of S2 cells.
+     * {@code false} if the satellite S2 file contains a disallowed list of S2 cells.
+     */
+    public boolean isAllowedList() {
+        return mIsAllowedList;
+    }
+
+    /** Extracts the prefix bits from a cell ID and returns them as an unsigned int. */
+    public int extractPrefixValueFromCellId(long cellId) {
+        checkS2Level("cellId", cellId);
+        return (int) (cellId >>> (mSuffixBitCount + mUnusedCellIdBitCount));
+    }
+
+    /** Extracts the suffix bits from a cell ID and returns them as an unsigned int. */
+    public int extractSuffixValueFromCellId(long cellId) {
+        checkS2Level("cellId", cellId);
+        return (int) (cellId >>> (mUnusedCellIdBitCount)) & mMaxSuffixValue;
+    }
+
+    /** Extracts the range length from a table entry value. */
+    public int extractRangeLengthFromTableEntryValue(int value) {
+        long mask = BitwiseUtils.getLowBitsMask(mTableEntryRangeLengthBitCount);
+        return (int) (value & mask);
+    }
+
+    /** Creates a table entry value from a range length. */
+    public long createSuffixTableValue(int rangeLength) {
+        Conditions.checkArgInRange(
+                "rangeLength", rangeLength, 0, getTableEntryMaxRangeLengthValue());
+        return rangeLength;
+    }
+
+    /** Creates a cell ID from a prefix and a suffix component. */
+    public long createCellId(int prefixValue, int suffixValue) {
+        Conditions.checkArgInRange("prefixValue", prefixValue, 0, mMaxPrefixValue);
+        Conditions.checkArgInRange("suffixValue", suffixValue, 0, mMaxSuffixValue);
+        long cellId = prefixValue;
+        cellId <<= mSuffixBitCount;
+        cellId |= suffixValue;
+        cellId <<= 1;
+        cellId |= 1;
+        cellId <<= mUnusedCellIdBitCount - 1;
+
+        checkS2Level("cellId", cellId);
+        return cellId;
+    }
+
+    /** Extracts the face ID bits from a prefix value. */
+    public int extractFaceIdFromPrefix(int prefixValue) {
+        return prefixValue >>> (mPrefixBitCount - FACE_BIT_COUNT);
+    }
+
+    /**
+     * Calculates the number of cell IDs in the given range. Throws {@link IllegalArgumentException}
+     * if {@code rangeStartCellId} is "higher" than {@code rangeEndCellId} or the range length would
+     * be outside of the int range.
+     *
+     * @param rangeStartCellId the start of the range (inclusive)
+     * @param rangeEndCellId the end of the range (exclusive)
+     */
+    public int calculateRangeLength(long rangeStartCellId, long rangeEndCellId) {
+        checkS2Level("rangeStartCellId", rangeStartCellId);
+        checkS2Level("rangeEndCellId", rangeEndCellId);
+
+        // Convert to numeric values that can just be subtracted without worrying about sign
+        // issues.
+        long rangeEndCellIdNumeric = rangeEndCellId >>> mUnusedCellIdBitCount;
+        long rangeStartCellIdNumeric = rangeStartCellId >>> mUnusedCellIdBitCount;
+        if (rangeStartCellIdNumeric >= rangeEndCellIdNumeric) {
+            throw new IllegalArgumentException(
+                    "rangeStartCellId=" + cellIdToString(rangeStartCellId)
+                            + " is >= rangeEndCellId=" + cellIdToString(rangeEndCellId));
+        }
+        long differenceNumeric = rangeEndCellIdNumeric - rangeStartCellIdNumeric;
+        if (differenceNumeric < 0 || differenceNumeric > Integer.MAX_VALUE) {
+            throw new IllegalArgumentException("rangeLength=" + differenceNumeric
+                    + " is outside of expected range");
+        }
+        return (int) differenceNumeric;
+    }
+
+    /** Formats a cellId in terms of prefix and suffix values. */
+    public String cellIdToString(long cellId) {
+        int prefix = extractPrefixValueFromCellId(cellId);
+        int suffix = extractSuffixValueFromCellId(cellId);
+        String prefixBitsString = BitwiseUtils.toUnsignedString(mPrefixBitCount, prefix);
+        String suffixBitsString = BitwiseUtils.toUnsignedString(mSuffixBitCount, suffix);
+        return "cellId{prefix=" + prefix + " (" + prefixBitsString + ")"
+                + ", suffix=" + suffix + " (" + suffixBitsString + ")"
+                + "}";
+    }
+
+    @Override
+    public String toString() {
+        return "SatS2RangeFileFormat{"
+                + "mDataS2Level=" + mDataS2Level
+                + ", mPrefixBitCount=" + mPrefixBitCount
+                + ", mMaxPrefixValue=" + mMaxPrefixValue
+                + ", mSuffixBitCount=" + mSuffixBitCount
+                + ", mMaxSuffixValue=" + mMaxSuffixValue
+                + ", mTableEntryBitCount=" + mTableEntryBitCount
+                + ", mTableEntryRangeLengthBitCount=" + mTableEntryRangeLengthBitCount
+                + ", mTableEntryMaxRangeLengthValue=" + mTableEntryMaxRangeLengthValue
+                + ", mSuffixTableBlockIdOffset=" + mSuffixTableBlockIdOffset
+                + ", mUnusedCellIdBitCount=" + mUnusedCellIdBitCount
+                + ", mIsAllowedList=" + mIsAllowedList
+                + '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        SatS2RangeFileFormat that = (SatS2RangeFileFormat) o;
+        return mDataS2Level == that.mDataS2Level
+                && mPrefixBitCount == that.mPrefixBitCount
+                && mMaxPrefixValue == that.mMaxPrefixValue
+                && mSuffixBitCount == that.mSuffixBitCount
+                && mMaxSuffixValue == that.mMaxSuffixValue
+                && mTableEntryBitCount == that.mTableEntryBitCount
+                && mTableEntryRangeLengthBitCount == that.mTableEntryRangeLengthBitCount
+                && mTableEntryMaxRangeLengthValue == that.mTableEntryMaxRangeLengthValue
+                && mSuffixTableBlockIdOffset == that.mSuffixTableBlockIdOffset
+                && mIsAllowedList == that.mIsAllowedList
+                && mUnusedCellIdBitCount == that.mUnusedCellIdBitCount;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mDataS2Level, mPrefixBitCount, mMaxPrefixValue, mSuffixBitCount,
+                mMaxSuffixValue, mTableEntryBitCount, mTableEntryRangeLengthBitCount,
+                mTableEntryMaxRangeLengthValue, mSuffixTableBlockIdOffset, mIsAllowedList,
+                mUnusedCellIdBitCount);
+    }
+
+    private void checkS2Level(String name, long cellId) {
+        if (S2Support.getS2Level(cellId) != mDataS2Level) {
+            throw new IllegalArgumentException(
+                    name + "=" + S2Support.cellIdToString(cellId) + " is at the wrong level");
+        }
+    }
+}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileReader.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileReader.java
new file mode 100644
index 0000000..ecfa0a9
--- /dev/null
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SatS2RangeFileReader.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.read;
+
+import com.android.storage.block.read.Block;
+import com.android.storage.block.read.BlockFileReader;
+import com.android.storage.block.read.BlockInfo;
+import com.android.storage.s2.S2LevelRange;
+import com.android.storage.s2.S2Support;
+import com.android.storage.util.Conditions;
+import com.android.storage.util.Visitor;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Objects;
+
+/** Provides access to the content of a satellite S2 data file. */
+public final class SatS2RangeFileReader implements AutoCloseable {
+
+    private final BlockFileReader mBlockFileReader;
+
+    private HeaderBlock mHeaderBlock;
+
+    private SuffixTableExtraInfo[] mSuffixTableExtraInfos;
+
+    /** Convenience field to avoid calling {@link HeaderBlock#getFileFormat()} repeatedly. */
+    private SatS2RangeFileFormat mFileFormat;
+
+    private boolean mClosed;
+
+    private SatS2RangeFileReader(BlockFileReader blockFileReader) {
+        mBlockFileReader = Objects.requireNonNull(blockFileReader);
+    }
+
+    /**
+     * Opens the specified file. Throws {@link IOException} in the event of a access problem reading
+     * the file. Throws {@link IllegalArgumentException} if the file has a format / syntax problem.
+     *
+     * <p>After open, use methods like {@link #findEntryByCellId(long)} to access the data.
+     */
+    public static SatS2RangeFileReader open(File file) throws IOException {
+        boolean memoryMapBlocks = false;
+        BlockFileReader blockFileReader = BlockFileReader.open(
+                memoryMapBlocks, file, SatS2RangeFileFormat.MAGIC, SatS2RangeFileFormat.VERSION);
+        SatS2RangeFileReader satS2RangeFileReader = new SatS2RangeFileReader(blockFileReader);
+        satS2RangeFileReader.initialize();
+        return satS2RangeFileReader;
+    }
+
+    private void initialize() throws IOException {
+        // Check the BlockInfo for the header block is what we expect.
+        int headerBlockId = 0;
+        BlockInfo firstBlockInfo = mBlockFileReader.getBlockInfo(headerBlockId);
+        if (firstBlockInfo.getType() != SatS2RangeFileFormat.BLOCK_TYPE_HEADER) {
+            throw new IllegalArgumentException("headerBlockInfo.getType()="
+                    + firstBlockInfo.getType() + " must be "
+                    + SatS2RangeFileFormat.BLOCK_TYPE_HEADER);
+        }
+
+        // So far so good. Open the header block itself and extract the information held there.
+        Block firstBlock = mBlockFileReader.getBlock(headerBlockId);
+        if (firstBlock.getType() != SatS2RangeFileFormat.BLOCK_TYPE_HEADER) {
+            throw new IllegalArgumentException("firstBlock.getType()=" + firstBlock.getType()
+                    + " must be " + SatS2RangeFileFormat.BLOCK_TYPE_HEADER);
+        }
+        mHeaderBlock = HeaderBlock.wrap(firstBlock.getData());
+
+        // Optimization: hold a direct reference to fileFormat since it is referenced often.
+        mFileFormat = mHeaderBlock.getFileFormat();
+
+        // Read all the BlockInfos for data blocks and precache the SuffixTableBlock.Info instances.
+        mSuffixTableExtraInfos = new SuffixTableExtraInfo[mFileFormat.getMaxPrefixValue() + 1];
+        for (int prefix = 0; prefix < mSuffixTableExtraInfos.length; prefix++) {
+            int blockId = prefix + mFileFormat.getSuffixTableBlockIdOffset();
+            BlockInfo blockInfo = mBlockFileReader.getBlockInfo(blockId);
+            int type = blockInfo.getType();
+            if (type == SatS2RangeFileFormat.BLOCK_TYPE_SUFFIX_TABLE) {
+                mSuffixTableExtraInfos[prefix] =
+                        SuffixTableExtraInfo.create(mFileFormat, blockInfo);
+            } else {
+                throw new IllegalStateException("Unknown block type=" + type);
+            }
+        }
+    }
+
+    /** A {@link Visitor} for the {@link SatS2RangeFileReader}. See {@link #visit} */
+    public interface SatS2RangeFileVisitor extends Visitor {
+
+        /** Called after {@link #begin()}, once only. */
+        void visitHeaderBlock(HeaderBlock headerBlock) throws VisitException;
+
+        /**
+         * Called after {@link #visitHeaderBlock(HeaderBlock)}}, once for each suffix table in the
+         * file.
+         */
+        void visitSuffixTableExtraInfo(SuffixTableExtraInfo suffixTableExtraInfo)
+                throws VisitException;
+
+        /**
+         * Called after {@link #visitHeaderBlock(HeaderBlock)}, once per suffix table in the file.
+         */
+        void visitSuffixTableBlock(SuffixTableBlock suffixTableBlock) throws VisitException;
+    }
+
+    /**
+     * Issues callbacks to the supplied {@link SatS2RangeFileVisitor} containing information from
+     * the satellite S2 data file.
+     */
+    public void visit(SatS2RangeFileVisitor visitor) throws Visitor.VisitException {
+        try {
+            visitor.begin();
+
+            visitor.visitHeaderBlock(mHeaderBlock);
+
+            for (int i = 0; i < mSuffixTableExtraInfos.length; i++) {
+                visitor.visitSuffixTableExtraInfo(mSuffixTableExtraInfos[i]);
+            }
+
+            try {
+                for (int i = 0; i < mSuffixTableExtraInfos.length; i++) {
+                    SuffixTableBlock suffixTableBlock = getSuffixTableBlockForPrefix(i);
+                    visitor.visitSuffixTableBlock(suffixTableBlock);
+                }
+            } catch (IOException e) {
+                throw new Visitor.VisitException(e);
+            }
+        } finally {
+            visitor.end();
+        }
+    }
+
+    /**
+     * Finds an {@link S2LevelRange} associated with a range covering {@code cellId}.
+     * Returns {@code null} if no range exists. Throws {@link IllegalArgumentException} if
+     * {@code cellId} is not the correct S2 level for the file. See {@link #getS2Level()}.
+     */
+    public S2LevelRange findEntryByCellId(long cellId) throws IOException {
+        checkNotClosed();
+        int dataS2Level = mFileFormat.getS2Level();
+        int searchS2Level = S2Support.getS2Level(cellId);
+        if (dataS2Level != searchS2Level) {
+            throw new IllegalArgumentException(
+                    "data S2 level=" + dataS2Level + ", search S2 level=" + searchS2Level);
+        }
+
+        int prefix = mFileFormat.extractPrefixValueFromCellId(cellId);
+        SuffixTableBlock suffixTableBlock = getSuffixTableBlockForPrefix(prefix);
+        SuffixTableBlock.Entry suffixTableEntry = suffixTableBlock.findEntryByCellId(cellId);
+        if (suffixTableEntry == null) {
+            return null;
+        }
+        return suffixTableEntry.getSuffixTableRange();
+    }
+
+    private SuffixTableExtraInfo getSuffixTableExtraInfoForPrefix(int prefixValue) {
+        Conditions.checkArgInRange(
+                "prefixValue", prefixValue, "minPrefixValue", 0, "maxPrefixValue",
+                mFileFormat.getMaxPrefixValue());
+
+        return mSuffixTableExtraInfos[prefixValue];
+    }
+
+    private SuffixTableBlock getSuffixTableBlockForPrefix(int prefix) throws IOException {
+        SuffixTableExtraInfo suffixTableExtraInfo = getSuffixTableExtraInfoForPrefix(prefix);
+        if (suffixTableExtraInfo.isEmpty()) {
+            return SuffixTableBlock.createEmpty(mFileFormat, prefix);
+        }
+        Block block = mBlockFileReader.getBlock(prefix + mFileFormat.getSuffixTableBlockIdOffset());
+        SuffixTableBlock suffixTableBlock =
+                SuffixTableBlock.createPopulated(mFileFormat, block.getData());
+        if (prefix != suffixTableBlock.getPrefix()) {
+            throw new IllegalArgumentException("prefixValue=" + prefix
+                    + " != suffixTableBlock.getPrefix()=" + suffixTableBlock.getPrefix());
+        }
+        return suffixTableBlock;
+    }
+
+    @Override
+    public void close() throws IOException {
+        mClosed = true;
+        mHeaderBlock = null;
+        mBlockFileReader.close();
+    }
+
+    private void checkNotClosed() throws IOException {
+        if (mClosed) {
+            throw new IOException("Closed");
+        }
+    }
+
+    /** Returns the S2 level for the file. See also {@link #findEntryByCellId(long)}. */
+    public int getS2Level() throws IOException {
+        checkNotClosed();
+        return mHeaderBlock.getFileFormat().getS2Level();
+    }
+
+    /**
+     * @return {@code true} if the satellite S2 file contains an allowed list of S2 cells.
+     * {@code false} if the satellite S2 file contains a disallowed list of S2 cells.
+     */
+    public boolean isAllowedList() {
+        return mFileFormat.isAllowedList();
+    }
+}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableBlock.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableBlock.java
new file mode 100644
index 0000000..1a6fad7
--- /dev/null
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableBlock.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.read;
+
+import static com.android.storage.s2.S2Support.cellIdToString;
+import static com.android.storage.s2.S2Support.getS2Level;
+
+import com.android.storage.block.read.BlockData;
+import com.android.storage.s2.S2LevelRange;
+import com.android.storage.table.packed.read.IntValueTypedPackedTable;
+import com.android.storage.util.BitwiseUtils;
+import com.android.storage.util.Visitor;
+
+import java.util.Objects;
+
+/**
+ * The main type of block for a satellite S2 data file.
+ *
+ * <p>Logically, each suffix table block holds zero or more entries for S2 ranges, e.g.:
+ * <pre>
+ *     startCellId=X, endCellId=Y
+ * </pre>
+ *
+ * <p>Tables are generated so that all entries in the table have the same S2 level and "prefix
+ * bits" for the S2 cell IDs they describe, i.e. if the table's assigned prefix is "1011000", then
+ * every cell ID included in every range entry (i.e. from X to Y) must start with "1011000". The
+ * entries in the table are ordered by startCellId and ranges cannot overlap. There is only one
+ * block / suffix table for each possible prefix.
+ *
+ * <p>Note that because the endCellId is <em>exclusive</em>, the last entry's endCellId <em>can</em>
+ * refer the first S2 cell ID from the next prefix, or wrap around to face 0 for the last entry
+ * for face ID 5.
+ *
+ * <p>Any S2 cell id with a prefix that is not covered by a range entry in the associated table can
+ * be inferred to have a value of zero.
+ *
+ * <p>Entries can be obtained by called methods such as {@link #getEntryByIndex(int)},
+ * {@link #findEntryByCellId(long)}.
+ */
+public final class SuffixTableBlock {
+
+    private final SatS2RangeFileFormat mFileFormat;
+
+    private final SuffixTableBlockDelegate mDelegate;
+
+    private final int mPrefix;
+
+    /**
+     * The implementation of the suffix table block. Suffix table blocks have two main
+     * implementations: zero-length blocks used to represent empty tables, and blocks containing
+     * {@link IntValueTypedPackedTable} data. Since they are so different they are implemented
+     * independently.
+     */
+    interface SuffixTableBlockDelegate {
+
+        /** Returns the prefix for cell IDs in this table. */
+        int getPrefix();
+
+        /**
+         * Returns the entry containing the specified cell ID, or {@code null} if there isn't one.
+         */
+        Entry findEntryByCellId(long cellId);
+
+        /**
+         * Returns the entry with the specified index. Throws {@link IndexOutOfBoundsException} if
+         * the index is invalid.
+         */
+        Entry findEntryByIndex(int i);
+
+        /** Returns the number of entries in the table. */
+        int getEntryCount();
+    }
+
+    private SuffixTableBlock(SatS2RangeFileFormat fileFormat, SuffixTableBlockDelegate delegate) {
+        mFileFormat = Objects.requireNonNull(fileFormat);
+        mDelegate = Objects.requireNonNull(delegate);
+        mPrefix = delegate.getPrefix();
+    }
+
+    /**
+     * Creates a populated {@link SuffixTableBlock} by interpreting {@link BlockData} and using
+     * the supplied format information.
+     */
+    public static SuffixTableBlock createPopulated(
+            SatS2RangeFileFormat fileFormat, BlockData blockData) {
+        if (blockData.getSize() == 0) {
+            throw new IllegalArgumentException("blockData=" + blockData + ", is zero length");
+        }
+        IntValueTypedPackedTable packedTable = new IntValueTypedPackedTable(blockData);
+        PopulatedSuffixTableBlock delegate = new PopulatedSuffixTableBlock(fileFormat, packedTable);
+        return new SuffixTableBlock(fileFormat, delegate);
+    }
+
+    /**
+     * Creates an unpopulated {@link SuffixTableBlock} for the supplied prefix and using
+     * the supplied format information.
+     */
+    public static SuffixTableBlock createEmpty(SatS2RangeFileFormat fileFormat, int prefix) {
+        return new SuffixTableBlock(fileFormat, new UnpopulatedSuffixTableBlock(prefix));
+    }
+
+    /** Returns the prefix for this table. */
+    public int getPrefix() {
+        return mDelegate.getPrefix();
+    }
+
+    /**
+     * Returns the entry for a given cell ID or {@code null} if there isn't one. The
+     * {@code cellId} must be the same level as the table and have the same prefix otherwise an
+     * {@link IllegalArgumentException} is thrown.
+     */
+    public Entry findEntryByCellId(long cellId) {
+        if (getS2Level(cellId) != mFileFormat.getS2Level()) {
+            throw new IllegalArgumentException(
+                    cellIdToString(cellId) + " s2 level is not "
+                            + mFileFormat.getS2Level());
+        }
+        if (mFileFormat.extractPrefixValueFromCellId(cellId) != mPrefix) {
+            String prefixBitString =
+                    BitwiseUtils.toUnsignedString(mFileFormat.getPrefixBitCount(), mPrefix);
+            throw new IllegalArgumentException(
+                    cellId + "(" + mFileFormat.cellIdToString(cellId)
+                            + ") does not have prefix bits " + mPrefix
+                            + " (" + prefixBitString + ")");
+        }
+
+        return mDelegate.findEntryByCellId(cellId);
+    }
+
+    /** Returns the entry at the specified index. */
+    public Entry getEntryByIndex(int i) {
+        return mDelegate.findEntryByIndex(i);
+    }
+
+    /** Returns the number of entries in the table. */
+    public int getEntryCount() {
+        return mDelegate.getEntryCount();
+    }
+
+    /** A {@link Visitor} for the {@link SuffixTableBlock}. See {@link #visit} */
+    public interface SuffixTableBlockVisitor extends Visitor {
+
+        /** Called after {@link #begin()}, once. */
+        void visit(SuffixTableBlock suffixTableBlock) throws VisitException;
+    }
+
+    /**
+     * Issues callbacks to the supplied {@link SuffixTableBlockVisitor}.
+     */
+    public void visit(SuffixTableBlockVisitor visitor) throws Visitor.VisitException {
+        try {
+            visitor.begin();
+            visitor.visit(this);
+        } finally {
+            visitor.end();
+        }
+    }
+
+    /**
+     * An entry from the {@link SuffixTableBlock}. Use {@link #getSuffixTableRange()} to get the
+     * full, interpreted entry data.
+     */
+    public abstract static class Entry {
+
+        /** Returns the position of this entry in the table. */
+        public abstract int getIndex();
+
+        /** Returns the data for this entry. */
+        public abstract S2LevelRange getSuffixTableRange();
+    }
+}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableExtraInfo.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableExtraInfo.java
new file mode 100644
index 0000000..2b179fe
--- /dev/null
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableExtraInfo.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.read;
+
+import com.android.storage.block.read.BlockInfo;
+import com.android.storage.io.read.TypedInputStream;
+import com.android.storage.util.Conditions;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/**
+ * Information about a suffix table block held in the header of a satellite S2 data file. It can be
+ * used to work out whether to read the associated block data.
+ */
+public final class SuffixTableExtraInfo {
+
+    /**
+     * The suffix table's S2 cell ID prefix. This information is not stored in the block info
+     * directly; during file read it is calculated from the block ID, i.e.  {block id} - {suffix
+     * table block id offset}.
+     */
+    private final int mPrefix;
+
+    private final int mEntryCount;
+
+    /** Creates metadata about a suffix table. */
+    public SuffixTableExtraInfo(int prefix, int entryCount) {
+        if (prefix < 0) {
+            throw new IllegalArgumentException("prefix=" + prefix + " must be >= 0");
+        }
+        mPrefix = prefix;
+
+        if (entryCount < 0) {
+            throw new IllegalArgumentException("entryCount=" + entryCount + " must be >= 0");
+        }
+        mEntryCount = entryCount;
+    }
+
+    /**
+     * Creates a {@link SuffixTableExtraInfo} from a {@link BlockInfo}. Throws an
+     * {@link IllegalArgumentException} if the block info is the wrong type or malformed.
+     */
+    public static SuffixTableExtraInfo create(
+            SatS2RangeFileFormat fileFormat, BlockInfo blockInfo) {
+        if (blockInfo.getType() != SatS2RangeFileFormat.BLOCK_TYPE_SUFFIX_TABLE) {
+            throw new IllegalArgumentException("blockType=" + blockInfo.getType()
+                    + " is not of expected type=" + SatS2RangeFileFormat.BLOCK_TYPE_SUFFIX_TABLE);
+        }
+        int prefix = blockInfo.getId() - fileFormat.getSuffixTableBlockIdOffset();
+        if (blockInfo.getBlockSizeBytes() == 0) {
+            // Empty blocks have no data and no extra bytes but we know they have zero elements.
+            return new SuffixTableExtraInfo(prefix, 0 /* entryCount */);
+        }
+
+        byte[] extraBytes = blockInfo.getExtraBytes();
+        if (extraBytes == null || extraBytes.length == 0) {
+            throw new IllegalArgumentException(
+                    "Extra bytes null or empty in blockInfo=" + blockInfo);
+        }
+
+        try (TypedInputStream typedInputStream = new TypedInputStream(
+                new ByteArrayInputStream(extraBytes))) {
+            int entryCount = typedInputStream.readInt();
+            Conditions.checkStateInRange(
+                    "entryCount", entryCount, "minSuffixValue", 0, "maxSuffixValue",
+                    fileFormat.getMaxSuffixValue());
+            return new SuffixTableExtraInfo(prefix, entryCount);
+        } catch (IOException e) {
+            // This shouldn't happen with a byte[]
+            throw new IllegalStateException("Unexpected exception while reading a byte[]", e);
+        }
+    }
+
+    /** Returns the prefix of the associated suffix table. */
+    public int getPrefix() {
+        return mPrefix;
+    }
+
+    /** Returns the number of entries in the associated suffix table. */
+    public int getEntryCount() {
+        return mEntryCount;
+    }
+
+    /** Returns true if the number of entries in the associated suffix table is zero. */
+    public boolean isEmpty() {
+        return mEntryCount == 0;
+    }
+}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableSharedData.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableSharedData.java
new file mode 100644
index 0000000..2221b2c
--- /dev/null
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/SuffixTableSharedData.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.read;
+
+import com.android.storage.io.read.TypedInputStream;
+import com.android.storage.table.reader.Table;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * Shared data for a suffix table held in a suffix table block: the information applies to all
+ * entries in the table and is required when interpreting the table's block data.
+ */
+public final class SuffixTableSharedData {
+
+    private final int mTablePrefix;
+
+    /**
+     * Creates a {@link SuffixTableSharedData}. See also {@link #fromBytes(byte[])}.
+     */
+    public SuffixTableSharedData(int tablePrefix) {
+        mTablePrefix = tablePrefix;
+    }
+
+    /**
+     * Returns the S2 cell ID prefix associated with the table. i.e. all S2 ranges in the table will
+     * have this prefix.
+     */
+    public int getTablePrefix() {
+        return mTablePrefix;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        SuffixTableSharedData that = (SuffixTableSharedData) o;
+        return mTablePrefix == that.mTablePrefix;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mTablePrefix);
+    }
+
+    @Override
+    public String toString() {
+        return "SuffixTableSharedData{"
+                + "mTablePrefix=" + mTablePrefix
+                + '}';
+    }
+
+    /**
+     * Creates a {@link SuffixTableSharedData} using shared data from a {@link Table}.
+     */
+    public static SuffixTableSharedData fromBytes(byte[] bytes) {
+        try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+                TypedInputStream tis = new TypedInputStream(bis)) {
+            int tablePrefixValue = tis.readInt();
+            return new SuffixTableSharedData(tablePrefixValue);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/UnpopulatedSuffixTableBlock.java b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/UnpopulatedSuffixTableBlock.java
new file mode 100644
index 0000000..56730c2
--- /dev/null
+++ b/utils/satellite/s2storage/src/readonly/java/com/android/telephony/sats2range/read/UnpopulatedSuffixTableBlock.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.read;
+
+/**
+ * An implementation of {@link SuffixTableBlock.SuffixTableBlockDelegate} for tables that are not
+ * backed by real block data, i.e. have zero entries.
+ */
+final class UnpopulatedSuffixTableBlock implements SuffixTableBlock.SuffixTableBlockDelegate {
+
+    private final int mPrefix;
+
+    UnpopulatedSuffixTableBlock(int prefix) {
+        mPrefix = prefix;
+    }
+
+    @Override
+    public int getPrefix() {
+        return mPrefix;
+    }
+
+    @Override
+    public SuffixTableBlock.Entry findEntryByCellId(long cellId) {
+        return null;
+    }
+
+    @Override
+    public SuffixTableBlock.Entry findEntryByIndex(int i) {
+        throw new IndexOutOfBoundsException("Unpopulated table");
+    }
+
+    @Override
+    public int getEntryCount() {
+        return 0;
+    }
+}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/HeaderBlockTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/HeaderBlockTest.java
new file mode 100644
index 0000000..e7bad01
--- /dev/null
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/HeaderBlockTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import com.android.storage.block.write.BlockWriter;
+import com.android.telephony.sats2range.read.HeaderBlock;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.utils.TestUtils;
+import com.android.telephony.sats2range.write.HeaderBlockWriter;
+
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+
+import java.io.IOException;
+
+/** Tests for {@link HeaderBlockWriter} and {@link HeaderBlock}. */
+public class HeaderBlockTest {
+    @Test
+    public void readWrite() throws IOException {
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+
+        // Create header data using HeaderBlockWriter.
+        HeaderBlockWriter headerBlockWriter = HeaderBlockWriter.create(fileFormat);
+        BlockWriter.ReadBack readBack = headerBlockWriter.close();
+        assertEquals(SatS2RangeFileFormat.BLOCK_TYPE_HEADER, readBack.getType());
+        assertArrayEquals(new byte[0], readBack.getExtraBytes());
+
+        // Read the data back and confirm it matches what we expected.
+        HeaderBlock headerBlock = HeaderBlock.wrap(readBack.getBlockData());
+        assertEquals(fileFormat, headerBlock.getFileFormat());
+    }
+
+    @Test
+    public void visit() throws Exception {
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+
+        // Create header data using HeaderBlockWriter.
+        HeaderBlockWriter headerBlockWriter = HeaderBlockWriter.create(fileFormat);
+        BlockWriter.ReadBack readBack = headerBlockWriter.close();
+
+        // Read the data back and confirm it matches what we expected.
+        HeaderBlock headerBlock = HeaderBlock.wrap(readBack.getBlockData());
+
+        HeaderBlock.HeaderBlockVisitor mockVisitor =
+                Mockito.mock(HeaderBlock.HeaderBlockVisitor.class);
+
+        headerBlock.visit(mockVisitor);
+
+        InOrder inOrder = Mockito.inOrder(mockVisitor);
+        inOrder.verify(mockVisitor).begin();
+        inOrder.verify(mockVisitor).visitFileFormat(fileFormat);
+        inOrder.verify(mockVisitor).end();
+    }
+}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/PushBackIteratorTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/PushBackIteratorTest.java
new file mode 100644
index 0000000..84a960a
--- /dev/null
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/PushBackIteratorTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import com.android.telephony.sats2range.write.PushBackIterator;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/** Tests for {@link PushBackIterator}. */
+public class PushBackIteratorTest {
+
+    @Test
+    public void test() {
+        List<String> values = listOf("One", "Two", "Three", "Four");
+        PushBackIterator<String> iterator = new PushBackIterator<>(values.iterator());
+        assertTrue(iterator.hasNext());
+
+        // iterator = One, Two, Three, Four
+        iterator.pushBack("Zero");
+        assertTrue(iterator.hasNext());
+        assertEquals("Zero", iterator.next());
+
+        // iterator = One, Two, Three, Four
+        assertTrue(iterator.hasNext());
+        assertEquals("One", iterator.next());
+
+        // iterator = Two, Three, Four
+        iterator.pushBack("One");
+        iterator.pushBack("Zero");
+        assertTrue(iterator.hasNext());
+        assertEquals("Zero", iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals("One", iterator.next());
+
+        // iterator = Two, Three, Four
+        assertTrue(iterator.hasNext());
+        assertEquals("Two", iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals("Three", iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals("Four", iterator.next());
+        assertFalse(iterator.hasNext());
+
+        assertThrows(NoSuchElementException.class, iterator::next);
+
+        // iterator = Empty
+        iterator.pushBack("Four");
+        assertTrue(iterator.hasNext());
+        assertEquals("Four", iterator.next());
+    }
+
+    @Test
+    public void removeNotSupported() {
+        List<String> values = listOf("One", "Two", "Three", "Four");
+        PushBackIterator<String> iterator = new PushBackIterator<>(values.iterator());
+        assertEquals("One", iterator.next());
+
+        assertThrows(UnsupportedOperationException.class, iterator::remove);
+
+        iterator.pushBack("One");
+        iterator.pushBack("Zero");
+
+        assertThrows(UnsupportedOperationException.class, iterator::remove);
+
+        assertEquals("Zero", iterator.next());
+        assertThrows(UnsupportedOperationException.class, iterator::remove);
+    }
+
+    /** Returns a list from a varargs param. */
+    @SafeVarargs
+    private static <E> List<E> listOf(E... values) {
+        return Arrays.asList(values);
+    }
+}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileFormatTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileFormatTest.java
new file mode 100644
index 0000000..80ef467
--- /dev/null
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileFormatTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range;
+
+import static com.android.storage.s2.S2Support.cellId;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+
+import org.junit.Test;
+
+/** Tests for {@link SatS2RangeFileFormat}. */
+public class SatS2RangeFileFormatTest {
+    @Test
+    public void accessors() {
+        int s2Level = 12;
+        int prefixBitCount = 11;
+        int suffixBitCount = 16;
+        int suffixTableBlockIdOffset = 5;
+        int tableEntryBitCount = 24;
+        int entryRangeLengthBitCount = 8;
+        boolean isAllowedList = true;
+        SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
+                prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, tableEntryBitCount,
+                isAllowedList);
+
+        assertEquals(s2Level, satS2RangeFileFormat.getS2Level());
+        assertEquals(prefixBitCount, satS2RangeFileFormat.getPrefixBitCount());
+        assertEquals(suffixBitCount, satS2RangeFileFormat.getSuffixBitCount());
+        assertEquals(suffixTableBlockIdOffset, satS2RangeFileFormat.getSuffixTableBlockIdOffset());
+        assertEquals(tableEntryBitCount, satS2RangeFileFormat.getTableEntryBitCount());
+        assertEquals(entryRangeLengthBitCount,
+                satS2RangeFileFormat.getTableEntryRangeLengthBitCount());
+
+        // Derived values
+        assertEquals((6 * intPow2(prefixBitCount - 3)) - 1,
+                satS2RangeFileFormat.getMaxPrefixValue());
+        assertEquals(maxValForBits(suffixBitCount), satS2RangeFileFormat.getMaxSuffixValue());
+        assertEquals(tableEntryBitCount / 8, satS2RangeFileFormat.getTableEntryByteCount());
+        assertEquals(maxValForBits(entryRangeLengthBitCount),
+                satS2RangeFileFormat.getTableEntryMaxRangeLengthValue());
+        assertTrue(satS2RangeFileFormat.isAllowedList());
+    }
+
+    @Test
+    public void calculateRangeLength() {
+        int s2Level = 12;
+        int prefixBitCount = 11;
+        int suffixBitCount = 16;
+        int suffixTableBlockIdOffset = 5;
+        int suffixTableEntryBitCount = 24;
+        boolean isAllowedList = false;
+        SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
+                prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
+                isAllowedList);
+
+        assertEquals(2, satS2RangeFileFormat.calculateRangeLength(
+                cellId(s2Level, 0, 0), cellId(s2Level, 0, 2)));
+        assertEquals(2, satS2RangeFileFormat.calculateRangeLength(
+                cellId(s2Level, 0, 2), cellId(s2Level, 0, 4)));
+
+        int cellsPerFace = intPow2(s2Level * 2);
+        assertEquals(cellsPerFace + 2,
+                satS2RangeFileFormat.calculateRangeLength(
+                        cellId(s2Level, 0, 2), cellId(s2Level, 1, 4)));
+        assertFalse(satS2RangeFileFormat.isAllowedList());
+    }
+
+    @Test
+    public void createCellId() {
+        int s2Level = 12;
+        int prefixBitCount = 11;
+        int suffixBitCount = 16;
+        int suffixTableBlockIdOffset = 5;
+        int suffixTableEntryBitCount = 24;
+        boolean isAllowedList = true;
+        SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
+                prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
+                isAllowedList);
+
+        // Too many bits for prefixValue
+        assertThrows(IllegalArgumentException.class,
+                () -> satS2RangeFileFormat.createCellId(0b1000_00000000, 0b10000000_00000000));
+
+        // Too many bits for suffixValue
+        assertThrows(IllegalArgumentException.class,
+                () -> satS2RangeFileFormat.createCellId(0b1000_00000000, 0b100000000_00000000));
+
+        // Some valid cases.
+        assertEquals(cellId(s2Level, 4, 0),
+                satS2RangeFileFormat.createCellId(0b100_00000000, 0b00000000_00000000));
+        assertEquals(cellId(s2Level, 4, 1),
+                satS2RangeFileFormat.createCellId(0b100_00000000, 0b00000000_00000001));
+
+        assertEquals(cellId(s2Level, 5, intPow2(0)),
+                satS2RangeFileFormat.createCellId(0b101_00000000, 0b00000000_00000001));
+        assertEquals(cellId(s2Level, 5, intPow2(8)),
+                satS2RangeFileFormat.createCellId(0b101_00000000, 0b00000001_00000000));
+        assertEquals(cellId(s2Level, 5, intPow2(16)),
+                satS2RangeFileFormat.createCellId(0b101_00000001, 0b00000000_00000000));
+        assertTrue(satS2RangeFileFormat.isAllowedList());
+    }
+
+    @Test
+    public void extractFaceIdFromPrefix() {
+        int s2Level = 12;
+        int prefixBitCount = 11;
+        int suffixBitCount = 16;
+        int suffixTableBlockIdOffset = 5;
+        int suffixTableEntryBitCount = 24;
+        boolean isAllowedList = true;
+        SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
+                prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
+                isAllowedList);
+
+        assertEquals(0, satS2RangeFileFormat.extractFaceIdFromPrefix(0b00000000000));
+        assertEquals(5, satS2RangeFileFormat.extractFaceIdFromPrefix(0b10100000000));
+        // We require this (invalid) face ID to work, since this method is used to detect face ID
+        // overflow.
+        assertEquals(6, satS2RangeFileFormat.extractFaceIdFromPrefix(0b11000000000));
+        assertTrue(satS2RangeFileFormat.isAllowedList());
+    }
+
+    @Test
+    public void createSuffixTableValue() {
+        int s2Level = 12;
+        int prefixBitCount = 11;
+        int suffixBitCount = 16;
+        int suffixTableBlockIdOffset = 5;
+        int suffixTableEntryBitCount = 24;
+        boolean isAllowedList = true;
+        SatS2RangeFileFormat satS2RangeFileFormat = new SatS2RangeFileFormat(s2Level,
+                prefixBitCount, suffixBitCount, suffixTableBlockIdOffset, suffixTableEntryBitCount,
+                isAllowedList);
+
+        // Too many bits for rangeLength
+        assertThrows(IllegalArgumentException.class,
+                () -> satS2RangeFileFormat.createSuffixTableValue(0b100000000));
+
+        // Some valid cases.
+        assertEquals(0b10101, satS2RangeFileFormat.createSuffixTableValue(0b10101));
+        assertEquals(0b00000, satS2RangeFileFormat.createSuffixTableValue(0b00000));
+        assertTrue(satS2RangeFileFormat.isAllowedList());
+    }
+
+    private static int maxValForBits(int bits) {
+        return intPow2(bits) - 1;
+    }
+
+    private static int intPow2(int value) {
+        return (int) Math.pow(2, value);
+    }
+}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileReaderTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileReaderTest.java
new file mode 100644
index 0000000..bbfaef7
--- /dev/null
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SatS2RangeFileReaderTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.storage.s2.S2LevelRange;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+import com.android.telephony.sats2range.utils.TestUtils;
+import com.android.telephony.sats2range.write.SatS2RangeFileWriter;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SatS2RangeFileReaderTest {
+    @Test
+    public void findEntryByCellId() throws IOException {
+        File file = File.createTempFile("test", ".dat");
+
+        SatS2RangeFileFormat fileFormat;
+        boolean isAllowedList = true;
+        S2LevelRange expectedRange1, expectedRange2, expectedRange3;
+        try (SatS2RangeFileWriter satS2RangeFileWriter = SatS2RangeFileWriter.open(
+                file, TestUtils.createS2RangeFileFormat(isAllowedList))) {
+            fileFormat = satS2RangeFileWriter.getFileFormat();
+
+            // Two ranges that share a prefix.
+            expectedRange1 = new S2LevelRange(
+                    TestUtils.createCellId(fileFormat, 1, 1000, 1000),
+                    TestUtils.createCellId(fileFormat, 1, 1000, 2000));
+            expectedRange2 = new S2LevelRange(
+                    TestUtils.createCellId(fileFormat, 1, 1000, 2000),
+                    TestUtils.createCellId(fileFormat, 1, 1000, 3000));
+            // This range has a different prefix, so will be in a different suffix table.
+            expectedRange3 = new S2LevelRange(
+                    TestUtils.createCellId(fileFormat, 1, 1001, 1000),
+                    TestUtils.createCellId(fileFormat, 1, 1001, 2000));
+
+            List<S2LevelRange> ranges = new ArrayList<>();
+            ranges.add(expectedRange1);
+            ranges.add(expectedRange2);
+            ranges.add(expectedRange3);
+            satS2RangeFileWriter.createSortedSuffixBlocks(ranges.iterator());
+        }
+
+        try (SatS2RangeFileReader satS2RangeFileReader = SatS2RangeFileReader.open(file)) {
+            assertEquals(isAllowedList, satS2RangeFileReader.isAllowedList());
+
+            S2LevelRange range1 = satS2RangeFileReader.findEntryByCellId(
+                    TestUtils.createCellId(fileFormat, 1, 1000, 1500));
+            assertEquals(expectedRange1, range1);
+
+            S2LevelRange range2 = satS2RangeFileReader.findEntryByCellId(
+                    TestUtils.createCellId(fileFormat, 1, 1000, 2500));
+            assertEquals(expectedRange2, range2);
+
+            S2LevelRange range3 = satS2RangeFileReader.findEntryByCellId(
+                    TestUtils.createCellId(fileFormat, 1, 1001, 1500));
+            assertEquals(expectedRange3, range3);
+        }
+    }
+}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockMatcher.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockMatcher.java
new file mode 100644
index 0000000..483d5f5
--- /dev/null
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockMatcher.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range;
+
+import com.android.telephony.sats2range.read.SuffixTableBlock;
+
+import org.mockito.ArgumentMatcher;
+
+import java.util.Objects;
+
+/** A matcher for {@link SuffixTableBlock} - checks all the various fields and content. */
+public class SuffixTableBlockMatcher implements ArgumentMatcher<SuffixTableBlock> {
+
+    private final SuffixTableBlock mSuffixTableBlock;
+
+    public SuffixTableBlockMatcher(SuffixTableBlock suffixTableBlock) {
+        mSuffixTableBlock = suffixTableBlock;
+    }
+
+    @Override
+    public boolean matches(SuffixTableBlock block) {
+        if (mSuffixTableBlock.getPrefix() != block.getPrefix()
+                || mSuffixTableBlock.getEntryCount() != block.getEntryCount()) {
+            return false;
+        }
+        for (int i = 0; i < mSuffixTableBlock.getEntryCount(); i++) {
+            SuffixTableBlock.Entry expectedEntry = mSuffixTableBlock.getEntryByIndex(i);
+            SuffixTableBlock.Entry actualEntry = block.getEntryByIndex(i);
+            if (!Objects.equals(expectedEntry, actualEntry)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockTest.java
new file mode 100644
index 0000000..04b915b
--- /dev/null
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableBlockTest.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.argThat;
+
+import com.android.storage.block.write.BlockWriter;
+import com.android.storage.s2.S2LevelRange;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SuffixTableBlock;
+import com.android.telephony.sats2range.read.SuffixTableSharedData;
+import com.android.telephony.sats2range.utils.TestUtils;
+import com.android.telephony.sats2range.write.SuffixTableWriter;
+
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+
+/** Tests for {@link SuffixTableWriter} and {@link SuffixTableBlock}. */
+public class SuffixTableBlockTest {
+    @Test
+    public void writer_createEmptyBlockWriter() throws Exception {
+        BlockWriter blockWriter = SuffixTableWriter.createEmptyBlockWriter();
+        BlockWriter.ReadBack readBack = blockWriter.close();
+        assertEquals(SatS2RangeFileFormat.BLOCK_TYPE_SUFFIX_TABLE, readBack.getType());
+        assertArrayEquals(new byte[0], readBack.getExtraBytes());
+        assertEquals(0, readBack.getBlockData().getSize());
+    }
+
+    @Test
+    public void writer_createPopulatedBlockWriter_noEntriesThrows() throws Exception {
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+        assertEquals(13, fileFormat.getPrefixBitCount());
+
+        int tablePrefixValue = 0b0010011_00110100;
+        SuffixTableSharedData suffixTableSharedData = new SuffixTableSharedData(tablePrefixValue);
+
+        SuffixTableWriter suffixTableWriter =
+                SuffixTableWriter.createPopulated(fileFormat, suffixTableSharedData);
+        // IllegalStateException is thrown because there is no entry in the block
+        assertThrows(IllegalStateException.class, suffixTableWriter::close);
+    }
+
+    @Test
+    public void writer_createPopulatedBlockWriter_addRange() throws Exception {
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+        assertEquals(13, fileFormat.getPrefixBitCount());
+        assertEquals(14, fileFormat.getSuffixBitCount());
+
+        int tablePrefixValue = 0b0010011_00110100;
+        int maxSuffixValue = 0b00111111_11111111;
+        SuffixTableSharedData suffixTableSharedData = new SuffixTableSharedData(tablePrefixValue);
+
+        SuffixTableWriter suffixTableWriter =
+                SuffixTableWriter.createPopulated(fileFormat, suffixTableSharedData);
+
+        long invalidStartCellId = fileFormat.createCellId(tablePrefixValue - 1, 0);
+        long validStartCellId = fileFormat.createCellId(tablePrefixValue, 0);
+        long invalidEndCellId = fileFormat.createCellId(tablePrefixValue + 1, maxSuffixValue);
+        long validEndCellId = fileFormat.createCellId(tablePrefixValue, maxSuffixValue);
+        {
+            S2LevelRange badStartCellId = new S2LevelRange(invalidStartCellId, validEndCellId);
+            assertThrows(IllegalArgumentException.class,
+                    () -> suffixTableWriter.addRange(badStartCellId));
+        }
+        {
+            S2LevelRange badEndCellId = new S2LevelRange(validStartCellId, invalidEndCellId);
+            assertThrows(IllegalArgumentException.class,
+                    () -> suffixTableWriter.addRange(badEndCellId));
+        }
+    }
+
+    @Test
+    public void writer_createPopulatedBlockWriter_rejectOverlappingRanges() throws Exception {
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+        assertEquals(13, fileFormat.getPrefixBitCount());
+        assertEquals(14, fileFormat.getSuffixBitCount());
+
+        int tablePrefixValue = 0b0010011_00110100;
+        int maxSuffixValue = 0b00111111_11111111;
+        SuffixTableSharedData suffixTableSharedData = new SuffixTableSharedData(tablePrefixValue);
+
+        SuffixTableWriter suffixTableWriter =
+                SuffixTableWriter.createPopulated(fileFormat, suffixTableSharedData);
+        S2LevelRange suffixTableRange1 = new S2LevelRange(
+                fileFormat.createCellId(tablePrefixValue, 1000),
+                fileFormat.createCellId(tablePrefixValue, 1001));
+        suffixTableWriter.addRange(suffixTableRange1);
+
+        // It's fine to add a range that starts adjacent to the last one.
+        S2LevelRange suffixTableRange2 = new S2LevelRange(
+                fileFormat.createCellId(tablePrefixValue, 1001),
+                fileFormat.createCellId(tablePrefixValue, 1002));
+        suffixTableWriter.addRange(suffixTableRange2);
+
+        // IllegalArgumentException is thrown because suffixTableRange2 already exists
+        assertThrows(IllegalArgumentException.class,
+                () -> suffixTableWriter.addRange(suffixTableRange2));
+
+        // Try similar checks at the top end of the table.
+        S2LevelRange suffixTableRange3 = new S2LevelRange(
+                fileFormat.createCellId(tablePrefixValue, maxSuffixValue - 1),
+                fileFormat.createCellId(tablePrefixValue, maxSuffixValue));
+        suffixTableWriter.addRange(suffixTableRange3);
+
+        // IllegalArgumentException is thrown because ranges already exist
+        assertThrows(IllegalArgumentException.class,
+                () -> suffixTableWriter.addRange(suffixTableRange1));
+        assertThrows(IllegalArgumentException.class,
+                () -> suffixTableWriter.addRange(suffixTableRange2));
+        assertThrows(IllegalArgumentException.class,
+                () -> suffixTableWriter.addRange(suffixTableRange3));
+
+        // Now "complete" the table: there can be no entry after this one.
+        S2LevelRange suffixTableRange4 = new S2LevelRange(
+                fileFormat.createCellId(tablePrefixValue, maxSuffixValue),
+                fileFormat.createCellId(tablePrefixValue + 1, 0));
+        suffixTableWriter.addRange(suffixTableRange4);
+
+        assertThrows(IllegalArgumentException.class,
+                () -> suffixTableWriter.addRange(suffixTableRange4));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> suffixTableWriter.addRange(suffixTableRange1));
+        assertThrows(IllegalArgumentException.class,
+                () -> suffixTableWriter.addRange(suffixTableRange2));
+        assertThrows(IllegalArgumentException.class,
+                () -> suffixTableWriter.addRange(suffixTableRange3));
+        assertThrows(IllegalArgumentException.class,
+                () -> suffixTableWriter.addRange(suffixTableRange4));
+    }
+
+    @Test
+    public void suffixTableBlock_empty() {
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+        assertEquals(13, fileFormat.getPrefixBitCount());
+        int tablePrefix = 0b10011_00110100;
+
+        SuffixTableBlock suffixTableBlock = SuffixTableBlock.createEmpty(fileFormat, tablePrefix);
+        assertEquals(tablePrefix, suffixTableBlock.getPrefix());
+        assertNull(suffixTableBlock.findEntryByCellId(fileFormat.createCellId(tablePrefix, 1)));
+        assertEquals(0, suffixTableBlock.getEntryCount());
+        assertThrows(IndexOutOfBoundsException.class,
+                () -> suffixTableBlock.getEntryByIndex(0));
+        assertThrows(IndexOutOfBoundsException.class,
+                () -> suffixTableBlock.getEntryByIndex(1));
+    }
+
+    @Test
+    public void suffixTableBlock_populated_findEntryByCellId() throws Exception {
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+        assertEquals(13, fileFormat.getPrefixBitCount());
+        assertEquals(14, fileFormat.getSuffixBitCount());
+
+        int tablePrefix = 0b10011_00110100;
+        int maxSuffix = 0b111111_11111111;
+        SuffixTableSharedData suffixTableSharedData = new SuffixTableSharedData(tablePrefix);
+
+        SuffixTableWriter suffixTableWriter =
+                SuffixTableWriter.createPopulated(fileFormat, suffixTableSharedData);
+
+        long entry1StartCellId = fileFormat.createCellId(tablePrefix, 1000);
+        long entry1EndCellId = fileFormat.createCellId(tablePrefix, 2000);
+        S2LevelRange entry1 = new S2LevelRange(entry1StartCellId, entry1EndCellId);
+        suffixTableWriter.addRange(entry1);
+
+        long entry2StartCellId = fileFormat.createCellId(tablePrefix, 2000);
+        long entry2EndCellId = fileFormat.createCellId(tablePrefix, 3000);
+        S2LevelRange entry2 = new S2LevelRange(entry2StartCellId, entry2EndCellId);
+        suffixTableWriter.addRange(entry2);
+
+        // There is a deliberate gap here between entry2 and entry3.
+        long entry3StartCellId = fileFormat.createCellId(tablePrefix, 4000);
+        long entry3EndCellId = fileFormat.createCellId(tablePrefix, 5000);
+        S2LevelRange entry3 = new S2LevelRange(entry3StartCellId, entry3EndCellId);
+        suffixTableWriter.addRange(entry3);
+
+        long entry4StartCellId = fileFormat.createCellId(tablePrefix, maxSuffix - 999);
+        long entry4EndCellId = fileFormat.createCellId(tablePrefix + 1, 0);
+        S2LevelRange entry4 = new S2LevelRange(entry4StartCellId, entry4EndCellId);
+        suffixTableWriter.addRange(entry4);
+
+        BlockWriter.ReadBack blockReadback = suffixTableWriter.close();
+        SuffixTableBlock suffixTableBlock =
+                SuffixTableBlock.createPopulated(fileFormat, blockReadback.getBlockData());
+        assertEquals(tablePrefix, suffixTableBlock.getPrefix());
+
+        assertNull(findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 999));
+        assertEquals(entry1, findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 1000));
+        assertEquals(entry1, findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 1001));
+        assertEquals(entry1, findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 1999));
+        assertEquals(entry2, findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 2000));
+        assertEquals(entry2, findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 2001));
+        assertEquals(entry2, findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 2999));
+        assertNull(findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 3000));
+        assertNull(findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 3999));
+        assertEquals(entry3, findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 4000));
+        assertEquals(entry3, findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, 4999));
+        assertNull(findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, maxSuffix - 1000));
+        assertEquals(
+                entry4,
+                findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, maxSuffix - 999));
+        assertEquals(
+                entry4,
+                findEntryByCellId(fileFormat, suffixTableBlock, tablePrefix, maxSuffix));
+
+        assertEquals(4, suffixTableBlock.getEntryCount());
+        assertThrows(IndexOutOfBoundsException.class,
+                () -> suffixTableBlock.getEntryByIndex(-1));
+        assertThrows(IndexOutOfBoundsException.class,
+                () -> suffixTableBlock.getEntryByIndex(4));
+
+        assertEquals(entry1, suffixTableBlock.getEntryByIndex(0).getSuffixTableRange());
+        assertEquals(entry2, suffixTableBlock.getEntryByIndex(1).getSuffixTableRange());
+        assertEquals(entry3, suffixTableBlock.getEntryByIndex(2).getSuffixTableRange());
+        assertEquals(entry4, suffixTableBlock.getEntryByIndex(3).getSuffixTableRange());
+    }
+
+    @Test
+    public void suffixTableBlock_populated_findEntryByCellId_cellIdOutOfRange() throws Exception {
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+
+        int tablePrefix = 0b10011_00110100;
+        assertEquals(13, fileFormat.getPrefixBitCount());
+
+        int tzIdSetBankId = 5;
+        assertTrue(tzIdSetBankId <= fileFormat.getMaxPrefixValue());
+
+        SuffixTableSharedData suffixTableSharedData = new SuffixTableSharedData(tablePrefix);
+
+        SuffixTableWriter suffixTableWriter =
+                SuffixTableWriter.createPopulated(fileFormat, suffixTableSharedData);
+        long entry1StartCellId = fileFormat.createCellId(tablePrefix, 1000);
+        long entry1EndCellId = fileFormat.createCellId(tablePrefix, 2000);
+        S2LevelRange entry1 = new S2LevelRange(entry1StartCellId, entry1EndCellId);
+        suffixTableWriter.addRange(entry1);
+        BlockWriter.ReadBack blockReadback = suffixTableWriter.close();
+
+        SuffixTableBlock suffixTableBlock =
+                SuffixTableBlock.createPopulated(fileFormat, blockReadback.getBlockData());
+
+        assertThrows(IllegalArgumentException.class, () -> suffixTableBlock.findEntryByCellId(
+                fileFormat.createCellId(tablePrefix - 1, 0)));
+        assertThrows(IllegalArgumentException.class, () -> suffixTableBlock.findEntryByCellId(
+                fileFormat.createCellId(tablePrefix + 1, 0)));
+    }
+
+    @Test
+    public void suffixTableBlock_visit() throws Exception {
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+
+        int tablePrefix = 0b10011_00110100;
+        assertEquals(13, fileFormat.getPrefixBitCount());
+
+        SuffixTableSharedData sharedData = new SuffixTableSharedData(tablePrefix);
+
+        SuffixTableWriter suffixTableWriter =
+                SuffixTableWriter.createPopulated(fileFormat, sharedData);
+
+        S2LevelRange entry1 = new S2LevelRange(
+                fileFormat.createCellId(tablePrefix, 1001),
+                fileFormat.createCellId(tablePrefix, 1101));
+        suffixTableWriter.addRange(entry1);
+
+        S2LevelRange entry2 = new S2LevelRange(
+                fileFormat.createCellId(tablePrefix, 2001),
+                fileFormat.createCellId(tablePrefix, 2101));
+        suffixTableWriter.addRange(entry2);
+
+        BlockWriter.ReadBack readBack = suffixTableWriter.close();
+
+        // Read the data back and confirm it matches what we expected.
+        SuffixTableBlock suffixTableBlock =
+                SuffixTableBlock.createPopulated(fileFormat, readBack.getBlockData());
+        SuffixTableBlock.SuffixTableBlockVisitor mockVisitor =
+                Mockito.mock(SuffixTableBlock.SuffixTableBlockVisitor.class);
+
+        suffixTableBlock.visit(mockVisitor);
+
+        InOrder inOrder = Mockito.inOrder(mockVisitor);
+        inOrder.verify(mockVisitor).begin();
+        inOrder.verify(mockVisitor).visit(argThat(new SuffixTableBlockMatcher(suffixTableBlock)));
+        inOrder.verify(mockVisitor).end();
+    }
+
+    private S2LevelRange findEntryByCellId(SatS2RangeFileFormat fileFormat,
+            SuffixTableBlock suffixTableBlock, int prefix, int suffix) {
+        long cellId = fileFormat.createCellId(prefix, suffix);
+        SuffixTableBlock.Entry entry = suffixTableBlock.findEntryByCellId(cellId);
+        return entry == null ? null : entry.getSuffixTableRange();
+    }
+}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableExtraInfoTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableExtraInfoTest.java
new file mode 100644
index 0000000..f992ae7
--- /dev/null
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableExtraInfoTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.storage.block.read.BlockInfo;
+import com.android.storage.block.write.BlockWriter;
+import com.android.storage.s2.S2LevelRange;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SuffixTableExtraInfo;
+import com.android.telephony.sats2range.read.SuffixTableSharedData;
+import com.android.telephony.sats2range.utils.TestUtils;
+import com.android.telephony.sats2range.write.SuffixTableWriter;
+
+import org.junit.Test;
+public class SuffixTableExtraInfoTest {
+
+    @Test
+    public void create_emptyBlock() throws Exception {
+        // Generate a real suffix table block info and an empty block.
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+        BlockWriter emptyBlockWriter =
+                SuffixTableWriter.createEmptyBlockWriter();
+        BlockWriter.ReadBack readBack = emptyBlockWriter.close();
+
+        // Read back the block info.
+        BlockInfo blockInfo = createBlockInfo(readBack);
+
+        SuffixTableExtraInfo extraInfo = SuffixTableExtraInfo.create(fileFormat, blockInfo);
+        assertEquals(0, extraInfo.getEntryCount());
+    }
+
+    @Test
+    public void create_nonEmptyBlock() throws Exception {
+        // Generate a real suffix table block info and block containing some elements.
+        SatS2RangeFileFormat fileFormat = TestUtils.createS2RangeFileFormat(true);
+        SuffixTableSharedData suffixTableSharedData = createSuffixTableSharedData();
+        SuffixTableWriter suffixTableWriter =
+                SuffixTableWriter.createPopulated(fileFormat, suffixTableSharedData);
+
+        int tablePrefix = suffixTableSharedData.getTablePrefix();
+        S2LevelRange range1 = new S2LevelRange(
+                fileFormat.createCellId(tablePrefix, 1000),
+                fileFormat.createCellId(tablePrefix, 1001));
+        S2LevelRange range2 = new S2LevelRange(
+                fileFormat.createCellId(tablePrefix, 1002),
+                fileFormat.createCellId(tablePrefix, 1003));
+        S2LevelRange range3 = new S2LevelRange(
+                fileFormat.createCellId(tablePrefix, 1004),
+                fileFormat.createCellId(tablePrefix, 1005));
+
+        suffixTableWriter.addRange(range1);
+        suffixTableWriter.addRange(range2);
+        suffixTableWriter.addRange(range3);
+        BlockWriter.ReadBack readBack = suffixTableWriter.close();
+
+        // Read back the block info.
+        BlockInfo blockInfo = createBlockInfo(readBack);
+
+        SuffixTableExtraInfo extraInfo = SuffixTableExtraInfo.create(fileFormat, blockInfo);
+        assertEquals(3, extraInfo.getEntryCount());
+    }
+
+    private static SuffixTableSharedData createSuffixTableSharedData() {
+        int arbitraryPrefixValue = 1111;
+        return new SuffixTableSharedData(arbitraryPrefixValue);
+    }
+
+    /** Creates a BlockInfo for a written block. */
+    private static BlockInfo createBlockInfo(BlockWriter.ReadBack readBack) {
+        int arbitraryBlockId = 2222;
+        long arbitraryByteOffset = 12345L;
+        return new BlockInfo(
+                arbitraryBlockId, readBack.getType(), arbitraryByteOffset,
+                readBack.getBlockData().getSize(), readBack.getExtraBytes());
+    }
+}
diff --git a/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableSharedDataTest.java b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableSharedDataTest.java
new file mode 100644
index 0000000..2baefa9
--- /dev/null
+++ b/utils/satellite/s2storage/src/test/java/com/android/telephony/sats2range/SuffixTableSharedDataTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.telephony.sats2range.read.SuffixTableSharedData;
+import com.android.telephony.sats2range.write.SuffixTableSharedDataWriter;
+
+import org.junit.Test;
+
+/** Tests for {@link SuffixTableSharedData} and {@link SuffixTableSharedDataWriter}. */
+public class SuffixTableSharedDataTest {
+    @Test
+    public void testSuffixTableSharedData() {
+        int prefix = 321;
+        SuffixTableSharedData sharedData = new SuffixTableSharedData(prefix);
+        byte[] bytes = SuffixTableSharedDataWriter.toBytes(sharedData);
+
+        assertEquals(sharedData, SuffixTableSharedData.fromBytes(bytes));
+    }
+}
+
diff --git a/utils/satellite/s2storage/src/testutils/java/com/android/telephony/sats2range/testutils/TestUtils.java b/utils/satellite/s2storage/src/testutils/java/com/android/telephony/sats2range/testutils/TestUtils.java
new file mode 100644
index 0000000..4b8a026
--- /dev/null
+++ b/utils/satellite/s2storage/src/testutils/java/com/android/telephony/sats2range/testutils/TestUtils.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.utils;
+
+import static com.android.storage.s2.S2Support.FACE_BIT_COUNT;
+
+import static org.junit.Assert.assertFalse;
+
+import com.android.storage.util.BitwiseUtils;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+/** A utility class for satellite tests */
+public class TestUtils {
+    public static final int TEST_S2_LEVEL = 12;
+
+    /** Returns a valid {@link SatS2RangeFileFormat}. */
+    public static SatS2RangeFileFormat createS2RangeFileFormat(boolean isAllowedList) {
+        int dataS2Level = TEST_S2_LEVEL;
+        int faceIdBits = 3;
+        int bitCountPerLevel = 2;
+        int s2LevelBitCount = (dataS2Level * bitCountPerLevel) + faceIdBits;
+        int prefixLevel = 5;
+        int prefixBitCount = faceIdBits + (prefixLevel * bitCountPerLevel);
+        int suffixBitCount = s2LevelBitCount - prefixBitCount;
+        int suffixTableEntryBitCount = 4 * Byte.SIZE;
+        int suffixTableBlockIdOffset = 5;
+        return new SatS2RangeFileFormat(dataS2Level, prefixBitCount, suffixBitCount,
+                suffixTableBlockIdOffset, suffixTableEntryBitCount, isAllowedList);
+    }
+
+    /** Create an S2 cell ID */
+    public static long createCellId(
+            SatS2RangeFileFormat fileFormat, int faceId, int otherPrefixBits, int suffixBits) {
+        int prefixBitCount = fileFormat.getPrefixBitCount();
+        int otherPrefixBitsCount = prefixBitCount - FACE_BIT_COUNT;
+        int maxOtherPrefixBits = (int) BitwiseUtils.getLowBitsMask(otherPrefixBitsCount);
+        if (otherPrefixBits > maxOtherPrefixBits) {
+            throw new IllegalArgumentException("otherPrefixBits=" + otherPrefixBits
+                    + " (" + Integer.toBinaryString(otherPrefixBits) + ")"
+                    + " has more bits than otherPrefixBitsCount=" + otherPrefixBitsCount
+                    + " allows");
+        }
+
+        int prefixValue = faceId;
+        prefixValue <<= otherPrefixBitsCount;
+        prefixValue |= otherPrefixBits;
+
+        int suffixBitCount = fileFormat.getSuffixBitCount();
+        if (suffixBits > BitwiseUtils.getLowBitsMask(suffixBitCount)) {
+            throw new IllegalArgumentException(
+                    "suffixBits=" + suffixBits + " (" + Integer.toBinaryString(suffixBits)
+                            + ") has more bits than " + suffixBitCount + " bits allows");
+        }
+        return fileFormat.createCellId(prefixValue, suffixBits);
+    }
+
+    /** Create a temporary directory */
+    public static Path createTempDir(Class<?> testClass) throws IOException {
+        return Files.createTempDirectory(testClass.getSimpleName());
+    }
+
+    /** Delete a directory */
+    public static void deleteDirectory(Path dir) throws IOException {
+        Files.walkFileTree(dir, new SimpleFileVisitor<>() {
+            @Override
+            public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes)
+                    throws IOException {
+                Files.deleteIfExists(path);
+                return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult postVisitDirectory(Path path, IOException e) throws IOException {
+                Files.delete(path);
+                return FileVisitResult.CONTINUE;
+            }
+        });
+        assertFalse(Files.exists(dir));
+    }
+
+    /** Create a valid test satellite S2 cell file */
+    public static void createValidTestS2CellFile(
+            File outputFile, SatS2RangeFileFormat fileFormat) throws Exception {
+        try (PrintStream printer = new PrintStream(outputFile)) {
+            // Range 1
+            for (int suffix = 1000; suffix < 2000; suffix++) {
+                printer.println(String.valueOf(fileFormat.createCellId(0b100_11111111, suffix)));
+            }
+
+            // Range 2
+            for (int suffix = 2001; suffix < 3000; suffix++) {
+                printer.println(String.valueOf(fileFormat.createCellId(0b100_11111111, suffix)));
+            }
+
+            // Range 3
+            for (int suffix = 1000; suffix < 2000; suffix++) {
+                printer.println(String.valueOf(fileFormat.createCellId(0b101_11111111, suffix)));
+            }
+            printer.print(String.valueOf(fileFormat.createCellId(0b101_11111111, 2000)));
+
+            printer.close();
+        }
+    }
+
+    /** Create a invalid test satellite S2 cell file */
+    public static void createInvalidTestS2CellFile(
+            File outputFile, SatS2RangeFileFormat fileFormat) throws Exception {
+        try (PrintStream printer = new PrintStream(outputFile)) {
+            // Valid line
+            printer.println(String.valueOf(fileFormat.createCellId(0b100_11111111, 100)));
+
+            // Invalid line
+            printer.print("Invalid line");
+
+            // Another valid line
+            printer.println(String.valueOf(fileFormat.createCellId(0b100_11111111, 200)));
+
+            printer.close();
+        }
+    }
+}
diff --git a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/HeaderBlockWriter.java b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/HeaderBlockWriter.java
new file mode 100644
index 0000000..d4e9310
--- /dev/null
+++ b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/HeaderBlockWriter.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.write;
+
+import com.android.storage.block.read.BlockData;
+import com.android.storage.block.write.BlockWriter;
+import com.android.storage.io.write.TypedOutputStream;
+import com.android.telephony.sats2range.read.HeaderBlock;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+
+/** A {@link BlockWriter} that can generate a satellite S2 data file header block. */
+public final class HeaderBlockWriter implements BlockWriter {
+
+    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+    private final File mFile;
+
+    private final SatS2RangeFileFormat mFileFormat;
+
+    private boolean mIsOpen = true;
+
+    private HeaderBlockWriter(SatS2RangeFileFormat fileFormat, File file) {
+        mFileFormat = fileFormat;
+        mFile = file;
+    }
+
+    /** Creates a new {@link HeaderBlockWriter}. */
+    public static HeaderBlockWriter create(SatS2RangeFileFormat fileFormat) throws IOException {
+        return new HeaderBlockWriter(fileFormat, File.createTempFile("header", ".bin"));
+    }
+
+    @Override
+    public ReadBack close() throws IOException {
+        checkIsOpen();
+        mIsOpen = false;
+
+        try (TypedOutputStream tos = new TypedOutputStream(new FileOutputStream(mFile))) {
+            tos.writeUnsignedByte(mFileFormat.getS2Level());
+            tos.writeUnsignedByte(mFileFormat.getPrefixBitCount());
+            tos.writeUnsignedByte(mFileFormat.getSuffixBitCount());
+            tos.writeUnsignedByte(mFileFormat.getTableEntryBitCount());
+            tos.writeUnsignedByte(mFileFormat.getSuffixTableBlockIdOffset());
+            tos.writeUnsignedByte(mFileFormat.isAllowedList()
+                    ? HeaderBlock.TRUE : HeaderBlock.FALSE);
+        }
+
+        FileChannel fileChannel = FileChannel.open(mFile.toPath(), StandardOpenOption.READ);
+        MappedByteBuffer map = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, mFile.length());
+        fileChannel.close();
+        BlockData blockData = new BlockData(map);
+        return new ReadBack() {
+            @Override
+            public byte[] getExtraBytes() {
+                return EMPTY_BYTE_ARRAY;
+            }
+
+            @Override
+            public int getType() {
+                return SatS2RangeFileFormat.BLOCK_TYPE_HEADER;
+            }
+
+            @Override
+            public BlockData getBlockData() {
+                return blockData;
+            }
+        };
+    }
+
+    private void checkIsOpen() {
+        if (!mIsOpen) {
+            throw new IllegalStateException("Writer is closed.");
+        }
+    }
+}
diff --git a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/PushBackIterator.java b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/PushBackIterator.java
new file mode 100644
index 0000000..7bc375e
--- /dev/null
+++ b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/PushBackIterator.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.write;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * An iterator that can have elements pushed back onto it. {@link #remove()} is not supported.
+ *
+ * @param <E> The type of the element returned by this iterator
+ */
+public final class PushBackIterator<E> implements Iterator<E> {
+
+    private final ArrayList<E> mPushBackStack = new ArrayList<>();
+
+    private final Iterator<E> mIterator;
+
+    public PushBackIterator(Iterator<E> iterator) {
+        mIterator = iterator;
+    }
+
+    @Override
+    public boolean hasNext() {
+        return !mPushBackStack.isEmpty() || mIterator.hasNext();
+    }
+
+    @Override
+    public E next() {
+        if (!mPushBackStack.isEmpty()) {
+            return mPushBackStack.remove(mPushBackStack.size() - 1);
+        }
+        return mIterator.next();
+    }
+
+    /**
+     * Pushes the element to the front of the iterator again.
+     */
+    public void pushBack(E element) {
+        mPushBackStack.add(element);
+    }
+}
diff --git a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SatS2RangeFileWriter.java b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SatS2RangeFileWriter.java
new file mode 100644
index 0000000..9b3c20e
--- /dev/null
+++ b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SatS2RangeFileWriter.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.write;
+
+import com.android.storage.block.write.BlockFileWriter;
+import com.android.storage.block.write.BlockWriter;
+import com.android.storage.block.write.EmptyBlockWriter;
+import com.android.storage.s2.S2LevelRange;
+import com.android.storage.s2.S2Support;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SuffixTableSharedData;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.List;
+
+/** Writes a satellite S2 data file. */
+public final class SatS2RangeFileWriter implements AutoCloseable {
+
+    private final HeaderBlockWriter mHeaderBlockWriter;
+
+    private final List<BlockWriter> mSuffixTableBlockWriters = new ArrayList<>();
+
+    private final BlockFileWriter mBlockFileWriter;
+
+    private final SatS2RangeFileFormat mFileFormat;
+
+    private SatS2RangeFileWriter(SatS2RangeFileFormat fileFormat, BlockFileWriter blockFileWriter)
+            throws IOException {
+        mBlockFileWriter = blockFileWriter;
+        mFileFormat = fileFormat;
+
+        mHeaderBlockWriter = HeaderBlockWriter.create(fileFormat);
+    }
+
+    /** Opens a file for writing with the specified format. */
+    public static SatS2RangeFileWriter open(File outFile, SatS2RangeFileFormat fileFormat)
+            throws IOException {
+        BlockFileWriter writer = BlockFileWriter.open(
+                SatS2RangeFileFormat.MAGIC, SatS2RangeFileFormat.VERSION, outFile);
+        return new SatS2RangeFileWriter(fileFormat, writer);
+    }
+
+    /**
+     * Group the sorted ranges into contiguous suffix blocks. Big ranges might get split as
+     * needed to fit them into suffix blocks. The ranges must be of the expected S2 level
+     * and ordered by cell ID.
+     */
+    public void createSortedSuffixBlocks(Iterator<S2LevelRange> ranges) throws IOException {
+        PushBackIterator<S2LevelRange> pushBackIterator = new PushBackIterator<>(ranges);
+
+        // For each prefix value, collect all the ranges that match.
+        for (int currentPrefix = 0;
+                currentPrefix <= mFileFormat.getMaxPrefixValue();
+                currentPrefix++) {
+
+            // Step 1:
+            // populate samePrefixRanges, which holds ranges that have a prefix of currentPrefix.
+            List<S2LevelRange> samePrefixRanges =
+                    collectSamePrefixRanges(pushBackIterator, currentPrefix);
+
+            // Step 2: Write samePrefixRanges to a suffix table.
+            BlockWriter blockWriter = writeSamePrefixRanges(currentPrefix, samePrefixRanges);
+            mSuffixTableBlockWriters.add(blockWriter);
+        }
+
+        // At this point there should be no data left.
+        if (pushBackIterator.hasNext()) {
+            throw new IllegalStateException("Unexpected ranges left at the end.");
+        }
+    }
+
+    private List<S2LevelRange> collectSamePrefixRanges(
+            PushBackIterator<S2LevelRange> pushBackIterator, int currentPrefix) {
+        List<S2LevelRange> samePrefixRanges = new ArrayList<>();
+        while (pushBackIterator.hasNext()) {
+            S2LevelRange currentRange = pushBackIterator.next();
+
+            long startCellId = currentRange.getStartCellId();
+            if (mFileFormat.getS2Level() != S2Support.getS2Level(startCellId)) {
+                throw new IllegalArgumentException(
+                        "Input data level does not match file format level");
+            }
+            int startCellPrefix = mFileFormat.extractPrefixValueFromCellId(startCellId);
+            if (startCellPrefix != currentPrefix) {
+                if (startCellPrefix < currentPrefix) {
+                    throw new IllegalStateException("Prefix out of order:"
+                            + " currentPrefixValue=" + currentPrefix
+                            + " startCellPrefixValue=" + startCellPrefix);
+                }
+                // The next range is for a later prefix. Put it back and move to step 2.
+                pushBackIterator.pushBack(currentRange);
+                break;
+            }
+
+            long endCellId = currentRange.getEndCellId();
+            if (mFileFormat.getS2Level() != S2Support.getS2Level(endCellId)) {
+                throw new IllegalArgumentException("endCellId in range " + currentRange
+                        + " has the wrong S2 level");
+            }
+
+            // Split ranges if they span a prefix.
+            int endCellPrefixValue = mFileFormat.extractPrefixValueFromCellId(endCellId);
+            if (startCellPrefix != endCellPrefixValue) {
+                // Create a range for the current prefix.
+                {
+                    long newEndCellId = mFileFormat.createCellId(startCellPrefix + 1, 0);
+                    S2LevelRange satS2Range = new S2LevelRange(startCellId, newEndCellId);
+                    samePrefixRanges.add(satS2Range);
+                }
+
+                Deque<S2LevelRange> otherRanges = new ArrayDeque<>();
+                // Intermediate prefixes.
+                startCellPrefix = startCellPrefix + 1;
+                while (startCellPrefix != endCellPrefixValue) {
+                    long newStartCellId = mFileFormat.createCellId(startCellPrefix, 0);
+                    long newEndCellId = mFileFormat.createCellId(startCellPrefix + 1, 0);
+                    S2LevelRange satS2Range = new S2LevelRange(newStartCellId, newEndCellId);
+                    otherRanges.add(satS2Range);
+                    startCellPrefix++;
+                }
+
+                // Final prefix.
+                {
+                    long newStartCellId = mFileFormat.createCellId(endCellPrefixValue, 0);
+                    if (newStartCellId != endCellId) {
+                        S2LevelRange satS2Range = new S2LevelRange(newStartCellId, endCellId);
+                        otherRanges.add(satS2Range);
+                    }
+                }
+
+                // Push back the ranges in reverse order so they come back out in sorted order.
+                while (!otherRanges.isEmpty()) {
+                    pushBackIterator.pushBack(otherRanges.removeLast());
+                }
+                break;
+            } else {
+                samePrefixRanges.add(currentRange);
+            }
+        }
+        return samePrefixRanges;
+    }
+
+    private BlockWriter writeSamePrefixRanges(
+            int currentPrefix, List<S2LevelRange> samePrefixRanges) throws IOException {
+        BlockWriter blockWriter;
+        if (samePrefixRanges.size() == 0) {
+            // Add an empty block.
+            blockWriter = SuffixTableWriter.createEmptyBlockWriter();
+        } else {
+            // Create a suffix table block.
+            SuffixTableSharedData sharedData = new SuffixTableSharedData(currentPrefix);
+            SuffixTableWriter suffixTableWriter =
+                    SuffixTableWriter.createPopulated(mFileFormat, sharedData);
+            S2LevelRange lastRange = null;
+            for (S2LevelRange currentRange : samePrefixRanges) {
+                // Validate ranges don't overlap.
+                if (lastRange != null) {
+                    if (lastRange.overlaps(currentRange)) {
+                        throw new IllegalStateException("lastRange=" + lastRange + " overlaps"
+                                + " currentRange=" + currentRange);
+                    }
+                }
+                lastRange = currentRange;
+
+                // Split the range so it fits.
+                final int maxRangeLength = mFileFormat.getTableEntryMaxRangeLengthValue();
+                long startCellId = currentRange.getStartCellId();
+                long endCellId = currentRange.getEndCellId();
+                int rangeLength = mFileFormat.calculateRangeLength(startCellId, endCellId);
+                while (rangeLength > maxRangeLength) {
+                    long newEndCellId = S2Support.offsetCellId(startCellId, maxRangeLength);
+                    S2LevelRange suffixTableRange = new S2LevelRange(startCellId, newEndCellId);
+                    suffixTableWriter.addRange(suffixTableRange);
+                    startCellId = newEndCellId;
+                    rangeLength = mFileFormat.calculateRangeLength(startCellId, endCellId);
+                }
+                S2LevelRange suffixTableRange = new S2LevelRange(startCellId, endCellId);
+                suffixTableWriter.addRange(suffixTableRange);
+            }
+            blockWriter = suffixTableWriter;
+        }
+        return blockWriter;
+    }
+
+    @Override
+    public void close() throws IOException {
+        try {
+            BlockWriter.ReadBack headerReadBack = mHeaderBlockWriter.close();
+            mBlockFileWriter.addBlock(headerReadBack.getType(), headerReadBack.getExtraBytes(),
+                    headerReadBack.getBlockData());
+
+            // Add empty blocks padding.
+            EmptyBlockWriter emptyBlockWriterHelper =
+                    new EmptyBlockWriter(SatS2RangeFileFormat.BLOCK_TYPE_PADDING);
+            BlockWriter.ReadBack emptyBlockReadBack = emptyBlockWriterHelper.close();
+            for (int i = 0; i < mFileFormat.getSuffixTableBlockIdOffset() - 1; i++) {
+                mBlockFileWriter.addBlock(
+                        emptyBlockReadBack.getType(), emptyBlockReadBack.getExtraBytes(),
+                        emptyBlockReadBack.getBlockData());
+            }
+
+            // Add the suffix tables.
+            for (BlockWriter blockWriter : mSuffixTableBlockWriters) {
+                BlockWriter.ReadBack readBack = blockWriter.close();
+
+                mBlockFileWriter.addBlock(readBack.getType(), readBack.getExtraBytes(),
+                        readBack.getBlockData());
+            }
+        } finally {
+            mBlockFileWriter.close();
+        }
+    }
+
+    /** Returns the{@link SatS2RangeFileFormat} for the file being written. */
+    public SatS2RangeFileFormat getFileFormat() {
+        return mFileFormat;
+    }
+}
diff --git a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableSharedDataWriter.java b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableSharedDataWriter.java
new file mode 100644
index 0000000..5499148
--- /dev/null
+++ b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableSharedDataWriter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.write;
+
+import com.android.storage.io.write.TypedOutputStream;
+import com.android.telephony.sats2range.read.SuffixTableSharedData;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * Converts a {@link SuffixTableSharedData} to a byte[] for writing.
+ * See also {@link SuffixTableSharedData#fromBytes(byte[])}.
+ */
+public final class SuffixTableSharedDataWriter {
+
+    private SuffixTableSharedDataWriter() {
+    }
+
+    /** Returns the byte[] for the supplied {@link SuffixTableSharedData} */
+    public static byte[] toBytes(SuffixTableSharedData suffixTableSharedData) {
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                TypedOutputStream tos = new TypedOutputStream(baos)) {
+            tos.writeInt(suffixTableSharedData.getTablePrefix());
+            tos.flush();
+            return baos.toByteArray();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableWriter.java b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableWriter.java
new file mode 100644
index 0000000..d9e4575
--- /dev/null
+++ b/utils/satellite/s2storage/src/write/java/com/android/telephony/sats2range/write/SuffixTableWriter.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.sats2range.write;
+
+import static com.android.storage.s2.S2Support.cellIdToString;
+
+import com.android.storage.block.read.BlockData;
+import com.android.storage.block.write.BlockWriter;
+import com.android.storage.block.write.EmptyBlockWriter;
+import com.android.storage.io.write.TypedOutputStream;
+import com.android.storage.s2.S2LevelRange;
+import com.android.storage.s2.S2Support;
+import com.android.storage.table.packed.write.PackedTableWriter;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SuffixTableExtraInfo;
+import com.android.telephony.sats2range.read.SuffixTableSharedData;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+
+/**
+ * A class used to generate suffix tables block info and block data.
+ * To write empty tables use {@link #createEmptyBlockWriter()}.
+ * To write populated tables use {@link
+ * #createPopulated(SatS2RangeFileFormat, SuffixTableSharedData)} and add entries with
+ * {@link #addRange(S2LevelRange)}
+ */
+public final class SuffixTableWriter implements BlockWriter {
+
+    private final SuffixTableSharedData mSharedData;
+
+    private final SatS2RangeFileFormat mFileFormat;
+
+    private final PackedTableWriter mPackedTableWriter;
+
+    private final File mFile;
+
+    private S2LevelRange mLastRangeAdded;
+
+    private SuffixTableWriter(SatS2RangeFileFormat fileFormat, SuffixTableSharedData sharedData)
+            throws IOException {
+        mFileFormat = fileFormat;
+        mSharedData = sharedData;
+
+        int keySizeBits = fileFormat.getSuffixBitCount();
+        int entrySizeByteCount = fileFormat.getTableEntryByteCount();
+        mFile = File.createTempFile("suffixtablewriter", ".packed");
+
+        byte[] blockSharedData = SuffixTableSharedDataWriter.toBytes(sharedData);
+        FileOutputStream fileOutputStream = new FileOutputStream(mFile);
+        boolean signedValue = false;
+        mPackedTableWriter = PackedTableWriter.create(
+                fileOutputStream, entrySizeByteCount, keySizeBits, signedValue, blockSharedData);
+    }
+
+    /** Returns a {@link BlockWriter} capable of generating the block data for an empty table. */
+    public static BlockWriter createEmptyBlockWriter() {
+        return new EmptyBlockWriter(SatS2RangeFileFormat.BLOCK_TYPE_SUFFIX_TABLE);
+    }
+
+    /** Returns a {@link BlockWriter} capable of generating the block data for a populated table. */
+    public static SuffixTableWriter createPopulated(
+            SatS2RangeFileFormat fileFormat, SuffixTableSharedData sharedData) throws IOException {
+        return new SuffixTableWriter(fileFormat, sharedData);
+    }
+
+    /**
+     * Adds the supplied range to the table. The range must start after any previously added range,
+     * no overlap is allowed. Gaps are permitted. The range must have the expected S2 cell ID
+     * prefix. Invalid ranges will cause {@link IllegalArgumentException}. This method must be
+     * called at least once. See {@link SuffixTableWriter#createEmptyBlockWriter()} for empty
+     * tables.
+     */
+    public void addRange(S2LevelRange suffixTableRange) throws IOException {
+        checkIsOpen();
+
+        long rangeStartCellId = suffixTableRange.getStartCellId();
+        long rangeEndCellId = suffixTableRange.getEndCellId();
+
+        // Check range belongs in this table.
+        int rangeStartPrefixValue = mFileFormat.extractPrefixValueFromCellId(rangeStartCellId);
+        int rangeStartSuffixValue = mFileFormat.extractSuffixValueFromCellId(rangeStartCellId);
+        if (rangeStartPrefixValue != mSharedData.getTablePrefix()) {
+            throw new IllegalArgumentException(
+                    "rangeStartCellId=" + cellIdToString(rangeStartCellId)
+                            + " has a different prefix=" + rangeStartPrefixValue
+                            + " than the table prefix=" + mSharedData.getTablePrefix());
+        }
+
+        long rangeEndCellIdInclusive = S2Support.offsetCellId(rangeEndCellId, -1);
+        int rangeEndPrefixValue = mFileFormat.extractPrefixValueFromCellId(rangeEndCellIdInclusive);
+        if (rangeEndPrefixValue != rangeStartPrefixValue) {
+            // Because SuffixTableRange has an exclusive end value, rangeEndPrefixValue is allowed
+            // to be the next prefix value if the rangeEndSuffixValue == 0.
+            int rangeEndSuffixValue = mFileFormat.extractSuffixValueFromCellId(rangeEndCellId);
+            if (!(rangeEndPrefixValue == rangeStartPrefixValue + 1 && rangeEndSuffixValue == 0)) {
+                throw new IllegalArgumentException("rangeEndPrefixValue=" + rangeEndPrefixValue
+                        + " != rangeStartPrefixValue=" + rangeStartPrefixValue);
+            }
+        }
+
+        // Confirm the new range starts after the end of the last one that was added, if any.
+        if (mLastRangeAdded != null) {
+            long lastRangeAddedEndCellId = mLastRangeAdded.getEndCellId();
+            int lastRangeEndPrefixValue =
+                    mFileFormat.extractPrefixValueFromCellId(lastRangeAddedEndCellId);
+            if (lastRangeEndPrefixValue != mSharedData.getTablePrefix()) {
+                // Deal with the special case where the last range added completed the table.
+                throw new IllegalArgumentException(
+                        "Suffix table is full: last range added=" + mLastRangeAdded);
+            } else {
+                int lastRangeEndSuffixValue =
+                        mFileFormat.extractSuffixValueFromCellId(lastRangeAddedEndCellId);
+                if (rangeStartSuffixValue < lastRangeEndSuffixValue) {
+                    throw new IllegalArgumentException("suffixTableRange=" + suffixTableRange
+                            + " overlaps with last range added=" + mLastRangeAdded);
+                }
+            }
+        }
+
+        int rangeLength = mFileFormat.calculateRangeLength(rangeStartCellId, rangeEndCellId);
+
+        long value = mFileFormat.createSuffixTableValue(rangeLength);
+        mPackedTableWriter.addEntry(rangeStartSuffixValue, value);
+        mLastRangeAdded = suffixTableRange;
+    }
+
+    @Override
+    public ReadBack close() throws IOException {
+        checkIsOpen();
+        mPackedTableWriter.close();
+        mLastRangeAdded = null;
+
+        int entryCount = mPackedTableWriter.getEntryCount();
+        if (entryCount == 0) {
+            throw new IllegalStateException("No ranges added. For an empty suffix table, use"
+                    + " createEmptySuffixTableBlockWriter()");
+        }
+
+        FileChannel fileChannel = FileChannel.open(mFile.toPath(), StandardOpenOption.READ);
+        MappedByteBuffer map = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, mFile.length());
+        fileChannel.close();
+
+        // Writes the number of entries into the extra bytes stored in the BlockInfo. This means the
+        // number of entries can be known without reading the block data at all.
+        SuffixTableExtraInfo suffixTableExtraInfo =
+                new SuffixTableExtraInfo(mSharedData.getTablePrefix(), entryCount);
+        byte[] blockInfoExtraBytes = generateBlockInfoExtraBytes(suffixTableExtraInfo);
+        BlockData blockData = new BlockData(map);
+        return new ReadBack() {
+            @Override
+            public byte[] getExtraBytes() {
+                return blockInfoExtraBytes;
+            }
+
+            @Override
+            public int getType() {
+                return SatS2RangeFileFormat.BLOCK_TYPE_SUFFIX_TABLE;
+            }
+
+            @Override
+            public BlockData getBlockData() {
+                return blockData;
+            }
+        };
+    }
+
+    private void checkIsOpen() {
+        if (!mPackedTableWriter.isOpen()) {
+            throw new IllegalStateException("Writer is closed.");
+        }
+    }
+
+    private static byte[] generateBlockInfoExtraBytes(SuffixTableExtraInfo suffixTableBlockInfo) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (TypedOutputStream tos = new TypedOutputStream(baos)) {
+            tos.writeInt(suffixTableBlockInfo.getEntryCount());
+        } catch (IOException e) {
+            throw new IllegalStateException("Unexpected IOException writing to byte array", e);
+        }
+        return baos.toByteArray();
+    }
+}
diff --git a/utils/satellite/tools/Android.bp b/utils/satellite/tools/Android.bp
new file mode 100644
index 0000000..9aacdd9
--- /dev/null
+++ b/utils/satellite/tools/Android.bp
@@ -0,0 +1,71 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library_host {
+    name: "satellite-s2storage-tools",
+    srcs: [
+        "src/main/java/**/*.java",
+    ],
+    static_libs: [
+        "jcommander",
+        "guava",
+        "satellite-s2storage-rw",
+        "s2storage_tools",
+        "s2-geometry-library-java",
+    ],
+}
+
+// A tool to create a binary satellite S2 file.
+java_binary_host {
+    name: "satellite_createsats2file",
+    main_class: "com.android.telephony.tools.sats2.CreateSatS2File",
+    static_libs: [
+        "satellite-s2storage-tools",
+    ],
+}
+
+// A tool to create a test satellite S2 file.
+java_binary_host {
+    name: "satellite_createsats2file_test",
+    main_class: "com.android.telephony.tools.sats2.CreateTestSatS2File",
+    static_libs: [
+        "satellite-s2storage-tools",
+    ],
+}
+
+// A tool to dump a satellite S2 file as text for debugging.
+java_binary_host {
+    name: "satellite_dumpsats2file",
+    main_class: "com.android.telephony.tools.sats2.DumpSatS2File",
+    static_libs: [
+        "satellite-s2storage-tools",
+    ],
+}
+
+// Tests for CreateSatS2File.
+java_test_host {
+    name: "SatelliteToolsTests",
+    srcs: ["src/test/java/**/*.java"],
+    static_libs: [
+        "junit",
+        "satellite-s2storage-tools",
+        "s2-geometry-library-java",
+        "satellite-s2storage-testutils"
+    ],
+    test_suites: ["general-tests"],
+}
\ No newline at end of file
diff --git a/utils/satellite/tools/TEST_MAPPING b/utils/satellite/tools/TEST_MAPPING
new file mode 100644
index 0000000..df9511a
--- /dev/null
+++ b/utils/satellite/tools/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+    "postsubmit": [
+        {
+            "name": "SatelliteToolsTests"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateSatS2File.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateSatS2File.java
new file mode 100644
index 0000000..f82cd5c
--- /dev/null
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateSatS2File.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+
+/** Creates a Sat S2 file from the list of S2 cells. */
+public final class CreateSatS2File {
+    /**
+     * Usage:
+     * CreateSatS2File <[input] s2 cells file> <[input] s2 level of input data>
+     *     <[input] whether s2 cells is an allowed list> <[output] sat s2 file>
+     */
+    public static void main(String[] args) throws Exception {
+        Arguments arguments = new Arguments();
+        JCommander.newBuilder()
+                .addObject(arguments)
+                .build()
+                .parse(args);
+        String inputFile = arguments.inputFile;
+        int s2Level = arguments.s2Level;
+        String outputFile = arguments.outputFile;
+        boolean isAllowedList = Arguments.getBooleanValue(arguments.isAllowedList);
+        SatS2FileCreator.create(inputFile, s2Level, isAllowedList, outputFile);
+    }
+
+    private static class Arguments {
+        @Parameter(names = "--input-file",
+                description = "s2 cells file",
+                required = true)
+        public String inputFile;
+
+        @Parameter(names = "--s2-level",
+                description = "s2 level of input data",
+                required = true)
+        public int s2Level;
+
+        @Parameter(names = "--is-allowed-list",
+                description = "whether s2 cells file contains an allowed list of cells",
+                required = true)
+        public String isAllowedList;
+
+        @Parameter(names = "--output-file",
+                description = "sat s2 file",
+                required = true)
+        public String outputFile;
+
+        public static Boolean getBooleanValue(String value) {
+            if ("false".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value)) {
+                return Boolean.parseBoolean(value);
+            } else {
+                throw new ParameterException("Invalid boolean string:" + value);
+            }
+        }
+    }
+}
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateTestSatS2File.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateTestSatS2File.java
new file mode 100644
index 0000000..f9a9347
--- /dev/null
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/CreateTestSatS2File.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2;
+
+import com.android.storage.s2.S2LevelRange;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.write.SatS2RangeFileWriter;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+
+/** Creates a Sat S2 file with a small amount of test data. Useful for testing other tools. */
+public final class CreateTestSatS2File {
+
+    /**
+     * Usage:
+     * CreateTestSatS2File &lt;file name&gt;
+     */
+    public static void main(String[] args) throws Exception {
+        File file = new File(args[0]);
+
+        SatS2RangeFileFormat fileFormat = FileFormats.getFileFormatForLevel(12, true);
+        if (fileFormat.getPrefixBitCount() != 11) {
+            throw new IllegalStateException("Fake data requires 11 prefix bits");
+        }
+
+        try (SatS2RangeFileWriter satS2RangeFileWriter =
+                     SatS2RangeFileWriter.open(file, fileFormat)) {
+            // Two ranges that share a prefix.
+            S2LevelRange range1 = new S2LevelRange(
+                    fileFormat.createCellId(0b100_11111111, 1000),
+                    fileFormat.createCellId(0b100_11111111, 2000));
+            S2LevelRange range2 = new S2LevelRange(
+                    fileFormat.createCellId(0b100_11111111, 2000),
+                    fileFormat.createCellId(0b100_11111111, 3000));
+            // This range has a different face, so a different prefix, and will be in a different
+            // suffix table.
+            S2LevelRange range3 = new S2LevelRange(
+                    fileFormat.createCellId(0b101_11111111, 1000),
+                    fileFormat.createCellId(0b101_11111111, 2000));
+            List<S2LevelRange> allRanges = listOf(range1, range2, range3);
+            satS2RangeFileWriter.createSortedSuffixBlocks(allRanges.iterator());
+        }
+    }
+
+    @SafeVarargs
+    private static <E> List<E> listOf(E... values) {
+        return Arrays.asList(values);
+    }
+}
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/DumpSatS2File.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/DumpSatS2File.java
new file mode 100644
index 0000000..2a9ce37
--- /dev/null
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/DumpSatS2File.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2;
+
+import com.android.storage.tools.block.DumpBlockFile;
+import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+import com.android.telephony.tools.sats2.dump.SatS2RangeFileDumper;
+
+import java.io.File;
+
+/**
+ * Dumps information about a Sat S2 data file. Like {@link DumpBlockFile} but it knows details about
+ * the Sat S2 format and can provide more detailed information.
+ */
+public final class DumpSatS2File {
+
+    /**
+     * Usage:
+     * DumpSatFile <[input] sat s2 file name> <[output] output directory name>
+     */
+    public static void main(String[] args) throws Exception {
+        String satS2FileName = args[0];
+        String outputDirName = args[1];
+
+        File outputDir = new File(outputDirName);
+        outputDir.mkdirs();
+
+        File satS2File = new File(satS2FileName);
+        try (SatS2RangeFileReader reader = SatS2RangeFileReader.open(satS2File)) {
+            reader.visit(new SatS2RangeFileDumper(outputDir));
+        }
+    }
+}
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/FileFormats.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/FileFormats.java
new file mode 100644
index 0000000..b800897
--- /dev/null
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/FileFormats.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2;
+
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+
+/** Some sample file formats. */
+public final class FileFormats {
+
+    // level 12: 27 S2 cell ID bits split 11 + 16,
+    // suffix table: 24 bits, 16/24 for cell id suffix, 8/24 dedicated to range
+    private static final SatS2RangeFileFormat FILE_FORMAT_12_ALLOWED_LIST =
+            new SatS2RangeFileFormat(12, 11, 16, 1, 24, true);
+    private static final SatS2RangeFileFormat FILE_FORMAT_12_DISALLOWED_LIST =
+            new SatS2RangeFileFormat(12, 11, 16, 1, 24, false);
+
+    // level 14: 31 S2 cell ID bits split 13 + 18,
+    // suffix table: 32 bits, 18/32 for cell id suffix, 14/32 dedicated to range
+    private static final SatS2RangeFileFormat FILE_FORMAT_14_ALLOWED_LIST =
+            new SatS2RangeFileFormat(14, 13, 18, 1, 32, true);
+    private static final SatS2RangeFileFormat FILE_FORMAT_14_DISALLOWED_LIST =
+            new SatS2RangeFileFormat(14, 13, 18, 1, 32, false);
+
+    // level 16: 35 S2 cell ID bits split 13 + 22,
+    // suffix table: 32 bits, 22/32 for cell id suffix, 10/32 dedicated to range
+    private static final SatS2RangeFileFormat FILE_FORMAT_16_ALLOWED_LIST =
+            new SatS2RangeFileFormat(16, 13, 22, 1, 32, true);
+    private static final SatS2RangeFileFormat FILE_FORMAT_16_DISALLOWED_LIST =
+            new SatS2RangeFileFormat(16, 13, 22, 1, 32, false);
+
+    /** Maps an S2 level to one of the file format constants declared on by class. */
+    public static SatS2RangeFileFormat getFileFormatForLevel(int s2Level, boolean isAllowedList) {
+        switch (s2Level) {
+            case 12:
+                return isAllowedList ? FILE_FORMAT_12_ALLOWED_LIST : FILE_FORMAT_12_DISALLOWED_LIST;
+            case 14:
+                return isAllowedList ? FILE_FORMAT_14_ALLOWED_LIST : FILE_FORMAT_14_DISALLOWED_LIST;
+            case 16:
+                return isAllowedList ? FILE_FORMAT_16_ALLOWED_LIST : FILE_FORMAT_16_DISALLOWED_LIST;
+            default:
+                throw new IllegalArgumentException("s2Level=" + s2Level
+                        + ", isAllowedList=" + isAllowedList + " not mapped");
+        }
+    }
+}
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java
new file mode 100644
index 0000000..b701a7b
--- /dev/null
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/SatS2FileCreator.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2;
+
+import com.android.storage.s2.S2LevelRange;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+import com.android.telephony.sats2range.write.SatS2RangeFileWriter;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.geometry.S2CellId;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Scanner;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/** A util class for creating a satellite S2 file from the list of S2 cells. */
+public final class SatS2FileCreator {
+    /**
+     * @param inputFile The input text file containing the list of S2 Cell IDs. Each line in the
+     *                  file contains a number in the range of a signed-64bit number which
+     *                  represents the ID of a S2 cell.
+     * @param s2Level The S2 level of all S2 cells in the input file.
+     * @param isAllowedList {@code true} means the input file contains an allowed list of S2 cells.
+     *                      {@code false} means the input file contains a disallowed list of S2
+     *                      cells.
+     * @param outputFile The output file to which the satellite S2 data in block format will be
+     *                   written.
+     */
+    public static void create(String inputFile, int s2Level, boolean isAllowedList,
+            String outputFile) throws Exception {
+        // Read a list of S2 cells from input file
+        List<Long> s2Cells = readS2CellsFromFile(inputFile);
+        System.out.println("Number of S2 cells read from file:" + s2Cells.size());
+
+        // Convert the input list of S2 Cells into the list of sorted S2CellId
+        List<S2CellId> sortedS2CellIds = s2Cells.stream()
+                .map(x -> new S2CellId(x))
+                .collect(Collectors.toList());
+        // IDs of S2CellId are converted to unsigned long numbers, which will be then used to
+        // compare S2CellId.
+        Collections.sort(sortedS2CellIds);
+
+        // Compress the list of S2CellId into S2 ranges
+        List<SatS2Range> satS2Ranges = createSatS2Ranges(sortedS2CellIds, s2Level);
+
+        // Write the S2 ranges into a block file
+        SatS2RangeFileFormat fileFormat =
+                FileFormats.getFileFormatForLevel(s2Level, isAllowedList);
+        try (SatS2RangeFileWriter satS2RangeFileWriter =
+                     SatS2RangeFileWriter.open(new File(outputFile), fileFormat)) {
+            Iterator<S2LevelRange> s2LevelRangeIterator = satS2Ranges
+                    .stream()
+                    .map(x -> new S2LevelRange(x.rangeStart.id(), x.rangeEnd.id()))
+                    .iterator();
+            /*
+             * Group the sorted ranges into contiguous suffix blocks. Big ranges might get split as
+             * needed to fit them into suffix blocks.
+             */
+            satS2RangeFileWriter.createSortedSuffixBlocks(s2LevelRangeIterator);
+        }
+
+        // Validate the output block file
+        System.out.println("Validating the output block file...");
+        try (SatS2RangeFileReader satS2RangeFileReader =
+                     SatS2RangeFileReader.open(new File(outputFile))) {
+            if (isAllowedList != satS2RangeFileReader.isAllowedList()) {
+                throw new IllegalStateException("isAllowedList="
+                        + satS2RangeFileReader.isAllowedList() + " does not match the input "
+                        + "argument=" + isAllowedList);
+            }
+
+            // Verify that all input S2 cells are present in the output block file
+            for (S2CellId s2CellId : sortedS2CellIds) {
+                if (satS2RangeFileReader.findEntryByCellId(s2CellId.id()) == null) {
+                    throw new IllegalStateException("s2CellId=" + s2CellId
+                            + " is not present in the output sat s2 file");
+                }
+            }
+
+            // Verify the cell right before the first cell in the sortedS2CellIds is not present in
+            // the output block file
+            S2CellId prevCell = sortedS2CellIds.get(0).prev();
+            if (!sortedS2CellIds.contains(prevCell)
+                    && satS2RangeFileReader.findEntryByCellId(prevCell.id()) != null) {
+                throw new IllegalStateException("The cell " + prevCell + ", which is right "
+                        + "before the first cell is unexpectedly present in the output sat s2"
+                        + " file");
+            } else {
+                System.out.println("prevCell=" + prevCell + " is in the sortedS2CellIds");
+            }
+
+            // Verify the cell right after the last cell in the sortedS2CellIds is not present in
+            // the output block file
+            S2CellId nextCell = sortedS2CellIds.get(sortedS2CellIds.size() - 1).next();
+            if (!sortedS2CellIds.contains(nextCell)
+                    && satS2RangeFileReader.findEntryByCellId(nextCell.id()) != null) {
+                throw new IllegalStateException("The cell " + nextCell + ", which is right "
+                        + "after the last cell is unexpectedly present in the output sat s2"
+                        + " file");
+            } else {
+                System.out.println("nextCell=" + nextCell + " is in the sortedS2CellIds");
+            }
+        }
+        System.out.println("Successfully validated the output block file");
+    }
+
+    /**
+     * Read a list of S2 cells from the inputFile.
+     *
+     * @param inputFile A file containing the list of S2 cells. Each line in the inputFile contains
+     *                  a long number - the ID of a S2 cell.
+     * @return A list of S2 cells.
+     */
+    private static List<Long> readS2CellsFromFile(String inputFile) throws Exception {
+        List<Long> s2Cells = new ArrayList();
+        InputStream inputStream = new FileInputStream(inputFile);
+        try (Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name())) {
+            while (scanner.hasNextLong()) {
+                s2Cells.add(scanner.nextLong());
+            }
+            if (scanner.hasNextLine()) {
+                throw new IllegalStateException("Input s2 cell file has invalid format, "
+                        + "current line=" + scanner.nextLine());
+            }
+        }
+        return s2Cells;
+    }
+
+    /**
+     * Compress the list of sorted S2CellId into S2 ranges.
+     *
+     * @param sortedS2CellIds List of S2CellId sorted in ascending order.
+     * @param s2Level The level of all S2CellId.
+     * @return List of S2 ranges.
+     */
+    private static List<SatS2Range> createSatS2Ranges(List<S2CellId> sortedS2CellIds, int s2Level) {
+        Stopwatch stopwatch = Stopwatch.createStarted();
+        List<SatS2Range> ranges = new ArrayList<>();
+        if (sortedS2CellIds != null && sortedS2CellIds.size() > 0) {
+            S2CellId rangeStart = null;
+            S2CellId rangeEnd = null;
+            for (int i = 0; i < sortedS2CellIds.size(); i++) {
+                S2CellId currentS2CellId = sortedS2CellIds.get(i);
+                checkCellIdIsAtLevel(currentS2CellId, s2Level);
+
+                SatS2Range currentRange = createS2Range(currentS2CellId, s2Level);
+                S2CellId currentS2CellRangeStart = currentRange.rangeStart;
+                S2CellId currentS2CellRangeEnd = currentRange.rangeEnd;
+
+                if (rangeStart == null) {
+                    // First time round the loop initialize rangeStart / rangeEnd only.
+                    rangeStart = currentS2CellRangeStart;
+                } else if (rangeEnd.id() != currentS2CellRangeStart.id()) {
+                    // If there's a gap between cellIds, store the range we have so far and start a
+                    // new range.
+                    ranges.add(new SatS2Range(rangeStart, rangeEnd));
+                    rangeStart = currentS2CellRangeStart;
+                }
+                rangeEnd = currentS2CellRangeEnd;
+            }
+            ranges.add(new SatS2Range(rangeStart, rangeEnd));
+        }
+
+        // Sorting the ranges is not necessary. As the input is sorted , it will already be sorted.
+        System.out.printf("Created %s SatS2Ranges in %s milliseconds\n",
+                ranges.size(), stopwatch.elapsed(TimeUnit.MILLISECONDS));
+        return ranges;
+    }
+
+    /**
+     * @return A pair of S2CellId for the range [s2CellId, s2CellId's next sibling)
+     */
+    private static SatS2Range createS2Range(
+            S2CellId s2CellId, int s2Level) {
+        // Since s2CellId is at s2Level, s2CellId.childBegin(s2Level) returns itself.
+        S2CellId firstS2CellRangeStart = s2CellId.childBegin(s2Level);
+        // Get the immediate next sibling of s2CellId
+        S2CellId firstS2CellRangeEnd = s2CellId.childEnd(s2Level);
+
+        if (firstS2CellRangeEnd.face() < firstS2CellRangeStart.face()
+                || !firstS2CellRangeEnd.isValid()) {
+            // Fix this if it becomes an issue.
+            throw new IllegalStateException("firstS2CellId=" + s2CellId
+                    + ", childEnd(" + s2Level + ") produced an unsupported"
+                    + " value=" + firstS2CellRangeEnd);
+        }
+        return new SatS2Range(firstS2CellRangeStart, firstS2CellRangeEnd);
+    }
+
+    private static void checkCellIdIsAtLevel(S2CellId cellId, int s2Level) {
+        if (cellId.level() != s2Level) {
+            throw new IllegalStateException("Bad level for cellId=" + cellId
+                    + ". Must be s2Level=" + s2Level);
+        }
+    }
+
+    /**
+     * A range of S2 cell IDs at a fixed S2 level. The range is expressed as a start cell ID
+     * (inclusive) and an end cell ID (exclusive).
+     */
+    private static class SatS2Range {
+        public final S2CellId rangeStart;
+        public final S2CellId rangeEnd;
+
+        /**
+         * Creates an instance. If the range is invalid or the cell IDs are from different levels
+         * this method throws an {@link IllegalArgumentException}.
+         */
+        SatS2Range(S2CellId rangeStart, S2CellId rangeEnd) {
+            this.rangeStart = Objects.requireNonNull(rangeStart);
+            this.rangeEnd = Objects.requireNonNull(rangeEnd);
+            if (rangeStart.level() != rangeEnd.level()) {
+                throw new IllegalArgumentException(
+                        "Levels differ: rangeStart=" + rangeStart + ", rangeEnd=" + rangeEnd);
+            }
+            if (rangeStart.greaterOrEquals(rangeEnd)) {
+                throw new IllegalArgumentException(
+                        "Range start (" + rangeStart + " >= range end (" + rangeEnd + ")");
+            }
+        }
+    }
+}
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/dump/HeaderBlockDumper.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/dump/HeaderBlockDumper.java
new file mode 100644
index 0000000..69a3f70
--- /dev/null
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/dump/HeaderBlockDumper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2.dump;
+
+import com.android.storage.tools.block.dump.SingleFileDumper;
+import com.android.telephony.sats2range.read.HeaderBlock;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+
+import java.io.File;
+
+/** A {@link HeaderBlock.HeaderBlockVisitor} that dumps information to a file. */
+final class HeaderBlockDumper extends SingleFileDumper implements HeaderBlock.HeaderBlockVisitor {
+
+    HeaderBlockDumper(File headerBlockFile) {
+        super(headerBlockFile);
+    }
+
+    @Override
+    public void visitFileFormat(SatS2RangeFileFormat fileFormat) {
+        println("File format");
+        println("===========");
+        println(fileFormat.toString());
+        println();
+    }
+}
+
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/dump/SatS2RangeFileDumper.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/dump/SatS2RangeFileDumper.java
new file mode 100644
index 0000000..307275a
--- /dev/null
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/dump/SatS2RangeFileDumper.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2.dump;
+
+import static com.android.storage.tools.block.dump.DumpUtils.binaryStringLength;
+import static com.android.storage.tools.block.dump.DumpUtils.hexStringLength;
+import static com.android.storage.tools.block.dump.DumpUtils.zeroPadBinary;
+import static com.android.storage.tools.block.dump.DumpUtils.zeroPadHex;
+
+import com.android.storage.tools.block.dump.SingleFileDumper;
+import com.android.telephony.sats2range.read.HeaderBlock;
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+import com.android.telephony.sats2range.read.SuffixTableBlock;
+import com.android.telephony.sats2range.read.SuffixTableExtraInfo;
+
+import java.io.File;
+
+/** A {@link SatS2RangeFileReader.SatS2RangeFileVisitor} that dumps information to a file. */
+public final class SatS2RangeFileDumper implements SatS2RangeFileReader.SatS2RangeFileVisitor {
+
+    private final File mOutputDir;
+
+    private int mMaxPrefix;
+
+    private int mMaxPrefixBinaryLength;
+
+    private int mMaxPrefixHexLength;
+
+    private SingleFileDumper mExtraInfoDumper;
+
+    public SatS2RangeFileDumper(File outputDir) {
+        mOutputDir = outputDir;
+    }
+
+    @Override
+    public void begin() throws VisitException {
+        mExtraInfoDumper = new SingleFileDumper(new File(mOutputDir, "suffixtable_extrainfo.txt"));
+        mExtraInfoDumper.begin();
+    }
+
+    @Override
+    public void visitSuffixTableExtraInfo(SuffixTableExtraInfo suffixTableExtraInfo) {
+        int prefix = suffixTableExtraInfo.getPrefix();
+        mExtraInfoDumper.println("prefix=" + zeroPadBinary(mMaxPrefixBinaryLength, prefix)
+                + "(" + zeroPadHex(mMaxPrefixHexLength, prefix) + ")"
+                + ", entryCount=" + suffixTableExtraInfo.getEntryCount());
+    }
+
+    @Override
+    public void visitHeaderBlock(HeaderBlock headerBlock) throws VisitException {
+        File headerFile = new File(mOutputDir, "header.txt");
+        headerBlock.visit(new HeaderBlockDumper(headerFile));
+        SatS2RangeFileFormat fileFormat = headerBlock.getFileFormat();
+        mMaxPrefix = fileFormat.getMaxPrefixValue();
+        mMaxPrefixBinaryLength = binaryStringLength(mMaxPrefix);
+        mMaxPrefixHexLength = hexStringLength(mMaxPrefix);
+    }
+
+    @Override
+    public void visitSuffixTableBlock(SuffixTableBlock suffixTableBlock)
+            throws VisitException {
+        suffixTableBlock.visit(new SuffixTableBlockDumper(mOutputDir, mMaxPrefix));
+    }
+
+    @Override
+    public void end() throws VisitException {
+        mExtraInfoDumper.end();
+    }
+}
+
diff --git a/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/dump/SuffixTableBlockDumper.java b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/dump/SuffixTableBlockDumper.java
new file mode 100644
index 0000000..a5d75b4
--- /dev/null
+++ b/utils/satellite/tools/src/main/java/com/android/telephony/tools/sats2/dump/SuffixTableBlockDumper.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2.dump;
+
+import static com.android.storage.tools.block.dump.DumpUtils.binaryStringLength;
+import static com.android.storage.tools.block.dump.DumpUtils.createPrintWriter;
+import static com.android.storage.tools.block.dump.DumpUtils.generateDumpFile;
+import static com.android.storage.tools.block.dump.DumpUtils.hexStringLength;
+import static com.android.storage.tools.block.dump.DumpUtils.zeroPadBinary;
+import static com.android.storage.tools.block.dump.DumpUtils.zeroPadHex;
+
+import com.android.telephony.sats2range.read.SuffixTableBlock;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.util.Objects;
+
+/** A {@link SuffixTableBlock.SuffixTableBlockVisitor} that dumps information to a file. */
+public final class SuffixTableBlockDumper implements SuffixTableBlock.SuffixTableBlockVisitor {
+
+    private final File mOutputDir;
+
+    private final int mMaxPrefix;
+
+    public SuffixTableBlockDumper(File outputDir, int maxPrefix) {
+        mOutputDir = Objects.requireNonNull(outputDir);
+        mMaxPrefix = maxPrefix;
+    }
+
+    @Override
+    public void visit(SuffixTableBlock suffixTableBlock) throws VisitException {
+        int tablePrefix = suffixTableBlock.getPrefix();
+        int prefixHexLength = hexStringLength(tablePrefix);
+        int prefixBinaryLength = binaryStringLength(tablePrefix);
+        File suffixTableFile =
+                generateDumpFile(mOutputDir, "suffixtable_", tablePrefix, mMaxPrefix);
+        try (PrintWriter writer = createPrintWriter(suffixTableFile)) {
+            writer.println("Prefix value=" + zeroPadBinary(prefixBinaryLength, tablePrefix)
+                    + " (" + zeroPadHex(prefixHexLength, tablePrefix) + ")");
+            int entryCount = suffixTableBlock.getEntryCount();
+            writer.println("Entry count=" + entryCount);
+            if (entryCount > 0) {
+                for (int i = 0; i < entryCount; i++) {
+                    writer.println(
+                            "[" + i + "]=" + suffixTableBlock.getEntryByIndex(i)
+                                    .getSuffixTableRange());
+                }
+            }
+        }
+    }
+}
+
diff --git a/utils/satellite/tools/src/test/java/com/android/telephony/tools/sats2/CreateSatS2FileTest.java b/utils/satellite/tools/src/test/java/com/android/telephony/tools/sats2/CreateSatS2FileTest.java
new file mode 100644
index 0000000..80c1807
--- /dev/null
+++ b/utils/satellite/tools/src/test/java/com/android/telephony/tools/sats2/CreateSatS2FileTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telephony.tools.sats2;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import com.android.telephony.sats2range.read.SatS2RangeFileFormat;
+import com.android.telephony.sats2range.read.SatS2RangeFileReader;
+import com.android.telephony.sats2range.utils.TestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+
+/** Tests for {@link CreateSatS2File} */
+public final class CreateSatS2FileTest {
+    private Path mTempDirPath;
+
+    @Before
+    public void setUp() throws IOException {
+        mTempDirPath = TestUtils.createTempDir(this.getClass());
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        if (mTempDirPath != null) {
+            TestUtils.deleteDirectory(mTempDirPath);
+        }
+    }
+
+    @Test
+    public void testCreateSatS2FileWithValidInput_AllowedList() throws Exception {
+        testCreateSatS2FileWithValidInput(true);
+    }
+
+    @Test
+    public void testCreateSatS2FileWithValidInput_DisallowedList() throws Exception {
+        testCreateSatS2FileWithValidInput(false);
+    }
+
+    @Test
+    public void testCreateSatS2FileWithInvalidInput() throws Exception {
+        int s2Level = 12;
+        boolean isAllowedList = true;
+        Path inputDirPath = mTempDirPath.resolve("input");
+        Files.createDirectory(inputDirPath);
+        Path inputFilePath = inputDirPath.resolve("s2cells.txt");
+
+        Path outputDirPath = mTempDirPath.resolve("output");
+        Files.createDirectory(outputDirPath);
+        Path outputFilePath = outputDirPath.resolve("sats2.dat");
+
+        // Create test input S2 cell file
+        SatS2RangeFileFormat fileFormat = FileFormats.getFileFormatForLevel(s2Level, isAllowedList);
+        TestUtils.createInvalidTestS2CellFile(inputFilePath.toFile(), fileFormat);
+
+        // Commandline input arguments
+        String[] args = {
+                "--input-file", inputFilePath.toAbsolutePath().toString(),
+                "--s2-level", String.valueOf(s2Level),
+                "--is-allowed-list", isAllowedList ? "true" : "false",
+                "--output-file", outputFilePath.toAbsolutePath().toString()
+        };
+
+        // Execute the tool CreateSatS2File and expect exception
+        try {
+            CreateSatS2File.main(args);
+        } catch (Exception ex) {
+            // Expected exception
+            return;
+        }
+        fail("Exception should have been caught");
+    }
+
+    private void testCreateSatS2FileWithValidInput(boolean isAllowedList) throws Exception {
+        int s2Level = 12;
+        Path inputDirPath = mTempDirPath.resolve("input");
+        Files.createDirectory(inputDirPath);
+        Path inputFilePath = inputDirPath.resolve("s2cells.txt");
+
+        Path outputDirPath = mTempDirPath.resolve("output");
+        Files.createDirectory(outputDirPath);
+        Path outputFilePath = outputDirPath.resolve("sats2.dat");
+
+        /*
+         * Create test input S2 cell file with the following ranges:
+         * 1) [(prefix=0b100_11111111, suffix=1000), (prefix=0b100_11111111, suffix=2000))
+         * 2) [(prefix=0b100_11111111, suffix=2001), (prefix=0b100_11111111, suffix=3000))
+         * 3) [(prefix=0b101_11111111, suffix=1000), (prefix=0b101_11111111, suffix=2001))
+         */
+        SatS2RangeFileFormat fileFormat = FileFormats.getFileFormatForLevel(s2Level, isAllowedList);
+        TestUtils.createValidTestS2CellFile(inputFilePath.toFile(), fileFormat);
+
+        // Commandline input arguments
+        String[] args = {
+                "--input-file", inputFilePath.toAbsolutePath().toString(),
+                "--s2-level", String.valueOf(s2Level),
+                "--is-allowed-list", isAllowedList ? "true" : "false",
+                "--output-file", outputFilePath.toAbsolutePath().toString()
+        };
+
+        // Execute the tool CreateSatS2File and expect successful result
+        try {
+            CreateSatS2File.main(args);
+        } catch (Exception ex) {
+            fail("Unexpected exception when executing the tool ex=" + ex);
+        }
+
+        // Validate the output block file
+        try {
+            SatS2RangeFileReader satS2RangeFileReader =
+                         SatS2RangeFileReader.open(outputFilePath.toFile());
+            if (isAllowedList != satS2RangeFileReader.isAllowedList()) {
+                fail("isAllowedList="
+                        + satS2RangeFileReader.isAllowedList() + " does not match the input "
+                        + "argument=" + isAllowedList);
+            }
+
+            // Verify an edge cell (prefix=0b100_11111111, suffix=100)
+            long s2CellId = fileFormat.createCellId(0b100_11111111, 100);
+            assertNull(satS2RangeFileReader.findEntryByCellId(s2CellId));
+
+            // Verify a middle cell (prefix=0b100_11111111, suffix=2000)
+            s2CellId = fileFormat.createCellId(0b100_11111111, 2000);
+            assertNull(satS2RangeFileReader.findEntryByCellId(s2CellId));
+
+            // Verify an edge cell (prefix=0b100_11111111, suffix=4000)
+            s2CellId = fileFormat.createCellId(0b100_11111111, 4000);
+            assertNull(satS2RangeFileReader.findEntryByCellId(s2CellId));
+
+            // Verify an edge cell (prefix=0b101_11111111, suffix=500)
+            s2CellId = fileFormat.createCellId(0b101_11111111, 500);
+            assertNull(satS2RangeFileReader.findEntryByCellId(s2CellId));
+
+            // Verify an edge cell (prefix=0b101_11111111, suffix=2001)
+            s2CellId = fileFormat.createCellId(0b101_11111111, 2500);
+            assertNull(satS2RangeFileReader.findEntryByCellId(s2CellId));
+
+            // Verify an edge cell (prefix=0b101_11111111, suffix=2500)
+            s2CellId = fileFormat.createCellId(0b101_11111111, 2500);
+            assertNull(satS2RangeFileReader.findEntryByCellId(s2CellId));
+        } catch (Exception ex) {
+            fail("Unexpected exception when validating the output ex=" + ex);
+        }
+    }
+}
