Merge "Link in libshaders into composer VTS"
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
index 54c65ba..22c690c 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable CreateUserRequest {
   int requestId;
   android.hardware.automotive.vehicle.UserInfo newUserInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
index 6126f99..7d0196b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable CreateUserResponse {
   int requestId;
   android.hardware.automotive.vehicle.CreateUserStatus status = android.hardware.automotive.vehicle.CreateUserStatus.SUCCESS;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
index 177966b..d88cd8b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable GetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue prop;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl
index 5ecf4dd..a7df2ff 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable GetValueRequests {
   android.hardware.automotive.vehicle.GetValueRequest[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
index 60c46e4..25f3575 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable GetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl
index 778ba8e..4c365b1 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable GetValueResults {
   android.hardware.automotive.vehicle.GetValueResult[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
index c2c2500..a4c048a 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable InitialUserInfoRequest {
   int requestId;
   android.hardware.automotive.vehicle.InitialUserInfoRequestType requestType = android.hardware.automotive.vehicle.InitialUserInfoRequestType.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
index ffb1781..f0e1612 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable InitialUserInfoResponse {
   int requestId;
   android.hardware.automotive.vehicle.InitialUserInfoResponseAction action = android.hardware.automotive.vehicle.InitialUserInfoResponseAction.DEFAULT;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
index e553d60..e7b0a13 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable RawPropValues {
   int[] int32Values = {};
   float[] floatValues;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
index 6861309..74457b9 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable RemoveUserRequest {
   int requestId;
   android.hardware.automotive.vehicle.UserInfo removedUserInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
index d6cddb6..6a65307 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SetValueRequest {
   long requestId;
   android.hardware.automotive.vehicle.VehiclePropValue value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl
index ea9ac9a..15fd7ea 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SetValueRequests {
   android.hardware.automotive.vehicle.SetValueRequest[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
index 6c25bc8..ec5fabb 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SetValueResult {
   long requestId;
   android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl
index 65ff8f0..47f1656 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SetValueResults {
   android.hardware.automotive.vehicle.SetValueResult[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index dcefd09..91e7c14 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SubscribeOptions {
   int propId;
   int[] areaIds;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
index bb18e02..3012b7a 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SwitchUserRequest {
   int requestId;
   android.hardware.automotive.vehicle.SwitchUserMessageType messageType = android.hardware.automotive.vehicle.SwitchUserMessageType.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
index efc1911..8915d1b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable SwitchUserResponse {
   int requestId;
   android.hardware.automotive.vehicle.SwitchUserMessageType messageType = android.hardware.automotive.vehicle.SwitchUserMessageType.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
index a0f9879..a540f8e 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationAssociation {
   android.hardware.automotive.vehicle.UserIdentificationAssociationType type = android.hardware.automotive.vehicle.UserIdentificationAssociationType.INVALID;
   android.hardware.automotive.vehicle.UserIdentificationAssociationValue value = android.hardware.automotive.vehicle.UserIdentificationAssociationValue.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
index 744030e..fe7fd6f 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationGetRequest {
   int requestId;
   android.hardware.automotive.vehicle.UserInfo userInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
index b47b003..3e2a257 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationResponse {
   int requestId;
   int numberAssociation;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
index 5297349..57840fb 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationSetAssociation {
   android.hardware.automotive.vehicle.UserIdentificationAssociationType type = android.hardware.automotive.vehicle.UserIdentificationAssociationType.INVALID;
   android.hardware.automotive.vehicle.UserIdentificationAssociationSetValue value = android.hardware.automotive.vehicle.UserIdentificationAssociationSetValue.INVALID;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
index 725040d..db01b51 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserIdentificationSetRequest {
   int requestId;
   android.hardware.automotive.vehicle.UserInfo userInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
index b99272b..f47d5e7 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UserInfo {
   int userId = 0;
   int flags;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
index 7234316..edcef2e 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable UsersInfo {
   android.hardware.automotive.vehicle.UserInfo currentUser;
   int numberUsers;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 7a42ec8..b93a11b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehicleAreaConfig {
   int areaId;
   int minInt32Value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 16ba6db..8602d2d 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropConfig {
   int prop;
   android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
index e5d146d..04c8006 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropConfigs {
   android.hardware.automotive.vehicle.VehiclePropConfig[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 8b2e104..9835295 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropError {
   int propId;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
index 6303d3a..9dcb10b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropErrors {
   android.hardware.automotive.vehicle.VehiclePropError[] payloads;
   @nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index fc1ae53..c87379f 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropValue {
   long timestamp;
   int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl
index da8c60b..e09a6b9 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
 parcelable VehiclePropValues {
   android.hardware.automotive.vehicle.VehiclePropValue[] payloads;
   long sharedMemoryId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
index 1f7c9cc..624e5a6 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable CreateUserRequest {
     /**
      * Arbitrary id used to map the response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
index d011366..29db442 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
@@ -25,6 +25,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable CreateUserResponse {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
index 43a89d0..e5b3929 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -19,6 +19,7 @@
 import android.hardware.automotive.vehicle.VehiclePropValue;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable GetValueRequest {
     // A unique request ID. For every client, the request ID must start with 1
     // and monotonically increase for every SetValueRequest. If it hits
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl
index 6601233..3bbb88c 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable GetValueRequests {
     // A list of GetValueRequest to get if they fit the binder memory
     // limitation.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
index b099a85..24c5757 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -20,6 +20,7 @@
 import android.hardware.automotive.vehicle.VehiclePropValue;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable GetValueResult {
     // The ID for the request this response is for.
     long requestId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl
index 919e644..a8bfb2c 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable GetValueResults {
     // The list of responses if they fit the binder memory limitation.
     GetValueResult[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
index 7879d44..c7ba836 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable InitialUserInfoRequest {
     /**
      * Arbitrary id used to map the HAL response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
index 8be0c69..4c46fcb 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable InitialUserInfoResponse {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
index 5d8febd..9c6875b 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -17,6 +17,7 @@
 package android.hardware.automotive.vehicle;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable RawPropValues {
     /**
      * This is used for properties of types VehiclePropertyType#INT
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
index 1a3d4dd..cb61da8 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable RemoveUserRequest {
     /**
      * Arbitrary id used to map the response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
index f2b0e27..625f901 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -19,6 +19,7 @@
 import android.hardware.automotive.vehicle.VehiclePropValue;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SetValueRequest {
     // A unique request ID. For every client, the request ID must start with 1
     // and monotonically increase for every SetValueRequest. If it hits
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl
index 5d6ad85..a690fa2 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SetValueRequests {
     // The list of request if they fit the binder memory limitation.
     SetValueRequest[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
index a468f3b..b3feeaa 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -19,6 +19,7 @@
 import android.hardware.automotive.vehicle.StatusCode;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SetValueResult {
     // The ID for the request this response is for.
     long requestId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl
index 6df9de0..9b0e505 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SetValueResults {
     // The list of responses if they fit the binder memory limitation.
     SetValueResult[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index bc7d84a..e68f7e3 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -20,6 +20,7 @@
  * Encapsulates information about subscription to vehicle property events.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SubscribeOptions {
     /** Property to subscribe */
     int propId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
index 10858a4..320632c 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
@@ -27,6 +27,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SwitchUserRequest {
     /**
      * Arbitrary id used to map the response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
index d5d44e5..106386d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable SwitchUserResponse {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
index cdd11bf..4af5f72 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
@@ -23,6 +23,7 @@
  * Helper struct used when getting a user/identification association type.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationAssociation {
     UserIdentificationAssociationType type = UserIdentificationAssociationType.INVALID;
     UserIdentificationAssociationValue value = UserIdentificationAssociationValue.UNKNOWN;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
index 58620ef..82580d7 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
@@ -26,6 +26,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationGetRequest {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
index 06341c7..1487a70 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
@@ -25,6 +25,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationResponse {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
index fe5017f..bfb9544 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
@@ -23,6 +23,7 @@
  * Helper struct used when setting a user/identification association type.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationSetAssociation {
     UserIdentificationAssociationType type = UserIdentificationAssociationType.INVALID;
     UserIdentificationAssociationSetValue value = UserIdentificationAssociationSetValue.INVALID;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
index 13f3677..223ff08 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
@@ -25,6 +25,7 @@
  * VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserIdentificationSetRequest {
     /**
      * Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
index e4ecc4b..20c72bd 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
@@ -20,6 +20,7 @@
  * Information about a specific Android user.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UserInfo {
     /**
      * System user.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
index 77468b1..ede36f7 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
@@ -26,6 +26,7 @@
  * Vehicle HAL implementation.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable UsersInfo {
     /**
      * The current foreground user.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index b33dcbc..b44996d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -17,6 +17,7 @@
 package android.hardware.automotive.vehicle;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehicleAreaConfig {
     /**
      * Area id is ignored for VehiclePropertyGroup:GLOBAL properties.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 5e0dbec..1b48f0b 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -21,6 +21,7 @@
 import android.hardware.automotive.vehicle.VehiclePropertyChangeMode;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropConfig {
     /** Property identifier */
     int prop;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
index 98abdef..9c2d5f7 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropConfigs {
     // The list of vehicle property configs if they fit the binder memory
     // limitation.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 1608977..2c31c72 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -19,6 +19,7 @@
 import android.hardware.automotive.vehicle.StatusCode;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropError {
     // Property ID.
     int propId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
index 6a77d35..10a164d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropErrors {
     // List of property set errors if they fit binder memory limitation.
     VehiclePropError[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index 37dac59..289f270 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -25,6 +25,7 @@
  * events.
  */
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropValue {
     /** Time is elapsed nanoseconds since boot */
     long timestamp;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl
index 1944f8e..df44fdb 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 
 @VintfStability
+@JavaDerive(equals=true, toString=true)
 parcelable VehiclePropValues {
     // The list of vehicle properties if they fit the binder memory limitation.
     VehiclePropValue[] payloads;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index a3cd8ae..9bd04a0 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -42,6 +42,7 @@
   android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication();
   @nullable android.hardware.gnss.IGnssBatching getExtensionGnssBatching();
   @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence();
+  @nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
   const int ERROR_INVALID_ARGUMENT = 1;
   const int ERROR_ALREADY_INIT = 2;
   const int ERROR_GENERIC = 3;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
new file mode 100644
index 0000000..d513c15
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssNavigationMessageCallback {
+  void gnssNavigationMessageCb(in android.hardware.gnss.IGnssNavigationMessageCallback.GnssNavigationMessage message);
+  @VintfStability
+  parcelable GnssNavigationMessage {
+    int svid;
+    android.hardware.gnss.IGnssNavigationMessageCallback.GnssNavigationMessage.GnssNavigationMessageType type;
+    int status;
+    int messageId;
+    int submessageId;
+    byte[] data;
+    const int STATUS_PARITY_PASSED = 1;
+    const int STATUS_PARITY_REBUILT = 2;
+    const int STATUS_UNKNOWN = 0;
+    @Backing(type="int") @VintfStability
+    enum GnssNavigationMessageType {
+      UNKNOWN = 0,
+      GPS_L1CA = 257,
+      GPS_L2CNAV = 258,
+      GPS_L5CNAV = 259,
+      SBS = 513,
+      GPS_CNAV2 = 260,
+      GLO_L1CA = 769,
+      QZS_L1CA = 1025,
+      BDS_D1 = 1281,
+      BDS_D2 = 1282,
+      BDS_CNAV1 = 1283,
+      BDS_CNAV2 = 1284,
+      GAL_I = 1537,
+      GAL_F = 1538,
+      IRN_L5CA = 1793,
+    }
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
new file mode 100644
index 0000000..196e9b9
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssNavigationMessageInterface {
+  void setCallback(in android.hardware.gnss.IGnssNavigationMessageCallback callback);
+  void close();
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index e019d35..42cc496 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -21,6 +21,7 @@
 import android.hardware.gnss.IGnssConfiguration;
 import android.hardware.gnss.IGnssGeofence;
 import android.hardware.gnss.IGnssMeasurementInterface;
+import android.hardware.gnss.IGnssNavigationMessageInterface;
 import android.hardware.gnss.IGnssPowerIndication;
 import android.hardware.gnss.IGnssPsds;
 
@@ -118,4 +119,11 @@
      * @return Handle to the IGnssGeofence interface.
      */
     @nullable IGnssGeofence getExtensionGnssGeofence();
+
+    /**
+     * This method returns the IGnssNavigationMessageInterface.
+     *
+     * @return Handle to the IGnssNavigationMessageInterface.
+     */
+    @nullable IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
new file mode 100644
index 0000000..0fdfaf8
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.gnss;
+
+/** Represents a GNSS navigation message (or a fragment of it). */
+@VintfStability
+interface IGnssNavigationMessageCallback {
+    /**
+     * Represents a reading of GNSS measurements. For devices launched in Android Q or newer, it is
+     * mandatory that these be provided, on request, when the GNSS receiver is searching/tracking
+     * signals.
+     *
+     * - Reporting of GNSS constellation measurements is mandatory.
+     * - Reporting of all tracked constellations are encouraged.
+     */
+    @VintfStability
+    parcelable GnssNavigationMessage {
+        /**
+         * Status of Navigation Message
+         *
+         * When a message is received properly without any parity error in its
+         * navigation words, the status must be set to PARITY_PASSED.
+         *
+         * If a message is received with words that failed a parity check, but the GNSS
+         * receiver has corrected those words, the status must be set to PARITY_REBUILT.
+         *
+         * Do not send any navigation message that contains words with parity errors
+         * that cannot be corrected.
+         */
+        const int STATUS_PARITY_PASSED = (1 << 0);
+        const int STATUS_PARITY_REBUILT = (1 << 1);
+        const int STATUS_UNKNOWN = 0;
+
+        /**
+         * Enumeration of available values to indicate the GNSS Navigation message
+         * types.
+         *
+         * For convenience, first byte is the GnssConstellationType on which that signal
+         * is typically transmitted.
+         */
+        @VintfStability
+        @Backing(type="int")
+        enum GnssNavigationMessageType {
+            UNKNOWN = 0,
+
+            /** GPS L1 C/A message contained in the structure.  */
+            GPS_L1CA = 0x0101,
+
+            /** GPS L2-CNAV message contained in the structure. */
+            GPS_L2CNAV = 0x0102,
+
+            /** GPS L5-CNAV message contained in the structure. */
+            GPS_L5CNAV = 0x0103,
+
+            /* SBAS message contained in the structure. */
+            SBS = 0x0201,
+
+            /** GPS CNAV-2 message contained in the structure. */
+            GPS_CNAV2 = 0x0104,
+
+            /** Glonass L1 CA message contained in the structure. */
+            GLO_L1CA = 0x0301,
+
+            /** QZSS L1 C/A message contained in the structure. */
+            QZS_L1CA = 0x0401,
+
+            /** Beidou D1 message contained in the structure. */
+            BDS_D1 = 0x0501,
+
+            /** Beidou D2 message contained in the structure. */
+            BDS_D2 = 0x0502,
+
+            /** Beidou CNAV1 message contained in the structure. */
+            BDS_CNAV1 = 0x0503,
+
+            /** Beidou CNAV2 message contained in the structure. */
+            BDS_CNAV2 = 0x0504,
+
+            /** Galileo I/NAV message contained in the structure. */
+            GAL_I = 0x0601,
+
+            /** Galileo F/NAV message contained in the structure. */
+            GAL_F = 0x0602,
+
+            /** IRNSS L5 C/A message contained in the structure. */
+            IRN_L5CA = 0x0701,
+        }
+
+        /**
+         * Satellite vehicle ID number, as defined in GnssSvInfo::svid
+         *
+         * This is a mandatory value.
+         */
+        int svid;
+
+        /**
+         * The type of message contained in the structure.
+         *
+         * This is a mandatory value.
+         */
+        GnssNavigationMessageType type;
+
+        /**
+         * The status of the received navigation message.
+         *
+         * It is a bitfield of constants with prefix "STATUS_" defined in this structure.
+         *
+         * No need to send any navigation message that contains words with parity
+         * errors that cannot be corrected.
+         */
+        int status;
+
+        /**
+         * Message identifier. It provides an index so the complete Navigation
+         * Message can be assembled.
+         *
+         * - For GNSS L1 C/A subframe 4 and 5, this value corresponds to the 'frame
+         *   id' of the navigation message, in the range of 1-25 (Subframe 1, 2, 3
+         *   does not contain a 'frame id' and this value can be set to -1.)
+         *
+         * - For Glonass L1 C/A, this refers to the frame ID, in the range of 1-5.
+         *
+         * - For BeiDou D1, this refers to the frame number in the range of 1-24
+         *
+         * - For Beidou D2, this refers to the frame number, in the range of 1-120
+         *
+         * - For Galileo F/NAV nominal frame structure, this refers to the subframe
+         *   number, in the range of 1-12
+         *
+         * - For Galileo I/NAV nominal frame structure, this refers to the subframe
+         *   number in the range of 1-24
+         *
+         * - For SBAS and Beidou CNAV2, this is unused and can be set to -1.
+         *
+         * - For QZSS L1 C/A subframe 4 and 5, this value corresponds to the 'frame id' of the
+         *   navigation message, in the range of 1-25. (Subframe 1, 2, 3 does not contain a 'frame
+         *   id' and this value can be set to -1.)
+         *
+         * - For Beidou CNAV1 this refers to the page type number in the range of 1-63.
+         *
+         * - For IRNSS L5 C/A subframe 3 and 4, this value corresponds to the Message Id of the
+         *   navigation message, in the range of 1-63. (Subframe 1 and 2 does not contain a message
+         *   type id and this value can be set to -1.)
+         */
+        int messageId;
+
+        /**
+         * Sub-message identifier. If required by the message 'type', this value contains a
+         * sub-index within the current message (or frame) that is being transmitted.
+         *
+         * - For GNSS L1 C/A, BeiDou D1 & BeiDou D2, the submessage id corresponds to the subframe
+         *   number of the navigation message, in the range of 1-5.
+         *
+         * - For Glonass L1 C/A, this refers to the String number, in the range from 1-15.
+         *
+         * - For Galileo F/NAV, this refers to the page type in the range 1-6.
+         *
+         * - For Galileo I/NAV, this refers to the word type in the range 0-10+. A value of 0 is
+         *   only allowed if the Satellite is transmiting a Spare Word.
+         *
+         * - For Galileo in particular, the type information embedded within the data bits may be
+         *   even more useful in interpretation, than the nominal page and word types provided in
+         *   this field.
+         *
+         * - For SBAS, the submessage id corresponds to the message type, in the range 1-63.
+         *
+         * - For Beidou CNAV1, the submessage id corresponds to the subframe number of the
+         *   navigation message, in the range of 1-3.
+         *
+         * - For Beidou CNAV2, the submessage id corresponds to the message type, in the range 1-63.
+         *
+         * - For IRNSS L5 C/A, the submessage id corresponds to the subframe number of the
+         *   navigation message, in the range of 1-4.
+         */
+        int submessageId;
+
+        /**
+         * The data of the reported GNSS message. The bytes (or words) are specified
+         * using big endian format (MSB first).
+         *
+         * - For GNSS L1 C/A, Beidou D1 & Beidou D2, each subframe contains 10 30-bit
+         *   words. Each word (30 bits) must fit into the last 30 bits in a
+         *   4-byte word (skip B31 and B32), with MSB first, for a total of 40
+         *   bytes, covering a time period of 6, 6, and 0.6 seconds, respectively.
+         *   The standard followed is 1995 SPS Signal specification.
+         *
+         * - For Glonass L1 C/A, each string contains 85 data bits, including the
+         *   checksum.  These bits must fit into 11 bytes, with MSB first (skip
+         *   B86-B88), covering a time period of 2 seconds.
+         *   The standard followed is Glonass Interface Control Document Edition 5.1.
+         *
+         * - For Galileo F/NAV, each word consists of 238-bit (sync & tail symbols
+         *   excluded). Each word must fit into 30-bytes, with MSB first (skip
+         *   B239, B240), covering a time period of 10 seconds. The standard
+         *   followed is European GNSS(Galileo) Signal in Space Interface
+         *   Control Document Issue 1.2.
+         *
+         * - For Galileo I/NAV, each page contains 2 page parts, even and odd, with
+         *   a total of 2x114 = 228 bits, (sync & tail excluded) that must fit
+         *   into 29 bytes, with MSB first (skip B229-B232). The standard followed
+         *   is same as above.
+         *
+         * - For SBAS, each block consists of 250 data bits, that should be fit into 32 bytes. MSB
+         *   first (skip B251-B256).
+         *
+         * - For Beidou CNAV1, subframe #1 consists of 14 data bits, that should be fit into 2
+         *   bytes. MSB first (skip B15-B16).  subframe #2 consists of 600 bits that should be fit
+         *   into 75 bytes. subframe #3 consists of 264 data bits that should be fit into 33 bytes.
+         *
+         * - For Beidou CNAV2, each subframe consists of 288 data bits, that should be fit into 36
+         *   bytes.
+         *
+         * The data reported here must be the raw data as demodulated by the GNSS receiver, not data
+         * received from an external source (i.e. not from a server download.)
+         */
+        byte[] data;
+    }
+
+    /**
+     * The callback to report an available fragment of a GNSS navigation messages
+     * from the HAL.
+     *
+     * @param message - The GNSS navigation submessage/subframe representation.
+     */
+    void gnssNavigationMessageCb(in GnssNavigationMessage message);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
new file mode 100644
index 0000000..e2f57c3
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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 android.hardware.gnss;
+
+import android.hardware.gnss.IGnssNavigationMessageCallback;
+
+/**
+ * Extended interface for GNSS navigation message reporting support.
+ */
+@VintfStability
+interface IGnssNavigationMessageInterface {
+    /**
+     * Initializes the interface and registers the callback routines with the HAL.
+     *
+     * After a successful call to 'setCallback' the HAL must begin to provide updates as
+     * they become available.
+     *
+     * @param callback handle to IGnssNavigationMessageCallack interface.
+     */
+    void setCallback(in IGnssNavigationMessageCallback callback);
+
+    /**
+     * Stops updates from the HAL, and unregisters the callback routines.
+     *
+     * After a call to close(), the previously registered callbacks must be
+     * considered invalid by the HAL.
+     *
+     * If close() is invoked without a previous setCallback, this function must perform
+     * no work.
+     */
+    void close();
+}
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 29bc5c4..b6df895 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -59,6 +59,7 @@
         "GnssBatching.cpp",
         "GnssGeofence.cpp",
         "GnssHidlHal.cpp",
+        "GnssNavigationMessageInterface.cpp",
         "GnssPowerIndication.cpp",
         "GnssPsds.cpp",
         "GnssConfiguration.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 03d9e31..8d58a20 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -22,6 +22,7 @@
 #include "GnssConfiguration.h"
 #include "GnssGeofence.h"
 #include "GnssMeasurementInterface.h"
+#include "GnssNavigationMessageInterface.h"
 #include "GnssPsds.h"
 
 namespace aidl::android::hardware::gnss {
@@ -104,4 +105,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
+        std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) {
+    ALOGD("Gnss::getExtensionGnssNavigationMessage");
+
+    *iGnssNavigationMessage = SharedRefBase::make<GnssNavigationMessageInterface>();
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 8e573b5..128a6c1 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -42,6 +42,8 @@
             std::shared_ptr<IGnssBatching>* iGnssBatching) override;
     ndk::ScopedAStatus getExtensionGnssGeofence(
             std::shared_ptr<IGnssGeofence>* iGnssGeofence) override;
+    ndk::ScopedAStatus getExtensionGnssNavigationMessage(
+            std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) override;
 
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
diff --git a/gnss/aidl/default/GnssNavigationMessageInterface.cpp b/gnss/aidl/default/GnssNavigationMessageInterface.cpp
new file mode 100644
index 0000000..4bc859d
--- /dev/null
+++ b/gnss/aidl/default/GnssNavigationMessageInterface.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define LOG_TAG "GnssNavigationMessageAidl"
+
+#include "GnssNavigationMessageInterface.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <log/log.h>
+#include "Utils.h"
+
+namespace aidl::android::hardware::gnss {
+
+using namespace ::android::hardware::gnss;
+using GnssNavigationMessage = IGnssNavigationMessageCallback::GnssNavigationMessage;
+using GnssNavigationMessageType = GnssNavigationMessage::GnssNavigationMessageType;
+
+std::shared_ptr<IGnssNavigationMessageCallback> GnssNavigationMessageInterface::sCallback = nullptr;
+
+GnssNavigationMessageInterface::GnssNavigationMessageInterface() : mMinIntervalMillis(1000) {}
+
+GnssNavigationMessageInterface::~GnssNavigationMessageInterface() {
+    stop();
+}
+
+ndk::ScopedAStatus GnssNavigationMessageInterface::setCallback(
+        const std::shared_ptr<IGnssNavigationMessageCallback>& callback) {
+    ALOGD("setCallback");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+    start();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssNavigationMessageInterface::close() {
+    ALOGD("close");
+    stop();
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = nullptr;
+    return ndk::ScopedAStatus::ok();
+}
+
+void GnssNavigationMessageInterface::start() {
+    ALOGD("start");
+    mIsActive = true;
+    mThread = std::thread([this]() {
+        while (mIsActive == true) {
+            GnssNavigationMessage message = {
+                    .svid = 19,
+                    .type = GnssNavigationMessageType::GPS_L1CA,
+                    .status = GnssNavigationMessage::STATUS_PARITY_PASSED,
+                    .messageId = 2,
+                    .submessageId = 3,
+                    .data = std::vector<uint8_t>(40, 0xF9),
+            };
+            this->reportMessage(message);
+            std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
+        }
+    });
+    mThread.detach();
+}
+
+void GnssNavigationMessageInterface::stop() {
+    ALOGD("stop");
+    mIsActive = false;
+}
+
+void GnssNavigationMessageInterface::reportMessage(const GnssNavigationMessage& message) {
+    ALOGD("reportMessage()");
+    std::shared_ptr<IGnssNavigationMessageCallback> callbackCopy;
+    {
+        std::unique_lock<std::mutex> lock(mMutex);
+        if (sCallback == nullptr) {
+            ALOGE("%s: GnssNavigationMessageInterface::sCallback is null.", __func__);
+            return;
+        }
+        callbackCopy = sCallback;
+    }
+    callbackCopy->gnssNavigationMessageCb(message);
+}
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssNavigationMessageInterface.h b/gnss/aidl/default/GnssNavigationMessageInterface.h
new file mode 100644
index 0000000..600b23a
--- /dev/null
+++ b/gnss/aidl/default/GnssNavigationMessageInterface.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssNavigationMessageInterface.h>
+#include <atomic>
+#include <thread>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssNavigationMessageInterface : public BnGnssNavigationMessageInterface {
+  public:
+    GnssNavigationMessageInterface();
+    ~GnssNavigationMessageInterface();
+    ndk::ScopedAStatus setCallback(
+            const std::shared_ptr<IGnssNavigationMessageCallback>& callback) override;
+    ndk::ScopedAStatus close() override;
+
+  private:
+    void start();
+    void stop();
+    void reportMessage(const IGnssNavigationMessageCallback::GnssNavigationMessage& message);
+
+    std::atomic<long> mMinIntervalMillis;
+    std::atomic<bool> mIsActive;
+    std::thread mThread;
+
+    // Guarded by mMutex
+    static std::shared_ptr<IGnssNavigationMessageCallback> sCallback;
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+};
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index 8582b62..4d81519 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -34,6 +34,7 @@
         "GnssCallbackAidl.cpp",
         "GnssGeofenceCallback.cpp",
         "GnssMeasurementCallbackAidl.cpp",
+        "GnssNavigationMessageCallback.cpp",
         "GnssPowerIndicationCallback.cpp",
         "VtsHalGnssTargetTest.cpp",
     ],
diff --git a/gnss/aidl/vts/GnssNavigationMessageCallback.cpp b/gnss/aidl/vts/GnssNavigationMessageCallback.cpp
new file mode 100644
index 0000000..cf4a6eb
--- /dev/null
+++ b/gnss/aidl/vts/GnssNavigationMessageCallback.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#define LOG_TAG "GnssNavMsgCallback"
+
+#include "GnssNavigationMessageCallback.h"
+#include <log/log.h>
+
+android::binder::Status GnssNavigationMessageCallback::gnssNavigationMessageCb(
+        const android::hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage& msg) {
+    ALOGD("gnssNavigationMessageCb. svid=%d, type=%d, status=%d, msgId=%d, subMsgId=%d, "
+          "data.size=%d",
+          msg.svid, (int)msg.type, (int)msg.status, msg.messageId, msg.submessageId,
+          (int)msg.data.size());
+    return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssNavigationMessageCallback.h b/gnss/aidl/vts/GnssNavigationMessageCallback.h
new file mode 100644
index 0000000..55114ca
--- /dev/null
+++ b/gnss/aidl/vts/GnssNavigationMessageCallback.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnGnssNavigationMessageCallback.h>
+
+/** Implementation for IGnssNavigationMessageCallback. */
+class GnssNavigationMessageCallback
+    : public android::hardware::gnss::BnGnssNavigationMessageCallback {
+  public:
+    GnssNavigationMessageCallback() {}
+    ~GnssNavigationMessageCallback() {}
+
+    android::binder::Status gnssNavigationMessageCb(
+            const android::hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage&
+                    message) override;
+};
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 09f9412..830922c 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -25,6 +25,7 @@
 #include "GnssBatchingCallback.h"
 #include "GnssGeofenceCallback.h"
 #include "GnssMeasurementCallbackAidl.h"
+#include "GnssNavigationMessageCallback.h"
 #include "GnssPowerIndicationCallback.h"
 #include "gnss_hal_test.h"
 
@@ -43,6 +44,7 @@
 using android::hardware::gnss::IGnssGeofenceCallback;
 using android::hardware::gnss::IGnssMeasurementCallback;
 using android::hardware::gnss::IGnssMeasurementInterface;
+using android::hardware::gnss::IGnssNavigationMessageInterface;
 using android::hardware::gnss::IGnssPowerIndication;
 using android::hardware::gnss::IGnssPsds;
 using android::hardware::gnss::PsdsType;
@@ -779,4 +781,15 @@
         status = iGnssGeofence->setCallback(gnssGeofenceCallback);
         ASSERT_TRUE(status.isOk());
     }
+
+    sp<IGnssNavigationMessageInterface> iGnssNavMsgIface;
+    status = aidl_gnss_hal_->getExtensionGnssNavigationMessage(&iGnssNavMsgIface);
+    if (status.isOk() && iGnssNavMsgIface != nullptr) {
+        auto gnssNavMsgCallback = sp<GnssNavigationMessageCallback>::make();
+        status = iGnssNavMsgIface->setCallback(gnssNavMsgCallback);
+        ASSERT_TRUE(status.isOk());
+
+        status = iGnssNavMsgIface->close();
+        ASSERT_TRUE(status.isOk());
+    }
 }
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 19b1b45..c5a186b 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -523,7 +523,7 @@
     using Capabilities = V2_1::IGnssCallback::Capabilities;
     const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
                               Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST |
-                              Capabilities::ANTENNA_INFO;
+                              Capabilities::ANTENNA_INFO | Capabilities::NAV_MESSAGES;
     auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_1(capabilities);
     if (!ret.isOk()) {
         ALOGE("%s: Unable to invoke callback", __func__);
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
new file mode 100644
index 0000000..43d9378
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -0,0 +1,93 @@
+// Copyright (C) 2021 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+    name: "android.hardware.radio-library.compat",
+    relative_install_path: "hw",
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        //"-Wold-style-cast",  // TODO(b/203699028) enable after aosp/1900880 gets merged
+        "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+    ],
+    shared_libs: [
+        "android.hardware.radio.config-V1-ndk",
+        "android.hardware.radio.config@1.0",
+        "android.hardware.radio.config@1.1",
+        "android.hardware.radio.config@1.2",
+        "android.hardware.radio.config@1.3",
+        "android.hardware.radio.data-V1-ndk",
+        "android.hardware.radio.messaging-V1-ndk",
+        "android.hardware.radio.modem-V1-ndk",
+        "android.hardware.radio.network-V1-ndk",
+        "android.hardware.radio.sim-V1-ndk",
+        "android.hardware.radio.voice-V1-ndk",
+        "android.hardware.radio@1.0",
+        "android.hardware.radio@1.1",
+        "android.hardware.radio@1.2",
+        "android.hardware.radio@1.3",
+        "android.hardware.radio@1.4",
+        "android.hardware.radio@1.5",
+        "android.hardware.radio@1.6",
+        "libbase",
+        "libbinder_ndk",
+        "libhidlbase",
+        "libutils",
+    ],
+    srcs: [
+        "RadioCompatBase.cpp",
+        "RadioResponse.cpp",
+        "commonStructs.cpp",
+        "config/RadioConfig.cpp",
+        "config/RadioConfigIndication.cpp",
+        "config/RadioConfigResponse.cpp",
+        "config/structs.cpp",
+        "data/RadioIndication-data.cpp",
+        "data/RadioResponse-data.cpp",
+        "data/RadioData.cpp",
+        "data/structs.cpp",
+        "messaging/RadioIndication-messaging.cpp",
+        "messaging/RadioMessaging.cpp",
+        "messaging/RadioResponse-messaging.cpp",
+        "messaging/structs.cpp",
+        "modem/RadioIndication-modem.cpp",
+        "modem/RadioResponse-modem.cpp",
+        "modem/RadioModem.cpp",
+        "modem/structs.cpp",
+        "network/RadioIndication-network.cpp",
+        "network/RadioNetwork.cpp",
+        "network/RadioResponse-network.cpp",
+        "network/structs.cpp",
+        "network/utils.cpp",
+        "sim/RadioIndication-sim.cpp",
+        "sim/RadioResponse-sim.cpp",
+        "sim/RadioSim.cpp",
+        "sim/structs.cpp",
+        "voice/RadioIndication-voice.cpp",
+        "voice/RadioResponse-voice.cpp",
+        "voice/RadioVoice.cpp",
+        "voice/structs.cpp",
+    ],
+    export_include_dirs: ["include"],
+}
diff --git a/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
new file mode 100644
index 0000000..a9eac68
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioCompatBase.h>
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+RadioCompatBase::RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
+                                 sp<RadioIndication> radioIndication)
+    : mHal1_5(hidlHal),
+      mHal1_6(V1_6::IRadio::castFrom(hidlHal)),
+      mRadioResponse(radioResponse),
+      mRadioIndication(radioIndication) {}
+
+V1_6::IRadioResponse& RadioCompatBase::respond() {
+    CHECK(mRadioResponse) << "This shouldn't happen (response functions are passed in constructor)";
+    return *mRadioResponse;
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioResponse.cpp b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
new file mode 100644
index 0000000..35b0ac1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "debug.h"
+
+#define RADIO_MODULE "Common"
+
+namespace android::hardware::radio::compat {
+
+Return<void> RadioResponse::acknowledgeRequest(int32_t serial) {
+    LOG_CALL << serial;
+    // TODO(b/203699028): send to correct requestor or confirm if spam is not a problem
+    if (mDataCb) mDataCb->acknowledgeRequest(serial);
+    if (mMessagingCb) mMessagingCb->acknowledgeRequest(serial);
+    if (mModemCb) mModemCb->acknowledgeRequest(serial);
+    if (mNetworkCb) mNetworkCb->acknowledgeRequest(serial);
+    if (mSimCb) mSimCb->acknowledgeRequest(serial);
+    if (mVoiceCb) mVoiceCb->acknowledgeRequest(serial);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/collections.h b/radio/aidl/compat/libradiocompat/collections.h
new file mode 100644
index 0000000..082ef17
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/collections.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <hidl/HidlSupport.h>
+
+#include <type_traits>
+#include <variant>
+
+namespace android::hardware::radio::compat {
+
+/**
+ * Converts hidl_vec<T> HIDL list to std::vector<T> AIDL list.
+ *
+ * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
+ *
+ * \param inp vector to convert
+ */
+template <typename T>
+auto toAidl(const hidl_vec<T>& inp) {
+    std::vector<decltype(toAidl(T{}))> out(inp.size());
+    for (size_t i = 0; i < inp.size(); i++) {
+        out[i] = toAidl(inp[i]);
+    }
+    return out;
+}
+
+/**
+ * Converts std::vector<T> AIDL list to hidl_vec<T> HIDL list.
+ *
+ * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
+ *
+ * \param inp vector to convert
+ */
+template <typename T>
+auto toHidl(const std::vector<T>& inp) {
+    hidl_vec<decltype(toHidl(T{}))> out(inp.size());
+    for (size_t i = 0; i < inp.size(); i++) {
+        out[i] = toHidl(inp[i]);
+    }
+    return out;
+}
+
+/**
+ * Converts hidl_array<T> HIDL list to std::vector<T> AIDL list.
+ *
+ * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
+ *
+ * \param inp array to convert
+ */
+template <typename T, size_t N>
+auto toAidl(const hidl_array<T, N>& inp) {
+    std::vector<decltype(toAidl(T{}))> out(N);
+    for (size_t i = 0; i < N; i++) {
+        out[i] = toAidl(inp[i]);
+    }
+    return out;
+}
+
+/**
+ * Converts T=OptionalX HIDL value to std::optional<X> AIDL value.
+ *
+ * To convert values, the template uses toAidl functions for a given type T.value.
+ */
+template <typename T>
+std::optional<decltype(toAidl(T{}.value()))> toAidl(const T& opt) {
+    if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return std::nullopt;
+    return toAidl(opt.value());
+}
+
+/**
+ * Converts T=OptionalX HIDL value to std::variant<bool, X> AIDL value.
+ *
+ * For some reason, not every OptionalX gets generated into a std::optional<X>.
+ */
+template <typename T>
+std::variant<bool, decltype(toAidl(T{}.value()))> toAidlVariant(const T& opt) {
+    if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return false;
+    return toAidl(opt.value());
+}
+
+/**
+ * Converts std::optional<X> AIDL value to T=OptionalX HIDL value.
+ *
+ * X is inferred from toAidl(T.value) declaration. Please note that toAidl(T.value) doesn't have to
+ * be implemented if it's not needed for anything else than giving this hint to type system.
+ *
+ * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
+ *
+ * \param opt value to convert
+ */
+template <typename T>
+T toHidl(const std::optional<decltype(toAidl(T{}.value()))>& opt) {
+    T hidl;
+    if (opt.has_value()) hidl.value(toHidl(*opt));
+    return hidl;
+}
+
+/**
+ * Converts U AIDL bitfield value to HIDL T bitfield value.
+ *
+ * \param val value to convert
+ */
+template <typename T, typename U>
+hidl_bitfield<T> toHidlBitfield(U val) {
+    return static_cast<int>(val);
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.cpp b/radio/aidl/compat/libradiocompat/commonStructs.cpp
new file mode 100644
index 0000000..c25768d
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/commonStructs.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "commonStructs.h"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio;
+
+V1_6::RadioResponseInfo notSupported(int32_t serial) {
+    return {
+            .type = V1_0::RadioResponseType::SOLICITED,
+            .serial = serial,
+            .error = V1_6::RadioError::REQUEST_NOT_SUPPORTED,
+    };
+}
+
+std::string toAidl(const hidl_string& str) {
+    return str;
+}
+
+hidl_string toHidl(const std::string& str) {
+    return str;
+}
+
+uint8_t toAidl(int8_t v) {
+    return v;
+}
+
+int8_t toAidl(uint8_t v) {
+    return v;
+}
+
+int32_t toAidl(uint32_t v) {
+    return v;
+}
+
+aidl::RadioIndicationType toAidl(V1_0::RadioIndicationType type) {
+    return aidl::RadioIndicationType(type);
+}
+
+aidl::RadioResponseType toAidl(V1_0::RadioResponseType type) {
+    return aidl::RadioResponseType(type);
+}
+
+aidl::RadioError toAidl(V1_0::RadioError err) {
+    return aidl::RadioError(err);
+}
+
+aidl::RadioError toAidl(V1_6::RadioError err) {
+    return aidl::RadioError(err);
+}
+
+aidl::RadioResponseInfo toAidl(const V1_0::RadioResponseInfo& info) {
+    return {
+            .type = toAidl(info.type),
+            .serial = info.serial,
+            .error = toAidl(info.error),
+    };
+}
+
+aidl::RadioResponseInfo toAidl(const V1_6::RadioResponseInfo& info) {
+    return {
+            .type = toAidl(info.type),
+            .serial = info.serial,
+            .error = toAidl(info.error),
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.h b/radio/aidl/compat/libradiocompat/commonStructs.h
new file mode 100644
index 0000000..b859916
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/commonStructs.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/RadioIndicationType.h>
+#include <aidl/android/hardware/radio/RadioResponseInfo.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_6::RadioResponseInfo notSupported(int32_t serial);
+
+std::string toAidl(const hidl_string& str);
+hidl_string toHidl(const std::string& str);
+uint8_t toAidl(int8_t v);
+int8_t toAidl(uint8_t v);
+int32_t toAidl(uint32_t v);
+
+aidl::android::hardware::radio::RadioIndicationType toAidl(V1_0::RadioIndicationType type);
+aidl::android::hardware::radio::RadioResponseType toAidl(V1_0::RadioResponseType type);
+aidl::android::hardware::radio::RadioError toAidl(V1_0::RadioError type);
+aidl::android::hardware::radio::RadioError toAidl(V1_6::RadioError type);
+
+aidl::android::hardware::radio::RadioResponseInfo toAidl(const V1_0::RadioResponseInfo& info);
+aidl::android::hardware::radio::RadioResponseInfo toAidl(const V1_6::RadioResponseInfo& info);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
new file mode 100644
index 0000000..d0d6f7a
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioConfig.h>
+
+#include "RadioConfigIndication.h"
+#include "RadioConfigResponse.h"
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#define RADIO_MODULE "Config"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::config;
+constexpr auto ok = &ScopedAStatus::ok;
+
+RadioConfig::RadioConfig(sp<config::V1_1::IRadioConfig> hidlHal)
+    : mHal1_1(hidlHal), mHal1_3(config::V1_3::IRadioConfig::castFrom(hidlHal)) {}
+
+config::V1_3::IRadioConfigResponse& RadioConfig::respond() {
+    CHECK(mRadioConfigResponse) << "setResponseFunctions was not called yet";
+    return *mRadioConfigResponse;
+}
+
+ScopedAStatus RadioConfig::getHalDeviceCapabilities(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_3) {
+        mHal1_3->getHalDeviceCapabilities(serial);
+    } else {
+        respond().getHalDeviceCapabilitiesResponse(notSupported(serial), false);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioConfig::getNumOfLiveModems(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_1->getModemsConfig(serial);
+    return ok();
+}
+
+ScopedAStatus RadioConfig::getPhoneCapability(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_1->getPhoneCapability(serial);
+    return ok();
+}
+
+ScopedAStatus RadioConfig::getSimSlotsStatus(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_1->getSimSlotsStatus(serial);
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setNumOfLiveModems(int32_t serial, int8_t numOfLiveModems) {
+    LOG_CALL << serial;
+    mHal1_1->setModemsConfig(serial, {static_cast<uint8_t>(numOfLiveModems)});
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setPreferredDataModem(int32_t serial, int8_t modemId) {
+    LOG_CALL << serial;
+    mHal1_1->setPreferredDataModem(serial, modemId);
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioConfigResponse>& radioConfigResponse,
+        const std::shared_ptr<aidl::IRadioConfigIndication>& radioConfigIndication) {
+    LOG_CALL << radioConfigResponse << ' ' << radioConfigIndication;
+
+    CHECK(radioConfigResponse);
+    CHECK(radioConfigIndication);
+
+    mRadioConfigResponse = sp<RadioConfigResponse>::make(radioConfigResponse);
+    mRadioConfigIndication = sp<RadioConfigIndication>::make(radioConfigIndication);
+    mHal1_1->setResponseFunctions(mRadioConfigResponse, mRadioConfigIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setSimSlotsMapping(  //
+        int32_t serial, const std::vector<aidl::SlotPortMapping>& slotMap) {
+    LOG_CALL << serial;
+    mHal1_1->setSimSlotsMapping(serial, toHidl(slotMap));
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
new file mode 100644
index 0000000..0320ad7
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "RadioConfigIndication.h"
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ConfigIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::config;
+
+RadioConfigIndication::RadioConfigIndication(std::shared_ptr<aidl::IRadioConfigIndication> callback)
+    : mCallback(callback) {}
+
+Return<void> RadioConfigIndication::simSlotsStatusChanged(
+        V1_0::RadioIndicationType type, const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
+    LOG_CALL << type;
+    mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+    return {};
+}
+
+Return<void> RadioConfigIndication::simSlotsStatusChanged_1_2(
+        V1_0::RadioIndicationType type, const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
+    LOG_CALL << type;
+    mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
new file mode 100644
index 0000000..3d8d971
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/config/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioConfigIndication : public config::V1_2::IRadioConfigIndication {
+    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> mCallback;
+
+    Return<void> simSlotsStatusChanged(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) override;
+    Return<void> simSlotsStatusChanged_1_2(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) override;
+
+  public:
+    RadioConfigIndication(
+            std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> cb);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
new file mode 100644
index 0000000..7066ae4
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "RadioConfigResponse.h"
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ConfigResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::config;
+
+RadioConfigResponse::RadioConfigResponse(std::shared_ptr<aidl::IRadioConfigResponse> callback)
+    : mCallback(callback) {}
+
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
+    LOG_CALL << info.serial;
+    mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+    return {};
+};
+
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse_1_2(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
+    LOG_CALL << info.serial;
+    mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+    return {};
+};
+
+Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    mCallback->setSimSlotsMappingResponse(toAidl(info));
+    return {};
+};
+
+Return<void> RadioConfigResponse::getPhoneCapabilityResponse(
+        const V1_0::RadioResponseInfo& info, const config::V1_1::PhoneCapability& phoneCapability) {
+    LOG_CALL << info.serial;
+    mCallback->getPhoneCapabilityResponse(toAidl(info), toAidl(phoneCapability));
+    return {};
+};
+
+Return<void> RadioConfigResponse::setPreferredDataModemResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    mCallback->setPreferredDataModemResponse(toAidl(info));
+    return {};
+};
+
+Return<void> RadioConfigResponse::setModemsConfigResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    mCallback->setNumOfLiveModemsResponse(toAidl(info));
+    return {};
+};
+
+Return<void> RadioConfigResponse::getModemsConfigResponse(
+        const V1_0::RadioResponseInfo& info, const config::V1_1::ModemsConfig& modemsConfig) {
+    LOG_CALL << info.serial;
+    mCallback->getNumOfLiveModemsResponse(toAidl(info), modemsConfig.numOfLiveModems);
+    return {};
+};
+
+Return<void> RadioConfigResponse::getHalDeviceCapabilitiesResponse(
+        const V1_6::RadioResponseInfo& info, bool modemReducedFeatureSet1) {
+    LOG_CALL << info.serial;
+    mCallback->getHalDeviceCapabilitiesResponse(toAidl(info), modemReducedFeatureSet1);
+    return {};
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
new file mode 100644
index 0000000..1461dd2
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/config/IRadioConfigResponse.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioConfigResponse : public config::V1_3::IRadioConfigResponse {
+    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> mCallback;
+
+    Return<void> getSimSlotsStatusResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) override;
+    Return<void> setSimSlotsMappingResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getPhoneCapabilityResponse(
+            const V1_0::RadioResponseInfo& info,
+            const config::V1_1::PhoneCapability& phoneCapability) override;
+    Return<void> setPreferredDataModemResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setModemsConfigResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getModemsConfigResponse(const V1_0::RadioResponseInfo& info,
+                                         const config::V1_1::ModemsConfig& modemsConfig) override;
+    Return<void> getSimSlotsStatusResponse_1_2(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) override;
+    Return<void> getHalDeviceCapabilitiesResponse(const V1_6::RadioResponseInfo& info,
+                                                  bool modemReducedFeatureSet1) override;
+
+  public:
+    RadioConfigResponse(
+            std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> callback);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/structs.cpp b/radio/aidl/compat/libradiocompat/config/structs.cpp
new file mode 100644
index 0000000..9ba5623
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/structs.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "structs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::config;
+
+hidl_vec<uint32_t> toHidl(const std::vector<aidl::SlotPortMapping>& slotMap) {
+    hidl_vec<uint32_t> out(slotMap.size());
+    for (const auto& el : slotMap) {
+        CHECK_GE(el.portId, 0);
+        CHECK_LT(static_cast<size_t>(el.portId), out.size());
+        out[el.portId] = el.physicalSlotId;
+    }
+    return out;
+}
+
+aidl::SimSlotStatus toAidl(const config::V1_0::SimSlotStatus& sst) {
+    return toAidl({sst, ""});
+}
+
+aidl::SimSlotStatus toAidl(const config::V1_2::SimSlotStatus& sst) {
+    const aidl::SimPortInfo portInfo = {
+            .iccId = sst.base.iccid,
+            .logicalSlotId = static_cast<int32_t>(sst.base.logicalSlotId),
+            .portActive = sst.base.slotState == config::V1_0::SlotState::ACTIVE,
+    };
+
+    return {
+            .cardState = static_cast<int32_t>(sst.base.cardState),
+            .atr = sst.base.atr,
+            .eid = sst.eid,
+            .portInfo = {portInfo},
+    };
+}
+
+uint8_t toAidl(const config::V1_1::ModemInfo& info) {
+    return info.modemId;
+}
+
+aidl::PhoneCapability toAidl(const config::V1_1::PhoneCapability& phoneCapability) {
+    return {
+            .maxActiveData = static_cast<int8_t>(phoneCapability.maxActiveData),
+            .maxActiveInternetData = static_cast<int8_t>(phoneCapability.maxActiveInternetData),
+            .isInternetLingeringSupported = phoneCapability.isInternetLingeringSupported,
+            .logicalModemIds = toAidl(phoneCapability.logicalModemList),
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/structs.h b/radio/aidl/compat/libradiocompat/config/structs.h
new file mode 100644
index 0000000..b8a0385
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/structs.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/config/PhoneCapability.h>
+#include <aidl/android/hardware/radio/config/SimSlotStatus.h>
+#include <aidl/android/hardware/radio/config/SlotPortMapping.h>
+#include <android/hardware/radio/config/1.1/types.h>
+#include <android/hardware/radio/config/1.2/types.h>
+
+namespace android::hardware::radio::compat {
+
+hidl_vec<uint32_t>  //
+toHidl(const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap);
+
+aidl::android::hardware::radio::config::SimSlotStatus  //
+toAidl(const config::V1_0::SimSlotStatus& sst);
+aidl::android::hardware::radio::config::SimSlotStatus  //
+toAidl(const config::V1_2::SimSlotStatus& sst);
+
+uint8_t toAidl(const config::V1_1::ModemInfo& info);
+
+aidl::android::hardware::radio::config::PhoneCapability  //
+toAidl(const config::V1_1::PhoneCapability& pc);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/RadioData.cpp b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
new file mode 100644
index 0000000..fdb1273
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioData.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Data"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::data;
+namespace aidlCommon = ::aidl::android::hardware::radio;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioData::allocatePduSessionId(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->allocatePduSessionId(serial);
+    } else {
+        respond().allocatePduSessionIdResponse(notSupported(serial), 0);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::cancelHandover(int32_t serial, int32_t callId) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->cancelHandover(serial, callId);
+    } else {
+        respond().cancelHandoverResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::deactivateDataCall(int32_t serial, int32_t cid,
+                                            aidl::DataRequestReason reason) {
+    LOG_CALL << serial;
+    mHal1_5->deactivateDataCall_1_2(serial, cid, V1_2::DataRequestReason(reason));
+    return ok();
+}
+
+ScopedAStatus RadioData::getDataCallList(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getDataCallList(serial);
+    return ok();
+}
+
+ScopedAStatus RadioData::getSlicingConfig(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getSlicingConfig(serial);
+    } else {
+        respond().getSlicingConfigResponse(notSupported(serial), {});
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::releasePduSessionId(int32_t serial, int32_t id) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->releasePduSessionId(serial, id);
+    } else {
+        respond().releasePduSessionIdResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioData::setDataAllowed(int32_t serial, bool allow) {
+    LOG_CALL << serial;
+    mHal1_5->setDataAllowed(serial, allow);
+    return ok();
+}
+
+ScopedAStatus RadioData::setDataProfile(int32_t serial,
+                                        const std::vector<aidl::DataProfileInfo>& profiles) {
+    LOG_CALL << serial;
+    mHal1_5->setDataProfile_1_5(serial, toHidl(profiles));
+    return ok();
+}
+
+ScopedAStatus RadioData::setDataThrottling(int32_t serial, aidl::DataThrottlingAction dta,
+                                           int64_t completionDurationMs) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setDataThrottling(serial, V1_6::DataThrottlingAction(dta), completionDurationMs);
+    } else {
+        respond().setDataThrottlingResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::setInitialAttachApn(int32_t serial, const aidl::DataProfileInfo& info) {
+    LOG_CALL << serial;
+    mHal1_5->setInitialAttachApn_1_5(serial, toHidl(info));
+    return ok();
+}
+
+ScopedAStatus RadioData::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioDataResponse>& dataResponse,
+        const std::shared_ptr<aidl::IRadioDataIndication>& dataIndication) {
+    LOG_CALL << dataResponse << ' ' << dataIndication;
+
+    CHECK(dataResponse);
+    CHECK(dataIndication);
+
+    mRadioResponse->setResponseFunction(dataResponse);
+    mRadioIndication->setResponseFunction(dataIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioData::setupDataCall(  //
+        int32_t serial, aidlCommon::AccessNetwork accessNetwork,
+        const aidl::DataProfileInfo& dataProfileInfo, bool roamingAllowed,
+        aidl::DataRequestReason reason, const std::vector<aidl::LinkAddress>& addresses,
+        const std::vector<std::string>& dnses, int32_t pduSessId,
+        const std::optional<aidl::SliceInfo>& sliceInfo,
+        const std::optional<aidl::TrafficDescriptor>& trDesc, bool matchAllRuleAllowed) {
+    if (mHal1_6) {
+        mHal1_6->setupDataCall_1_6(  //
+                serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
+                V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses), pduSessId,
+                toHidl<V1_6::OptionalSliceInfo>(sliceInfo),
+                toHidl<V1_6::OptionalTrafficDescriptor>(trDesc), matchAllRuleAllowed);
+    } else {
+        mHal1_5->setupDataCall_1_5(  //
+                serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
+                V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::startHandover(int32_t serial, int32_t callId) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->startHandover(serial, callId);
+    } else {
+        respond().startHandoverResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioData::startKeepalive(int32_t serial, const aidl::KeepaliveRequest& keepalive) {
+    LOG_CALL << serial;
+    mHal1_5->startKeepalive(serial, toHidl(keepalive));
+    return ok();
+}
+
+ScopedAStatus RadioData::stopKeepalive(int32_t serial, int32_t sessionHandle) {
+    LOG_CALL << serial;
+    mHal1_5->stopKeepalive(serial, sessionHandle);
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
new file mode 100644
index 0000000..f51d1a8
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "DataIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::data;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioDataIndication> dataCb) {
+    CHECK(dataCb);
+    mDataCb = dataCb;
+}
+
+Return<void> RadioIndication::dataCallListChanged(V1_0::RadioIndicationType type,
+                                                  const hidl_vec<V1_0::SetupDataCallResult>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_4(V1_0::RadioIndicationType type,
+                                                      const hidl_vec<V1_4::SetupDataCallResult>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_5(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_5::SetupDataCallResult>& dcList) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+    return {};
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_6(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_6::SetupDataCallResult>& dcList) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+    return {};
+}
+
+Return<void> RadioIndication::keepaliveStatus(V1_0::RadioIndicationType type,
+                                              const V1_1::KeepaliveStatus& status) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->keepaliveStatus(toAidl(type), toAidl(status));
+    return {};
+}
+
+Return<void> RadioIndication::pcoData(V1_0::RadioIndicationType type,
+                                      const V1_0::PcoDataInfo& pco) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->pcoData(toAidl(type), toAidl(pco));
+    return {};
+}
+
+Return<void> RadioIndication::unthrottleApn(V1_0::RadioIndicationType type,
+                                            const hidl_string& apn) {
+    LOG_CALL << type;
+    CHECK_CB(mDataCb);
+    mDataCb->unthrottleApn(toAidl(type), apn);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
new file mode 100644
index 0000000..171f692
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "DataResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::data;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioDataResponse> dataCb) {
+    CHECK(dataCb);
+    mDataCb = dataCb;
+}
+
+Return<void> RadioResponse::allocatePduSessionIdResponse(const V1_6::RadioResponseInfo& info,
+                                                         int32_t id) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->allocatePduSessionIdResponse(toAidl(info), id);
+    return {};
+}
+
+Return<void> RadioResponse::cancelHandoverResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->cancelHandoverResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::deactivateDataCallResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->deactivateDataCallResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse(const V1_0::RadioResponseInfo& info,
+                                                    const hidl_vec<V1_0::SetupDataCallResult>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_4::SetupDataCallResult>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_5(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<V1_5::SetupDataCallResult>& dcResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_6(
+        const V1_6::RadioResponseInfo& info,
+        const hidl_vec<V1_6::SetupDataCallResult>& dcResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getSlicingConfigResponse(const V1_6::RadioResponseInfo& info,
+                                                     const V1_6::SlicingConfig& slicingConfig) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->getSlicingConfigResponse(toAidl(info), toAidl(slicingConfig));
+    return {};
+}
+
+Return<void> RadioResponse::releasePduSessionIdResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->releasePduSessionIdResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setDataAllowedResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setDataAllowedResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setDataProfileResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setDataProfileResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setDataProfileResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setDataProfileResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setDataThrottlingResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setDataThrottlingResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setInitialAttachApnResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setInitialAttachApnResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setInitialAttachApnResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setInitialAttachApnResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse(const V1_0::RadioResponseInfo& info,
+                                                  const V1_0::SetupDataCallResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                                      const V1_4::SetupDataCallResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                                      const V1_5::SetupDataCallResult& dcResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+    return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                      const V1_6::SetupDataCallResult& dcResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+    return {};
+}
+
+Return<void> RadioResponse::startHandoverResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->startHandoverResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startKeepaliveResponse(const V1_0::RadioResponseInfo& info,
+                                                   const V1_1::KeepaliveStatus& status) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->startKeepaliveResponse(toAidl(info), toAidl(status));
+    return {};
+}
+
+Return<void> RadioResponse::stopKeepaliveResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mDataCb);
+    mDataCb->stopKeepaliveResponse(toAidl(info));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/structs.cpp b/radio/aidl/compat/libradiocompat/data/structs.cpp
new file mode 100644
index 0000000..4ff89a1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/structs.cpp
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::data;
+
+V1_5::DataProfileInfo toHidl(const aidl::DataProfileInfo& info) {
+    return {
+            .profileId = V1_0::DataProfileId{info.profileId},
+            .apn = info.apn,
+            .protocol = V1_4::PdpProtocolType{info.protocol},
+            .roamingProtocol = V1_4::PdpProtocolType{info.roamingProtocol},
+            .authType = V1_0::ApnAuthType{info.authType},
+            .user = info.user,
+            .password = info.password,
+            .type = V1_0::DataProfileInfoType{info.type},
+            .maxConnsTime = info.maxConnsTime,
+            .maxConns = info.maxConns,
+            .waitTime = info.waitTime,
+            .enabled = info.enabled,
+            .supportedApnTypesBitmap = toHidlBitfield<V1_5::ApnTypes>(info.supportedApnTypesBitmap),
+            .bearerBitmap = toHidlBitfield<V1_4::RadioAccessFamily>(info.bearerBitmap),
+            .mtuV4 = info.mtuV4,
+            .mtuV6 = info.mtuV6,
+            .preferred = info.preferred,
+            .persistent = info.persistent,
+    };
+}
+
+V1_5::LinkAddress toHidl(const aidl::LinkAddress& addr) {
+    return {
+            .address = addr.address,
+            .properties = addr.addressProperties,
+            .deprecationTime = static_cast<uint64_t>(addr.deprecationTime),
+            .expirationTime = static_cast<uint64_t>(addr.expirationTime),
+    };
+}
+
+aidl::SliceInfo toAidl(const V1_6::SliceInfo& info) {
+    return {
+            .sliceServiceType = static_cast<int8_t>(info.sst),
+            .sliceDifferentiator = info.sliceDifferentiator,
+            .mappedHplmnSst = static_cast<int8_t>(info.mappedHplmnSst),
+            .mappedHplmnSd = info.mappedHplmnSD,
+            .status = static_cast<int8_t>(info.status),
+    };
+}
+
+V1_6::SliceInfo toHidl(const aidl::SliceInfo& info) {
+    return {
+            .sst = static_cast<V1_6::SliceServiceType>(info.sliceServiceType),
+            .sliceDifferentiator = info.sliceDifferentiator,
+            .mappedHplmnSst = static_cast<V1_6::SliceServiceType>(info.mappedHplmnSst),
+            .mappedHplmnSD = info.mappedHplmnSd,
+            .status = V1_6::SliceStatus{info.status},
+    };
+}
+
+aidl::TrafficDescriptor toAidl(const V1_6::TrafficDescriptor& descr) {
+    return {
+            .dnn = toAidl(descr.dnn),
+            .osAppId = toAidl(descr.osAppId),
+    };
+}
+
+V1_6::TrafficDescriptor toHidl(const aidl::TrafficDescriptor& descr) {
+    return {
+            .dnn = toHidl<V1_6::OptionalDnn>(descr.dnn),
+            .osAppId = toHidl<V1_6::OptionalOsAppId>(descr.osAppId),
+    };
+}
+
+aidl::OsAppId toAidl(const V1_6::OsAppId& appId) {
+    return {
+            .osAppId = appId.osAppId,
+    };
+}
+
+V1_6::OsAppId toHidl(const aidl::OsAppId& appId) {
+    return {
+            .osAppId = appId.osAppId,
+    };
+}
+
+V1_1::KeepaliveRequest toHidl(const aidl::KeepaliveRequest& keep) {
+    return {
+            .type = V1_1::KeepaliveType{keep.type},
+            .sourceAddress = keep.sourceAddress,
+            .sourcePort = keep.sourcePort,
+            .destinationAddress = keep.destinationAddress,
+            .destinationPort = keep.destinationPort,
+            .maxKeepaliveIntervalMillis = keep.maxKeepaliveIntervalMillis,
+            .cid = keep.cid,
+    };
+}
+
+static aidl::QosBandwidth toAidl(const V1_6::QosBandwidth& bw) {
+    return {
+            .maxBitrateKbps = static_cast<int32_t>(bw.maxBitrateKbps),
+            .guaranteedBitrateKbps = static_cast<int32_t>(bw.guaranteedBitrateKbps),
+    };
+}
+
+static aidl::EpsQos toAidl(const V1_6::EpsQos& qos) {
+    return {
+            .qci = qos.qci,
+            .downlink = toAidl(qos.downlink),
+            .uplink = toAidl(qos.uplink),
+    };
+}
+
+static aidl::NrQos toAidl(const V1_6::NrQos& qos) {
+    return {
+            .fiveQi = qos.fiveQi,
+            .downlink = toAidl(qos.downlink),
+            .uplink = toAidl(qos.uplink),
+            .qfi = static_cast<int8_t>(qos.qfi),
+            .averagingWindowMs = qos.averagingWindowMs,
+    };
+}
+
+static std::variant<bool, aidl::EpsQos, aidl::NrQos> toAidl(const V1_6::Qos& qos) {
+    if (qos.getDiscriminator() == V1_6::Qos::hidl_discriminator::eps) return toAidl(qos.eps());
+    if (qos.getDiscriminator() == V1_6::Qos::hidl_discriminator::nr) return toAidl(qos.nr());
+    return false;
+}
+
+aidl::SetupDataCallResult toAidl(const V1_5::SetupDataCallResult& res) {
+    return {
+            .cause = aidl::DataCallFailCause(res.cause),
+            .suggestedRetryTime = res.suggestedRetryTime,
+            .cid = res.cid,
+            .active = static_cast<int32_t>(res.active),
+            .type = aidl::PdpProtocolType(res.type),
+            .ifname = res.ifname,
+            .addresses = toAidl(res.addresses),
+            .dnses = toAidl(res.dnses),
+            .gateways = toAidl(res.gateways),
+            .pcscf = toAidl(res.pcscf),
+            .mtuV4 = res.mtuV4,
+            .mtuV6 = res.mtuV6,
+    };
+}
+
+aidl::SetupDataCallResult toAidl(const V1_6::SetupDataCallResult& res) {
+    return {
+            .cause = aidl::DataCallFailCause(res.cause),
+            .suggestedRetryTime = res.suggestedRetryTime,
+            .cid = res.cid,
+            .active = static_cast<int32_t>(res.active),
+            .type = aidl::PdpProtocolType(res.type),
+            .ifname = res.ifname,
+            .addresses = toAidl(res.addresses),
+            .dnses = toAidl(res.dnses),
+            .gateways = toAidl(res.gateways),
+            .pcscf = toAidl(res.pcscf),
+            .mtuV4 = res.mtuV4,
+            .mtuV6 = res.mtuV6,
+            .defaultQos = toAidl(res.defaultQos),
+            .qosSessions = toAidl(res.qosSessions),
+            .handoverFailureMode = static_cast<int8_t>(res.handoverFailureMode),
+            .pduSessionId = res.pduSessionId,
+            .sliceInfo = toAidl(res.sliceInfo),
+            .trafficDescriptors = toAidl(res.trafficDescriptors),
+    };
+}
+
+aidl::LinkAddress toAidl(const V1_5::LinkAddress& addr) {
+    return {
+            .address = addr.address,
+            .addressProperties = addr.properties,
+            .deprecationTime = static_cast<int64_t>(addr.deprecationTime),
+            .expirationTime = static_cast<int64_t>(addr.expirationTime),
+    };
+}
+
+aidl::QosSession toAidl(const V1_6::QosSession& sess) {
+    return {
+            .qosSessionId = sess.qosSessionId,
+            .qos = toAidl(sess.qos),
+            .qosFilters = toAidl(sess.qosFilters),
+    };
+}
+
+static aidl::PortRange toAidl(const V1_6::PortRange& range) {
+    return {
+            .start = range.start,
+            .end = range.end,
+    };
+}
+
+static std::optional<aidl::PortRange> toAidl(const V1_6::MaybePort& opt) {
+    if (opt.getDiscriminator() == V1_6::MaybePort::hidl_discriminator::noinit) return std::nullopt;
+    return toAidl(opt.range());  // can't use MaybeX template - this field is not named "value"
+}
+
+aidl::QosFilter toAidl(const V1_6::QosFilter& filter) {
+    return {
+            .localAddresses = toAidl(filter.localAddresses),
+            .remoteAddresses = toAidl(filter.remoteAddresses),
+            .localPort = toAidl(filter.localPort),
+            .remotePort = toAidl(filter.remotePort),
+            .protocol = static_cast<int8_t>(filter.protocol),
+            .tos = toAidlVariant(filter.tos),
+            .flowLabel = toAidlVariant(filter.flowLabel),
+            .spi = toAidlVariant(filter.spi),
+            .direction = static_cast<int8_t>(filter.direction),
+            .precedence = filter.precedence,
+    };
+}
+
+aidl::KeepaliveStatus toAidl(const V1_1::KeepaliveStatus& status) {
+    return {
+            .sessionHandle = status.sessionHandle,
+            .code = static_cast<int32_t>(status.code),
+    };
+}
+
+aidl::PcoDataInfo toAidl(const V1_0::PcoDataInfo& info) {
+    return {
+            .cid = info.cid,
+            .bearerProto = info.bearerProto,
+            .pcoId = info.pcoId,
+            .contents = info.contents,
+    };
+}
+
+aidl::SlicingConfig toAidl(const V1_6::SlicingConfig& cfg) {
+    return {
+            .urspRules = toAidl(cfg.urspRules),
+            .sliceInfo = toAidl(cfg.sliceInfo),
+    };
+}
+
+aidl::UrspRule toAidl(const V1_6::UrspRule& rule) {
+    return {
+            .precedence = rule.precedence,
+            .trafficDescriptors = toAidl(rule.trafficDescriptors),
+            .routeSelectionDescriptor = toAidl(rule.routeSelectionDescriptor),
+    };
+}
+
+static int8_t toAidl(const V1_6::OptionalSscMode& opt) {
+    if (opt.getDiscriminator() == V1_6::OptionalSscMode::hidl_discriminator::noinit) {
+        return aidl::RouteSelectionDescriptor::SSC_MODE_UNKNOWN;
+    }
+    return static_cast<int8_t>(opt.value());
+}
+
+static aidl::PdpProtocolType toAidl(const V1_6::OptionalPdpProtocolType& opt) {
+    using discriminator = V1_6::OptionalPdpProtocolType::hidl_discriminator;
+    if (opt.getDiscriminator() == discriminator::noinit) return aidl::PdpProtocolType::UNKNOWN;
+    return aidl::PdpProtocolType(opt.value());
+}
+
+aidl::RouteSelectionDescriptor toAidl(const V1_6::RouteSelectionDescriptor& descr) {
+    return {
+            .precedence = static_cast<int8_t>(descr.precedence),
+            .sessionType = toAidl(descr.sessionType),
+            .sscMode = toAidl(descr.sscMode),
+            .sliceInfo = toAidl(descr.sliceInfo),
+            .dnn = toAidl(descr.dnn),
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/structs.h b/radio/aidl/compat/libradiocompat/data/structs.h
new file mode 100644
index 0000000..60fad57
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/structs.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/DataProfileInfo.h>
+#include <aidl/android/hardware/radio/data/KeepaliveRequest.h>
+#include <aidl/android/hardware/radio/data/KeepaliveStatus.h>
+#include <aidl/android/hardware/radio/data/LinkAddress.h>
+#include <aidl/android/hardware/radio/data/OsAppId.h>
+#include <aidl/android/hardware/radio/data/PcoDataInfo.h>
+#include <aidl/android/hardware/radio/data/RouteSelectionDescriptor.h>
+#include <aidl/android/hardware/radio/data/SetupDataCallResult.h>
+#include <aidl/android/hardware/radio/data/SliceInfo.h>
+#include <aidl/android/hardware/radio/data/SlicingConfig.h>
+#include <aidl/android/hardware/radio/data/TrafficDescriptor.h>
+#include <aidl/android/hardware/radio/data/UrspRule.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_5::DataProfileInfo toHidl(const ::aidl::android::hardware::radio::data::DataProfileInfo& info);
+
+V1_5::LinkAddress toHidl(const ::aidl::android::hardware::radio::data::LinkAddress& addr);
+
+::aidl::android::hardware::radio::data::SliceInfo toAidl(const V1_6::SliceInfo& info);
+V1_6::SliceInfo toHidl(const ::aidl::android::hardware::radio::data::SliceInfo& info);
+
+::aidl::android::hardware::radio::data::TrafficDescriptor toAidl(const V1_6::TrafficDescriptor& td);
+V1_6::TrafficDescriptor toHidl(const ::aidl::android::hardware::radio::data::TrafficDescriptor& td);
+
+V1_1::KeepaliveRequest toHidl(const ::aidl::android::hardware::radio::data::KeepaliveRequest& keep);
+
+::aidl::android::hardware::radio::data::OsAppId toAidl(const V1_6::OsAppId& appId);
+V1_6::OsAppId toHidl(const ::aidl::android::hardware::radio::data::OsAppId& appId);
+
+::aidl::android::hardware::radio::data::SetupDataCallResult  //
+toAidl(const V1_5::SetupDataCallResult& res);
+::aidl::android::hardware::radio::data::SetupDataCallResult  //
+toAidl(const V1_6::SetupDataCallResult& res);
+
+::aidl::android::hardware::radio::data::LinkAddress toAidl(const V1_5::LinkAddress& addr);
+
+::aidl::android::hardware::radio::data::QosSession toAidl(const V1_6::QosSession& session);
+
+::aidl::android::hardware::radio::data::QosFilter toAidl(const V1_6::QosFilter& filter);
+
+::aidl::android::hardware::radio::data::KeepaliveStatus toAidl(const V1_1::KeepaliveStatus& status);
+
+::aidl::android::hardware::radio::data::PcoDataInfo toAidl(const V1_0::PcoDataInfo& info);
+
+::aidl::android::hardware::radio::data::SlicingConfig toAidl(const V1_6::SlicingConfig& cfg);
+
+::aidl::android::hardware::radio::data::UrspRule toAidl(const V1_6::UrspRule& rule);
+
+::aidl::android::hardware::radio::data::RouteSelectionDescriptor  //
+toAidl(const V1_6::RouteSelectionDescriptor& descr);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/debug.h b/radio/aidl/compat/libradiocompat/debug.h
new file mode 100644
index 0000000..4158059
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/debug.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace debug {
+
+static constexpr bool kSuperVerbose = true;
+
+#define LOG_CALL \
+    if constexpr (debug::kSuperVerbose) LOG(VERBOSE) << (RADIO_MODULE ".") << __func__ << ' '
+
+#define CHECK_CB(field)                     \
+    if (!field) {                           \
+        LOG(WARNING) << "Callback not set"; \
+        return {};                          \
+    }
+
+}  // namespace debug
+
+inline std::ostream& operator<<(std::ostream& os, const V1_0::RadioIndicationType& type) {
+    return os << static_cast<int>(type);
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
new file mode 100644
index 0000000..a412c34
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include "RadioIndication.h"
+#include "RadioResponse.h"
+
+#include <android/hardware/radio/1.6/IRadio.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioCompatBase {
+  protected:
+    sp<V1_5::IRadio> mHal1_5;
+    sp<V1_6::IRadio> mHal1_6;
+
+    sp<RadioResponse> mRadioResponse;
+    sp<RadioIndication> mRadioIndication;
+
+    V1_6::IRadioResponse& respond();
+
+  public:
+    RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
+                    sp<RadioIndication> radioIndication);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
new file mode 100644
index 0000000..31ad207
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/config/BnRadioConfig.h>
+#include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.3/IRadioConfig.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+
+namespace android::hardware::radio::compat {
+
+/**
+ * HAL translator from HIDL IRadioConfig to AIDL IRadioConfig.
+ *
+ * This class wraps existing HIDL implementation (either a binder stub or real
+ * class implementing the HAL) and implements AIDL HAL. It's up to the caller to
+ * fetch source implementation and publish resulting HAL instance.
+ */
+class RadioConfig : public aidl::android::hardware::radio::config::BnRadioConfig {
+    sp<config::V1_1::IRadioConfig> mHal1_1;
+    sp<config::V1_3::IRadioConfig> mHal1_3;
+
+    sp<config::V1_3::IRadioConfigResponse> mRadioConfigResponse;
+    sp<config::V1_2::IRadioConfigIndication> mRadioConfigIndication;
+
+    ::ndk::ScopedAStatus getHalDeviceCapabilities(int32_t serial) override;
+    ::ndk::ScopedAStatus getNumOfLiveModems(int32_t serial) override;
+    ::ndk::ScopedAStatus getPhoneCapability(int32_t serial) override;
+    ::ndk::ScopedAStatus getSimSlotsStatus(int32_t serial) override;
+    ::ndk::ScopedAStatus setNumOfLiveModems(int32_t serial, int8_t numOfLiveModems) override;
+    ::ndk::ScopedAStatus setPreferredDataModem(int32_t serial, int8_t modemId) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse>&
+                    radioConfigResponse,
+            const std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication>&
+                    radioConfigIndication) override;
+    ::ndk::ScopedAStatus setSimSlotsMapping(
+            int32_t serial,
+            const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap)
+            override;
+
+    config::V1_3::IRadioConfigResponse& respond();
+
+  public:
+    /**
+     * Constructs AIDL IRadioConfig instance wrapping existing HIDL IRadioConfig instance.
+     *
+     * \param hidlHal existing HIDL IRadioConfig HAL instance
+     */
+    RadioConfig(sp<config::V1_1::IRadioConfig> hidlHal);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
new file mode 100644
index 0000000..900a669
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/data/BnRadioData.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioData : public RadioCompatBase, public aidl::android::hardware::radio::data::BnRadioData {
+    ::ndk::ScopedAStatus allocatePduSessionId(int32_t serial) override;
+    ::ndk::ScopedAStatus cancelHandover(int32_t serial, int32_t callId) override;
+    ::ndk::ScopedAStatus deactivateDataCall(
+            int32_t serial, int32_t cid,
+            ::aidl::android::hardware::radio::data::DataRequestReason reason) override;
+    ::ndk::ScopedAStatus getDataCallList(int32_t serial) override;
+    ::ndk::ScopedAStatus getSlicingConfig(int32_t serial) override;
+    ::ndk::ScopedAStatus releasePduSessionId(int32_t serial, int32_t id) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus setDataAllowed(int32_t serial, bool allow) override;
+    ::ndk::ScopedAStatus setDataProfile(
+            int32_t serial,
+            const std::vector<::aidl::android::hardware::radio::data::DataProfileInfo>& profiles)
+            override;
+    ::ndk::ScopedAStatus setDataThrottling(
+            int32_t serial,
+            ::aidl::android::hardware::radio::data::DataThrottlingAction dataThrottlingAction,
+            int64_t completionDurationMillis) override;
+    ::ndk::ScopedAStatus setInitialAttachApn(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::data::DataProfileInfo& dpInfo) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse>&
+                    radioDataResponse,
+            const std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication>&
+                    radioDataIndication) override;
+    ::ndk::ScopedAStatus setupDataCall(
+            int32_t serial, ::aidl::android::hardware::radio::AccessNetwork accessNetwork,
+            const ::aidl::android::hardware::radio::data::DataProfileInfo& dataProfileInfo,
+            bool roamingAllowed, ::aidl::android::hardware::radio::data::DataRequestReason reason,
+            const std::vector<::aidl::android::hardware::radio::data::LinkAddress>& addresses,
+            const std::vector<std::string>& dnses, int32_t pduSessionId,
+            const std::optional<::aidl::android::hardware::radio::data::SliceInfo>& sliceInfo,
+            const std::optional<::aidl::android::hardware::radio::data::TrafficDescriptor>& trDescr,
+            bool matchAllRuleAllowed) override;
+    ::ndk::ScopedAStatus startHandover(int32_t serial, int32_t callId) override;
+    ::ndk::ScopedAStatus startKeepalive(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::data::KeepaliveRequest& keepalive) override;
+    ::ndk::ScopedAStatus stopKeepalive(int32_t serial, int32_t sessionHandle) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
new file mode 100644
index 0000000..20e0973
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/IRadioDataIndication.h>
+#include <aidl/android/hardware/radio/messaging/IRadioMessagingIndication.h>
+#include <aidl/android/hardware/radio/modem/IRadioModemIndication.h>
+#include <aidl/android/hardware/radio/network/IRadioNetworkIndication.h>
+#include <aidl/android/hardware/radio/sim/IRadioSimIndication.h>
+#include <aidl/android/hardware/radio/voice/IRadioVoiceIndication.h>
+#include <android/hardware/radio/1.6/IRadioIndication.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioIndication : public V1_6::IRadioIndication {
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> mDataCb;
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+            mMessagingCb;
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> mModemCb;
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> mNetworkCb;
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> mSimCb;
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> mVoiceCb;
+
+    // IRadioIndication @ 1.0
+    Return<void> radioStateChanged(V1_0::RadioIndicationType type,
+                                   V1_0::RadioState radioState) override;
+    Return<void> callStateChanged(V1_0::RadioIndicationType type) override;
+    Return<void> networkStateChanged(V1_0::RadioIndicationType type) override;
+    Return<void> newSms(V1_0::RadioIndicationType type, const hidl_vec<uint8_t>& pdu) override;
+    Return<void> newSmsStatusReport(V1_0::RadioIndicationType type,
+                                    const hidl_vec<uint8_t>& pdu) override;
+    Return<void> newSmsOnSim(V1_0::RadioIndicationType type, int32_t recordNumber) override;
+    Return<void> onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
+                        const hidl_string& msg) override;
+    Return<void> nitzTimeReceived(V1_0::RadioIndicationType type, const hidl_string& nitzTime,
+                                  uint64_t receivedTime) override;
+    Return<void> currentSignalStrength(V1_0::RadioIndicationType type,
+                                       const V1_0::SignalStrength& signalStrength) override;
+    Return<void> dataCallListChanged(V1_0::RadioIndicationType type,
+                                     const hidl_vec<V1_0::SetupDataCallResult>& dcList) override;
+    Return<void> suppSvcNotify(V1_0::RadioIndicationType type,
+                               const V1_0::SuppSvcNotification& suppSvc) override;
+    Return<void> stkSessionEnd(V1_0::RadioIndicationType type) override;
+    Return<void> stkProactiveCommand(V1_0::RadioIndicationType type,
+                                     const hidl_string& cmd) override;
+    Return<void> stkEventNotify(V1_0::RadioIndicationType type, const hidl_string& cmd) override;
+    Return<void> stkCallSetup(V1_0::RadioIndicationType type, int64_t timeout) override;
+    Return<void> simSmsStorageFull(V1_0::RadioIndicationType type) override;
+    Return<void> simRefresh(V1_0::RadioIndicationType type,
+                            const V1_0::SimRefreshResult& refreshResult) override;
+    Return<void> callRing(V1_0::RadioIndicationType type, bool isGsm,
+                          const V1_0::CdmaSignalInfoRecord& record) override;
+    Return<void> simStatusChanged(V1_0::RadioIndicationType type) override;
+    Return<void> cdmaNewSms(V1_0::RadioIndicationType type,
+                            const V1_0::CdmaSmsMessage& msg) override;
+    Return<void> newBroadcastSms(V1_0::RadioIndicationType type,
+                                 const hidl_vec<uint8_t>& data) override;
+    Return<void> cdmaRuimSmsStorageFull(V1_0::RadioIndicationType type) override;
+    Return<void> restrictedStateChanged(V1_0::RadioIndicationType type,
+                                        V1_0::PhoneRestrictedState state) override;
+    Return<void> enterEmergencyCallbackMode(V1_0::RadioIndicationType type) override;
+    Return<void> cdmaCallWaiting(V1_0::RadioIndicationType type,
+                                 const V1_0::CdmaCallWaiting& callWaitingRecord) override;
+    Return<void> cdmaOtaProvisionStatus(V1_0::RadioIndicationType type,
+                                        V1_0::CdmaOtaProvisionStatus status) override;
+    Return<void> cdmaInfoRec(V1_0::RadioIndicationType type,
+                             const V1_0::CdmaInformationRecords& records) override;
+    Return<void> indicateRingbackTone(V1_0::RadioIndicationType type, bool start) override;
+    Return<void> resendIncallMute(V1_0::RadioIndicationType type) override;
+    Return<void> cdmaSubscriptionSourceChanged(V1_0::RadioIndicationType type,
+                                               V1_0::CdmaSubscriptionSource cdmaSource) override;
+    Return<void> cdmaPrlChanged(V1_0::RadioIndicationType type, int32_t version) override;
+    Return<void> exitEmergencyCallbackMode(V1_0::RadioIndicationType type) override;
+    Return<void> rilConnected(V1_0::RadioIndicationType type) override;
+    Return<void> voiceRadioTechChanged(V1_0::RadioIndicationType type,
+                                       V1_0::RadioTechnology rat) override;
+    Return<void> cellInfoList(V1_0::RadioIndicationType type,
+                              const hidl_vec<V1_0::CellInfo>& records) override;
+    Return<void> imsNetworkStateChanged(V1_0::RadioIndicationType type) override;
+    Return<void> subscriptionStatusChanged(V1_0::RadioIndicationType type, bool activate) override;
+    Return<void> srvccStateNotify(V1_0::RadioIndicationType type, V1_0::SrvccState state) override;
+    Return<void> hardwareConfigChanged(V1_0::RadioIndicationType type,
+                                       const hidl_vec<V1_0::HardwareConfig>& configs) override;
+    Return<void> radioCapabilityIndication(V1_0::RadioIndicationType type,
+                                           const V1_0::RadioCapability& rc) override;
+    Return<void> onSupplementaryServiceIndication(V1_0::RadioIndicationType type,
+                                                  const V1_0::StkCcUnsolSsResult& ss) override;
+    Return<void> stkCallControlAlphaNotify(V1_0::RadioIndicationType type,
+                                           const hidl_string& alpha) override;
+    Return<void> lceData(V1_0::RadioIndicationType type, const V1_0::LceDataInfo& lce) override;
+    Return<void> pcoData(V1_0::RadioIndicationType type, const V1_0::PcoDataInfo& pco) override;
+    Return<void> modemReset(V1_0::RadioIndicationType type, const hidl_string& reason) override;
+
+    // IRadioIndication @ 1.1
+    Return<void> carrierInfoForImsiEncryption(V1_0::RadioIndicationType info) override;
+    Return<void> networkScanResult(V1_0::RadioIndicationType type,
+                                   const V1_1::NetworkScanResult& result) override;
+    Return<void> keepaliveStatus(V1_0::RadioIndicationType type,
+                                 const V1_1::KeepaliveStatus& status) override;
+
+    // IRadioIndication @ 1.2
+    Return<void> networkScanResult_1_2(V1_0::RadioIndicationType type,
+                                       const V1_2::NetworkScanResult& result) override;
+    Return<void> cellInfoList_1_2(V1_0::RadioIndicationType type,
+                                  const hidl_vec<V1_2::CellInfo>& records) override;
+    Return<void> currentLinkCapacityEstimate(V1_0::RadioIndicationType type,
+                                             const V1_2::LinkCapacityEstimate& lce) override;
+    Return<void> currentPhysicalChannelConfigs(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_2::PhysicalChannelConfig>& configs) override;
+    Return<void> currentSignalStrength_1_2(V1_0::RadioIndicationType type,
+                                           const V1_2::SignalStrength& signalStrength) override;
+
+    // IRadioIndication @ 1.4
+    Return<void> currentEmergencyNumberList(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_4::EmergencyNumber>& emergencyNumberList) override;
+    Return<void> cellInfoList_1_4(V1_0::RadioIndicationType type,
+                                  const hidl_vec<V1_4::CellInfo>& records) override;
+    Return<void> networkScanResult_1_4(V1_0::RadioIndicationType type,
+                                       const V1_4::NetworkScanResult& result) override;
+    Return<void> currentPhysicalChannelConfigs_1_4(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_4::PhysicalChannelConfig>& configs) override;
+    Return<void> dataCallListChanged_1_4(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_4::SetupDataCallResult>& dcList) override;
+    Return<void> currentSignalStrength_1_4(V1_0::RadioIndicationType type,
+                                           const V1_4::SignalStrength& signalStrength) override;
+
+    // IRadioIndication @ 1.5
+    Return<void> uiccApplicationsEnablementChanged(V1_0::RadioIndicationType type,
+                                                   bool enabled) override;
+    Return<void> registrationFailed(  //
+            V1_0::RadioIndicationType type, const V1_5::CellIdentity& cellIdentity,
+            const hidl_string& chosenPlmn, hidl_bitfield<V1_5::Domain> domain, int32_t causeCode,
+            int32_t additionalCauseCode) override;
+    Return<void> barringInfoChanged(  //
+            V1_0::RadioIndicationType type, const V1_5::CellIdentity& cellIdentity,
+            const hidl_vec<V1_5::BarringInfo>& barringInfos) override;
+    Return<void> cellInfoList_1_5(V1_0::RadioIndicationType type,
+                                  const hidl_vec<V1_5::CellInfo>& records) override;
+    Return<void> networkScanResult_1_5(V1_0::RadioIndicationType type,
+                                       const V1_5::NetworkScanResult& result) override;
+    Return<void> dataCallListChanged_1_5(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_5::SetupDataCallResult>& dcList) override;
+
+    // IRadioIndication @ 1.6
+    Return<void> dataCallListChanged_1_6(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_6::SetupDataCallResult>& dcList) override;
+    Return<void> unthrottleApn(V1_0::RadioIndicationType type, const hidl_string& apn) override;
+    Return<void> currentLinkCapacityEstimate_1_6(V1_0::RadioIndicationType type,
+                                                 const V1_6::LinkCapacityEstimate& lce) override;
+    Return<void> currentSignalStrength_1_6(V1_0::RadioIndicationType type,
+                                           const V1_6::SignalStrength& signalStrength) override;
+    Return<void> cellInfoList_1_6(V1_0::RadioIndicationType type,
+                                  const hidl_vec<V1_6::CellInfo>& records) override;
+    Return<void> networkScanResult_1_6(V1_0::RadioIndicationType type,
+                                       const V1_6::NetworkScanResult& result) override;
+    Return<void> currentPhysicalChannelConfigs_1_6(
+            V1_0::RadioIndicationType type,
+            const hidl_vec<V1_6::PhysicalChannelConfig>& configs) override;
+    Return<void> simPhonebookChanged(V1_0::RadioIndicationType type) override;
+    Return<void> simPhonebookRecordsReceived(
+            V1_0::RadioIndicationType type, V1_6::PbReceivedStatus status,
+            const hidl_vec<V1_6::PhonebookRecordInfo>& records) override;
+
+  public:
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+                    radioMessagingIndication);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> modmCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> ni);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voicCb);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
new file mode 100644
index 0000000..0cd3381
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/messaging/BnRadioMessaging.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioMessaging : public RadioCompatBase,
+                       public aidl::android::hardware::radio::messaging::BnRadioMessaging {
+    ::ndk::ScopedAStatus acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success,
+                                                          const std::string& ackPdu) override;
+    ::ndk::ScopedAStatus acknowledgeLastIncomingCdmaSms(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::CdmaSmsAck& smsAck) override;
+    ::ndk::ScopedAStatus acknowledgeLastIncomingGsmSms(
+            int32_t serial, bool success,
+            ::aidl::android::hardware::radio::messaging::SmsAcknowledgeFailCause cause) override;
+    ::ndk::ScopedAStatus cancelPendingUssd(int32_t serial) override;
+    ::ndk::ScopedAStatus deleteSmsOnRuim(int32_t serial, int32_t index) override;
+    ::ndk::ScopedAStatus deleteSmsOnSim(int32_t serial, int32_t index) override;
+    ::ndk::ScopedAStatus getCdmaBroadcastConfig(int32_t serial) override;
+    ::ndk::ScopedAStatus getGsmBroadcastConfig(int32_t serial) override;
+    ::ndk::ScopedAStatus getSmscAddress(int32_t serial) override;
+    ::ndk::ScopedAStatus reportSmsMemoryStatus(int32_t serial, bool available) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus sendCdmaSms(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::CdmaSmsMessage& sms) override;
+    ::ndk::ScopedAStatus sendCdmaSmsExpectMore(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::CdmaSmsMessage& sms) override;
+    ::ndk::ScopedAStatus sendImsSms(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::ImsSmsMessage& message) override;
+    ::ndk::ScopedAStatus sendSms(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& message) override;
+    ::ndk::ScopedAStatus sendSmsExpectMore(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& message) override;
+    ::ndk::ScopedAStatus sendUssd(int32_t serial, const std::string& ussd) override;
+    ::ndk::ScopedAStatus setCdmaBroadcastActivation(int32_t serial, bool activate) override;
+    ::ndk::ScopedAStatus setCdmaBroadcastConfig(
+            int32_t serial,
+            const std::vector<
+                    ::aidl::android::hardware::radio::messaging::CdmaBroadcastSmsConfigInfo>&
+                    configInfo) override;
+    ::ndk::ScopedAStatus setGsmBroadcastActivation(int32_t serial, bool activate) override;
+    ::ndk::ScopedAStatus setGsmBroadcastConfig(
+            int32_t serial,
+            const std::vector<
+                    ::aidl::android::hardware::radio::messaging::GsmBroadcastSmsConfigInfo>&
+                    configInfo) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<
+                    ::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>&
+                    radioMessagingResponse,
+            const std::shared_ptr<
+                    ::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>&
+                    radioMessagingIndication) override;
+    ::ndk::ScopedAStatus setSmscAddress(int32_t serial, const std::string& smsc) override;
+    ::ndk::ScopedAStatus writeSmsToRuim(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::CdmaSmsWriteArgs& cdmaSms) override;
+    ::ndk::ScopedAStatus writeSmsToSim(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::messaging::SmsWriteArgs& smsWriteArgs) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
new file mode 100644
index 0000000..666ff47
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/modem/BnRadioModem.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioModem : public RadioCompatBase,
+                   public aidl::android::hardware::radio::modem::BnRadioModem {
+    ::ndk::ScopedAStatus enableModem(int32_t serial, bool on) override;
+    ::ndk::ScopedAStatus getBasebandVersion(int32_t serial) override;
+    ::ndk::ScopedAStatus getDeviceIdentity(int32_t serial) override;
+    ::ndk::ScopedAStatus getHardwareConfig(int32_t serial) override;
+    ::ndk::ScopedAStatus getModemActivityInfo(int32_t serial) override;
+    ::ndk::ScopedAStatus getModemStackStatus(int32_t serial) override;
+    ::ndk::ScopedAStatus getRadioCapability(int32_t serial) override;
+    ::ndk::ScopedAStatus nvReadItem(
+            int32_t serial, ::aidl::android::hardware::radio::modem::NvItem itemId) override;
+    ::ndk::ScopedAStatus nvResetConfig(
+            int32_t serial, ::aidl::android::hardware::radio::modem::ResetNvType type) override;
+    ::ndk::ScopedAStatus nvWriteCdmaPrl(int32_t serial, const std::vector<uint8_t>& prl) override;
+    ::ndk::ScopedAStatus nvWriteItem(
+            int32_t serial, const ::aidl::android::hardware::radio::modem::NvWriteItem& i) override;
+    ::ndk::ScopedAStatus requestShutdown(int32_t serial) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus sendDeviceState(
+            int32_t serial, ::aidl::android::hardware::radio::modem::DeviceStateType stateType,
+            bool state) override;
+    ::ndk::ScopedAStatus setRadioCapability(
+            int32_t s, const ::aidl::android::hardware::radio::modem::RadioCapability& rc) override;
+    ::ndk::ScopedAStatus setRadioPower(int32_t serial, bool powerOn, bool forEmergencyCall,
+                                       bool preferredForEmergencyCall) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse>&
+                    radioModemResponse,
+            const std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication>&
+                    radioModemIndication) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
new file mode 100644
index 0000000..c776fd1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/network/BnRadioNetwork.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioNetwork : public RadioCompatBase,
+                     public aidl::android::hardware::radio::network::BnRadioNetwork {
+    ::ndk::ScopedAStatus getAllowedNetworkTypesBitmap(int32_t serial) override;
+    ::ndk::ScopedAStatus getAvailableBandModes(int32_t serial) override;
+    ::ndk::ScopedAStatus getAvailableNetworks(int32_t serial) override;
+    ::ndk::ScopedAStatus getBarringInfo(int32_t serial) override;
+    ::ndk::ScopedAStatus getCdmaRoamingPreference(int32_t serial) override;
+    ::ndk::ScopedAStatus getCellInfoList(int32_t serial) override;
+    ::ndk::ScopedAStatus getDataRegistrationState(int32_t serial) override;
+    ::ndk::ScopedAStatus getImsRegistrationState(int32_t serial) override;
+    ::ndk::ScopedAStatus getNetworkSelectionMode(int32_t serial) override;
+    ::ndk::ScopedAStatus getOperator(int32_t serial) override;
+    ::ndk::ScopedAStatus getSignalStrength(int32_t serial) override;
+    ::ndk::ScopedAStatus getSystemSelectionChannels(int32_t serial) override;
+    ::ndk::ScopedAStatus getVoiceRadioTechnology(int32_t serial) override;
+    ::ndk::ScopedAStatus getVoiceRegistrationState(int32_t serial) override;
+    ::ndk::ScopedAStatus isNrDualConnectivityEnabled(int32_t serial) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus setAllowedNetworkTypesBitmap(
+            int32_t serial,
+            ::aidl::android::hardware::radio::RadioAccessFamily networkTypeBitmap) override;
+    ::ndk::ScopedAStatus setBandMode(
+            int32_t serial, ::aidl::android::hardware::radio::network::RadioBandMode mode) override;
+    ::ndk::ScopedAStatus setBarringPassword(int32_t serial, const std::string& facility,
+                                            const std::string& oldPassword,
+                                            const std::string& newPassword) override;
+    ::ndk::ScopedAStatus setCdmaRoamingPreference(
+            int32_t serial,
+            ::aidl::android::hardware::radio::network::CdmaRoamingType type) override;
+    ::ndk::ScopedAStatus setCellInfoListRate(int32_t serial, int32_t rate) override;
+    ::ndk::ScopedAStatus setIndicationFilter(
+            int32_t serial,
+            ::aidl::android::hardware::radio::network::IndicationFilter indicationFilter) override;
+    ::ndk::ScopedAStatus setLinkCapacityReportingCriteria(
+            int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps,
+            int32_t hysteresisUlKbps, const std::vector<int32_t>& thresholdsDownlinkKbps,
+            const std::vector<int32_t>& thresholdsUplinkKbps,
+            ::aidl::android::hardware::radio::AccessNetwork accessNetwork) override;
+    ::ndk::ScopedAStatus setLocationUpdates(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus setNetworkSelectionModeAutomatic(int32_t serial) override;
+    ::ndk::ScopedAStatus setNetworkSelectionModeManual(
+            int32_t serial, const std::string& operatorNumeric,
+            ::aidl::android::hardware::radio::AccessNetwork ran) override;
+    ::ndk::ScopedAStatus setNrDualConnectivityState(
+            int32_t serial,
+            ::aidl::android::hardware::radio::network::NrDualConnectivityState nrSt) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse>&
+                    radioNetworkResponse,
+            const std::shared_ptr<
+                    ::aidl::android::hardware::radio::network::IRadioNetworkIndication>&
+                    radioNetworkIndication) override;
+    ::ndk::ScopedAStatus setSignalStrengthReportingCriteria(
+            int32_t serial,
+            const std::vector<::aidl::android::hardware::radio::network::SignalThresholdInfo>&
+                    signalThresholdInfos) override;
+    ::ndk::ScopedAStatus setSuppServiceNotifications(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus setSystemSelectionChannels(
+            int32_t serial, bool specifyChannels,
+            const std::vector<::aidl::android::hardware::radio::network::RadioAccessSpecifier>&
+                    specifiers) override;
+    ::ndk::ScopedAStatus startNetworkScan(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::network::NetworkScanRequest& request) override;
+    ::ndk::ScopedAStatus stopNetworkScan(int32_t serial) override;
+    ::ndk::ScopedAStatus supplyNetworkDepersonalization(int32_t serial,
+                                                        const std::string& netPin) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
new file mode 100644
index 0000000..5db963f
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/IRadioDataResponse.h>
+#include <aidl/android/hardware/radio/messaging/IRadioMessagingResponse.h>
+#include <aidl/android/hardware/radio/modem/IRadioModemResponse.h>
+#include <aidl/android/hardware/radio/network/IRadioNetworkResponse.h>
+#include <aidl/android/hardware/radio/sim/IRadioSimResponse.h>
+#include <aidl/android/hardware/radio/voice/IRadioVoiceResponse.h>
+#include <android/hardware/radio/1.6/IRadioResponse.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioResponse : public V1_6::IRadioResponse {
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> mDataCb;
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+            mMessagingCb;
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> mModemCb;
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> mNetworkCb;
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> mSimCb;
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> mVoiceCb;
+
+    // IRadioResponse @ 1.0
+    Return<void> getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
+                                          const V1_0::CardStatus& cardStatus) override;
+    Return<void> supplyIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                            int32_t remainingRetries) override;
+    Return<void> supplyIccPukForAppResponse(const V1_0::RadioResponseInfo& info,
+                                            int32_t remainingRetries) override;
+    Return<void> supplyIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                             int32_t remainingRetries) override;
+    Return<void> supplyIccPuk2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                             int32_t remainingRetries) override;
+    Return<void> changeIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                            int32_t remainingRetries) override;
+    Return<void> changeIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                             int32_t remainingRetries) override;
+    Return<void> supplyNetworkDepersonalizationResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) override;
+    Return<void> getCurrentCallsResponse(const V1_0::RadioResponseInfo& info,
+                                         const hidl_vec<V1_0::Call>& calls) override;
+    Return<void> dialResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getIMSIForAppResponse(const V1_0::RadioResponseInfo& info,
+                                       const hidl_string& imsi) override;
+    Return<void> hangupConnectionResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> hangupWaitingOrBackgroundResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> hangupForegroundResumeBackgroundResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> switchWaitingOrHoldingAndActiveResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> conferenceResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> rejectCallResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getLastCallFailCauseResponse(
+            const V1_0::RadioResponseInfo& info,
+            const V1_0::LastCallFailCauseInfo& failCauseinfo) override;
+    Return<void> getSignalStrengthResponse(const V1_0::RadioResponseInfo& info,
+                                           const V1_0::SignalStrength& sigStrength) override;
+    Return<void> getVoiceRegistrationStateResponse(
+            const V1_0::RadioResponseInfo& info,
+            const V1_0::VoiceRegStateResult& voiceRegResponse) override;
+    Return<void> getDataRegistrationStateResponse(
+            const V1_0::RadioResponseInfo& info,
+            const V1_0::DataRegStateResult& dataRegResponse) override;
+    Return<void> getOperatorResponse(const V1_0::RadioResponseInfo& info,
+                                     const hidl_string& longName, const hidl_string& shortName,
+                                     const hidl_string& numeric) override;
+    Return<void> setRadioPowerResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendSmsResponse(const V1_0::RadioResponseInfo& info,
+                                 const V1_0::SendSmsResult& sms) override;
+    Return<void> sendSMSExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+                                           const V1_0::SendSmsResult& sms) override;
+    Return<void> setupDataCallResponse(const V1_0::RadioResponseInfo& info,
+                                       const V1_0::SetupDataCallResult& dcResponse) override;
+    Return<void> iccIOForAppResponse(const V1_0::RadioResponseInfo& info,
+                                     const V1_0::IccIoResult& iccIo) override;
+    Return<void> sendUssdResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getClirResponse(const V1_0::RadioResponseInfo& info, int32_t n,
+                                 int32_t m) override;
+    Return<void> setClirResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCallForwardStatusResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::CallForwardInfo>& callForwardInfos) override;
+    Return<void> setCallForwardResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCallWaitingResponse(const V1_0::RadioResponseInfo& info, bool enable,
+                                        int32_t serviceClass) override;
+    Return<void> setCallWaitingResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> acknowledgeLastIncomingGsmSmsResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> acceptCallResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> deactivateDataCallResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                               int32_t response) override;
+    Return<void> setFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                               int32_t retry) override;
+    Return<void> setBarringPasswordResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getNetworkSelectionModeResponse(const V1_0::RadioResponseInfo& info,
+                                                 bool manual) override;
+    Return<void> setNetworkSelectionModeAutomaticResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> setNetworkSelectionModeManualResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> getAvailableNetworksResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::OperatorInfo>& networkInfos) override;
+    Return<void> startDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> stopDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getBasebandVersionResponse(const V1_0::RadioResponseInfo& info,
+                                            const hidl_string& version) override;
+    Return<void> separateConnectionResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setMuteResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getMuteResponse(const V1_0::RadioResponseInfo& info, bool enable) override;
+    Return<void> getClipResponse(const V1_0::RadioResponseInfo& info,
+                                 V1_0::ClipStatus status) override;
+    Return<void> getDataCallListResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::SetupDataCallResult>& dcResponse) override;
+    Return<void> setSuppServiceNotificationsResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> writeSmsToSimResponse(const V1_0::RadioResponseInfo& info, int32_t index) override;
+    Return<void> deleteSmsOnSimResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setBandModeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getAvailableBandModesResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::RadioBandMode>& bandModes) override;
+    Return<void> sendEnvelopeResponse(const V1_0::RadioResponseInfo& info,
+                                      const hidl_string& commandResponse) override;
+    Return<void> sendTerminalResponseToSimResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> handleStkCallSetupRequestFromSimResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> explicitCallTransferResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info,
+                                                 V1_0::PreferredNetworkType nwType) override;
+    Return<void> getNeighboringCidsResponse(const V1_0::RadioResponseInfo& info,
+                                            const hidl_vec<V1_0::NeighboringCell>& cells) override;
+    Return<void> setLocationUpdatesResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info,
+                                                  V1_0::CdmaRoamingType type) override;
+    Return<void> setTTYModeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getTTYModeResponse(const V1_0::RadioResponseInfo& info,
+                                    V1_0::TtyMode mode) override;
+    Return<void> setPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info,
+                                                  bool enable) override;
+    Return<void> sendCDMAFeatureCodeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendBurstDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendCdmaSmsResponse(const V1_0::RadioResponseInfo& info,
+                                     const V1_0::SendSmsResult& sms) override;
+    Return<void> acknowledgeLastIncomingCdmaSmsResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> getGsmBroadcastConfigResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& configs) override;
+    Return<void> setGsmBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setGsmBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCdmaBroadcastConfigResponse(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configs) override;
+    Return<void> setCdmaBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setCdmaBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCDMASubscriptionResponse(  //
+            const V1_0::RadioResponseInfo& info, const hidl_string& mdn, const hidl_string& hSid,
+            const hidl_string& hNid, const hidl_string& min, const hidl_string& prl) override;
+    Return<void> writeSmsToRuimResponse(const V1_0::RadioResponseInfo& info,
+                                        uint32_t index) override;
+    Return<void> deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getDeviceIdentityResponse(  //
+            const V1_0::RadioResponseInfo& info, const hidl_string& imei, const hidl_string& imeisv,
+            const hidl_string& esn, const hidl_string& meid) override;
+    Return<void> exitEmergencyCallbackModeResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getSmscAddressResponse(const V1_0::RadioResponseInfo& info,
+                                        const hidl_string& smsc) override;
+    Return<void> setSmscAddressResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> reportSmsMemoryStatusResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> reportStkServiceIsRunningResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info,
+                                                   V1_0::CdmaSubscriptionSource source) override;
+    Return<void> requestIsimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                   const hidl_string& response) override;
+    Return<void> acknowledgeIncomingGsmSmsWithPduResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendEnvelopeWithStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::IccIoResult& iccIo) override;
+    Return<void> getVoiceRadioTechnologyResponse(const V1_0::RadioResponseInfo& info,
+                                                 V1_0::RadioTechnology rat) override;
+    Return<void> getCellInfoListResponse(const V1_0::RadioResponseInfo& info,
+                                         const hidl_vec<V1_0::CellInfo>& cellInfo) override;
+    Return<void> setCellInfoListRateResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setInitialAttachApnResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getImsRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+                                                 bool isRegistered,
+                                                 V1_0::RadioTechnologyFamily ratFamily) override;
+    Return<void> sendImsSmsResponse(const V1_0::RadioResponseInfo& info,
+                                    const V1_0::SendSmsResult& sms) override;
+    Return<void> iccTransmitApduBasicChannelResponse(const V1_0::RadioResponseInfo& info,
+                                                     const V1_0::IccIoResult& result) override;
+    Return<void> iccOpenLogicalChannelResponse(const V1_0::RadioResponseInfo& info,
+                                               int32_t channelId,
+                                               const hidl_vec<int8_t>& selectResponse) override;
+    Return<void> iccCloseLogicalChannelResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> iccTransmitApduLogicalChannelResponse(const V1_0::RadioResponseInfo& info,
+                                                       const V1_0::IccIoResult& result) override;
+    Return<void> nvReadItemResponse(const V1_0::RadioResponseInfo& info,
+                                    const hidl_string& result) override;
+    Return<void> nvWriteItemResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> nvWriteCdmaPrlResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> nvResetConfigResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setUiccSubscriptionResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setDataAllowedResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getHardwareConfigResponse(const V1_0::RadioResponseInfo& info,
+                                           const hidl_vec<V1_0::HardwareConfig>& config) override;
+    Return<void> requestIccSimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                     const V1_0::IccIoResult& result) override;
+    Return<void> setDataProfileResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> requestShutdownResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                            const V1_0::RadioCapability& rc) override;
+    Return<void> setRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                            const V1_0::RadioCapability& rc) override;
+    Return<void> startLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                         const V1_0::LceStatusInfo& statusInfo) override;
+    Return<void> stopLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                        const V1_0::LceStatusInfo& statusInfo) override;
+    Return<void> pullLceDataResponse(const V1_0::RadioResponseInfo& info,
+                                     const V1_0::LceDataInfo& lceInfo) override;
+    Return<void> getModemActivityInfoResponse(const V1_0::RadioResponseInfo& info,
+                                              const V1_0::ActivityStatsInfo& activityInfo) override;
+    Return<void> setAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
+                                            int32_t numAllowed) override;
+    Return<void> getAllowedCarriersResponse(const V1_0::RadioResponseInfo& info, bool allAllowed,
+                                            const V1_0::CarrierRestrictions& carriers) override;
+    Return<void> sendDeviceStateResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setIndicationFilterResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setSimCardPowerResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> acknowledgeRequest(int32_t serial) override;
+
+    // IRadioResponse @ 1.1
+    Return<void> setCarrierInfoForImsiEncryptionResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> setSimCardPowerResponse_1_1(const V1_0::RadioResponseInfo& info) override;
+    Return<void> startNetworkScanResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> stopNetworkScanResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> startKeepaliveResponse(const V1_0::RadioResponseInfo& info,
+                                        const V1_1::KeepaliveStatus& status) override;
+    Return<void> stopKeepaliveResponse(const V1_0::RadioResponseInfo& info) override;
+
+    // IRadioResponse @ 1.2
+    Return<void> getCellInfoListResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                             const hidl_vec<V1_2::CellInfo>& cellInfo) override;
+    Return<void> getIccCardStatusResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                              const V1_2::CardStatus& cardStatus) override;
+    Return<void> setSignalStrengthReportingCriteriaResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> setLinkCapacityReportingCriteriaResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCurrentCallsResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                             const hidl_vec<V1_2::Call>& calls) override;
+    Return<void> getSignalStrengthResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                               const V1_2::SignalStrength& signalStrength) override;
+    Return<void> getVoiceRegistrationStateResponse_1_2(
+            const V1_0::RadioResponseInfo& info,
+            const V1_2::VoiceRegStateResult& voiceRegResponse) override;
+    Return<void> getDataRegistrationStateResponse_1_2(
+            const V1_0::RadioResponseInfo& info,
+            const V1_2::DataRegStateResult& dataRegResponse) override;
+
+    // IRadioResponse @ 1.3
+    Return<void> setSystemSelectionChannelsResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> enableModemResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getModemStackStatusResponse(const V1_0::RadioResponseInfo& info,
+                                             bool isEnabled) override;
+
+    // IRadioResponse @ 1.4
+    Return<void> emergencyDialResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> startNetworkScanResponse_1_4(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getCellInfoListResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                             const hidl_vec<V1_4::CellInfo>& cellInfo) override;
+    Return<void> getDataRegistrationStateResponse_1_4(
+            const V1_0::RadioResponseInfo& info,
+            const V1_4::DataRegStateResult& dataRegResponse) override;
+    Return<void> getIccCardStatusResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                              const V1_4::CardStatus& cardStatus) override;
+    Return<void> getPreferredNetworkTypeBitmapResponse(
+            const V1_0::RadioResponseInfo& info,
+            hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) override;
+    Return<void> setPreferredNetworkTypeBitmapResponse(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> getDataCallListResponse_1_4(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_4::SetupDataCallResult>& dcResponse) override;
+    Return<void> setupDataCallResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                           const V1_4::SetupDataCallResult& dcResponse) override;
+    Return<void> setAllowedCarriersResponse_1_4(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getAllowedCarriersResponse_1_4(
+            const V1_0::RadioResponseInfo& info,
+            const V1_4::CarrierRestrictionsWithPriority& carriers,
+            V1_4::SimLockMultiSimPolicy multiSimPolicy) override;
+    Return<void> getSignalStrengthResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                               const V1_4::SignalStrength& signalStrength) override;
+
+    // IRadioResponse @ 1.5
+    Return<void> setSignalStrengthReportingCriteriaResponse_1_5(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> setLinkCapacityReportingCriteriaResponse_1_5(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> enableUiccApplicationsResponse(const V1_0::RadioResponseInfo& info) override;
+    Return<void> areUiccApplicationsEnabledResponse(const V1_0::RadioResponseInfo& info,
+                                                    bool enabled) override;
+    Return<void> setSystemSelectionChannelsResponse_1_5(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> startNetworkScanResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setupDataCallResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                           const V1_5::SetupDataCallResult& dcResponse) override;
+    Return<void> getDataCallListResponse_1_5(
+            const V1_0::RadioResponseInfo& info,
+            const hidl_vec<V1_5::SetupDataCallResult>& dcResponse) override;
+    Return<void> setInitialAttachApnResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setDataProfileResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setRadioPowerResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> setIndicationFilterResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+    Return<void> getBarringInfoResponse(const V1_0::RadioResponseInfo& info,
+                                        const V1_5::CellIdentity& cellIdentity,
+                                        const hidl_vec<V1_5::BarringInfo>& barringInfos) override;
+    Return<void> getVoiceRegistrationStateResponse_1_5(
+            const V1_0::RadioResponseInfo& info,
+            const V1_5::RegStateResult& voiceRegResponse) override;
+    Return<void> getDataRegistrationStateResponse_1_5(
+            const V1_0::RadioResponseInfo& info,
+            const V1_5::RegStateResult& dataRegResponse) override;
+    Return<void> getCellInfoListResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                             const hidl_vec<V1_5::CellInfo>& cellInfo) override;
+    Return<void> setNetworkSelectionModeManualResponse_1_5(
+            const V1_0::RadioResponseInfo& info) override;
+    Return<void> sendCdmaSmsExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+                                               const V1_0::SendSmsResult& sms) override;
+    Return<void> supplySimDepersonalizationResponse(const V1_0::RadioResponseInfo& info,
+                                                    V1_5::PersoSubstate persoType,
+                                                    int32_t remainingRetries) override;
+    Return<void> getIccCardStatusResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                              const V1_5::CardStatus& cardStatus) override;
+
+    // IRadioResponse @ 1.6
+    Return<void> setRadioPowerResponse_1_6(const V1_6::RadioResponseInfo& info) override;
+    Return<void> setupDataCallResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                           const V1_6::SetupDataCallResult& dcResponse) override;
+    Return<void> getDataCallListResponse_1_6(
+            const V1_6::RadioResponseInfo& info,
+            const hidl_vec<V1_6::SetupDataCallResult>& dcResponse) override;
+    Return<void> sendSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                     const V1_0::SendSmsResult& sms) override;
+    Return<void> sendSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                               const V1_0::SendSmsResult& sms) override;
+    Return<void> sendCdmaSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                         const V1_0::SendSmsResult& sms) override;
+    Return<void> sendCdmaSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                   const V1_0::SendSmsResult& sms) override;
+    Return<void> setSimCardPowerResponse_1_6(const V1_6::RadioResponseInfo& info) override;
+    Return<void> setNrDualConnectivityStateResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> isNrDualConnectivityEnabledResponse(const V1_6::RadioResponseInfo& info,
+                                                     bool isEnabled) override;
+    Return<void> allocatePduSessionIdResponse(const V1_6::RadioResponseInfo& info,
+                                              int32_t id) override;
+    Return<void> releasePduSessionIdResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> startHandoverResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> cancelHandoverResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> setAllowedNetworkTypesBitmapResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> getAllowedNetworkTypesBitmapResponse(
+            const V1_6::RadioResponseInfo& info,
+            hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) override;
+    Return<void> setDataThrottlingResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> getSystemSelectionChannelsResponse(
+            const V1_6::RadioResponseInfo& info,
+            const hidl_vec<V1_5::RadioAccessSpecifier>& specifiers) override;
+    Return<void> getCellInfoListResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                             const hidl_vec<V1_6::CellInfo>& cellInfo) override;
+    Return<void> getSignalStrengthResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                               const V1_6::SignalStrength& signalStrength) override;
+    Return<void> getVoiceRegistrationStateResponse_1_6(
+            const V1_6::RadioResponseInfo& info,
+            const V1_6::RegStateResult& voiceRegResponse) override;
+    Return<void> getDataRegistrationStateResponse_1_6(
+            const V1_6::RadioResponseInfo& info,
+            const V1_6::RegStateResult& dataRegResponse) override;
+    Return<void> getCurrentCallsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                             const hidl_vec<V1_6::Call>& calls) override;
+    Return<void> getSlicingConfigResponse(const V1_6::RadioResponseInfo& info,
+                                          const V1_6::SlicingConfig& slicingConfig) override;
+    Return<void> getSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info) override;
+    Return<void> getSimPhonebookCapacityResponse(const V1_6::RadioResponseInfo& info,
+                                                 const V1_6::PhonebookCapacity& capacity) override;
+    Return<void> updateSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info,
+                                                   int32_t updatedRecordIndex) override;
+
+  public:
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+                    radioMessagingResponse);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> modemCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> nwCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
new file mode 100644
index 0000000..a6b77fd
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/sim/BnRadioSim.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioSim : public RadioCompatBase, public aidl::android::hardware::radio::sim::BnRadioSim {
+    ::ndk::ScopedAStatus areUiccApplicationsEnabled(int32_t serial) override;
+    ::ndk::ScopedAStatus changeIccPin2ForApp(int32_t serial, const std::string& oldPin2,
+                                             const std::string& newPin2,
+                                             const std::string& aid) override;
+    ::ndk::ScopedAStatus changeIccPinForApp(int32_t serial, const std::string& oldPin,
+                                            const std::string& newPin,
+                                            const std::string& aid) override;
+    ::ndk::ScopedAStatus enableUiccApplications(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus getAllowedCarriers(int32_t serial) override;
+    ::ndk::ScopedAStatus getCdmaSubscription(int32_t serial) override;
+    ::ndk::ScopedAStatus getCdmaSubscriptionSource(int32_t serial) override;
+    ::ndk::ScopedAStatus getFacilityLockForApp(int32_t serial, const std::string& facility,
+                                               const std::string& password, int32_t serviceClass,
+                                               const std::string& appId) override;
+    ::ndk::ScopedAStatus getIccCardStatus(int32_t serial) override;
+    ::ndk::ScopedAStatus getImsiForApp(int32_t serial, const std::string& aid) override;
+    ::ndk::ScopedAStatus getSimPhonebookCapacity(int32_t serial) override;
+    ::ndk::ScopedAStatus getSimPhonebookRecords(int32_t serial) override;
+    ::ndk::ScopedAStatus iccCloseLogicalChannel(int32_t serial, int32_t channelId) override;
+    ::ndk::ScopedAStatus iccIoForApp(
+            int32_t serial, const ::aidl::android::hardware::radio::sim::IccIo& iccIo) override;
+    ::ndk::ScopedAStatus iccOpenLogicalChannel(int32_t serial, const std::string& aid,
+                                               int32_t p2) override;
+    ::ndk::ScopedAStatus iccTransmitApduBasicChannel(
+            int32_t serial, const ::aidl::android::hardware::radio::sim::SimApdu& message) override;
+    ::ndk::ScopedAStatus iccTransmitApduLogicalChannel(
+            int32_t serial, const ::aidl::android::hardware::radio::sim::SimApdu& message) override;
+    ::ndk::ScopedAStatus reportStkServiceIsRunning(int32_t serial) override;
+    ::ndk::ScopedAStatus requestIccSimAuthentication(int32_t serial, int32_t authContext,
+                                                     const std::string& authData,
+                                                     const std::string& aid) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus sendEnvelope(int32_t serial, const std::string& command) override;
+    ::ndk::ScopedAStatus sendEnvelopeWithStatus(int32_t serial,
+                                                const std::string& contents) override;
+    ::ndk::ScopedAStatus sendTerminalResponseToSim(int32_t serial,
+                                                   const std::string& commandResponse) override;
+    ::ndk::ScopedAStatus setAllowedCarriers(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::sim::CarrierRestrictions& carriers,
+            ::aidl::android::hardware::radio::sim::SimLockMultiSimPolicy multiSimPolicy) override;
+    ::ndk::ScopedAStatus setCarrierInfoForImsiEncryption(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::sim::ImsiEncryptionInfo& imsiEncryptionInfo)
+            override;
+    ::ndk::ScopedAStatus setCdmaSubscriptionSource(
+            int32_t serial,
+            ::aidl::android::hardware::radio::sim::CdmaSubscriptionSource cdmaSub) override;
+    ::ndk::ScopedAStatus setFacilityLockForApp(  //
+            int32_t serial, const std::string& facility, bool lockState, const std::string& passwd,
+            int32_t serviceClass, const std::string& appId) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse>&
+                    radioSimResponse,
+            const std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication>&
+                    radioSimIndication) override;
+    ::ndk::ScopedAStatus setSimCardPower(
+            int32_t serial, ::aidl::android::hardware::radio::sim::CardPowerState powerUp) override;
+    ::ndk::ScopedAStatus setUiccSubscription(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::sim::SelectUiccSub& uiccSub) override;
+    ::ndk::ScopedAStatus supplyIccPin2ForApp(int32_t serial, const std::string& pin2,
+                                             const std::string& aid) override;
+    ::ndk::ScopedAStatus supplyIccPinForApp(int32_t serial, const std::string& pin,
+                                            const std::string& aid) override;
+    ::ndk::ScopedAStatus supplyIccPuk2ForApp(int32_t serial, const std::string& puk2,
+                                             const std::string& pin2,
+                                             const std::string& aid) override;
+    ::ndk::ScopedAStatus supplyIccPukForApp(int32_t serial, const std::string& puk,
+                                            const std::string& pin,
+                                            const std::string& aid) override;
+    ::ndk::ScopedAStatus supplySimDepersonalization(
+            int32_t serial, ::aidl::android::hardware::radio::sim::PersoSubstate persoType,
+            const std::string& controlKey) override;
+    ::ndk::ScopedAStatus updateSimPhonebookRecords(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::sim::PhonebookRecordInfo& recordInfo) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
new file mode 100644
index 0000000..5bf93e0
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/voice/BnRadioVoice.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioVoice : public RadioCompatBase,
+                   public aidl::android::hardware::radio::voice::BnRadioVoice {
+    ::ndk::ScopedAStatus acceptCall(int32_t serial) override;
+    ::ndk::ScopedAStatus conference(int32_t serial) override;
+    ::ndk::ScopedAStatus dial(
+            int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo) override;
+    ::ndk::ScopedAStatus emergencyDial(
+            int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo,
+            ::aidl::android::hardware::radio::voice::EmergencyServiceCategory categories,
+            const std::vector<std::string>& urns,
+            ::aidl::android::hardware::radio::voice::EmergencyCallRouting routing,
+            bool hasKnownUserIntentEmergency, bool isTesting) override;
+    ::ndk::ScopedAStatus exitEmergencyCallbackMode(int32_t serial) override;
+    ::ndk::ScopedAStatus explicitCallTransfer(int32_t serial) override;
+    ::ndk::ScopedAStatus getCallForwardStatus(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::voice::CallForwardInfo& callInfo) override;
+    ::ndk::ScopedAStatus getCallWaiting(int32_t serial, int32_t serviceClass) override;
+    ::ndk::ScopedAStatus getClip(int32_t serial) override;
+    ::ndk::ScopedAStatus getClir(int32_t serial) override;
+    ::ndk::ScopedAStatus getCurrentCalls(int32_t serial) override;
+    ::ndk::ScopedAStatus getLastCallFailCause(int32_t serial) override;
+    ::ndk::ScopedAStatus getMute(int32_t serial) override;
+    ::ndk::ScopedAStatus getPreferredVoicePrivacy(int32_t serial) override;
+    ::ndk::ScopedAStatus getTtyMode(int32_t serial) override;
+    ::ndk::ScopedAStatus handleStkCallSetupRequestFromSim(int32_t serial, bool accept) override;
+    ::ndk::ScopedAStatus hangup(int32_t serial, int32_t gsmIndex) override;
+    ::ndk::ScopedAStatus hangupForegroundResumeBackground(int32_t serial) override;
+    ::ndk::ScopedAStatus hangupWaitingOrBackground(int32_t serial) override;
+    ::ndk::ScopedAStatus isVoNrEnabled(int32_t serial) override;
+    ::ndk::ScopedAStatus rejectCall(int32_t serial) override;
+    ::ndk::ScopedAStatus responseAcknowledgement() override;
+    ::ndk::ScopedAStatus sendBurstDtmf(int32_t serial, const std::string& dtmf, int32_t on,
+                                       int32_t off) override;
+    ::ndk::ScopedAStatus sendCdmaFeatureCode(int32_t serial, const std::string& fcode) override;
+    ::ndk::ScopedAStatus sendDtmf(int32_t serial, const std::string& s) override;
+    ::ndk::ScopedAStatus separateConnection(int32_t serial, int32_t gsmIndex) override;
+    ::ndk::ScopedAStatus setCallForward(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::voice::CallForwardInfo& callInfo) override;
+    ::ndk::ScopedAStatus setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) override;
+    ::ndk::ScopedAStatus setClir(int32_t serial, int32_t status) override;
+    ::ndk::ScopedAStatus setMute(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus setPreferredVoicePrivacy(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse>&
+                    radioVoiceResponse,
+            const std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication>&
+                    radioVoiceIndication) override;
+    ::ndk::ScopedAStatus setTtyMode(int32_t serial,
+                                    ::aidl::android::hardware::radio::voice::TtyMode mode) override;
+    ::ndk::ScopedAStatus setVoNrEnabled(int32_t serial, bool enable) override;
+    ::ndk::ScopedAStatus startDtmf(int32_t serial, const std::string& s) override;
+    ::ndk::ScopedAStatus stopDtmf(int32_t serial) override;
+    ::ndk::ScopedAStatus switchWaitingOrHoldingAndActive(int32_t serial) override;
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
new file mode 100644
index 0000000..c7342b1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#define RADIO_MODULE "MessagingIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingIndication> rmiCb) {
+    CHECK(rmiCb);
+    mMessagingCb = rmiCb;
+}
+
+Return<void> RadioIndication::cdmaNewSms(V1_0::RadioIndicationType type,
+                                         const V1_0::CdmaSmsMessage& msg) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->cdmaNewSms(toAidl(type), toAidl(msg));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaRuimSmsStorageFull(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->cdmaRuimSmsStorageFull(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::newBroadcastSms(V1_0::RadioIndicationType type,
+                                              const hidl_vec<uint8_t>& data) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->newBroadcastSms(toAidl(type), data);
+    return {};
+}
+
+Return<void> RadioIndication::newSms(V1_0::RadioIndicationType type, const hidl_vec<uint8_t>& pdu) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->newSms(toAidl(type), pdu);
+    return {};
+}
+
+Return<void> RadioIndication::newSmsOnSim(V1_0::RadioIndicationType type, int32_t recordNumber) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->newSmsOnSim(toAidl(type), recordNumber);
+    return {};
+}
+
+Return<void> RadioIndication::newSmsStatusReport(V1_0::RadioIndicationType type,
+                                                 const hidl_vec<uint8_t>& pdu) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->newSmsStatusReport(toAidl(type), pdu);
+    return {};
+}
+
+Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
+                                     const hidl_string& msg) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
+    return {};
+}
+
+Return<void> RadioIndication::simSmsStorageFull(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->simSmsStorageFull(toAidl(type));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
new file mode 100644
index 0000000..c1a82b5
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioMessaging.h>
+
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Messaging"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioMessaging::acknowledgeIncomingGsmSmsWithPdu(  //
+        int32_t serial, bool success, const std::string& ackPdu) {
+    LOG_CALL << serial << ' ' << success << ' ' << ackPdu;
+    mHal1_5->acknowledgeIncomingGsmSmsWithPdu(serial, success, ackPdu);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::acknowledgeLastIncomingCdmaSms(  //
+        int32_t serial, const aidl::CdmaSmsAck& smsAck) {
+    LOG_CALL << serial;
+    mHal1_5->acknowledgeLastIncomingCdmaSms(serial, toHidl(smsAck));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::acknowledgeLastIncomingGsmSms(  //
+        int32_t serial, bool success, aidl::SmsAcknowledgeFailCause cause) {
+    LOG_CALL << serial << ' ' << success;
+    mHal1_5->acknowledgeLastIncomingGsmSms(serial, success, V1_0::SmsAcknowledgeFailCause(cause));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::cancelPendingUssd(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->cancelPendingUssd(serial);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::deleteSmsOnRuim(int32_t serial, int32_t index) {
+    LOG_CALL << serial << ' ' << index;
+    mHal1_5->deleteSmsOnRuim(serial, index);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::deleteSmsOnSim(int32_t serial, int32_t index) {
+    LOG_CALL << serial << ' ' << index;
+    mHal1_5->deleteSmsOnSim(serial, index);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::getCdmaBroadcastConfig(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCdmaBroadcastConfig(serial);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::getGsmBroadcastConfig(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getGsmBroadcastConfig(serial);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::getSmscAddress(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getSmscAddress(serial);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::reportSmsMemoryStatus(int32_t serial, bool available) {
+    LOG_CALL << serial << ' ' << available;
+    mHal1_5->reportSmsMemoryStatus(serial, available);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendCdmaSms(int32_t serial, const aidl::CdmaSmsMessage& sms) {
+    LOG_CALL << serial;
+    mHal1_5->sendCdmaSms(serial, toHidl(sms));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendCdmaSmsExpectMore(int32_t serial, const aidl::CdmaSmsMessage& m) {
+    LOG_CALL << serial;
+    mHal1_5->sendCdmaSmsExpectMore(serial, toHidl(m));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendImsSms(int32_t serial, const aidl::ImsSmsMessage& message) {
+    LOG_CALL << serial;
+    mHal1_5->sendImsSms(serial, toHidl(message));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendSms(int32_t serial, const aidl::GsmSmsMessage& message) {
+    LOG_CALL << serial;
+    mHal1_5->sendSms(serial, toHidl(message));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendSmsExpectMore(int32_t serial, const aidl::GsmSmsMessage& msg) {
+    LOG_CALL << serial;
+    mHal1_5->sendSMSExpectMore(serial, toHidl(msg));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::sendUssd(int32_t serial, const std::string& ussd) {
+    LOG_CALL << serial << ' ' << ussd;
+    mHal1_5->sendUssd(serial, ussd);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setCdmaBroadcastActivation(int32_t serial, bool activate) {
+    LOG_CALL << serial << ' ' << activate;
+    mHal1_5->setCdmaBroadcastActivation(serial, activate);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setCdmaBroadcastConfig(
+        int32_t serial, const std::vector<aidl::CdmaBroadcastSmsConfigInfo>& cfgInfo) {
+    LOG_CALL << serial;
+    mHal1_5->setCdmaBroadcastConfig(serial, toHidl(cfgInfo));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setGsmBroadcastActivation(int32_t serial, bool activate) {
+    LOG_CALL << serial << ' ' << activate;
+    mHal1_5->setGsmBroadcastActivation(serial, activate);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setGsmBroadcastConfig(
+        int32_t serial, const std::vector<aidl::GsmBroadcastSmsConfigInfo>& configInfo) {
+    LOG_CALL << serial;
+    mHal1_5->setGsmBroadcastConfig(serial, toHidl(configInfo));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioMessagingResponse>& messagingResponse,
+        const std::shared_ptr<aidl::IRadioMessagingIndication>& messagingIndication) {
+    LOG_CALL << messagingResponse << ' ' << messagingIndication;
+
+    CHECK(messagingResponse);
+    CHECK(messagingIndication);
+
+    mRadioResponse->setResponseFunction(messagingResponse);
+    mRadioIndication->setResponseFunction(messagingIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::setSmscAddress(int32_t serial, const std::string& smsc) {
+    LOG_CALL << serial << ' ' << smsc;
+    mHal1_5->setSmscAddress(serial, smsc);
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::writeSmsToRuim(int32_t serial, const aidl::CdmaSmsWriteArgs& sms) {
+    LOG_CALL << serial;
+    mHal1_5->writeSmsToRuim(serial, toHidl(sms));
+    return ok();
+}
+
+ScopedAStatus RadioMessaging::writeSmsToSim(int32_t serial, const aidl::SmsWriteArgs& smsWrArgs) {
+    LOG_CALL << serial;
+    mHal1_5->writeSmsToSim(serial, toHidl(smsWrArgs));
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
new file mode 100644
index 0000000..379e463
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "MessagingResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingResponse> rmrCb) {
+    CHECK(rmrCb);
+    mMessagingCb = rmrCb;
+}
+
+Return<void> RadioResponse::acknowledgeIncomingGsmSmsWithPduResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->acknowledgeIncomingGsmSmsWithPduResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::acknowledgeLastIncomingCdmaSmsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->acknowledgeLastIncomingCdmaSmsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::acknowledgeLastIncomingGsmSmsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->acknowledgeLastIncomingGsmSmsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->cancelPendingUssdResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->deleteSmsOnRuimResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::deleteSmsOnSimResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->deleteSmsOnSimResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getCdmaBroadcastConfigResponse(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configs) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->getCdmaBroadcastConfigResponse(toAidl(info), toAidl(configs));
+    return {};
+}
+
+Return<void> RadioResponse::getGsmBroadcastConfigResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& cfg) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->getGsmBroadcastConfigResponse(toAidl(info), toAidl(cfg));
+    return {};
+}
+
+Return<void> RadioResponse::getSmscAddressResponse(const V1_0::RadioResponseInfo& info,
+                                                   const hidl_string& smsc) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->getSmscAddressResponse(toAidl(info), smsc);
+    return {};
+}
+
+Return<void> RadioResponse::reportSmsMemoryStatusResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->reportSmsMemoryStatusResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+                                                          const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                              const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                    const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendImsSmsResponse(const V1_0::RadioResponseInfo& info,
+                                               const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendImsSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendSMSExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+                                                      const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                          const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendSmsResponse(const V1_0::RadioResponseInfo& info,
+                                            const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                const V1_0::SendSmsResult& sms) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+    return {};
+}
+
+Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->sendUssdResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCdmaBroadcastActivationResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setCdmaBroadcastActivationResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setCdmaBroadcastConfigResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setGsmBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setGsmBroadcastActivationResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setGsmBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setGsmBroadcastConfigResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSmscAddressResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->setSmscAddressResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::writeSmsToRuimResponse(const V1_0::RadioResponseInfo& info,
+                                                   uint32_t index) {
+    LOG_CALL << info.serial << ' ' << index;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->writeSmsToRuimResponse(toAidl(info), index);
+    return {};
+}
+
+Return<void> RadioResponse::writeSmsToSimResponse(const V1_0::RadioResponseInfo& info,
+                                                  int32_t index) {
+    LOG_CALL << info.serial << ' ' << index;
+    CHECK_CB(mMessagingCb);
+    mMessagingCb->writeSmsToSimResponse(toAidl(info), index);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/structs.cpp b/radio/aidl/compat/libradiocompat/messaging/structs.cpp
new file mode 100644
index 0000000..9019680
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/structs.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "structs.h"
+
+#include "collections.h"
+
+#include <aidl/android/hardware/radio/messaging/CdmaSmsAddress.h>
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+
+V1_0::CdmaSmsAck toHidl(const aidl::CdmaSmsAck& smsAck) {
+    return {
+            .errorClass = (smsAck.errorClass ? V1_0::CdmaSmsErrorClass::ERROR
+                                             : V1_0::CdmaSmsErrorClass::NO_ERROR),
+            .smsCauseCode = smsAck.smsCauseCode,
+    };
+}
+
+static aidl::CdmaSmsAddress toAidl(const V1_0::CdmaSmsAddress& addr) {
+    return {
+            .digitMode = static_cast<int32_t>(addr.digitMode),
+            .isNumberModeDataNetwork = addr.numberMode == V1_0::CdmaSmsNumberMode::DATA_NETWORK,
+            .numberType = static_cast<int32_t>(addr.numberType),
+            .numberPlan = static_cast<int32_t>(addr.numberPlan),
+            .digits = addr.digits,
+    };
+}
+
+static V1_0::CdmaSmsAddress toHidl(const aidl::CdmaSmsAddress& addr) {
+    return {
+            .digitMode = V1_0::CdmaSmsDigitMode{addr.digitMode},
+            .numberMode = addr.isNumberModeDataNetwork ? V1_0::CdmaSmsNumberMode::DATA_NETWORK
+                                                       : V1_0::CdmaSmsNumberMode::NOT_DATA_NETWORK,
+            .numberType = V1_0::CdmaSmsNumberType{addr.numberType},
+            .numberPlan = V1_0::CdmaSmsNumberPlan{addr.numberPlan},
+            .digits = addr.digits,
+    };
+}
+
+static aidl::CdmaSmsSubaddress toAidl(const V1_0::CdmaSmsSubaddress& addr) {
+    return {
+            .subaddressType = static_cast<int32_t>(addr.subaddressType),
+            .odd = addr.odd,
+            .digits = addr.digits,
+    };
+}
+
+static V1_0::CdmaSmsSubaddress toHidl(const aidl::CdmaSmsSubaddress& addr) {
+    return {
+            .subaddressType = V1_0::CdmaSmsSubaddressType{addr.subaddressType},
+            .odd = addr.odd,
+            .digits = addr.digits,
+    };
+}
+
+::aidl::android::hardware::radio::messaging::CdmaSmsMessage toAidl(const V1_0::CdmaSmsMessage& m) {
+    return {
+            .teleserviceId = m.teleserviceId,
+            .isServicePresent = m.isServicePresent,
+            .serviceCategory = m.serviceCategory,
+            .address = toAidl(m.address),
+            .subAddress = toAidl(m.subAddress),
+            .bearerData = m.bearerData,
+    };
+}
+
+V1_0::CdmaSmsMessage toHidl(const aidl::CdmaSmsMessage& msg) {
+    return {
+            .teleserviceId = msg.teleserviceId,
+            .isServicePresent = msg.isServicePresent,
+            .serviceCategory = msg.serviceCategory,
+            .address = toHidl(msg.address),
+            .subAddress = toHidl(msg.subAddress),
+            .bearerData = msg.bearerData,
+    };
+}
+
+V1_0::ImsSmsMessage toHidl(const aidl::ImsSmsMessage& msg) {
+    return {
+            .tech = V1_0::RadioTechnologyFamily{msg.tech},
+            .retry = msg.retry,
+            .messageRef = msg.messageRef,
+            .cdmaMessage = toHidl(msg.cdmaMessage),
+            .gsmMessage = toHidl(msg.gsmMessage),
+    };
+}
+
+V1_0::GsmSmsMessage toHidl(const aidl::GsmSmsMessage& msg) {
+    return {
+            .smscPdu = msg.smscPdu,
+            .pdu = msg.pdu,
+    };
+}
+
+aidl::CdmaBroadcastSmsConfigInfo toAidl(const V1_0::CdmaBroadcastSmsConfigInfo& info) {
+    return {
+            .serviceCategory = info.serviceCategory,
+            .language = info.language,
+            .selected = info.selected,
+    };
+}
+
+V1_0::CdmaBroadcastSmsConfigInfo toHidl(const aidl::CdmaBroadcastSmsConfigInfo& info) {
+    return {
+            .serviceCategory = info.serviceCategory,
+            .language = info.language,
+            .selected = info.selected,
+    };
+}
+
+aidl::GsmBroadcastSmsConfigInfo toAidl(const V1_0::GsmBroadcastSmsConfigInfo& info) {
+    return {
+            .fromServiceId = info.fromServiceId,
+            .toServiceId = info.toServiceId,
+            .fromCodeScheme = info.fromCodeScheme,
+            .toCodeScheme = info.toCodeScheme,
+            .selected = info.selected,
+    };
+}
+
+V1_0::GsmBroadcastSmsConfigInfo toHidl(const aidl::GsmBroadcastSmsConfigInfo& info) {
+    return {
+            .fromServiceId = info.fromServiceId,
+            .toServiceId = info.toServiceId,
+            .fromCodeScheme = info.fromCodeScheme,
+            .toCodeScheme = info.toCodeScheme,
+            .selected = info.selected,
+    };
+}
+
+V1_0::CdmaSmsWriteArgs toHidl(const aidl::CdmaSmsWriteArgs& args) {
+    return {
+            .status = V1_0::CdmaSmsWriteArgsStatus{args.status},
+            .message = toHidl(args.message),
+    };
+}
+
+V1_0::SmsWriteArgs toHidl(const aidl::SmsWriteArgs& args) {
+    return {
+            .status = V1_0::SmsWriteArgsStatus{args.status},
+            .pdu = args.pdu,
+            .smsc = args.smsc,
+    };
+}
+
+::aidl::android::hardware::radio::messaging::SendSmsResult toAidl(
+        const V1_0::SendSmsResult& result) {
+    return {
+            .messageRef = result.messageRef,
+            .ackPDU = result.ackPDU,
+            .errorCode = result.errorCode,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/structs.h b/radio/aidl/compat/libradiocompat/messaging/structs.h
new file mode 100644
index 0000000..afb4941
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/structs.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.h>
+#include <aidl/android/hardware/radio/messaging/CdmaSmsAck.h>
+#include <aidl/android/hardware/radio/messaging/CdmaSmsMessage.h>
+#include <aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.h>
+#include <aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.h>
+#include <aidl/android/hardware/radio/messaging/GsmSmsMessage.h>
+#include <aidl/android/hardware/radio/messaging/ImsSmsMessage.h>
+#include <aidl/android/hardware/radio/messaging/SendSmsResult.h>
+#include <aidl/android/hardware/radio/messaging/SmsWriteArgs.h>
+#include <android/hardware/radio/1.0/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::CdmaSmsAck toHidl(const ::aidl::android::hardware::radio::messaging::CdmaSmsAck& ack);
+
+::aidl::android::hardware::radio::messaging::CdmaSmsMessage toAidl(const V1_0::CdmaSmsMessage& msg);
+V1_0::CdmaSmsMessage toHidl(const ::aidl::android::hardware::radio::messaging::CdmaSmsMessage& msg);
+
+V1_0::ImsSmsMessage toHidl(const ::aidl::android::hardware::radio::messaging::ImsSmsMessage& msg);
+
+V1_0::GsmSmsMessage toHidl(const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& msg);
+
+::aidl::android::hardware::radio::messaging::CdmaBroadcastSmsConfigInfo  //
+toAidl(const V1_0::CdmaBroadcastSmsConfigInfo& info);
+V1_0::CdmaBroadcastSmsConfigInfo  //
+toHidl(const ::aidl::android::hardware::radio::messaging::CdmaBroadcastSmsConfigInfo& info);
+
+::aidl::android::hardware::radio::messaging::GsmBroadcastSmsConfigInfo  //
+toAidl(const V1_0::GsmBroadcastSmsConfigInfo& info);
+V1_0::GsmBroadcastSmsConfigInfo  //
+toHidl(const ::aidl::android::hardware::radio::messaging::GsmBroadcastSmsConfigInfo& info);
+
+V1_0::CdmaSmsWriteArgs  //
+toHidl(const ::aidl::android::hardware::radio::messaging::CdmaSmsWriteArgs& args);
+
+V1_0::SmsWriteArgs toHidl(const ::aidl::android::hardware::radio::messaging::SmsWriteArgs& args);
+
+::aidl::android::hardware::radio::messaging::SendSmsResult toAidl(const V1_0::SendSmsResult& res);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
new file mode 100644
index 0000000..8fc4da6
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ModemIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::modem;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioModemIndication> modemCb) {
+    CHECK(modemCb);
+    mModemCb = modemCb;
+}
+
+Return<void> RadioIndication::hardwareConfigChanged(V1_0::RadioIndicationType type,
+                                                    const hidl_vec<V1_0::HardwareConfig>& configs) {
+    LOG_CALL << type;
+    CHECK_CB(mModemCb);
+    mModemCb->hardwareConfigChanged(toAidl(type), toAidl(configs));
+    return {};
+}
+
+Return<void> RadioIndication::modemReset(V1_0::RadioIndicationType type, const hidl_string& reasn) {
+    LOG_CALL << type;
+    CHECK_CB(mModemCb);
+    mModemCb->modemReset(toAidl(type), reasn);
+    return {};
+}
+
+Return<void> RadioIndication::radioCapabilityIndication(V1_0::RadioIndicationType type,
+                                                        const V1_0::RadioCapability& rc) {
+    LOG_CALL << type;
+    CHECK_CB(mModemCb);
+    mModemCb->radioCapabilityIndication(toAidl(type), toAidl(rc));
+    return {};
+}
+
+Return<void> RadioIndication::radioStateChanged(V1_0::RadioIndicationType t, V1_0::RadioState st) {
+    LOG_CALL << t;
+    CHECK_CB(mModemCb);
+    mModemCb->radioStateChanged(toAidl(t), aidl::RadioState(st));
+    return {};
+}
+
+Return<void> RadioIndication::rilConnected(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mModemCb);
+    mModemCb->rilConnected(toAidl(type));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
new file mode 100644
index 0000000..660ae9f
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioModem.h>
+
+#include "debug.h"
+#include "structs.h"
+
+#define RADIO_MODULE "Modem"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::modem;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioModem::enableModem(int32_t serial, bool on) {
+    LOG_CALL << serial;
+    mHal1_5->enableModem(serial, on);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getBasebandVersion(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getBasebandVersion(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getDeviceIdentity(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getDeviceIdentity(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getHardwareConfig(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getHardwareConfig(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getModemActivityInfo(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getModemActivityInfo(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getModemStackStatus(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getModemStackStatus(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::getRadioCapability(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getRadioCapability(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::nvReadItem(int32_t serial, aidl::NvItem itemId) {
+    LOG_CALL << serial;
+    mHal1_5->nvReadItem(serial, V1_0::NvItem(itemId));
+    return ok();
+}
+
+ScopedAStatus RadioModem::nvResetConfig(int32_t serial, aidl::ResetNvType resetType) {
+    LOG_CALL << serial;
+    mHal1_5->nvResetConfig(serial, V1_0::ResetNvType(resetType));
+    return ok();
+}
+
+ScopedAStatus RadioModem::nvWriteCdmaPrl(int32_t serial, const std::vector<uint8_t>& prl) {
+    LOG_CALL << serial;
+    mHal1_5->nvWriteCdmaPrl(serial, prl);
+    return ok();
+}
+
+ScopedAStatus RadioModem::nvWriteItem(int32_t serial, const aidl::NvWriteItem& item) {
+    LOG_CALL << serial;
+    mHal1_5->nvWriteItem(serial, toHidl(item));
+    return ok();
+}
+
+ScopedAStatus RadioModem::requestShutdown(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->requestShutdown(serial);
+    return ok();
+}
+
+ScopedAStatus RadioModem::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioModem::sendDeviceState(int32_t serial, aidl::DeviceStateType type, bool state) {
+    LOG_CALL << serial;
+    mHal1_5->sendDeviceState(serial, V1_0::DeviceStateType(type), state);
+    return ok();
+}
+
+ScopedAStatus RadioModem::setRadioCapability(int32_t serial, const aidl::RadioCapability& rc) {
+    LOG_CALL << serial;
+    mHal1_5->setRadioCapability(serial, toHidl(rc));
+    return ok();
+}
+
+ScopedAStatus RadioModem::setRadioPower(int32_t serial, bool powerOn, bool forEmergencyCall,
+                                        bool preferredForEmergencyCall) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setRadioPower_1_6(serial, powerOn, forEmergencyCall, preferredForEmergencyCall);
+    } else {
+        mHal1_5->setRadioPower_1_5(serial, powerOn, forEmergencyCall, preferredForEmergencyCall);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioModem::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioModemResponse>& modemResponse,
+        const std::shared_ptr<aidl::IRadioModemIndication>& modemIndication) {
+    LOG_CALL << modemResponse << ' ' << modemIndication;
+
+    CHECK(modemResponse);
+    CHECK(modemIndication);
+
+    mRadioResponse->setResponseFunction(modemResponse);
+    mRadioIndication->setResponseFunction(modemIndication);
+
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
new file mode 100644
index 0000000..300627c
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ModemResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::modem;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioModemResponse> modemCb) {
+    CHECK(modemCb);
+    mModemCb = modemCb;
+}
+
+Return<void> RadioResponse::enableModemResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->enableModemResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getBasebandVersionResponse(const V1_0::RadioResponseInfo& info,
+                                                       const hidl_string& version) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getBasebandVersionResponse(toAidl(info), version);
+    return {};
+}
+
+Return<void> RadioResponse::getDeviceIdentityResponse(  //
+        const V1_0::RadioResponseInfo& info, const hidl_string& imei, const hidl_string& imeisv,
+        const hidl_string& esn, const hidl_string& meid) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getDeviceIdentityResponse(toAidl(info), imei, imeisv, esn, meid);
+    return {};
+}
+
+Return<void> RadioResponse::getHardwareConfigResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::HardwareConfig>& config) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getHardwareConfigResponse(toAidl(info), toAidl(config));
+    return {};
+}
+
+Return<void> RadioResponse::getModemActivityInfoResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::ActivityStatsInfo& activityInfo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getModemActivityInfoResponse(toAidl(info), toAidl(activityInfo));
+    return {};
+}
+
+Return<void> RadioResponse::getModemStackStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                        bool isEnabled) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getModemStackStatusResponse(toAidl(info), isEnabled);
+    return {};
+}
+
+Return<void> RadioResponse::getRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                                       const V1_0::RadioCapability& rc) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->getRadioCapabilityResponse(toAidl(info), toAidl(rc));
+    return {};
+}
+
+Return<void> RadioResponse::nvReadItemResponse(const V1_0::RadioResponseInfo& info,
+                                               const hidl_string& result) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->nvReadItemResponse(toAidl(info), result);
+    return {};
+}
+
+Return<void> RadioResponse::nvResetConfigResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->nvResetConfigResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::nvWriteCdmaPrlResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->nvWriteCdmaPrlResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::nvWriteItemResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->nvWriteItemResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::requestShutdownResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->requestShutdownResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendDeviceStateResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->sendDeviceStateResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                                       const V1_0::RadioCapability& rc) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->setRadioCapabilityResponse(toAidl(info), toAidl(rc));
+    return {};
+}
+
+Return<void> RadioResponse::setRadioPowerResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->setRadioPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setRadioPowerResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->setRadioPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setRadioPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mModemCb);
+    mModemCb->setRadioPowerResponse(toAidl(info));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.cpp b/radio/aidl/compat/libradiocompat/modem/structs.cpp
new file mode 100644
index 0000000..c1cd64c
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/structs.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioAccessFamily;
+using ::aidl::android::hardware::radio::RadioTechnology;
+namespace aidl = ::aidl::android::hardware::radio::modem;
+
+V1_0::NvWriteItem toHidl(const aidl::NvWriteItem& item) {
+    return {
+            .itemId = V1_0::NvItem{item.itemId},
+            .value = item.value,
+    };
+}
+
+aidl::RadioCapability toAidl(const V1_0::RadioCapability& capa) {
+    return {
+            .session = capa.session,
+            .phase = static_cast<int32_t>(capa.phase),
+            .raf = RadioAccessFamily(capa.raf),
+            .logicalModemUuid = capa.logicalModemUuid,
+            .status = static_cast<int32_t>(capa.status),
+    };
+}
+
+V1_0::RadioCapability toHidl(const aidl::RadioCapability& capa) {
+    return {
+            .session = capa.session,
+            .phase = V1_0::RadioCapabilityPhase{capa.phase},
+            .raf = toHidlBitfield<V1_0::RadioAccessFamily>(capa.raf),
+            .logicalModemUuid = capa.logicalModemUuid,
+            .status = V1_0::RadioCapabilityStatus{capa.status},
+    };
+}
+
+aidl::HardwareConfig toAidl(const V1_0::HardwareConfig& config) {
+    return {
+            .type = static_cast<int32_t>(config.type),
+            .uuid = config.uuid,
+            .state = static_cast<int32_t>(config.state),
+            .modem = toAidl(config.modem),
+            .sim = toAidl(config.sim),
+    };
+}
+
+aidl::HardwareConfigModem toAidl(const V1_0::HardwareConfigModem& modem) {
+    return {
+            .rilModel = modem.rilModel,
+            .rat = RadioTechnology(modem.rat),
+            .maxVoiceCalls = modem.maxVoice,
+            .maxDataCalls = modem.maxData,
+            .maxStandby = modem.maxStandby,
+    };
+}
+
+aidl::HardwareConfigSim toAidl(const V1_0::HardwareConfigSim& sim) {
+    return {
+            .modemUuid = sim.modemUuid,
+    };
+}
+
+aidl::ActivityStatsInfo toAidl(const V1_0::ActivityStatsInfo& info) {
+    return {
+            .sleepModeTimeMs = static_cast<int32_t>(info.sleepModeTimeMs),
+            .idleModeTimeMs = static_cast<int32_t>(info.idleModeTimeMs),
+            .txmModetimeMs = toAidl(info.txmModetimeMs),
+            .rxModeTimeMs = static_cast<int32_t>(info.rxModeTimeMs),
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.h b/radio/aidl/compat/libradiocompat/modem/structs.h
new file mode 100644
index 0000000..3ac1edb
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/structs.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/modem/ActivityStatsInfo.h>
+#include <aidl/android/hardware/radio/modem/HardwareConfig.h>
+#include <aidl/android/hardware/radio/modem/HardwareConfigModem.h>
+#include <aidl/android/hardware/radio/modem/HardwareConfigSim.h>
+#include <aidl/android/hardware/radio/modem/NvWriteItem.h>
+#include <aidl/android/hardware/radio/modem/RadioCapability.h>
+#include <android/hardware/radio/1.0/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::NvWriteItem toHidl(const ::aidl::android::hardware::radio::modem::NvWriteItem& item);
+
+::aidl::android::hardware::radio::modem::RadioCapability toAidl(const V1_0::RadioCapability& capa);
+V1_0::RadioCapability toHidl(const ::aidl::android::hardware::radio::modem::RadioCapability& capa);
+
+::aidl::android::hardware::radio::modem::HardwareConfig toAidl(const V1_0::HardwareConfig& config);
+
+::aidl::android::hardware::radio::modem::HardwareConfigModem  //
+toAidl(const V1_0::HardwareConfigModem& modem);
+
+::aidl::android::hardware::radio::modem::HardwareConfigSim toAidl(const V1_0::HardwareConfigSim& s);
+
+::aidl::android::hardware::radio::modem::ActivityStatsInfo toAidl(const V1_0::ActivityStatsInfo& i);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
new file mode 100644
index 0000000..899b133
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "NetworkIndication"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioTechnology;
+namespace aidl = ::aidl::android::hardware::radio::network;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkIndication> netCb) {
+    CHECK(netCb);
+    mNetworkCb = netCb;
+}
+
+Return<void> RadioIndication::barringInfoChanged(V1_0::RadioIndicationType type,
+                                                 const V1_5::CellIdentity& cellIdentity,
+                                                 const hidl_vec<V1_5::BarringInfo>& barringInfos) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->barringInfoChanged(toAidl(type), toAidl(cellIdentity), toAidl(barringInfos));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaPrlChanged(V1_0::RadioIndicationType type, int32_t version) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->cdmaPrlChanged(toAidl(type), version);
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList(V1_0::RadioIndicationType type,
+                                           const hidl_vec<V1_0::CellInfo>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_2(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_2::CellInfo>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_4(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_4::CellInfo>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_5(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_5::CellInfo>& records) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+    return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_6(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_6::CellInfo>& records) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+    return {};
+}
+
+Return<void> RadioIndication::currentLinkCapacityEstimate(V1_0::RadioIndicationType type,
+                                                          const V1_2::LinkCapacityEstimate& lce) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+    return {};
+}
+
+Return<void> RadioIndication::currentLinkCapacityEstimate_1_6(
+        V1_0::RadioIndicationType type, const V1_6::LinkCapacityEstimate& lce) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+    return {};
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_2::PhysicalChannelConfig>&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs_1_4(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_4::PhysicalChannelConfig>& configs) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+    return {};
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs_1_6(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_6::PhysicalChannelConfig>& configs) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+    return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength(V1_0::RadioIndicationType type,
+                                                    const V1_0::SignalStrength&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_2(V1_0::RadioIndicationType type,
+                                                        const V1_2::SignalStrength&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_4(
+        V1_0::RadioIndicationType type, const V1_4::SignalStrength& signalStrength) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+    return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_6(
+        V1_0::RadioIndicationType type, const V1_6::SignalStrength& signalStrength) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+    return {};
+}
+
+Return<void> RadioIndication::imsNetworkStateChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->imsNetworkStateChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult(V1_0::RadioIndicationType type,
+                                                const V1_1::NetworkScanResult&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_2(V1_0::RadioIndicationType type,
+                                                    const V1_2::NetworkScanResult&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_4(V1_0::RadioIndicationType type,
+                                                    const V1_4::NetworkScanResult&) {
+    LOG_CALL << type;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_5(V1_0::RadioIndicationType type,
+                                                    const V1_5::NetworkScanResult& result) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+    return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_6(V1_0::RadioIndicationType type,
+                                                    const V1_6::NetworkScanResult& result) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+    return {};
+}
+
+Return<void> RadioIndication::networkStateChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->networkStateChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::nitzTimeReceived(V1_0::RadioIndicationType type,
+                                               const hidl_string& nitzTime, uint64_t receivedTime) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->nitzTimeReceived(toAidl(type), nitzTime, receivedTime, 0);
+    return {};
+}
+
+Return<void> RadioIndication::registrationFailed(  //
+        V1_0::RadioIndicationType type, const V1_5::CellIdentity& cellIdentity,
+        const hidl_string& chosenPlmn, hidl_bitfield<V1_5::Domain> domain, int32_t causeCode,
+        int32_t additionalCauseCode) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->registrationFailed(toAidl(type), toAidl(cellIdentity), chosenPlmn,
+                                   aidl::Domain(domain), causeCode, additionalCauseCode);
+    return {};
+}
+
+Return<void> RadioIndication::restrictedStateChanged(V1_0::RadioIndicationType type,
+                                                     V1_0::PhoneRestrictedState state) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->restrictedStateChanged(toAidl(type), aidl::PhoneRestrictedState(state));
+    return {};
+}
+
+Return<void> RadioIndication::suppSvcNotify(V1_0::RadioIndicationType type,
+                                            const V1_0::SuppSvcNotification& suppSvc) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->suppSvcNotify(toAidl(type), toAidl(suppSvc));
+    return {};
+}
+
+Return<void> RadioIndication::voiceRadioTechChanged(V1_0::RadioIndicationType type,
+                                                    V1_0::RadioTechnology rat) {
+    LOG_CALL << type;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->voiceRadioTechChanged(toAidl(type), RadioTechnology(rat));
+    return {};
+}
+
+Return<void> RadioIndication::lceData(V1_0::RadioIndicationType type, const V1_0::LceDataInfo&) {
+    LOG_CALL << type;
+    LOG(WARNING) << "lceData indication is deprecated";
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
new file mode 100644
index 0000000..af0bc46
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioNetwork.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+#include "utils.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Network"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::AccessNetwork;
+using ::aidl::android::hardware::radio::RadioAccessFamily;
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::network;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioNetwork::getAllowedNetworkTypesBitmap(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getAllowedNetworkTypesBitmap(serial);
+    } else {
+        mHal1_5->getPreferredNetworkType(serial);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getAvailableBandModes(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getAvailableBandModes(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getAvailableNetworks(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getAvailableNetworks(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getBarringInfo(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getBarringInfo(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getCdmaRoamingPreference(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCdmaRoamingPreference(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getCellInfoList(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCellInfoList(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getDataRegistrationState(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getDataRegistrationState(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getImsRegistrationState(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getImsRegistrationState(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getNetworkSelectionMode(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getNetworkSelectionMode(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getOperator(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getOperator(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getSignalStrength(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getSignalStrength(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getSystemSelectionChannels(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getSystemSelectionChannels(serial);
+    } else {
+        respond().getSystemSelectionChannelsResponse(notSupported(serial), {});
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getVoiceRadioTechnology(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getVoiceRadioTechnology(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getVoiceRegistrationState(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getVoiceRegistrationState(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::isNrDualConnectivityEnabled(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->isNrDualConnectivityEnabled(serial);
+    } else {
+        respond().isNrDualConnectivityEnabledResponse(notSupported(serial), false);
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setAllowedNetworkTypesBitmap(int32_t serial, RadioAccessFamily ntype) {
+    LOG_CALL << serial;
+    const auto raf = toHidlBitfield<V1_4::RadioAccessFamily>(ntype);
+    if (mHal1_6) {
+        mHal1_6->setAllowedNetworkTypesBitmap(serial, raf);
+    } else {
+        mHal1_5->setPreferredNetworkType(serial, getNetworkTypeFromRaf(raf));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setBandMode(int32_t serial, aidl::RadioBandMode mode) {
+    LOG_CALL << serial;
+    mHal1_5->setBandMode(serial, V1_0::RadioBandMode(mode));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setBarringPassword(int32_t serial, const std::string& facility,
+                                               const std::string& oldPw, const std::string& newPw) {
+    LOG_CALL << serial;
+    mHal1_5->setBarringPassword(serial, facility, oldPw, newPw);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setCdmaRoamingPreference(int32_t serial, aidl::CdmaRoamingType type) {
+    LOG_CALL << serial;
+    mHal1_5->setCdmaRoamingPreference(serial, V1_0::CdmaRoamingType(type));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setCellInfoListRate(int32_t serial, int32_t rate) {
+    LOG_CALL << serial;
+    mHal1_5->setCellInfoListRate(serial, rate);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setIndicationFilter(int32_t serial, aidl::IndicationFilter indFilter) {
+    LOG_CALL << serial;
+    mHal1_5->setIndicationFilter(serial, toHidlBitfield<V1_0::IndicationFilter>(indFilter));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setLinkCapacityReportingCriteria(  //
+        int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps, int32_t hysteresisUlKbps,
+        const std::vector<int32_t>& thrDownlinkKbps, const std::vector<int32_t>& thrUplinkKbps,
+        AccessNetwork accessNetwork) {
+    LOG_CALL << serial;
+    mHal1_5->setLinkCapacityReportingCriteria(  //
+            serial, hysteresisMs, hysteresisDlKbps, hysteresisUlKbps, thrDownlinkKbps,
+            thrUplinkKbps, V1_2::AccessNetwork(accessNetwork));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setLocationUpdates(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->setLocationUpdates(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setNetworkSelectionModeAutomatic(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->setNetworkSelectionModeAutomatic(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setNetworkSelectionModeManual(  //
+        int32_t serial, const std::string& opNumeric, AccessNetwork ran) {
+    LOG_CALL << serial;
+    mHal1_5->setNetworkSelectionModeManual_1_5(serial, opNumeric, V1_5::RadioAccessNetworks(ran));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setNrDualConnectivityState(int32_t serial,
+                                                       aidl::NrDualConnectivityState st) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setNrDualConnectivityState(serial, V1_6::NrDualConnectivityState(st));
+    } else {
+        respond().setNrDualConnectivityStateResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioNetworkResponse>& networkResponse,
+        const std::shared_ptr<aidl::IRadioNetworkIndication>& networkIndication) {
+    LOG_CALL << networkResponse << ' ' << networkIndication;
+
+    CHECK(networkResponse);
+    CHECK(networkIndication);
+
+    mRadioResponse->setResponseFunction(networkResponse);
+    mRadioIndication->setResponseFunction(networkIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setSignalStrengthReportingCriteria(
+        int32_t serial, const std::vector<aidl::SignalThresholdInfo>& infos) {
+    LOG_CALL << serial;
+    // TODO(b/203699028): how about other infos?
+    mHal1_5->setSignalStrengthReportingCriteria_1_5(serial, toHidl(infos[0]),
+                                                    V1_5::AccessNetwork(infos[0].ran));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setSuppServiceNotifications(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->setSuppServiceNotifications(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setSystemSelectionChannels(  //
+        int32_t serial, bool specifyCh, const std::vector<aidl::RadioAccessSpecifier>& specifiers) {
+    LOG_CALL << serial;
+    mHal1_5->setSystemSelectionChannels_1_5(serial, specifyCh, toHidl(specifiers));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::startNetworkScan(int32_t serial, const aidl::NetworkScanRequest& req) {
+    LOG_CALL << serial;
+    mHal1_5->startNetworkScan_1_5(serial, toHidl(req));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::stopNetworkScan(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->stopNetworkScan(serial);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::supplyNetworkDepersonalization(int32_t ser, const std::string& nPin) {
+    LOG_CALL << ser;
+    mHal1_5->supplyNetworkDepersonalization(ser, nPin);
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
new file mode 100644
index 0000000..81f7775
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+#include "utils.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "NetworkResponse"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioAccessFamily;
+using ::aidl::android::hardware::radio::RadioTechnology;
+using ::aidl::android::hardware::radio::RadioTechnologyFamily;
+namespace aidl = ::aidl::android::hardware::radio::network;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkResponse> netCb) {
+    CHECK(netCb);
+    mNetworkCb = netCb;
+}
+
+Return<void> RadioResponse::getAllowedNetworkTypesBitmapResponse(
+        const V1_6::RadioResponseInfo& info,
+        hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getAllowedNetworkTypesBitmapResponse(toAidl(info),
+                                                     RadioAccessFamily(networkTypeBitmap));
+    return {};
+}
+
+Return<void> RadioResponse::getPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info,
+                                                            V1_0::PreferredNetworkType nwType) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getAllowedNetworkTypesBitmapResponse(  //
+            toAidl(info), RadioAccessFamily(getRafFromNetworkType(nwType)));
+    return {};
+}
+
+Return<void> RadioResponse::getPreferredNetworkTypeBitmapResponse(
+        const V1_0::RadioResponseInfo& info, hidl_bitfield<V1_4::RadioAccessFamily>) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getAvailableBandModesResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::RadioBandMode>& bandModes) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getAvailableBandModesResponse(toAidl(info), toAidl(bandModes));
+    return {};
+}
+
+Return<void> RadioResponse::getAvailableNetworksResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::OperatorInfo>& networkInfos) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getAvailableNetworksResponse(toAidl(info), toAidl(networkInfos));
+    return {};
+}
+
+Return<void> RadioResponse::getBarringInfoResponse(
+        const V1_0::RadioResponseInfo& info, const V1_5::CellIdentity& cellIdentity,
+        const hidl_vec<V1_5::BarringInfo>& barringInfos) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getBarringInfoResponse(toAidl(info), toAidl(cellIdentity), toAidl(barringInfos));
+    return {};
+}
+
+Return<void> RadioResponse::getCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info,
+                                                             V1_0::CdmaRoamingType type) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getCdmaRoamingPreferenceResponse(toAidl(info), aidl::CdmaRoamingType(type));
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse(const V1_0::RadioResponseInfo& info,
+                                                    const hidl_vec<V1_0::CellInfo>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_2::CellInfo>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_4::CellInfo>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_5::CellInfo>& cellInfo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+    return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_6::CellInfo>& cellInfo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+                                                             const V1_0::DataRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_2(
+        const V1_0::RadioResponseInfo& info, const V1_2::DataRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const V1_4::DataRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_5(
+        const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& dataRegResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_6(
+        const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& dataRegResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getImsRegistrationStateResponse(  //
+        const V1_0::RadioResponseInfo& info, bool isRegd, V1_0::RadioTechnologyFamily ratFamily) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getImsRegistrationStateResponse(toAidl(info), isRegd,
+                                                RadioTechnologyFamily(ratFamily));
+    return {};
+}
+
+Return<void> RadioResponse::getNeighboringCidsResponse(const V1_0::RadioResponseInfo& info,
+                                                       const hidl_vec<V1_0::NeighboringCell>&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "getNeighboringCidsResponse is not supposed to be called";
+    return {};
+}
+
+Return<void> RadioResponse::getNetworkSelectionModeResponse(const V1_0::RadioResponseInfo& info,
+                                                            bool manual) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getNetworkSelectionModeResponse(toAidl(info), manual);
+    return {};
+}
+
+Return<void> RadioResponse::getOperatorResponse(  //
+        const V1_0::RadioResponseInfo& info, const hidl_string& longName,
+        const hidl_string& shortName, const hidl_string& numeric) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getOperatorResponse(toAidl(info), longName, shortName, numeric);
+    return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse(const V1_0::RadioResponseInfo& info,
+                                                      const V1_0::SignalStrength&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                          const V1_2::SignalStrength&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const V1_4::SignalStrength& signalStrength) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+    return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_6(
+        const V1_6::RadioResponseInfo& info, const V1_6::SignalStrength& signalStrength) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+    return {};
+}
+
+Return<void> RadioResponse::getSystemSelectionChannelsResponse(
+        const V1_6::RadioResponseInfo& info,
+        const hidl_vec<V1_5::RadioAccessSpecifier>& specifiers) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getSystemSelectionChannelsResponse(toAidl(info), toAidl(specifiers));
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRadioTechnologyResponse(const V1_0::RadioResponseInfo& info,
+                                                            V1_0::RadioTechnology rat) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getVoiceRadioTechnologyResponse(toAidl(info), RadioTechnology(rat));
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+                                                              const V1_0::VoiceRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.0 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_2(
+        const V1_0::RadioResponseInfo& info, const V1_2::VoiceRegStateResult&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.2 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_5(
+        const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& voiceRegResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+    return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_6(
+        const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& voiceRegResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+    return {};
+}
+
+Return<void> RadioResponse::isNrDualConnectivityEnabledResponse(const V1_6::RadioResponseInfo& info,
+                                                                bool isEnabled) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->isNrDualConnectivityEnabledResponse(toAidl(info), isEnabled);
+    return {};
+}
+
+Return<void> RadioResponse::pullLceDataResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::LceDataInfo&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "pullLceDataResponse is not supposed to be called";
+    return {};
+}
+
+Return<void> RadioResponse::setAllowedNetworkTypesBitmapResponse(const V1_6::RadioResponseInfo& i) {
+    LOG_CALL << i.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(i));
+    return {};
+}
+
+Return<void> RadioResponse::setPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setPreferredNetworkTypeBitmapResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "IRadio HAL 1.4 not supported";
+    return {};
+}
+
+Return<void> RadioResponse::setBandModeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setBandModeResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setBarringPasswordResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setBarringPasswordResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setCdmaRoamingPreferenceResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCellInfoListRateResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setCellInfoListRateResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setIndicationFilterResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setIndicationFilterResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setIndicationFilterResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setIndicationFilterResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse_1_5(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setLocationUpdatesResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setLocationUpdatesResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeAutomaticResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setNetworkSelectionModeAutomaticResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeManualResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeManualResponse_1_5(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setNrDualConnectivityStateResponse(
+        const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setNrDualConnectivityStateResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse_1_5(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSuppServiceNotificationsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSuppServiceNotificationsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSystemSelectionChannelsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSystemSelectionChannelsResponse_1_5(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startNetworkScanResponse_1_4(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startNetworkScanResponse_1_5(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::stopNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->stopNetworkScanResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::supplyNetworkDepersonalizationResponse(
+        const V1_0::RadioResponseInfo& info, int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mNetworkCb);
+    mNetworkCb->supplyNetworkDepersonalizationResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::startLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                                    const V1_0::LceStatusInfo&) {
+    LOG_CALL << info.serial;
+    LOG(WARNING) << "startLceServiceResponse is deprecated";
+    return {};
+}
+
+Return<void> RadioResponse::stopLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                                   const V1_0::LceStatusInfo&) {
+    LOG_CALL << info.serial;
+    LOG(WARNING) << "stopLceServiceResponse is deprecated";
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/structs.cpp b/radio/aidl/compat/libradiocompat/network/structs.cpp
new file mode 100644
index 0000000..87a021f
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/structs.cpp
@@ -0,0 +1,668 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::network;
+using ::aidl::android::hardware::radio::AccessNetwork;
+using ::aidl::android::hardware::radio::RadioTechnology;
+
+aidl::RadioBandMode toAidl(V1_0::RadioBandMode mode) {
+    return aidl::RadioBandMode(mode);
+}
+
+aidl::GeranBands toAidl(V1_1::GeranBands band) {
+    return aidl::GeranBands(band);
+}
+
+V1_1::GeranBands toHidl(aidl::GeranBands band) {
+    return V1_1::GeranBands(band);
+}
+
+aidl::UtranBands toAidl(V1_5::UtranBands band) {
+    return aidl::UtranBands(band);
+}
+
+V1_5::UtranBands toHidl(aidl::UtranBands band) {
+    return V1_5::UtranBands(band);
+}
+
+aidl::EutranBands toAidl(V1_5::EutranBands band) {
+    return aidl::EutranBands(band);
+}
+
+V1_5::EutranBands toHidl(aidl::EutranBands band) {
+    return V1_5::EutranBands(band);
+}
+
+aidl::NgranBands toAidl(V1_5::NgranBands band) {
+    return aidl::NgranBands(band);
+}
+
+V1_5::NgranBands toHidl(aidl::NgranBands band) {
+    return V1_5::NgranBands(band);
+}
+
+V1_5::SignalThresholdInfo toHidl(const aidl::SignalThresholdInfo& info) {
+    return {
+            .signalMeasurement = V1_5::SignalMeasurementType{info.signalMeasurement},
+            .hysteresisMs = info.hysteresisMs,
+            .hysteresisDb = info.hysteresisDb,
+            .thresholds = info.thresholds,
+            .isEnabled = info.isEnabled,
+    };
+}
+
+static aidl::RadioAccessSpecifierBands toAidl(const V1_5::RadioAccessSpecifier::Bands& bands) {
+    using Discr = V1_5::RadioAccessSpecifier::Bands::hidl_discriminator;
+    const auto discr = bands.getDiscriminator();
+
+    if (discr == Discr::geranBands) return toAidl(bands.geranBands());
+    if (discr == Discr::utranBands) return toAidl(bands.utranBands());
+    if (discr == Discr::eutranBands) return toAidl(bands.eutranBands());
+    if (discr == Discr::ngranBands) return toAidl(bands.ngranBands());
+
+    return {};
+}
+
+static V1_5::RadioAccessSpecifier::Bands toHidl(const aidl::RadioAccessSpecifierBands& bands) {
+    V1_5::RadioAccessSpecifier::Bands hidl;
+    using Tag = aidl::RadioAccessSpecifierBands::Tag;
+
+    if (bands.getTag() == Tag::geranBands) hidl.geranBands(toHidl(bands.get<Tag::geranBands>()));
+    if (bands.getTag() == Tag::utranBands) hidl.utranBands(toHidl(bands.get<Tag::utranBands>()));
+    if (bands.getTag() == Tag::eutranBands) hidl.eutranBands(toHidl(bands.get<Tag::eutranBands>()));
+    if (bands.getTag() == Tag::ngranBands) hidl.ngranBands(toHidl(bands.get<Tag::ngranBands>()));
+
+    return hidl;
+}
+
+aidl::RadioAccessSpecifier toAidl(const V1_5::RadioAccessSpecifier& spec) {
+    return {
+            .accessNetwork = AccessNetwork(spec.radioAccessNetwork),
+            .bands = toAidl(spec.bands),
+            .channels = spec.channels,
+    };
+}
+
+V1_5::RadioAccessSpecifier toHidl(const aidl::RadioAccessSpecifier& spec) {
+    return {
+            .radioAccessNetwork = V1_5::RadioAccessNetworks{spec.accessNetwork},
+            .bands = toHidl(spec.bands),
+            .channels = spec.channels,
+    };
+}
+
+V1_5::NetworkScanRequest toHidl(const aidl::NetworkScanRequest& req) {
+    return {
+            .type = V1_1::ScanType{req.type},
+            .interval = req.interval,
+            .specifiers = toHidl(req.specifiers),
+            .maxSearchTime = req.maxSearchTime,
+            .incrementalResults = req.incrementalResults,
+            .incrementalResultsPeriodicity = req.incrementalResultsPeriodicity,
+            .mccMncs = toHidl(req.mccMncs),
+    };
+}
+
+static aidl::OperatorInfo toAidl(const V1_2::CellIdentityOperatorNames& names) {
+    return {
+            .alphaLong = names.alphaLong,
+            .alphaShort = names.alphaShort,
+            .operatorNumeric = "",
+            .status = aidl::OperatorInfo::STATUS_UNKNOWN,
+    };
+}
+
+static aidl::CellIdentityGsm toAidl(const V1_5::CellIdentityGsm& ci) {
+    return {
+            .mcc = ci.base.base.mcc,
+            .mnc = ci.base.base.mnc,
+            .lac = ci.base.base.lac,
+            .cid = ci.base.base.cid,
+            .arfcn = ci.base.base.arfcn,
+            .bsic = static_cast<int8_t>(ci.base.base.bsic),
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+    };
+}
+
+aidl::ClosedSubscriberGroupInfo toAidl(const V1_5::ClosedSubscriberGroupInfo& info) {
+    return {
+            .csgIndication = info.csgIndication,
+            .homeNodebName = info.homeNodebName,
+            .csgIdentity = info.csgIdentity,
+    };
+}
+
+static std::optional<aidl::ClosedSubscriberGroupInfo> toAidl(const V1_5::OptionalCsgInfo& opt) {
+    using descr = V1_5::OptionalCsgInfo::hidl_discriminator;
+    if (opt.getDiscriminator() == descr::noinit) return std::nullopt;
+    return toAidl(opt.csgInfo());
+}
+
+static aidl::CellIdentityWcdma toAidl(const V1_5::CellIdentityWcdma& ci) {
+    return {
+            .mcc = ci.base.base.mcc,
+            .mnc = ci.base.base.mnc,
+            .lac = ci.base.base.lac,
+            .cid = ci.base.base.cid,
+            .psc = ci.base.base.psc,
+            .uarfcn = ci.base.base.uarfcn,
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+            .csgInfo = toAidl(ci.optionalCsgInfo),
+    };
+}
+
+static aidl::CellIdentityTdscdma toAidl(const V1_5::CellIdentityTdscdma& ci) {
+    return {
+            .mcc = ci.base.base.mcc,
+            .mnc = ci.base.base.mnc,
+            .lac = ci.base.base.lac,
+            .cid = ci.base.base.cid,
+            .cpid = ci.base.base.cpid,
+            .uarfcn = ci.base.uarfcn,
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+            .csgInfo = toAidl(ci.optionalCsgInfo),
+    };
+}
+
+static aidl::CellIdentityCdma toAidl(const V1_2::CellIdentityCdma& ci) {
+    return {
+            .networkId = ci.base.networkId,
+            .systemId = ci.base.systemId,
+            .baseStationId = ci.base.baseStationId,
+            .longitude = ci.base.longitude,
+            .latitude = ci.base.latitude,
+            .operatorNames = toAidl(ci.operatorNames),
+    };
+}
+
+static aidl::CellIdentityLte toAidl(const V1_5::CellIdentityLte& ci) {
+    return {
+            .mcc = ci.base.base.mcc,
+            .mnc = ci.base.base.mnc,
+            .ci = ci.base.base.ci,
+            .pci = ci.base.base.pci,
+            .tac = ci.base.base.tac,
+            .earfcn = ci.base.base.earfcn,
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .bandwidth = ci.base.bandwidth,
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+            .csgInfo = toAidl(ci.optionalCsgInfo),
+            .bands = toAidl(ci.bands),
+    };
+}
+
+static aidl::CellIdentityNr toAidl(const V1_5::CellIdentityNr& ci) {
+    return {
+            .mcc = ci.base.mcc,
+            .mnc = ci.base.mnc,
+            .nci = static_cast<int64_t>(ci.base.nci),
+            .pci = static_cast<int32_t>(ci.base.pci),
+            .tac = ci.base.tac,
+            .nrarfcn = ci.base.nrarfcn,
+            .operatorNames = toAidl(ci.base.operatorNames),
+            .additionalPlmns = toAidl(ci.additionalPlmns),
+            .bands = toAidl(ci.bands),
+    };
+}
+
+aidl::CellIdentity toAidl(const V1_5::CellIdentity& ci) {
+    using Discr = V1_5::CellIdentity::hidl_discriminator;
+    const auto discr = ci.getDiscriminator();
+
+    if (discr == Discr::gsm) return toAidl(ci.gsm());
+    if (discr == Discr::wcdma) return toAidl(ci.wcdma());
+    if (discr == Discr::tdscdma) return toAidl(ci.tdscdma());
+    if (discr == Discr::cdma) return toAidl(ci.cdma());
+    if (discr == Discr::lte) return toAidl(ci.lte());
+    if (discr == Discr::nr) return toAidl(ci.nr());
+
+    return {};
+}
+
+static std::optional<aidl::BarringTypeSpecificInfo>  //
+toAidl(const V1_5::BarringInfo::BarringTypeSpecificInfo& opt) {
+    using discr = V1_5::BarringInfo::BarringTypeSpecificInfo::hidl_discriminator;
+    if (opt.getDiscriminator() == discr::noinit) return std::nullopt;
+
+    const auto& info = opt.conditional();
+    return aidl::BarringTypeSpecificInfo{
+            .factor = info.factor,
+            .timeSeconds = info.timeSeconds,
+            .isBarred = info.isBarred,
+    };
+}
+
+aidl::BarringInfo toAidl(const V1_5::BarringInfo& info) {
+    return {
+            .serviceType = static_cast<int32_t>(info.serviceType),
+            .barringType = static_cast<int32_t>(info.barringType),
+            .barringTypeSpecificInfo = toAidl(info.barringTypeSpecificInfo),
+    };
+}
+
+static aidl::GsmSignalStrength toAidl(const V1_0::GsmSignalStrength& sig) {
+    return {
+            .signalStrength = static_cast<int32_t>(sig.signalStrength),
+            .bitErrorRate = static_cast<int32_t>(sig.bitErrorRate),
+            .timingAdvance = sig.timingAdvance,
+    };
+}
+
+static aidl::CellInfoGsm toAidl(const V1_5::CellInfoGsm& info) {
+    return {
+            .cellIdentityGsm = toAidl(info.cellIdentityGsm),
+            .signalStrengthGsm = toAidl(info.signalStrengthGsm),
+    };
+}
+
+static aidl::WcdmaSignalStrength toAidl(const V1_2::WcdmaSignalStrength& sig) {
+    return {
+            .signalStrength = sig.base.signalStrength,
+            .bitErrorRate = sig.base.bitErrorRate,
+            .rscp = static_cast<int32_t>(sig.rscp),
+            .ecno = static_cast<int32_t>(sig.ecno),
+    };
+}
+
+static aidl::CellInfoWcdma toAidl(const V1_5::CellInfoWcdma& info) {
+    return {
+            .cellIdentityWcdma = toAidl(info.cellIdentityWcdma),
+            .signalStrengthWcdma = toAidl(info.signalStrengthWcdma),
+    };
+}
+
+static aidl::TdscdmaSignalStrength toAidl(const V1_2::TdscdmaSignalStrength& sig) {
+    return {
+            .signalStrength = static_cast<int32_t>(sig.signalStrength),
+            .bitErrorRate = static_cast<int32_t>(sig.bitErrorRate),
+            .rscp = static_cast<int32_t>(sig.rscp),
+    };
+}
+
+static aidl::CellInfoTdscdma toAidl(const V1_5::CellInfoTdscdma& info) {
+    return {
+            .cellIdentityTdscdma = toAidl(info.cellIdentityTdscdma),
+            .signalStrengthTdscdma = toAidl(info.signalStrengthTdscdma),
+    };
+}
+
+static aidl::LteSignalStrength toAidl(const V1_6::LteSignalStrength& sig) {
+    return {
+            .signalStrength = static_cast<int32_t>(sig.base.signalStrength),
+            .rsrp = static_cast<int32_t>(sig.base.rsrp),
+            .rsrq = static_cast<int32_t>(sig.base.rsrq),
+            .rssnr = sig.base.rssnr,
+            .cqi = static_cast<int32_t>(sig.base.cqi),
+            .timingAdvance = static_cast<int32_t>(sig.base.timingAdvance),
+            .cqiTableIndex = static_cast<int32_t>(sig.cqiTableIndex),
+    };
+}
+
+static aidl::LteSignalStrength toAidl(const V1_0::LteSignalStrength& sig) {
+    return toAidl({sig, 0});
+}
+
+static aidl::CellInfoLte toAidl(const V1_5::CellInfoLte& info) {
+    return {
+            .cellIdentityLte = toAidl(info.cellIdentityLte),
+            .signalStrengthLte = toAidl(info.signalStrengthLte),
+    };
+}
+
+static aidl::CellInfoLte toAidl(const V1_6::CellInfoLte& info) {
+    return {
+            .cellIdentityLte = toAidl(info.cellIdentityLte),
+            .signalStrengthLte = toAidl(info.signalStrengthLte),
+    };
+}
+
+static aidl::NrSignalStrength toAidl(const V1_6::NrSignalStrength& sig) {
+    return {
+            .ssRsrp = sig.base.ssRsrp,
+            .ssRsrq = sig.base.ssRsrq,
+            .ssSinr = sig.base.ssSinr,
+            .csiRsrp = sig.base.csiRsrp,
+            .csiRsrq = sig.base.csiRsrq,
+            .csiSinr = sig.base.csiSinr,
+            .csiCqiTableIndex = static_cast<int32_t>(sig.csiCqiTableIndex),
+            .csiCqiReport = sig.csiCqiReport,
+    };
+}
+
+static aidl::NrSignalStrength toAidl(const V1_4::NrSignalStrength& sig) {
+    return toAidl({sig, 0, 0});
+}
+
+static aidl::CellInfoNr toAidl(const V1_5::CellInfoNr& info) {
+    return {
+            .cellIdentityNr = toAidl(info.cellIdentityNr),
+            .signalStrengthNr = toAidl(info.signalStrengthNr),
+    };
+}
+
+static aidl::CellInfoNr toAidl(const V1_6::CellInfoNr& info) {
+    return {
+            .cellIdentityNr = toAidl(info.cellIdentityNr),
+            .signalStrengthNr = toAidl(info.signalStrengthNr),
+    };
+}
+
+static aidl::CdmaSignalStrength toAidl(const V1_0::CdmaSignalStrength& sig) {
+    return {
+            .dbm = static_cast<int32_t>(sig.dbm),
+            .ecio = static_cast<int32_t>(sig.ecio),
+    };
+}
+
+static aidl::EvdoSignalStrength toAidl(const V1_0::EvdoSignalStrength& sig) {
+    return {
+            .dbm = static_cast<int32_t>(sig.dbm),
+            .ecio = static_cast<int32_t>(sig.ecio),
+            .signalNoiseRatio = static_cast<int32_t>(sig.signalNoiseRatio),
+    };
+}
+
+static aidl::CellInfoCdma toAidl(const V1_2::CellInfoCdma& info) {
+    return {
+            .cellIdentityCdma = toAidl(info.cellIdentityCdma),
+            .signalStrengthCdma = toAidl(info.signalStrengthCdma),
+            .signalStrengthEvdo = toAidl(info.signalStrengthEvdo),
+    };
+}
+
+static aidl::CellInfoRatSpecificInfo toAidl(const V1_5::CellInfo::CellInfoRatSpecificInfo& ci) {
+    using Discr = V1_5::CellInfo::CellInfoRatSpecificInfo::hidl_discriminator;
+    const auto discr = ci.getDiscriminator();
+
+    if (discr == Discr::gsm) return toAidl(ci.gsm());
+    if (discr == Discr::wcdma) return toAidl(ci.wcdma());
+    if (discr == Discr::tdscdma) return toAidl(ci.tdscdma());
+    if (discr == Discr::lte) return toAidl(ci.lte());
+    if (discr == Discr::nr) return toAidl(ci.nr());
+    if (discr == Discr::cdma) return toAidl(ci.cdma());
+
+    return {};
+}
+
+static aidl::CellInfoRatSpecificInfo toAidl(const V1_6::CellInfo::CellInfoRatSpecificInfo& ci) {
+    using Discr = V1_6::CellInfo::CellInfoRatSpecificInfo::hidl_discriminator;
+    const auto discr = ci.getDiscriminator();
+
+    if (discr == Discr::gsm) return toAidl(ci.gsm());
+    if (discr == Discr::wcdma) return toAidl(ci.wcdma());
+    if (discr == Discr::tdscdma) return toAidl(ci.tdscdma());
+    if (discr == Discr::lte) return toAidl(ci.lte());
+    if (discr == Discr::nr) return toAidl(ci.nr());
+    if (discr == Discr::cdma) return toAidl(ci.cdma());
+
+    return {};
+}
+
+aidl::CellInfo toAidl(const V1_5::CellInfo& info) {
+    return {
+            .registered = info.registered,
+            // ignored: timeStampType and timeStamp
+            .connectionStatus = aidl::CellConnectionStatus(info.connectionStatus),
+            .ratSpecificInfo = toAidl(info.ratSpecificInfo),
+    };
+}
+
+aidl::CellInfo toAidl(const V1_6::CellInfo& info) {
+    return {
+            .registered = info.registered,
+            .connectionStatus = aidl::CellConnectionStatus(info.connectionStatus),
+            .ratSpecificInfo = toAidl(info.ratSpecificInfo),
+    };
+}
+
+aidl::LinkCapacityEstimate toAidl(const V1_2::LinkCapacityEstimate& e) {
+    return {
+            .downlinkCapacityKbps = static_cast<int32_t>(e.downlinkCapacityKbps),
+            .uplinkCapacityKbps = static_cast<int32_t>(e.uplinkCapacityKbps),
+    };
+}
+
+aidl::LinkCapacityEstimate toAidl(const V1_6::LinkCapacityEstimate& e) {
+    return {
+            .downlinkCapacityKbps = static_cast<int32_t>(e.downlinkCapacityKbps),
+            .uplinkCapacityKbps = static_cast<int32_t>(e.uplinkCapacityKbps),
+            .secondaryDownlinkCapacityKbps = static_cast<int32_t>(e.secondaryDownlinkCapacityKbps),
+            .secondaryUplinkCapacityKbps = static_cast<int32_t>(e.secondaryUplinkCapacityKbps),
+    };
+}
+
+static aidl::PhysicalChannelConfigBand toAidl(const V1_6::PhysicalChannelConfig::Band& band) {
+    using Discr = V1_6::PhysicalChannelConfig::Band::hidl_discriminator;
+    const auto discr = band.getDiscriminator();
+
+    if (discr == Discr::geranBand) return aidl::GeranBands(band.geranBand());
+    if (discr == Discr::utranBand) return aidl::UtranBands(band.utranBand());
+    if (discr == Discr::eutranBand) return aidl::EutranBands(band.eutranBand());
+    if (discr == Discr::ngranBand) return aidl::NgranBands(band.ngranBand());
+
+    return {};
+}
+
+aidl::PhysicalChannelConfig toAidl(const V1_4::PhysicalChannelConfig& cfg) {
+    int32_t downlinkChannelNumber = 0;
+    // ignored rfInfo.range
+    using Discr = V1_4::RadioFrequencyInfo::hidl_discriminator;
+    if (cfg.rfInfo.getDiscriminator() == Discr::channelNumber) {
+        downlinkChannelNumber = cfg.rfInfo.channelNumber();
+    }
+
+    return {
+            .status = aidl::CellConnectionStatus(cfg.base.status),
+            .rat = RadioTechnology(cfg.rat),
+            .downlinkChannelNumber = downlinkChannelNumber,
+            .cellBandwidthDownlinkKhz = cfg.base.cellBandwidthDownlink,
+            .contextIds = cfg.contextIds,
+            .physicalCellId = static_cast<int32_t>(cfg.physicalCellId),
+    };
+}
+
+aidl::PhysicalChannelConfig toAidl(const V1_6::PhysicalChannelConfig& cfg) {
+    return {
+            .status = aidl::CellConnectionStatus(cfg.status),
+            .rat = RadioTechnology(cfg.rat),
+            .downlinkChannelNumber = cfg.downlinkChannelNumber,
+            .uplinkChannelNumber = cfg.uplinkChannelNumber,
+            .cellBandwidthDownlinkKhz = cfg.cellBandwidthDownlinkKhz,
+            .cellBandwidthUplinkKhz = cfg.cellBandwidthUplinkKhz,
+            .contextIds = cfg.contextIds,
+            .physicalCellId = static_cast<int32_t>(cfg.physicalCellId),
+            .band = toAidl(cfg.band),
+    };
+}
+
+aidl::SignalStrength toAidl(const V1_4::SignalStrength& sig) {
+    return {
+            .gsm = toAidl(sig.gsm),
+            .cdma = toAidl(sig.cdma),
+            .evdo = toAidl(sig.evdo),
+            .lte = toAidl(sig.lte),
+            .tdscdma = toAidl(sig.tdscdma),
+            .wcdma = toAidl(sig.wcdma),
+            .nr = toAidl(sig.nr),
+    };
+}
+
+aidl::SignalStrength toAidl(const V1_6::SignalStrength& sig) {
+    return {
+            .gsm = toAidl(sig.gsm),
+            .cdma = toAidl(sig.cdma),
+            .evdo = toAidl(sig.evdo),
+            .lte = toAidl(sig.lte),
+            .tdscdma = toAidl(sig.tdscdma),
+            .wcdma = toAidl(sig.wcdma),
+            .nr = toAidl(sig.nr),
+    };
+}
+
+aidl::NetworkScanResult toAidl(const V1_5::NetworkScanResult& res) {
+    return {
+            .status = static_cast<int32_t>(res.status),
+            .error = toAidl(res.error),
+            .networkInfos = toAidl(res.networkInfos),
+    };
+}
+
+aidl::NetworkScanResult toAidl(const V1_6::NetworkScanResult& res) {
+    return {
+            .status = static_cast<int32_t>(res.status),
+            .error = toAidl(res.error),
+            .networkInfos = toAidl(res.networkInfos),
+    };
+}
+
+aidl::SuppSvcNotification toAidl(const V1_0::SuppSvcNotification& svc) {
+    return {
+            .isMT = svc.isMT,
+            .code = svc.code,
+            .index = svc.index,
+            .type = svc.type,
+            .number = svc.number,
+    };
+}
+
+aidl::OperatorInfo toAidl(const V1_0::OperatorInfo& info) {
+    return {
+            .alphaLong = info.alphaLong,
+            .alphaShort = info.alphaShort,
+            .operatorNumeric = info.operatorNumeric,
+            .status = static_cast<int32_t>(info.status),
+    };
+}
+
+static aidl::Cdma2000RegistrationInfo  //
+toAidl(const V1_5::RegStateResult::AccessTechnologySpecificInfo::Cdma2000RegistrationInfo& info) {
+    return {
+            .cssSupported = info.cssSupported,
+            .roamingIndicator = info.roamingIndicator,
+            .systemIsInPrl = static_cast<int32_t>(info.systemIsInPrl),
+            .defaultRoamingIndicator = info.defaultRoamingIndicator,
+    };
+}
+
+static aidl::LteVopsInfo toAidl(const V1_4::LteVopsInfo& info) {
+    return {
+            .isVopsSupported = info.isVopsSupported,
+            .isEmcBearerSupported = info.isEmcBearerSupported,
+    };
+}
+
+static aidl::NrIndicators toAidl(const V1_4::NrIndicators& info) {
+    return {
+            .isEndcAvailable = info.isEndcAvailable,
+            .isDcNrRestricted = info.isDcNrRestricted,
+            .isNrAvailable = info.isNrAvailable,
+    };
+}
+
+static aidl::EutranRegistrationInfo  //
+toAidl(const V1_5::RegStateResult::AccessTechnologySpecificInfo::EutranRegistrationInfo& info) {
+    return {
+            .lteVopsInfo = toAidl(info.lteVopsInfo),
+            .nrIndicators = toAidl(info.nrIndicators),
+    };
+}
+
+static aidl::NrVopsInfo toAidl(const V1_6::NrVopsInfo& info) {
+    return {
+            .vopsSupported = static_cast<int8_t>(info.vopsSupported),
+            .emcSupported = static_cast<int8_t>(info.emcSupported),
+            .emfSupported = static_cast<int8_t>(info.emfSupported),
+    };
+}
+
+static aidl::AccessTechnologySpecificInfo  //
+toAidl(const V1_5::RegStateResult::AccessTechnologySpecificInfo& info) {
+    using Discr = V1_5::RegStateResult::AccessTechnologySpecificInfo::hidl_discriminator;
+    const auto discr = info.getDiscriminator();
+
+    if (discr == Discr::cdmaInfo) return toAidl(info.cdmaInfo());
+    if (discr == Discr::eutranInfo) return toAidl(info.eutranInfo());
+
+    return {};
+}
+
+static aidl::AccessTechnologySpecificInfo  //
+toAidl(const V1_6::RegStateResult::AccessTechnologySpecificInfo& info) {
+    using Discr = V1_6::RegStateResult::AccessTechnologySpecificInfo::hidl_discriminator;
+    const auto discr = info.getDiscriminator();
+
+    if (discr == Discr::cdmaInfo) return toAidl(info.cdmaInfo());
+    if (discr == Discr::eutranInfo) return toAidl(info.eutranInfo());
+    if (discr == Discr::ngranNrVopsInfo) return toAidl(info.ngranNrVopsInfo());
+    if (discr == Discr::geranDtmSupported) {
+        using T = aidl::AccessTechnologySpecificInfo;
+        return T::make<T::Tag::geranDtmSupported>(info.geranDtmSupported());
+    }
+
+    return {};
+}
+
+aidl::RegStateResult toAidl(const V1_5::RegStateResult& res) {
+    return {
+            .regState = aidl::RegState(res.regState),
+            .rat = RadioTechnology(res.rat),
+            .reasonForDenial = aidl::RegistrationFailCause(res.reasonForDenial),
+            .cellIdentity = toAidl(res.cellIdentity),
+            .registeredPlmn = res.registeredPlmn,
+            .accessTechnologySpecificInfo = toAidl(res.accessTechnologySpecificInfo),
+    };
+}
+
+aidl::RegStateResult toAidl(const V1_6::RegStateResult& res) {
+    return {
+            .regState = aidl::RegState(res.regState),
+            .rat = RadioTechnology(res.rat),
+            .reasonForDenial = aidl::RegistrationFailCause(res.reasonForDenial),
+            .cellIdentity = toAidl(res.cellIdentity),
+            .registeredPlmn = res.registeredPlmn,
+            .accessTechnologySpecificInfo = toAidl(res.accessTechnologySpecificInfo),
+    };
+}
+
+aidl::NeighboringCell toAidl(const V1_0::NeighboringCell& cell) {
+    return {
+            .cid = cell.cid,
+            .rssi = cell.rssi,
+    };
+}
+
+aidl::LceDataInfo toAidl(const V1_0::LceDataInfo& info) {
+    return {
+            .lastHopCapacityKbps = static_cast<int32_t>(info.lastHopCapacityKbps),
+            .confidenceLevel = static_cast<int8_t>(info.confidenceLevel),
+            .lceSuspended = info.lceSuspended,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/structs.h b/radio/aidl/compat/libradiocompat/network/structs.h
new file mode 100644
index 0000000..854cb38
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/structs.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/network/BarringInfo.h>
+#include <aidl/android/hardware/radio/network/CellIdentity.h>
+#include <aidl/android/hardware/radio/network/CellInfo.h>
+#include <aidl/android/hardware/radio/network/LceDataInfo.h>
+#include <aidl/android/hardware/radio/network/LinkCapacityEstimate.h>
+#include <aidl/android/hardware/radio/network/NeighboringCell.h>
+#include <aidl/android/hardware/radio/network/NetworkScanRequest.h>
+#include <aidl/android/hardware/radio/network/NetworkScanResult.h>
+#include <aidl/android/hardware/radio/network/OperatorInfo.h>
+#include <aidl/android/hardware/radio/network/PhysicalChannelConfig.h>
+#include <aidl/android/hardware/radio/network/RadioAccessSpecifier.h>
+#include <aidl/android/hardware/radio/network/RadioBandMode.h>
+#include <aidl/android/hardware/radio/network/RegStateResult.h>
+#include <aidl/android/hardware/radio/network/SignalStrength.h>
+#include <aidl/android/hardware/radio/network/SignalThresholdInfo.h>
+#include <aidl/android/hardware/radio/network/SuppSvcNotification.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+::aidl::android::hardware::radio::network::RadioBandMode toAidl(V1_0::RadioBandMode mode);
+::aidl::android::hardware::radio::network::GeranBands toAidl(V1_1::GeranBands band);
+V1_1::GeranBands toHidl(::aidl::android::hardware::radio::network::GeranBands band);
+::aidl::android::hardware::radio::network::UtranBands toAidl(V1_5::UtranBands band);
+V1_5::UtranBands toHidl(::aidl::android::hardware::radio::network::UtranBands band);
+::aidl::android::hardware::radio::network::EutranBands toAidl(V1_5::EutranBands band);
+V1_5::EutranBands toHidl(::aidl::android::hardware::radio::network::EutranBands band);
+::aidl::android::hardware::radio::network::NgranBands toAidl(V1_5::NgranBands band);
+V1_5::NgranBands toHidl(::aidl::android::hardware::radio::network::NgranBands band);
+
+V1_5::SignalThresholdInfo  //
+toHidl(const ::aidl::android::hardware::radio::network::SignalThresholdInfo& info);
+
+::aidl::android::hardware::radio::network::RadioAccessSpecifier  //
+toAidl(const V1_5::RadioAccessSpecifier& spec);
+V1_5::RadioAccessSpecifier  //
+toHidl(const ::aidl::android::hardware::radio::network::RadioAccessSpecifier& spec);
+
+V1_5::NetworkScanRequest  //
+toHidl(const ::aidl::android::hardware::radio::network::NetworkScanRequest& req);
+
+::aidl::android::hardware::radio::network::CellIdentity toAidl(const V1_5::CellIdentity& ci);
+
+::aidl::android::hardware::radio::network::BarringInfo toAidl(const V1_5::BarringInfo& info);
+
+::aidl::android::hardware::radio::network::ClosedSubscriberGroupInfo  //
+toAidl(const V1_5::ClosedSubscriberGroupInfo& info);
+
+::aidl::android::hardware::radio::network::CellInfo toAidl(const V1_5::CellInfo& info);
+::aidl::android::hardware::radio::network::CellInfo toAidl(const V1_6::CellInfo& info);
+
+::aidl::android::hardware::radio::network::LinkCapacityEstimate  //
+toAidl(const V1_2::LinkCapacityEstimate& lce);
+::aidl::android::hardware::radio::network::LinkCapacityEstimate  //
+toAidl(const V1_6::LinkCapacityEstimate& lce);
+
+::aidl::android::hardware::radio::network::PhysicalChannelConfig  //
+toAidl(const V1_4::PhysicalChannelConfig& cfg);
+::aidl::android::hardware::radio::network::PhysicalChannelConfig  //
+toAidl(const V1_6::PhysicalChannelConfig& cfg);
+
+::aidl::android::hardware::radio::network::SignalStrength toAidl(const V1_4::SignalStrength& sig);
+::aidl::android::hardware::radio::network::SignalStrength toAidl(const V1_6::SignalStrength& sig);
+
+::aidl::android::hardware::radio::network::NetworkScanResult  //
+toAidl(const V1_5::NetworkScanResult& res);
+::aidl::android::hardware::radio::network::NetworkScanResult  //
+toAidl(const V1_6::NetworkScanResult& res);
+
+::aidl::android::hardware::radio::network::SuppSvcNotification  //
+toAidl(const V1_0::SuppSvcNotification& svc);
+
+::aidl::android::hardware::radio::network::OperatorInfo toAidl(const V1_0::OperatorInfo& info);
+
+::aidl::android::hardware::radio::network::RegStateResult toAidl(const V1_5::RegStateResult& res);
+::aidl::android::hardware::radio::network::RegStateResult toAidl(const V1_6::RegStateResult& res);
+
+::aidl::android::hardware::radio::network::NeighboringCell toAidl(const V1_0::NeighboringCell& c);
+
+::aidl::android::hardware::radio::network::LceDataInfo toAidl(const V1_0::LceDataInfo& info);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/utils.cpp b/radio/aidl/compat/libradiocompat/network/utils.cpp
new file mode 100644
index 0000000..6fe3e6e
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/utils.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "utils.h"
+
+namespace android::hardware::radio::compat {
+
+namespace RAF {
+using E = V1_4::RadioAccessFamily;
+constexpr auto GSM = E::GSM | E::GPRS;
+constexpr auto CDMA = E::IS95A | E::IS95B | E::ONE_X_RTT;
+constexpr auto EVDO = E::EVDO_0 | E::EVDO_A | E::EVDO_B | E::EHRPD;
+constexpr auto HS = E::HSUPA | E::HSDPA | E::HSPA | E::HSPAP;
+constexpr auto WCDMA = HS | E::UMTS;
+constexpr auto LTE = E::LTE | E::LTE_CA;
+constexpr auto NR = E::NR;
+}  // namespace RAF
+
+static hidl_bitfield<V1_4::RadioAccessFamily>  //
+getAdjustedRaf(hidl_bitfield<V1_4::RadioAccessFamily> raf) {
+    if (raf & RAF::GSM) raf |= RAF::GSM;
+    if (raf & RAF::WCDMA) raf |= RAF::WCDMA;
+    if (raf & RAF::CDMA) raf |= RAF::CDMA;
+    if (raf & RAF::EVDO) raf |= RAF::EVDO;
+    if (raf & RAF::LTE) raf |= RAF::LTE;
+    if (raf & RAF::NR) raf |= RAF::NR;
+
+    return raf;
+}
+
+V1_0::PreferredNetworkType getNetworkTypeFromRaf(hidl_bitfield<V1_4::RadioAccessFamily> raf) {
+    raf = getAdjustedRaf(raf);
+    switch (raf) {
+        case RAF::GSM | RAF::WCDMA:
+            return V1_0::PreferredNetworkType::GSM_WCDMA_AUTO;
+        case RAF::GSM:
+            return V1_0::PreferredNetworkType::GSM_ONLY;
+        case RAF::WCDMA:
+            return V1_0::PreferredNetworkType::WCDMA;
+        case (RAF::CDMA | RAF::EVDO):
+            return V1_0::PreferredNetworkType::CDMA_EVDO_AUTO;
+        case (RAF::LTE | RAF::CDMA | RAF::EVDO):
+            return V1_0::PreferredNetworkType::LTE_CDMA_EVDO;
+        case (RAF::LTE | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::LTE_GSM_WCDMA;
+        case (RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA;  // CDMA typo
+        case RAF::LTE:
+            return V1_0::PreferredNetworkType::LTE_ONLY;
+        case (RAF::LTE | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::LTE_WCDMA;
+        case RAF::CDMA:
+            return V1_0::PreferredNetworkType::CDMA_ONLY;
+        case RAF::EVDO:
+            return V1_0::PreferredNetworkType::EVDO_ONLY;
+        case (RAF::GSM | RAF::WCDMA | RAF::CDMA | RAF::EVDO):
+            return V1_0::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO;
+        case static_cast<int>(RAF::E::TD_SCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_ONLY;
+        case (RAF::E::TD_SCDMA | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_WCDMA;
+        case (RAF::LTE | RAF::E::TD_SCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_LTE;
+        case (RAF::E::TD_SCDMA | RAF::GSM):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM;
+        case (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM_LTE;
+        case (RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA;
+        case (RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_WCDMA_LTE;
+        case (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE;
+        case (RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO;
+        case (RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType::TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA;
+        case static_cast<int>(RAF::NR):
+            return V1_0::PreferredNetworkType(23);  //  NR_ONLY
+        case (RAF::NR | RAF::LTE):
+            return V1_0::PreferredNetworkType(24);  //  NR_LTE
+        case (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO):
+            return V1_0::PreferredNetworkType(25);  //  NR_LTE_CDMA_EVDO
+        case (RAF::NR | RAF::LTE | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(26);  //  NR_LTE_GSM_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(27);  //  NR_LTE_CDMA_EVDO_GSM_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(28);  //  NR_LTE_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA):
+            return V1_0::PreferredNetworkType(29);  //  NR_LTE_TDSCDMA
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM):
+            return V1_0::PreferredNetworkType(30);  //  NR_LTE_TDSCDMA_GSM
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(31);  //  NR_LTE_TDSCDMA_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA):
+            return V1_0::PreferredNetworkType(32);  //  NR_LTE_TDSCDMA_GSM_WCDMA
+        case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM |
+              RAF::WCDMA):
+            return V1_0::PreferredNetworkType(33);  //  NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
+        default:
+            return V1_0::PreferredNetworkType::WCDMA;
+    }
+}
+
+hidl_bitfield<V1_4::RadioAccessFamily> getRafFromNetworkType(V1_0::PreferredNetworkType type) {
+    switch (type) {
+        case V1_0::PreferredNetworkType::GSM_WCDMA_AUTO:
+            return RAF::GSM | RAF::WCDMA;
+        case V1_0::PreferredNetworkType::GSM_ONLY:
+            return RAF::GSM;
+        case V1_0::PreferredNetworkType::WCDMA:
+            return RAF::WCDMA;
+        case V1_0::PreferredNetworkType::CDMA_EVDO_AUTO:
+            return (RAF::CDMA | RAF::EVDO);
+        case V1_0::PreferredNetworkType::LTE_CDMA_EVDO:
+            return (RAF::LTE | RAF::CDMA | RAF::EVDO);
+        case V1_0::PreferredNetworkType::LTE_GSM_WCDMA:
+            return (RAF::LTE | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA:
+            return (RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::LTE_ONLY:
+            return RAF::LTE;
+        case V1_0::PreferredNetworkType::LTE_WCDMA:
+            return (RAF::LTE | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::CDMA_ONLY:
+            return RAF::CDMA;
+        case V1_0::PreferredNetworkType::EVDO_ONLY:
+            return RAF::EVDO;
+        case V1_0::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO:
+            return (RAF::GSM | RAF::WCDMA | RAF::CDMA | RAF::EVDO);
+        case V1_0::PreferredNetworkType::TD_SCDMA_ONLY:
+            return static_cast<int>(RAF::E::TD_SCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_WCDMA:
+            return (RAF::E::TD_SCDMA | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_LTE:
+            return (RAF::LTE | RAF::E::TD_SCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM:
+            return (RAF::E::TD_SCDMA | RAF::GSM);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_LTE:
+            return (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA:
+            return (RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_WCDMA_LTE:
+            return (RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE:
+            return (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO:
+            return (RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType::TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA:
+            return (RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch"
+        case V1_0::PreferredNetworkType(23):  //  NR_ONLY
+            return static_cast<int>(RAF::NR);
+        case V1_0::PreferredNetworkType(24):  //  NR_LTE
+            return (RAF::NR | RAF::LTE);
+        case V1_0::PreferredNetworkType(25):  //  NR_LTE_CDMA_EVDO
+            return (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO);
+        case V1_0::PreferredNetworkType(26):  //  NR_LTE_GSM_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(27):  //  NR_LTE_CDMA_EVDO_GSM_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(28):  //  NR_LTE_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(29):  //  NR_LTE_TDSCDMA
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA);
+        case V1_0::PreferredNetworkType(30):  //  NR_LTE_TDSCDMA_GSM
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM);
+        case V1_0::PreferredNetworkType(31):  //  NR_LTE_TDSCDMA_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(32):  //  NR_LTE_TDSCDMA_GSM_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA);
+        case V1_0::PreferredNetworkType(33):  //  NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
+            return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM |
+                    RAF::WCDMA);
+#pragma GCC diagnostic pop
+        default:
+            return {};  // unknown
+    }
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/utils.h b/radio/aidl/compat/libradiocompat/network/utils.h
new file mode 100644
index 0000000..10714be
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/utils.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <android/hardware/radio/1.4/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::PreferredNetworkType getNetworkTypeFromRaf(hidl_bitfield<V1_4::RadioAccessFamily> raf);
+hidl_bitfield<V1_4::RadioAccessFamily> getRafFromNetworkType(V1_0::PreferredNetworkType type);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
new file mode 100644
index 0000000..6b906c6
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "SimIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sim;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioSimIndication> simCb) {
+    CHECK(simCb);
+    mSimCb = simCb;
+}
+
+Return<void> RadioIndication::carrierInfoForImsiEncryption(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->carrierInfoForImsiEncryption(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaSubscriptionSourceChanged(
+        V1_0::RadioIndicationType type, V1_0::CdmaSubscriptionSource cdmaSource) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->cdmaSubscriptionSourceChanged(toAidl(type), aidl::CdmaSubscriptionSource(cdmaSource));
+    return {};
+}
+
+Return<void> RadioIndication::simPhonebookChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->simPhonebookChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::simPhonebookRecordsReceived(
+        V1_0::RadioIndicationType type, V1_6::PbReceivedStatus status,
+        const hidl_vec<V1_6::PhonebookRecordInfo>& rec) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->simPhonebookRecordsReceived(toAidl(type), aidl::PbReceivedStatus(status), toAidl(rec));
+    return {};
+}
+
+Return<void> RadioIndication::simRefresh(V1_0::RadioIndicationType type,
+                                         const V1_0::SimRefreshResult& refreshResult) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->simRefresh(toAidl(type), toAidl(refreshResult));
+    return {};
+}
+
+Return<void> RadioIndication::simStatusChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->simStatusChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::stkEventNotify(V1_0::RadioIndicationType type,
+                                             const hidl_string& cmd) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->stkEventNotify(toAidl(type), cmd);
+    return {};
+}
+
+Return<void> RadioIndication::stkProactiveCommand(V1_0::RadioIndicationType type,
+                                                  const hidl_string& cmd) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->stkProactiveCommand(toAidl(type), cmd);
+    return {};
+}
+
+Return<void> RadioIndication::stkSessionEnd(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->stkSessionEnd(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::subscriptionStatusChanged(V1_0::RadioIndicationType type,
+                                                        bool activate) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->subscriptionStatusChanged(toAidl(type), activate);
+    return {};
+}
+
+Return<void> RadioIndication::uiccApplicationsEnablementChanged(V1_0::RadioIndicationType type,
+                                                                bool enabled) {
+    LOG_CALL << type;
+    CHECK_CB(mSimCb);
+    mSimCb->uiccApplicationsEnablementChanged(toAidl(type), enabled);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
new file mode 100644
index 0000000..2dfbc50
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "SimResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sim;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioSimResponse> simCb) {
+    CHECK(simCb);
+    mSimCb = simCb;
+}
+
+Return<void> RadioResponse::areUiccApplicationsEnabledResponse(const V1_0::RadioResponseInfo& info,
+                                                               bool enabled) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->areUiccApplicationsEnabledResponse(toAidl(info), enabled);
+    return {};
+}
+
+Return<void> RadioResponse::changeIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->changeIccPin2ForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::changeIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->changeIccPinForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::enableUiccApplicationsResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->enableUiccApplicationsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getAllowedCarriersResponse(  //
+        const V1_0::RadioResponseInfo& info, bool allAllowed, const V1_0::CarrierRestrictions& cr) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    aidl::CarrierRestrictions aidlCr = toAidl(cr);
+    if (allAllowed) aidlCr = {};
+    mSimCb->getAllowedCarriersResponse(toAidl(info), aidlCr, {});
+    return {};
+}
+
+Return<void> RadioResponse::getAllowedCarriersResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const V1_4::CarrierRestrictionsWithPriority& carriers,
+        V1_4::SimLockMultiSimPolicy multiSimPolicy) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getAllowedCarriersResponse(toAidl(info), toAidl(carriers),
+                                       aidl::SimLockMultiSimPolicy(multiSimPolicy));
+    return {};
+}
+
+Return<void> RadioResponse::getCDMASubscriptionResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_string& mdn, const hidl_string& hSid,
+        const hidl_string& hNid, const hidl_string& min, const hidl_string& prl) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getCdmaSubscriptionResponse(toAidl(info), mdn, hSid, hNid, min, prl);
+    return {};
+}
+
+Return<void> RadioResponse::getCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info,
+                                                              V1_0::CdmaSubscriptionSource s) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getCdmaSubscriptionSourceResponse(toAidl(info), aidl::CdmaSubscriptionSource(s));
+    return {};
+}
+
+Return<void> RadioResponse::getFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                          int32_t response) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getFacilityLockForAppResponse(toAidl(info), response);
+    return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                     const V1_0::CardStatus& cardStatus) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                         const V1_2::CardStatus& cardStatus) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                                         const V1_4::CardStatus& cardStatus) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_5(const V1_0::RadioResponseInfo& info,
+                                                         const V1_5::CardStatus& cardStatus) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    return {};
+}
+
+Return<void> RadioResponse::getIMSIForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                  const hidl_string& imsi) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getImsiForAppResponse(toAidl(info), imsi);
+    return {};
+}
+
+Return<void> RadioResponse::getSimPhonebookCapacityResponse(
+        const V1_6::RadioResponseInfo& info, const V1_6::PhonebookCapacity& capacity) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getSimPhonebookCapacityResponse(toAidl(info), toAidl(capacity));
+    return {};
+}
+
+Return<void> RadioResponse::getSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->getSimPhonebookRecordsResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::iccCloseLogicalChannelResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccCloseLogicalChannelResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::iccIOForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::IccIoResult& iccIo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccIoForAppResponse(toAidl(info), toAidl(iccIo));
+    return {};
+}
+
+Return<void> RadioResponse::iccOpenLogicalChannelResponse(  //
+        const V1_0::RadioResponseInfo& info, int32_t chanId, const hidl_vec<int8_t>& selectResp) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccOpenLogicalChannelResponse(toAidl(info), chanId, toAidl(selectResp));
+    return {};
+}
+
+Return<void> RadioResponse::iccTransmitApduBasicChannelResponse(const V1_0::RadioResponseInfo& info,
+                                                                const V1_0::IccIoResult& result) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccTransmitApduBasicChannelResponse(toAidl(info), toAidl(result));
+    return {};
+}
+
+Return<void> RadioResponse::iccTransmitApduLogicalChannelResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::IccIoResult& result) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->iccTransmitApduLogicalChannelResponse(toAidl(info), toAidl(result));
+    return {};
+}
+
+Return<void> RadioResponse::reportStkServiceIsRunningResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->reportStkServiceIsRunningResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::requestIccSimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                                const V1_0::IccIoResult& result) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->requestIccSimAuthenticationResponse(toAidl(info), toAidl(result));
+    return {};
+}
+
+Return<void> RadioResponse::requestIsimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                              const hidl_string&) {
+    LOG_CALL << info.serial;
+    LOG(ERROR) << "requestIsimAuthenticationResponse is not supposed to be called";
+    return {};
+}
+
+Return<void> RadioResponse::sendEnvelopeResponse(const V1_0::RadioResponseInfo& info,
+                                                 const hidl_string& commandResponse) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->sendEnvelopeResponse(toAidl(info), commandResponse);
+    return {};
+}
+
+Return<void> RadioResponse::sendEnvelopeWithStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                           const V1_0::IccIoResult& iccIo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->sendEnvelopeWithStatusResponse(toAidl(info), toAidl(iccIo));
+    return {};
+}
+
+Return<void> RadioResponse::sendTerminalResponseToSimResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->sendTerminalResponseToSimResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t numAllowed) {
+    LOG_CALL << info.serial << ' ' << numAllowed;
+    CHECK_CB(mSimCb);
+    mSimCb->setAllowedCarriersResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setAllowedCarriersResponse_1_4(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setAllowedCarriersResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCarrierInfoForImsiEncryptionResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setCarrierInfoForImsiEncryptionResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setCdmaSubscriptionSourceResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                          int32_t retry) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setFacilityLockForAppResponse(toAidl(info), retry);
+    return {};
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setSimCardPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse_1_1(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setSimCardPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setSimCardPowerResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setUiccSubscriptionResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->setUiccSubscriptionResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::supplyIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplyIccPin2ForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::supplyIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplyIccPinForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::supplyIccPuk2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplyIccPuk2ForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::supplyIccPukForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t remainingRetries) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplyIccPukForAppResponse(toAidl(info), remainingRetries);
+    return {};
+}
+
+Return<void> RadioResponse::supplySimDepersonalizationResponse(const V1_0::RadioResponseInfo& info,
+                                                               V1_5::PersoSubstate persoType,
+                                                               int32_t rRet) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->supplySimDepersonalizationResponse(toAidl(info), aidl::PersoSubstate(persoType), rRet);
+    return {};
+}
+
+Return<void> RadioResponse::updateSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info,
+                                                              int32_t updatedRecordIndex) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mSimCb);
+    mSimCb->updateSimPhonebookRecordsResponse(toAidl(info), updatedRecordIndex);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
new file mode 100644
index 0000000..ca27918
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioSim.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Sim"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::sim;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioSim::areUiccApplicationsEnabled(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->areUiccApplicationsEnabled(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::changeIccPin2ForApp(int32_t serial, const std::string& oldPin2,
+                                            const std::string& newPin2, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->changeIccPin2ForApp(serial, oldPin2, newPin2, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::changeIccPinForApp(int32_t serial, const std::string& oldPin,
+                                           const std::string& newPin, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->changeIccPinForApp(serial, oldPin, newPin, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::enableUiccApplications(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->enableUiccApplications(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getAllowedCarriers(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getAllowedCarriers(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getCdmaSubscription(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCDMASubscription(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getCdmaSubscriptionSource(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCdmaSubscriptionSource(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getFacilityLockForApp(  //
+        int32_t serial, const std::string& facility, const std::string& password,
+        int32_t serviceClass, const std::string& appId) {
+    LOG_CALL << serial;
+    mHal1_5->getFacilityLockForApp(serial, facility, password, serviceClass, appId);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getIccCardStatus(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getIccCardStatus(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getImsiForApp(int32_t serial, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->getImsiForApp(serial, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::getSimPhonebookCapacity(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getSimPhonebookCapacity(serial);
+    } else {
+        respond().getSimPhonebookCapacityResponse(notSupported(serial), {});
+    }
+    return ok();
+}
+
+ScopedAStatus RadioSim::getSimPhonebookRecords(int32_t serial) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->getSimPhonebookRecords(serial);
+    } else {
+        respond().getSimPhonebookRecordsResponse(notSupported(serial));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccCloseLogicalChannel(int32_t serial, int32_t channelId) {
+    LOG_CALL << serial;
+    mHal1_5->iccCloseLogicalChannel(serial, channelId);
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccIoForApp(int32_t serial, const aidl::IccIo& iccIo) {
+    LOG_CALL << serial;
+    mHal1_5->iccIOForApp(serial, toHidl(iccIo));
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccOpenLogicalChannel(int32_t serial, const std::string& aid, int32_t p2) {
+    LOG_CALL << serial;
+    mHal1_5->iccOpenLogicalChannel(serial, aid, p2);
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccTransmitApduBasicChannel(int32_t serial, const aidl::SimApdu& message) {
+    LOG_CALL << serial;
+    mHal1_5->iccTransmitApduBasicChannel(serial, toHidl(message));
+    return ok();
+}
+
+ScopedAStatus RadioSim::iccTransmitApduLogicalChannel(int32_t serial,
+                                                      const aidl::SimApdu& message) {
+    LOG_CALL << serial;
+    mHal1_5->iccTransmitApduLogicalChannel(serial, toHidl(message));
+    return ok();
+}
+
+ScopedAStatus RadioSim::reportStkServiceIsRunning(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->reportStkServiceIsRunning(serial);
+    return ok();
+}
+
+ScopedAStatus RadioSim::requestIccSimAuthentication(  //
+        int32_t serial, int32_t authContext, const std::string& authData, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->requestIccSimAuthentication(serial, authContext, authData, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioSim::sendEnvelope(int32_t serial, const std::string& command) {
+    LOG_CALL << serial;
+    mHal1_5->sendEnvelope(serial, command);
+    return ok();
+}
+
+ScopedAStatus RadioSim::sendEnvelopeWithStatus(int32_t serial, const std::string& contents) {
+    LOG_CALL << serial;
+    mHal1_5->sendEnvelopeWithStatus(serial, contents);
+    return ok();
+}
+
+ScopedAStatus RadioSim::sendTerminalResponseToSim(int32_t serial,
+                                                  const std::string& commandResponse) {
+    LOG_CALL << serial;
+    mHal1_5->sendTerminalResponseToSim(serial, commandResponse);
+    return ok();
+}
+
+ScopedAStatus RadioSim::setAllowedCarriers(  //
+        int32_t serial, const aidl::CarrierRestrictions& carriers, aidl::SimLockMultiSimPolicy mp) {
+    LOG_CALL << serial;
+    mHal1_5->setAllowedCarriers_1_4(serial, toHidl(carriers), V1_4::SimLockMultiSimPolicy(mp));
+    return ok();
+}
+
+ScopedAStatus RadioSim::setCarrierInfoForImsiEncryption(
+        int32_t serial, const aidl::ImsiEncryptionInfo& imsiEncryptionInfo) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setCarrierInfoForImsiEncryption_1_6(serial, toHidl_1_6(imsiEncryptionInfo));
+    } else {
+        mHal1_5->setCarrierInfoForImsiEncryption(serial, toHidl(imsiEncryptionInfo));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioSim::setCdmaSubscriptionSource(int32_t serial,
+                                                  aidl::CdmaSubscriptionSource cdmaSub) {
+    LOG_CALL << serial;
+    mHal1_5->setCdmaSubscriptionSource(serial, V1_0::CdmaSubscriptionSource(cdmaSub));
+    return ok();
+}
+
+ScopedAStatus RadioSim::setFacilityLockForApp(  //
+        int32_t serial, const std::string& facility, bool lockState, const std::string& password,
+        int32_t serviceClass, const std::string& appId) {
+    LOG_CALL << serial;
+    mHal1_5->setFacilityLockForApp(serial, facility, lockState, password, serviceClass, appId);
+    return ok();
+}
+
+ScopedAStatus RadioSim::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioSimResponse>& simResponse,
+        const std::shared_ptr<aidl::IRadioSimIndication>& simIndication) {
+    LOG_CALL << simResponse << ' ' << simIndication;
+
+    CHECK(simResponse);
+    CHECK(simIndication);
+
+    mRadioResponse->setResponseFunction(simResponse);
+    mRadioIndication->setResponseFunction(simIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioSim::setSimCardPower(int32_t serial, aidl::CardPowerState powerUp) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->setSimCardPower_1_6(serial, V1_1::CardPowerState(powerUp));
+    } else {
+        mHal1_5->setSimCardPower_1_1(serial, V1_1::CardPowerState(powerUp));
+    }
+    return ok();
+}
+
+ScopedAStatus RadioSim::setUiccSubscription(int32_t serial, const aidl::SelectUiccSub& uiccSub) {
+    LOG_CALL << serial;
+    mHal1_5->setUiccSubscription(serial, toHidl(uiccSub));
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPin2ForApp(int32_t serial, const std::string& pin2,
+                                            const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->supplyIccPin2ForApp(serial, pin2, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPinForApp(int32_t serial, const std::string& pin,
+                                           const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->supplyIccPinForApp(serial, pin, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPuk2ForApp(int32_t serial, const std::string& puk2,
+                                            const std::string& pin2, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->supplyIccPuk2ForApp(serial, puk2, pin2, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPukForApp(int32_t serial, const std::string& puk,
+                                           const std::string& pin, const std::string& aid) {
+    LOG_CALL << serial;
+    mHal1_5->supplyIccPukForApp(serial, puk, pin, aid);
+    return ok();
+}
+
+ScopedAStatus RadioSim::supplySimDepersonalization(int32_t serial, aidl::PersoSubstate pss,
+                                                   const std::string& controlKey) {
+    LOG_CALL << serial;
+    mHal1_5->supplySimDepersonalization(serial, V1_5::PersoSubstate(pss), controlKey);
+    return ok();
+}
+
+ScopedAStatus RadioSim::updateSimPhonebookRecords(int32_t serial,
+                                                  const aidl::PhonebookRecordInfo& recordInfo) {
+    LOG_CALL << serial;
+    if (mHal1_6) {
+        mHal1_6->updateSimPhonebookRecords(serial, toHidl(recordInfo));
+    } else {
+        respond().updateSimPhonebookRecordsResponse(notSupported(serial), 0);
+    }
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.cpp b/radio/aidl/compat/libradiocompat/sim/structs.cpp
new file mode 100644
index 0000000..97a21a1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/structs.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sim;
+
+V1_0::IccIo toHidl(const aidl::IccIo& icc) {
+    return {
+            .command = icc.command,
+            .fileId = icc.fileId,
+            .path = icc.path,
+            .p1 = icc.p1,
+            .p2 = icc.p2,
+            .p3 = icc.p3,
+            .data = icc.data,
+            .pin2 = icc.pin2,
+            .aid = icc.aid,
+    };
+}
+
+V1_0::SimApdu toHidl(const aidl::SimApdu& apdu) {
+    return {
+            .sessionId = apdu.sessionId,
+            .cla = apdu.cla,
+            .instruction = apdu.instruction,
+            .p1 = apdu.p1,
+            .p2 = apdu.p2,
+            .p3 = apdu.p3,
+            .data = apdu.data,
+    };
+}
+
+aidl::Carrier toAidl(const V1_0::Carrier& carrier) {
+    return {
+            .mcc = carrier.mcc,
+            .mnc = carrier.mnc,
+            .matchType = static_cast<int32_t>(carrier.matchType),
+            .matchData = carrier.matchData,
+    };
+}
+
+V1_0::Carrier toHidl(const aidl::Carrier& carrier) {
+    return {
+            .mcc = carrier.mcc,
+            .mnc = carrier.mnc,
+            .matchType = V1_0::CarrierMatchType{carrier.matchType},
+            .matchData = carrier.matchData,
+    };
+}
+
+aidl::CarrierRestrictions toAidl(const V1_0::CarrierRestrictions& cr) {
+    return {
+            .allowedCarriers = toAidl(cr.allowedCarriers),
+            .excludedCarriers = toAidl(cr.excludedCarriers),
+            .allowedCarriersPrioritized = true,
+    };
+}
+
+aidl::CarrierRestrictions toAidl(const V1_4::CarrierRestrictionsWithPriority& cr) {
+    return {
+            .allowedCarriers = toAidl(cr.allowedCarriers),
+            .excludedCarriers = toAidl(cr.excludedCarriers),
+            .allowedCarriersPrioritized = cr.allowedCarriersPrioritized,
+    };
+}
+
+V1_4::CarrierRestrictionsWithPriority toHidl(const aidl::CarrierRestrictions& cr) {
+    return {
+            .allowedCarriers = toHidl(cr.allowedCarriers),
+            .excludedCarriers = toHidl(cr.excludedCarriers),
+            .allowedCarriersPrioritized = cr.allowedCarriersPrioritized,
+    };
+}
+
+V1_1::ImsiEncryptionInfo toHidl(const aidl::ImsiEncryptionInfo& info) {
+    return {
+            .mcc = info.mcc,
+            .mnc = info.mnc,
+            .carrierKey = info.carrierKey,
+            .keyIdentifier = info.keyIdentifier,
+            .expirationTime = info.expirationTime,
+    };
+}
+
+V1_6::ImsiEncryptionInfo toHidl_1_6(const aidl::ImsiEncryptionInfo& info) {
+    return {
+            .base = toHidl(info),
+            .keyType = V1_6::PublicKeyType{info.keyType},
+    };
+}
+
+V1_0::SelectUiccSub toHidl(const aidl::SelectUiccSub& sub) {
+    return {
+            .slot = sub.slot,
+            .appIndex = sub.appIndex,
+            .subType = {},
+            .actStatus = {},
+    };
+}
+
+aidl::PhonebookRecordInfo toAidl(const V1_6::PhonebookRecordInfo& info) {
+    return {
+            .recordId = static_cast<int32_t>(info.recordId),
+            .name = info.name,
+            .number = info.number,
+            .emails = toAidl(info.emails),
+            .additionalNumbers = toAidl(info.additionalNumbers),
+    };
+}
+
+V1_6::PhonebookRecordInfo toHidl(const aidl::PhonebookRecordInfo& info) {
+    return {
+            .recordId = static_cast<uint32_t>(info.recordId),
+            .name = info.name,
+            .number = info.number,
+            .emails = toHidl(info.emails),
+            .additionalNumbers = toHidl(info.additionalNumbers),
+    };
+}
+
+aidl::SimRefreshResult toAidl(const V1_0::SimRefreshResult& res) {
+    return {
+            .type = static_cast<int32_t>(res.type),
+            .efId = res.efId,
+            .aid = res.aid,
+    };
+}
+
+aidl::CardStatus toAidl(const V1_0::CardStatus& status) {
+    return toAidl(V1_2::CardStatus{status, 0, "", ""});
+}
+
+aidl::CardStatus toAidl(const V1_2::CardStatus& status) {
+    return toAidl(V1_4::CardStatus{status, ""});
+}
+
+aidl::CardStatus toAidl(const V1_4::CardStatus& status) {
+    auto aidlStatus = toAidl(V1_5::CardStatus{status, {}});
+    aidlStatus.applications = toAidl(status.base.base.applications);
+    return aidlStatus;
+}
+
+aidl::CardStatus toAidl(const V1_5::CardStatus& status) {
+    return {
+            .cardState = static_cast<int32_t>(status.base.base.base.cardState),
+            .universalPinState = aidl::PinState(status.base.base.base.universalPinState),
+            .gsmUmtsSubscriptionAppIndex = status.base.base.base.gsmUmtsSubscriptionAppIndex,
+            .cdmaSubscriptionAppIndex = status.base.base.base.cdmaSubscriptionAppIndex,
+            .imsSubscriptionAppIndex = status.base.base.base.imsSubscriptionAppIndex,
+            .applications = toAidl(status.applications),
+            .atr = status.base.base.atr,
+            .iccid = status.base.base.iccid,
+            .eid = status.base.eid,
+            // TODO(b/203699028): we don't know portId here (but we can get it from RadioConfig)
+            .slotMap = {static_cast<int32_t>(status.base.base.physicalSlotId), 0},
+    };
+}
+
+aidl::AppStatus toAidl(const V1_0::AppStatus& status) {
+    return toAidl({status, V1_5::PersoSubstate(status.persoSubstate)});
+}
+
+aidl::AppStatus toAidl(const V1_5::AppStatus& status) {
+    return {
+            .appType = static_cast<int32_t>(status.base.appType),
+            .appState = static_cast<int32_t>(status.base.appState),
+            .persoSubstate = aidl::PersoSubstate(status.persoSubstate),
+            .aidPtr = status.base.aidPtr,
+            .appLabelPtr = status.base.appLabelPtr,
+            .pin1Replaced = (status.base.pin1Replaced != 0),
+            .pin1 = aidl::PinState(status.base.pin1),
+            .pin2 = aidl::PinState(status.base.pin2),
+    };
+}
+
+aidl::PhonebookCapacity toAidl(const V1_6::PhonebookCapacity& c) {
+    return {
+            .maxAdnRecords = c.maxAdnRecords,
+            .usedAdnRecords = c.usedAdnRecords,
+            .maxEmailRecords = c.maxEmailRecords,
+            .usedEmailRecords = c.usedEmailRecords,
+            .maxAdditionalNumberRecords = c.maxAdditionalNumberRecords,
+            .usedAdditionalNumberRecords = c.usedAdditionalNumberRecords,
+            .maxNameLen = c.maxNameLen,
+            .maxNumberLen = c.maxNumberLen,
+            .maxEmailLen = c.maxEmailLen,
+            .maxAdditionalNumberLen = c.maxAdditionalNumberLen,
+    };
+}
+
+aidl::IccIoResult toAidl(const V1_0::IccIoResult& iir) {
+    return {
+            .sw1 = iir.sw1,
+            .sw2 = iir.sw2,
+            .simResponse = iir.simResponse,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.h b/radio/aidl/compat/libradiocompat/sim/structs.h
new file mode 100644
index 0000000..54099b7
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/structs.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/sim/AppStatus.h>
+#include <aidl/android/hardware/radio/sim/CardStatus.h>
+#include <aidl/android/hardware/radio/sim/Carrier.h>
+#include <aidl/android/hardware/radio/sim/CarrierRestrictions.h>
+#include <aidl/android/hardware/radio/sim/IccIo.h>
+#include <aidl/android/hardware/radio/sim/IccIoResult.h>
+#include <aidl/android/hardware/radio/sim/ImsiEncryptionInfo.h>
+#include <aidl/android/hardware/radio/sim/PhonebookCapacity.h>
+#include <aidl/android/hardware/radio/sim/PhonebookRecordInfo.h>
+#include <aidl/android/hardware/radio/sim/SelectUiccSub.h>
+#include <aidl/android/hardware/radio/sim/SimApdu.h>
+#include <aidl/android/hardware/radio/sim/SimRefreshResult.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::IccIo toHidl(const ::aidl::android::hardware::radio::sim::IccIo& icc);
+
+V1_0::SimApdu toHidl(const ::aidl::android::hardware::radio::sim::SimApdu& apdu);
+
+::aidl::android::hardware::radio::sim::Carrier toAidl(const V1_0::Carrier& carrier);
+V1_0::Carrier toHidl(const ::aidl::android::hardware::radio::sim::Carrier& carrier);
+
+::aidl::android::hardware::radio::sim::CarrierRestrictions  //
+toAidl(const V1_0::CarrierRestrictions& cr);
+::aidl::android::hardware::radio::sim::CarrierRestrictions  //
+toAidl(const V1_4::CarrierRestrictionsWithPriority& cr);
+V1_4::CarrierRestrictionsWithPriority  //
+toHidl(const ::aidl::android::hardware::radio::sim::CarrierRestrictions& cr);
+
+V1_1::ImsiEncryptionInfo  //
+toHidl(const ::aidl::android::hardware::radio::sim::ImsiEncryptionInfo& info);
+V1_6::ImsiEncryptionInfo  //
+toHidl_1_6(const ::aidl::android::hardware::radio::sim::ImsiEncryptionInfo& info);
+
+V1_0::SelectUiccSub toHidl(const ::aidl::android::hardware::radio::sim::SelectUiccSub& sub);
+
+::aidl::android::hardware::radio::sim::PhonebookRecordInfo  //
+toAidl(const V1_6::PhonebookRecordInfo& info);
+V1_6::PhonebookRecordInfo  //
+toHidl(const ::aidl::android::hardware::radio::sim::PhonebookRecordInfo& info);
+
+::aidl::android::hardware::radio::sim::SimRefreshResult  //
+toAidl(const V1_0::SimRefreshResult& res);
+
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_0::CardStatus& status);
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_2::CardStatus& status);
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_4::CardStatus& status);
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_5::CardStatus& status);
+
+::aidl::android::hardware::radio::sim::AppStatus toAidl(const V1_0::AppStatus& status);
+::aidl::android::hardware::radio::sim::AppStatus toAidl(const V1_5::AppStatus& status);
+
+::aidl::android::hardware::radio::sim::PhonebookCapacity toAidl(const V1_6::PhonebookCapacity& c);
+
+::aidl::android::hardware::radio::sim::IccIoResult toAidl(const V1_0::IccIoResult& iir);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
new file mode 100644
index 0000000..6d9bda8
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "VoiceIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::voice;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceIndication> voiceCb) {
+    CHECK(voiceCb);
+    mVoiceCb = voiceCb;
+}
+
+Return<void> RadioIndication::callRing(V1_0::RadioIndicationType type, bool isGsm,
+                                       const V1_0::CdmaSignalInfoRecord& record) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->callRing(toAidl(type), isGsm, toAidl(record));
+    return {};
+}
+
+Return<void> RadioIndication::callStateChanged(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->callStateChanged(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaCallWaiting(V1_0::RadioIndicationType type,
+                                              const V1_0::CdmaCallWaiting& callWaitingRecord) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->cdmaCallWaiting(toAidl(type), toAidl(callWaitingRecord));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaInfoRec(V1_0::RadioIndicationType type,
+                                          const V1_0::CdmaInformationRecords& records) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->cdmaInfoRec(toAidl(type), toAidl(records.infoRec));
+    return {};
+}
+
+Return<void> RadioIndication::cdmaOtaProvisionStatus(V1_0::RadioIndicationType type,
+                                                     V1_0::CdmaOtaProvisionStatus status) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->cdmaOtaProvisionStatus(toAidl(type), aidl::CdmaOtaProvisionStatus(status));
+    return {};
+}
+
+Return<void> RadioIndication::currentEmergencyNumberList(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_4::EmergencyNumber>& emergencyNumbers) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->currentEmergencyNumberList(toAidl(type), toAidl(emergencyNumbers));
+    return {};
+}
+
+Return<void> RadioIndication::enterEmergencyCallbackMode(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->enterEmergencyCallbackMode(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::exitEmergencyCallbackMode(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->exitEmergencyCallbackMode(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::indicateRingbackTone(V1_0::RadioIndicationType type, bool start) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->indicateRingbackTone(toAidl(type), start);
+    return {};
+}
+
+Return<void> RadioIndication::onSupplementaryServiceIndication(V1_0::RadioIndicationType type,
+                                                               const V1_0::StkCcUnsolSsResult& ss) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->onSupplementaryServiceIndication(toAidl(type), toAidl(ss));
+    return {};
+}
+
+Return<void> RadioIndication::resendIncallMute(V1_0::RadioIndicationType type) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->resendIncallMute(toAidl(type));
+    return {};
+}
+
+Return<void> RadioIndication::srvccStateNotify(V1_0::RadioIndicationType type,
+                                               V1_0::SrvccState state) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->srvccStateNotify(toAidl(type), aidl::SrvccState(state));
+    return {};
+}
+
+Return<void> RadioIndication::stkCallControlAlphaNotify(V1_0::RadioIndicationType type,
+                                                        const hidl_string& alpha) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->stkCallControlAlphaNotify(toAidl(type), alpha);
+    return {};
+}
+
+Return<void> RadioIndication::stkCallSetup(V1_0::RadioIndicationType type, int64_t timeout) {
+    LOG_CALL << type;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->stkCallSetup(toAidl(type), timeout);
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
new file mode 100644
index 0000000..0a64c56
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "VoiceResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::voice;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceResponse> voiceCb) {
+    CHECK(voiceCb);
+    mVoiceCb = voiceCb;
+}
+
+Return<void> RadioResponse::acceptCallResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->acceptCallResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::conferenceResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->conferenceResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::dialResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->dialResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::emergencyDialResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->emergencyDialResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->exitEmergencyCallbackModeResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::explicitCallTransferResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->explicitCallTransferResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::getCallForwardStatusResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::CallForwardInfo>& callFwdInfos) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCallForwardStatusResponse(toAidl(info), toAidl(callFwdInfos));
+    return {};
+}
+
+Return<void> RadioResponse::getCallWaitingResponse(const V1_0::RadioResponseInfo& info, bool enable,
+                                                   int32_t serviceClass) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCallWaitingResponse(toAidl(info), enable, serviceClass);
+    return {};
+}
+
+Return<void> RadioResponse::getClipResponse(const V1_0::RadioResponseInfo& info,
+                                            V1_0::ClipStatus status) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getClipResponse(toAidl(info), aidl::ClipStatus(status));
+    return {};
+}
+
+Return<void> RadioResponse::getClirResponse(const V1_0::RadioResponseInfo& info, int32_t n,
+                                            int32_t m) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getClirResponse(toAidl(info), n, m);
+    return {};
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse(const V1_0::RadioResponseInfo& info,
+                                                    const hidl_vec<V1_0::Call>& calls) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    return {};
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_2::Call>& calls) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    return {};
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse_1_6(const V1_6::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_6::Call>& calls) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    return {};
+}
+
+Return<void> RadioResponse::getLastCallFailCauseResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::LastCallFailCauseInfo& failCauseinfo) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getLastCallFailCauseResponse(toAidl(info), toAidl(failCauseinfo));
+    return {};
+}
+
+Return<void> RadioResponse::getMuteResponse(const V1_0::RadioResponseInfo& info, bool enable) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getMuteResponse(toAidl(info), enable);
+    return {};
+}
+
+Return<void> RadioResponse::getPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info,
+                                                             bool enable) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getPreferredVoicePrivacyResponse(toAidl(info), enable);
+    return {};
+}
+
+Return<void> RadioResponse::getTTYModeResponse(const V1_0::RadioResponseInfo& info,
+                                               V1_0::TtyMode mode) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->getTtyModeResponse(toAidl(info), aidl::TtyMode(mode));
+    return {};
+}
+
+Return<void> RadioResponse::handleStkCallSetupRequestFromSimResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->handleStkCallSetupRequestFromSimResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::hangupConnectionResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->hangupConnectionResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::hangupForegroundResumeBackgroundResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->hangupForegroundResumeBackgroundResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::hangupWaitingOrBackgroundResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->hangupWaitingOrBackgroundResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::rejectCallResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->rejectCallResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendBurstDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->sendBurstDtmfResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendCDMAFeatureCodeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->sendCdmaFeatureCodeResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::sendDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->sendDtmfResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::separateConnectionResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->separateConnectionResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCallForwardResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setCallForwardResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setCallWaitingResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setCallWaitingResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setClirResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setClirResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setMuteResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setMuteResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setPreferredVoicePrivacyResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::setTTYModeResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->setTtyModeResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::startDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->startDtmfResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::stopDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->stopDtmfResponse(toAidl(info));
+    return {};
+}
+
+Return<void> RadioResponse::switchWaitingOrHoldingAndActiveResponse(
+        const V1_0::RadioResponseInfo& info) {
+    LOG_CALL << info.serial;
+    CHECK_CB(mVoiceCb);
+    mVoiceCb->switchWaitingOrHoldingAndActiveResponse(toAidl(info));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
new file mode 100644
index 0000000..16c6b14
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <libradiocompat/RadioVoice.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Voice"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::voice;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioVoice::acceptCall(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->acceptCall(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::conference(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->conference(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::dial(int32_t serial, const aidl::Dial& dialInfo) {
+    LOG_CALL << serial;
+    mHal1_5->dial(serial, toHidl(dialInfo));
+    return ok();
+}
+
+ScopedAStatus RadioVoice::emergencyDial(  //
+        int32_t serial, const aidl::Dial& dialInfo, aidl::EmergencyServiceCategory categories,
+        const std::vector<std::string>& urns, aidl::EmergencyCallRouting routing,
+        bool hasKnownUserIntentEmerg, bool isTesting) {
+    LOG_CALL << serial;
+    mHal1_5->emergencyDial(serial, toHidl(dialInfo),
+                           toHidlBitfield<V1_4::EmergencyServiceCategory>(categories), toHidl(urns),
+                           V1_4::EmergencyCallRouting(routing), hasKnownUserIntentEmerg, isTesting);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::exitEmergencyCallbackMode(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->exitEmergencyCallbackMode(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::explicitCallTransfer(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->explicitCallTransfer(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getCallForwardStatus(int32_t serial,
+                                               const aidl::CallForwardInfo& callInfo) {
+    LOG_CALL << serial;
+    mHal1_5->getCallForwardStatus(serial, toHidl(callInfo));
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getCallWaiting(int32_t serial, int32_t serviceClass) {
+    LOG_CALL << serial;
+    mHal1_5->getCallWaiting(serial, serviceClass);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getClip(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getClip(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getClir(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getClir(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getCurrentCalls(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getCurrentCalls(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getLastCallFailCause(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getLastCallFailCause(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getMute(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getMute(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getPreferredVoicePrivacy(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getPreferredVoicePrivacy(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::getTtyMode(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->getTTYMode(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::handleStkCallSetupRequestFromSim(int32_t serial, bool accept) {
+    LOG_CALL << serial;
+    mHal1_5->handleStkCallSetupRequestFromSim(serial, accept);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::hangup(int32_t serial, int32_t gsmIndex) {
+    LOG_CALL << serial;
+    mHal1_5->hangup(serial, gsmIndex);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::hangupForegroundResumeBackground(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->hangupForegroundResumeBackground(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::hangupWaitingOrBackground(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->hangupWaitingOrBackground(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::isVoNrEnabled(int32_t serial) {
+    LOG_CALL << serial;
+    // TODO(b/203699028): can't call isVoNrEnabledResponse with 1.6 callback
+    return ok();
+}
+
+ScopedAStatus RadioVoice::rejectCall(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->rejectCall(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::responseAcknowledgement() {
+    LOG_CALL;
+    mHal1_5->responseAcknowledgement();
+    return ok();
+}
+
+ScopedAStatus RadioVoice::sendBurstDtmf(int32_t serial, const std::string& dtmf, int32_t on,
+                                        int32_t off) {
+    LOG_CALL << serial;
+    mHal1_5->sendBurstDtmf(serial, dtmf, on, off);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::sendCdmaFeatureCode(int32_t serial, const std::string& featureCode) {
+    LOG_CALL << serial;
+    mHal1_5->sendCDMAFeatureCode(serial, featureCode);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::sendDtmf(int32_t serial, const std::string& s) {
+    LOG_CALL << serial;
+    mHal1_5->sendDtmf(serial, s);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::separateConnection(int32_t serial, int32_t gsmIndex) {
+    LOG_CALL << serial;
+    mHal1_5->separateConnection(serial, gsmIndex);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setCallForward(int32_t serial, const aidl::CallForwardInfo& callInfo) {
+    LOG_CALL << serial;
+    mHal1_5->setCallForward(serial, toHidl(callInfo));
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) {
+    LOG_CALL << serial;
+    mHal1_5->setCallWaiting(serial, enable, serviceClass);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setClir(int32_t serial, int32_t status) {
+    LOG_CALL << serial;
+    mHal1_5->setClir(serial, status);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setMute(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->setMute(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setPreferredVoicePrivacy(int32_t serial, bool enable) {
+    LOG_CALL << serial;
+    mHal1_5->setPreferredVoicePrivacy(serial, enable);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioVoiceResponse>& voiceResponse,
+        const std::shared_ptr<aidl::IRadioVoiceIndication>& voiceIndication) {
+    LOG_CALL << voiceResponse << ' ' << voiceIndication;
+
+    CHECK(voiceResponse);
+    CHECK(voiceIndication);
+
+    mRadioResponse->setResponseFunction(voiceResponse);
+    mRadioIndication->setResponseFunction(voiceIndication);
+
+    return ok();
+}
+
+ScopedAStatus RadioVoice::setTtyMode(int32_t serial, aidl::TtyMode mode) {
+    LOG_CALL << serial;
+    mHal1_5->setTTYMode(serial, V1_0::TtyMode(mode));
+    return ok();
+}
+
+ndk::ScopedAStatus RadioVoice::setVoNrEnabled(int32_t serial, [[maybe_unused]] bool enable) {
+    LOG_CALL << serial;
+    // TODO(b/203699028): should set `persist.radio.is_vonr_enabled_` property instead
+    return ok();
+}
+
+ScopedAStatus RadioVoice::startDtmf(int32_t serial, const std::string& s) {
+    LOG_CALL << serial;
+    mHal1_5->startDtmf(serial, s);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::stopDtmf(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->stopDtmf(serial);
+    return ok();
+}
+
+ScopedAStatus RadioVoice::switchWaitingOrHoldingAndActive(int32_t serial) {
+    LOG_CALL << serial;
+    mHal1_5->switchWaitingOrHoldingAndActive(serial);
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/structs.cpp b/radio/aidl/compat/libradiocompat/voice/structs.cpp
new file mode 100644
index 0000000..ae6342e
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/structs.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::voice;
+
+V1_0::Dial toHidl(const aidl::Dial& info) {
+    return {
+            .address = info.address,
+            .clir = V1_0::Clir{info.clir},
+            .uusInfo = toHidl(info.uusInfo),
+    };
+}
+
+V1_0::UusInfo toHidl(const aidl::UusInfo& info) {
+    return {
+            .uusType = V1_0::UusType{info.uusType},
+            .uusDcs = V1_0::UusDcs{info.uusDcs},
+            .uusData = info.uusData,
+    };
+}
+
+aidl::CallForwardInfo toAidl(const V1_0::CallForwardInfo& info) {
+    return {
+            .status = static_cast<int32_t>(info.status),
+            .reason = info.reason,
+            .serviceClass = info.serviceClass,
+            .toa = info.toa,
+            .number = info.number,
+            .timeSeconds = info.timeSeconds,
+    };
+}
+
+V1_0::CallForwardInfo toHidl(const aidl::CallForwardInfo& info) {
+    return {
+            .status = V1_0::CallForwardInfoStatus{info.status},
+            .reason = info.reason,
+            .serviceClass = info.serviceClass,
+            .toa = info.toa,
+            .number = info.number,
+            .timeSeconds = info.timeSeconds,
+    };
+}
+
+aidl::CdmaSignalInfoRecord toAidl(const V1_0::CdmaSignalInfoRecord& record) {
+    return {
+            .isPresent = record.isPresent,
+            .signalType = record.signalType,
+            .alertPitch = record.alertPitch,
+            .signal = record.signal,
+    };
+}
+
+aidl::CdmaCallWaiting toAidl(const V1_0::CdmaCallWaiting& call) {
+    return {
+            .number = call.number,
+            .numberPresentation = static_cast<int32_t>(call.numberPresentation),
+            .name = call.name,
+            .signalInfoRecord = toAidl(call.signalInfoRecord),
+            .numberType = static_cast<int32_t>(call.numberType),
+            .numberPlan = static_cast<int32_t>(call.numberPlan),
+    };
+}
+
+aidl::CdmaInformationRecord toAidl(const V1_0::CdmaInformationRecord& record) {
+    return {
+            .name = static_cast<int32_t>(record.name),
+            .display = toAidl(record.display),
+            .number = toAidl(record.number),
+            .signal = toAidl(record.signal),
+            .redir = toAidl(record.redir),
+            .lineCtrl = toAidl(record.lineCtrl),
+            .clir = toAidl(record.clir),
+            .audioCtrl = toAidl(record.audioCtrl),
+    };
+}
+
+aidl::CdmaDisplayInfoRecord toAidl(const V1_0::CdmaDisplayInfoRecord& record) {
+    return {
+            .alphaBuf = record.alphaBuf,
+    };
+}
+
+aidl::CdmaNumberInfoRecord toAidl(const V1_0::CdmaNumberInfoRecord& record) {
+    return {
+            .number = record.number,
+            .numberType = static_cast<int8_t>(record.numberType),
+            .numberPlan = static_cast<int8_t>(record.numberPlan),
+            .pi = static_cast<int8_t>(record.pi),
+            .si = static_cast<int8_t>(record.si),
+    };
+}
+
+aidl::CdmaRedirectingNumberInfoRecord toAidl(const V1_0::CdmaRedirectingNumberInfoRecord& record) {
+    return {
+            .redirectingNumber = toAidl(record.redirectingNumber),
+            .redirectingReason = static_cast<int32_t>(record.redirectingReason),
+    };
+}
+
+aidl::CdmaLineControlInfoRecord toAidl(const V1_0::CdmaLineControlInfoRecord& record) {
+    return {
+            .lineCtrlPolarityIncluded = static_cast<int8_t>(record.lineCtrlPolarityIncluded),
+            .lineCtrlToggle = static_cast<int8_t>(record.lineCtrlToggle),
+            .lineCtrlReverse = static_cast<int8_t>(record.lineCtrlReverse),
+            .lineCtrlPowerDenial = static_cast<int8_t>(record.lineCtrlPowerDenial),
+    };
+}
+
+aidl::CdmaT53ClirInfoRecord toAidl(const V1_0::CdmaT53ClirInfoRecord& record) {
+    return {
+            .cause = static_cast<int8_t>(record.cause),
+    };
+}
+
+aidl::CdmaT53AudioControlInfoRecord toAidl(const V1_0::CdmaT53AudioControlInfoRecord& record) {
+    return {
+            .upLink = static_cast<int8_t>(record.upLink),
+            .downLink = static_cast<int8_t>(record.downLink),
+    };
+}
+
+aidl::EmergencyNumber toAidl(const V1_4::EmergencyNumber& num) {
+    return {
+            .number = num.number,
+            .mcc = num.mcc,
+            .mnc = num.mnc,
+            .categories = aidl::EmergencyServiceCategory(num.categories),
+            .urns = toAidl(num.urns),
+            .sources = num.sources,
+    };
+}
+
+aidl::StkCcUnsolSsResult toAidl(const V1_0::StkCcUnsolSsResult& res) {
+    return {
+            .serviceType = static_cast<int32_t>(res.serviceType),
+            .requestType = static_cast<int32_t>(res.requestType),
+            .teleserviceType = static_cast<int32_t>(res.teleserviceType),
+            .serviceClass = res.serviceClass,
+            .result = toAidl(res.result),
+            .ssInfo = toAidl(res.ssInfo),
+            .cfData = toAidl(res.cfData),
+    };
+}
+
+aidl::SsInfoData toAidl(const V1_0::SsInfoData& info) {
+    return {
+            .ssInfo = info.ssInfo,
+    };
+}
+
+aidl::CfData toAidl(const V1_0::CfData& data) {
+    return {
+            .cfInfo = toAidl(data.cfInfo),
+    };
+}
+
+aidl::Call toAidl(const V1_0::Call& call) {
+    return toAidl(V1_2::Call{call, {}});
+}
+
+aidl::Call toAidl(const V1_2::Call& call) {
+    return toAidl(V1_6::Call{call, {}});
+}
+
+aidl::Call toAidl(const V1_6::Call& call) {
+    return {
+            .state = static_cast<int32_t>(call.base.base.state),
+            .index = call.base.base.index,
+            .toa = call.base.base.toa,
+            .isMpty = call.base.base.isMpty,
+            .isMT = call.base.base.isMT,
+            .als = static_cast<int8_t>(call.base.base.als),
+            .isVoice = call.base.base.isVoice,
+            .isVoicePrivacy = call.base.base.isVoicePrivacy,
+            .number = call.base.base.number,
+            .numberPresentation = static_cast<int32_t>(call.base.base.numberPresentation),
+            .name = call.base.base.name,
+            .namePresentation = static_cast<int32_t>(call.base.base.namePresentation),
+            .uusInfo = toAidl(call.base.base.uusInfo),
+            .audioQuality = aidl::AudioQuality(call.base.audioQuality),
+            .forwardedNumber = call.forwardedNumber,
+    };
+}
+
+aidl::UusInfo toAidl(const V1_0::UusInfo& info) {
+    return {
+            .uusType = static_cast<int32_t>(info.uusType),
+            .uusDcs = static_cast<int32_t>(info.uusDcs),
+            .uusData = info.uusData,
+    };
+}
+
+aidl::LastCallFailCauseInfo toAidl(const V1_0::LastCallFailCauseInfo& info) {
+    return {
+            .causeCode = aidl::LastCallFailCause(info.causeCode),
+            .vendorCause = info.vendorCause,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/structs.h b/radio/aidl/compat/libradiocompat/voice/structs.h
new file mode 100644
index 0000000..b55a089
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/structs.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/voice/Call.h>
+#include <aidl/android/hardware/radio/voice/CallForwardInfo.h>
+#include <aidl/android/hardware/radio/voice/CdmaCallWaiting.h>
+#include <aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaInformationRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CfData.h>
+#include <aidl/android/hardware/radio/voice/Dial.h>
+#include <aidl/android/hardware/radio/voice/EmergencyNumber.h>
+#include <aidl/android/hardware/radio/voice/LastCallFailCauseInfo.h>
+#include <aidl/android/hardware/radio/voice/SsInfoData.h>
+#include <aidl/android/hardware/radio/voice/StkCcUnsolSsResult.h>
+#include <aidl/android/hardware/radio/voice/UusInfo.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::Dial toHidl(const ::aidl::android::hardware::radio::voice::Dial& info);
+
+V1_0::UusInfo toHidl(const ::aidl::android::hardware::radio::voice::UusInfo& info);
+
+::aidl::android::hardware::radio::voice::CallForwardInfo toAidl(const V1_0::CallForwardInfo& info);
+V1_0::CallForwardInfo toHidl(const ::aidl::android::hardware::radio::voice::CallForwardInfo& info);
+
+::aidl::android::hardware::radio::voice::CdmaSignalInfoRecord  //
+toAidl(const V1_0::CdmaSignalInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaCallWaiting toAidl(const V1_0::CdmaCallWaiting& call);
+
+::aidl::android::hardware::radio::voice::CdmaInformationRecord  //
+toAidl(const V1_0::CdmaInformationRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaDisplayInfoRecord  //
+toAidl(const V1_0::CdmaDisplayInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaNumberInfoRecord  //
+toAidl(const V1_0::CdmaNumberInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaRedirectingNumberInfoRecord  //
+toAidl(const V1_0::CdmaRedirectingNumberInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaLineControlInfoRecord  //
+toAidl(const V1_0::CdmaLineControlInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaT53ClirInfoRecord  //
+toAidl(const V1_0::CdmaT53ClirInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaT53AudioControlInfoRecord  //
+toAidl(const V1_0::CdmaT53AudioControlInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::EmergencyNumber toAidl(const V1_4::EmergencyNumber& num);
+
+::aidl::android::hardware::radio::voice::StkCcUnsolSsResult  //
+toAidl(const V1_0::StkCcUnsolSsResult& res);
+
+::aidl::android::hardware::radio::voice::SsInfoData toAidl(const V1_0::SsInfoData& info);
+
+::aidl::android::hardware::radio::voice::CfData toAidl(const V1_0::CfData& data);
+
+::aidl::android::hardware::radio::voice::Call toAidl(const V1_0::Call& call);
+::aidl::android::hardware::radio::voice::Call toAidl(const V1_2::Call& call);
+::aidl::android::hardware::radio::voice::Call toAidl(const V1_6::Call& call);
+
+::aidl::android::hardware::radio::voice::UusInfo toAidl(const V1_0::UusInfo& info);
+
+::aidl::android::hardware::radio::voice::LastCallFailCauseInfo  //
+toAidl(const V1_0::LastCallFailCauseInfo& info);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/service/Android.bp b/radio/aidl/compat/service/Android.bp
new file mode 100644
index 0000000..52eb71f
--- /dev/null
+++ b/radio/aidl/compat/service/Android.bp
@@ -0,0 +1,64 @@
+// Copyright (C) 2021 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+    name: "android.hardware.radio-service.compat",
+    relative_install_path: "hw",
+    init_rc: ["radio-compat.rc"],
+    vintf_fragments: ["radio-compat.xml"],
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+    ],
+    shared_libs: [
+        "android.hardware.radio-library.compat",
+        "android.hardware.radio.config-V1-ndk",
+        "android.hardware.radio.config@1.0",
+        "android.hardware.radio.config@1.1",
+        "android.hardware.radio.config@1.2",
+        "android.hardware.radio.config@1.3",
+        "android.hardware.radio.data-V1-ndk",
+        "android.hardware.radio.messaging-V1-ndk",
+        "android.hardware.radio.modem-V1-ndk",
+        "android.hardware.radio.network-V1-ndk",
+        "android.hardware.radio.sim-V1-ndk",
+        "android.hardware.radio.voice-V1-ndk",
+        "android.hardware.radio@1.0",
+        "android.hardware.radio@1.1",
+        "android.hardware.radio@1.2",
+        "android.hardware.radio@1.3",
+        "android.hardware.radio@1.4",
+        "android.hardware.radio@1.5",
+        "android.hardware.radio@1.6",
+        "libbase",
+        "libbinder_ndk",
+        "libhidlbase",
+        "libutils",
+    ],
+    srcs: [
+        "hidl-utils.cpp",
+        "service.cpp",
+    ],
+}
diff --git a/radio/aidl/compat/service/hidl-utils.cpp b/radio/aidl/compat/service/hidl-utils.cpp
new file mode 100644
index 0000000..fc0d54d
--- /dev/null
+++ b/radio/aidl/compat/service/hidl-utils.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "hidl-utils.h"
+
+#include <android-base/logging.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+
+namespace android::hardware::hidl_utils {
+
+class HalDeathRecipient : public hidl_death_recipient {
+    void serviceDied(uint64_t /* cookie */, const wp<hidl::base::V1_0::IBase>& /* who */) override {
+        LOG(FATAL) << "One of the linked HALs died. Restarting...";
+    }
+};
+
+static const auto gHalDeathRecipient = sp<HalDeathRecipient>::make();
+
+void linkDeathToDeath(sp<::android::hidl::base::V1_0::IBase> hal) {
+    const auto linkStatus = hal->linkToDeath(gHalDeathRecipient, 0);
+    CHECK(linkStatus.withDefault(false)) << "Failed to link to HAL death";
+}
+
+hidl_vec<hidl_string> listManifestByInterface(const char* descriptor) {
+    auto manager = hidl::manager::V1_2::IServiceManager::getService();
+    hidl_vec<hidl_string> services;
+    manager->listManifestByInterface(descriptor, hidl_utils::fill(&services));
+    CHECK_GT(services.size(), 0u) << "No " << descriptor
+                                  << " services in manifest (missing privileges?)" << std::endl;
+    return services;
+}
+
+}  // namespace android::hardware::hidl_utils
diff --git a/radio/aidl/compat/service/hidl-utils.h b/radio/aidl/compat/service/hidl-utils.h
new file mode 100644
index 0000000..be3386f
--- /dev/null
+++ b/radio/aidl/compat/service/hidl-utils.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <android/hidl/base/1.0/IBase.h>
+
+#include <functional>
+
+namespace android::hardware::hidl_utils {
+
+/**
+ * Helper functor to fetch results from multi-return HIDL calls.
+ * It's meant to be used in place of _hidl_cb callbacks.
+ *
+ * Please note extracting these return variables outside of the callback scope requires making
+ * a copy of each return variable. This may be costly for frequently called HIDL methods with
+ * non-negligible return object size. Please be cautious about performance when using this.
+ *
+ * Example usage:
+ *     Result result;
+ *     sp<ISomeInterface> iface;
+ *     hidlObject->someMethod(arg1, arg2, hidl_utils::fill(&result, &iface)).assertOk();
+ *     // use result and iface
+ */
+template <typename... T>
+struct fill : public std::function<void(const T&...)> {
+    /**
+     * Create _hidl_cb functor that copies the call arguments to specified pointers.
+     *
+     * \param args... Targets to copy the call arguments to
+     */
+    fill(T*... args) : mTargets(args...) {}
+
+    void operator()(const T&... args) { copy<0, T...>(args...); }
+
+  private:
+    std::tuple<T*...> mTargets;
+
+    template <int Pos, typename First>
+    inline void copy(const First& first) {
+        *std::get<Pos>(mTargets) = first;
+    }
+
+    template <int Pos, typename First, typename... Rest>
+    inline void copy(const First& first, const Rest&... rest) {
+        *std::get<Pos>(mTargets) = first;
+        copy<Pos + 1, Rest...>(rest...);
+    }
+};
+
+/**
+ * Link to a given HALs death and restart the current process in such a case.
+ * \param hal HAL to which death to link
+ */
+void linkDeathToDeath(sp<hidl::base::V1_0::IBase> hal);
+
+/**
+ * List HAL instances of a given interface.
+ *
+ * \descriptor HIDL HAL descriptor
+ */
+hidl_vec<hidl_string> listManifestByInterface(const char* descriptor);
+
+}  // namespace android::hardware::hidl_utils
diff --git a/radio/aidl/compat/service/radio-compat.rc b/radio/aidl/compat/service/radio-compat.rc
new file mode 100644
index 0000000..a159876
--- /dev/null
+++ b/radio/aidl/compat/service/radio-compat.rc
@@ -0,0 +1,4 @@
+service vendor.radio-compat /vendor/bin/hw/android.hardware.radio-service.compat
+    class hal
+    user nobody
+    group system
diff --git a/radio/aidl/compat/service/radio-compat.xml b/radio/aidl/compat/service/radio-compat.xml
new file mode 100644
index 0000000..a7089e6
--- /dev/null
+++ b/radio/aidl/compat/service/radio-compat.xml
@@ -0,0 +1,37 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.radio.config</name>
+        <fqname>IRadioConfig/default</fqname>
+    </hal>
+<!--
+    Instances other than config are configured per-device, depending on the slot count (framework
+    currently supports slot1, slot2 and slot3 instances) and Radio HALs device wishes to provide.
+    You can either copy the following tags to device manifest or simply uncomment them here for
+    quick testing.
+
+    <hal format="aidl">
+        <name>android.hardware.radio.data</name>
+        <fqname>IRadioData/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.messaging</name>
+        <fqname>IRadioMessaging/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.modem</name>
+        <fqname>IRadioModem/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.network</name>
+        <fqname>IRadioNetwork/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.sim</name>
+        <fqname>IRadioSim/slot1</fqname>
+    </hal>
+    <hal format="aidl">
+        <name>android.hardware.radio.voice</name>
+        <fqname>IRadioVoice/slot1</fqname>
+    </hal>
+-->
+</manifest>
diff --git a/radio/aidl/compat/service/service.cpp b/radio/aidl/compat/service/service.cpp
new file mode 100644
index 0000000..2a67569
--- /dev/null
+++ b/radio/aidl/compat/service/service.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "hidl-utils.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <libradiocompat/RadioConfig.h>
+#include <libradiocompat/RadioData.h>
+#include <libradiocompat/RadioIndication.h>
+#include <libradiocompat/RadioMessaging.h>
+#include <libradiocompat/RadioModem.h>
+#include <libradiocompat/RadioNetwork.h>
+#include <libradiocompat/RadioResponse.h>
+#include <libradiocompat/RadioSim.h>
+#include <libradiocompat/RadioVoice.h>
+
+namespace android::hardware::radio::service {
+
+using namespace std::string_literals;
+
+static std::vector<std::shared_ptr<ndk::ICInterface>> gPublishedHals;
+
+template <typename T>
+static void publishRadioHal(sp<V1_5::IRadio> hidlHal, sp<compat::RadioResponse> responseCb,
+                            sp<compat::RadioIndication> indicationCb, const std::string& slot) {
+    const auto instance = T::descriptor + "/"s + slot;
+    if (!AServiceManager_isDeclared(instance.c_str())) {
+        LOG(INFO) << instance << " is not declared in VINTF (this may be intentional)";
+        return;
+    }
+    LOG(DEBUG) << "Publishing " << instance;
+
+    auto aidlHal = ndk::SharedRefBase::make<T>(hidlHal, responseCb, indicationCb);
+    gPublishedHals.push_back(aidlHal);
+    const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+}
+
+static void publishRadio(std::string slot) {
+    auto radioHidl = V1_5::IRadio::getService(slot);
+    CHECK(radioHidl) << "HIDL IRadio not present in VINTF";
+
+    hidl_utils::linkDeathToDeath(radioHidl);
+
+    auto responseCb = sp<compat::RadioResponse>::make();
+    auto indicationCb = sp<compat::RadioIndication>::make();
+    radioHidl->setResponseFunctions(responseCb, indicationCb).assertOk();
+
+    publishRadioHal<compat::RadioData>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioMessaging>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioModem>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioNetwork>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioSim>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioVoice>(radioHidl, responseCb, indicationCb, slot);
+}
+
+static void publishRadioConfig() {
+    auto hidlHal = config::V1_1::IRadioConfig::getService();
+    CHECK(hidlHal) << "HIDL IRadioConfig not present in VINTF";
+
+    hidl_utils::linkDeathToDeath(hidlHal);
+
+    auto aidlHal = ndk::SharedRefBase::make<compat::RadioConfig>(hidlHal);
+    gPublishedHals.push_back(aidlHal);
+    const auto instance = compat::RadioConfig::descriptor + "/default"s;
+    const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+}
+
+static void main() {
+    base::SetDefaultTag("radiocompat");
+    base::SetMinimumLogSeverity(base::VERBOSE);
+    LOG(DEBUG) << "Radio HAL compat service starting...";
+
+    publishRadioConfig();
+
+    const auto slots = hidl_utils::listManifestByInterface(V1_0::IRadio::descriptor);
+    LOG(INFO) << "Found " << slots.size() << " slot(s)";
+    for (const auto& slot : slots) {
+        publishRadio(slot);
+    }
+
+    LOG(DEBUG) << "Radio HAL compat service is operational";
+    ABinderProcess_joinThreadPool();
+    LOG(FATAL) << "Radio HAL compat service has stopped";
+}
+
+}  // namespace android::hardware::radio::service
+
+int main() {
+    android::hardware::radio::service::main();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
index 8e31bd9..95ecc51 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
@@ -47,4 +47,5 @@
   INVALID_FRONTEND_ID = -1,
   INVALID_LNB_ID = -1,
   INVALID_KEYTOKEN = 0,
+  INVALID_TABINFO_VERSION = -1,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
index 95911f9..3e5df2d 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
@@ -36,4 +36,5 @@
 @VintfStability
 parcelable DemuxFilterAvSettings {
   boolean isPassthrough;
+  boolean isSecureMemory;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
index 17bdd1f..02c478f 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
@@ -36,6 +36,6 @@
 @VintfStability
 parcelable DemuxFilterRecordSettings {
   int tsIndexMask;
-  android.hardware.tv.tuner.DemuxRecordScIndexType scIndexType = android.hardware.tv.tuner.DemuxRecordScIndexType.UNDEFINED;
+  android.hardware.tv.tuner.DemuxRecordScIndexType scIndexType = android.hardware.tv.tuner.DemuxRecordScIndexType.NONE;
   android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
index 3fd1910..371e075 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -36,5 +36,6 @@
 @VintfStability
 union DemuxFilterScIndexMask {
   int scIndex;
+  int scAvc;
   int scHevc;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index 91a5e52..30ec29a 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -38,5 +38,5 @@
   NONE = 0,
   SC = 1,
   SC_HEVC = 2,
-  UNDEFINED = 3,
+  SC_AVC = 3,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
new file mode 100644
index 0000000..651b66c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxScAvcIndex {
+  UNDEFINED = 0,
+  I_SLICE = 1,
+  P_SLICE = 2,
+  B_SLICE = 4,
+  SI_SLICE = 8,
+  SP_SLICE = 16,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
index 3035dad..670b34e 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -35,6 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxScHevcIndex {
+  UNDEFINED = 0,
   SPS = 1,
   AUD = 2,
   SLICE_CE_BLA_W_LP = 4,
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
index 808b212..25f0585 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -40,9 +40,4 @@
   P_FRAME = 2,
   B_FRAME = 4,
   SEQUENCE = 8,
-  I_SLICE = 16,
-  P_SLICE = 32,
-  B_SLICE = 64,
-  SI_SLICE = 128,
-  SP_SLICE = 256,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
index 891794a..0751d26 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
@@ -83,4 +83,9 @@
      * An invalid key token. It is used to remove the current key from the descrambler.
      */
     INVALID_KEYTOKEN = 0x00,
+
+     /**
+     * An invalid section filter version number.
+     */
+    INVALID_TABINFO_VERSION = 0xFFFFFFFF,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
index 30a1054..fe4db5b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
@@ -26,4 +26,9 @@
      * true if the filter output goes to decoder directly in pass through mode.
      */
     boolean isPassthrough;
+
+    /**
+     * true if the avMemory should be allocated from secure area.
+     */
+    boolean isSecureMemory;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
index 2f88864..475910b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
@@ -30,7 +30,7 @@
      */
     int tsIndexMask;
 
-    DemuxRecordScIndexType scIndexType = DemuxRecordScIndexType.UNDEFINED;
+    DemuxRecordScIndexType scIndexType = DemuxRecordScIndexType.NONE;
 
     DemuxFilterScIndexMask scIndexMask;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
index a9f4b6f..4036b06 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.tv.tuner;
 
+import android.hardware.tv.tuner.DemuxScAvcIndex;
 import android.hardware.tv.tuner.DemuxScHevcIndex;
 import android.hardware.tv.tuner.DemuxScIndex;
 
@@ -30,6 +31,11 @@
     int scIndex;
 
     /**
+     * Indexes defined by DemuxScAvcIndex.
+     */
+    int scAvc;
+
+    /**
      * Indexes defined by DemuxScHevcIndex.
      */
     int scHevc;
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
index 898b9cc..dbd438c 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
@@ -28,7 +28,8 @@
     int tableId;
 
     /**
-     * Version number for Section Filter
+     * Optional version number for Section Filter. It should be ignored if INVALID_TABINFO_VERSION
+     * is set.
      */
     int version;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index 44b985c..98427f7 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -39,7 +39,7 @@
     SC_HEVC,
 
     /**
-     * SC index is undefined
+     * Use Start Code index for AVC
      */
-    UNDEFINED,
+    SC_AVC,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScAvcIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
new file mode 100644
index 0000000..ed418f2
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2021 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 android.hardware.tv.tuner;
+
+/**
+ * Indexes can be tagged by start point of slice groups according to ISO/IEC 14496-10.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxScAvcIndex {
+    UNDEFINED = 0,
+
+    /**
+     * All blocks are coded as I blocks.
+     */
+    I_SLICE = 1 << 0,
+
+    /**
+     * Blocks are coded as I or P blocks.
+     */
+    P_SLICE = 1 << 1,
+
+    /**
+     * Blocks are coded as I, P or B blocks.
+     */
+    B_SLICE = 1 << 2,
+
+    /**
+     * A so-called switching I slice that is coded.
+     */
+    SI_SLICE = 1 << 3,
+
+    /**
+     * A so-called switching P slice that is coded.
+     */
+    SP_SLICE = 1 << 4,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
index f2ddd00..0d1f112 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -23,6 +23,8 @@
 @VintfStability
 @Backing(type="int")
 enum DemuxScHevcIndex {
+    UNDEFINED = 0,
+
     SPS = 1 << 0,
 
     AUD = 1 << 1,
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
index 0aef739..4fed1e5 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -18,7 +18,7 @@
 
 /**
  * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
- * according to ISO/IEC 13818-1 and Slice Groups according to ISO/IEC 14496-10.
+ * according to ISO/IEC 13818-1.
  * @hide
  */
 @VintfStability
@@ -45,29 +45,4 @@
      * Start Code is for a new Sequence
      */
     SEQUENCE = 1 << 3,
-
-    /**
-     * All blocks are coded as I blocks.
-     */
-    I_SLICE = 1 << 4,
-
-    /**
-     * Blocks are coded as I or P blocks.
-     */
-    P_SLICE = 1 << 5,
-
-    /**
-     * Blocks are coded as I, P or B blocks.
-     */
-    B_SLICE = 1 << 6,
-
-    /**
-     * A so-called switching I slice that is coded.
-     */
-    SI_SLICE = 1 << 7,
-
-    /**
-     * A so-called switching P slice that is coded.
-     */
-    SP_SLICE = 1 << 8,
 }
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index 006bf17..5a72ba4 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -52,7 +52,7 @@
 const int32_t FMQ_SIZE_4M = 0x400000;
 const int32_t FMQ_SIZE_16M = 0x1000000;
 
-const string configFilePath = "/vendor/etc/tuner_vts_config_1_1.xml";
+const string configFilePath = "/vendor/etc/tuner_vts_config_aidl_V1.xml";
 
 #define FILTER_MAIN_TYPE_BIT_COUNT 5
 
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 08270d6..7ccf31a 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -956,6 +956,7 @@
         }
         auto av = filterConfig.getFirstAvFilterSettings_optional();
         settings.isPassthrough = av->getIsPassthrough();
+        settings.isSecureMemory = av->getIsSecureMemory();
         return settings;
     }
 
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index d026bf9..6c637a4 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -5,9 +5,11 @@
     ctor public AvFilterSettings();
     method @Nullable public short getAudioStreamType_optional();
     method @Nullable public boolean getIsPassthrough();
+    method @Nullable public boolean getIsSecureMemory();
     method @Nullable public short getVideoStreamType_optional();
     method public void setAudioStreamType_optional(@Nullable short);
     method public void setIsPassthrough(@Nullable boolean);
+    method public void setIsSecureMemory(@Nullable boolean);
     method public void setVideoStreamType_optional(@Nullable short);
   }
 
diff --git a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
new file mode 100644
index 0000000..8a6229e
--- /dev/null
+++ b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<!-- The Sample Tuner Testing Configuration.
+    Name the customized xml with "tuner_vts_config.xml" and push into the device
+    "/vendor/etc" path. Please use "tuner_testing_dynamic_configuration.xsd" to verify the xml.
+    The version section contains a “version” tag in the form “major.minor” e.g. version=”1.0”
+    This shows the tuner dynamic configuration version. -->
+<TunerConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- Hardware Configuration section contains the configurations of all the hardwares
+        that would be used in the tests. In the "dataFlowConfiguration" section, each data flow
+        under test has its required/optional hardwares. The ids configured in the
+        "dataFlowConfiguration" would be used to connect the hardware to each data flow test. -->
+    <hardwareConfiguration>
+        <!-- Frontends section:
+            This section contains configurations of all the frontends that would be used
+                in the tests.
+                - This section is optional and can be skipped to use the default fe settings.
+                - The default settings can be found in the sample_tuner_vts_configurations.xml.
+                - The users can also override the default frontend settings using id="FE_DEFAULT".
+                - The users can configure 1 or more frontend elements in the frontends sections.
+
+            Each frontend element contain the following attributes:
+                "id": unique id of the frontend that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "type": the frontend type. The enums are defined in the xsd.
+                "isSoftwareFrontend": if the test environment is using hardware or software
+                    frontend. If using software, a ts input file path needs to be configured.
+                "softwareFeInputPath": used as the source of the software frontend.
+                "connectToCicamId": if the device supports frontend connecting to cicam, the target
+                    cicam id needs to be configured here. Supported in Tuner 1.1 or higher.
+                "frequency": the frequency used to configure tune and scan.
+                "endFrequency": the end frequency of scan. Supported in Tuner 1.1 or higher.
+
+            Each frontend element also contains one and only one type-related "frontendSettings".
+                - The settings type should match the frontend "type" attribute.
+                - For example, when frontend type="DVBT", dvbtFrontendSettings can be configured.
+                - This is optional and skipping the settings would pass a setting with frequency
+                    config only to the hal.
+        -->
+        <frontends>
+            <frontend id="FE_DEFAULT" type="DVBT" isSoftwareFrontend="true"
+                      connectToCicamId="0" frequency="578000000" endFrequency="800000000">
+                <dvbtFrontendSettings bandwidth="8" transmissionMode="128" isHighPriority="1"/>
+            </frontend>
+            <frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
+                      connectToCicamId="0" frequency="578000000" endFrequency="800000000">
+            </frontend>
+        </frontends>
+        <!-- Filter section:
+            This section contains configurations of all the filters that would be used in the tests.
+                - This section is optional and can be skipped to use the default filter settings.
+                - The default settings can be found in the sample_tuner_vts_configurations.xml.
+                - The users can also override the default filter settings using
+                - id="FILTER_AUDIO_DEFAULT" or "FILTER_VIDEO_DEFAULT".
+                - The users can configure 1 or more filter elements in the filters sections.
+
+            Each filter element contain the following attributes:
+                "id": unique id of the filter that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "mainType": the main filter type. The enums are defined in the xsd.
+                "subType": the sub filter type. The enums are defined in the xsd.
+                "bufferSize": the buffer size of the filter in hex.
+                "pid": the pid that would be used to configure the filter.
+                "useFMQ": if the filter uses FMQ.
+
+            Each filter element also contains at most one type-related "filterSettings".
+                - The settings type should match the filter "subType" attribute.
+                - For example, when filter subType is audio or video, the avFilterSettings can be
+                    configured.
+                - This is optional and skipping the settings would pass a setting with tpid config
+                    only to the hal.
+        -->
+        <filters>
+            <filter id="FILTER_AUDIO_DEFAULT" mainType="TS" subType="AUDIO"
+                    bufferSize="16777216" pid="257" useFMQ="false" monitorEventTypes="3">
+                <avFilterSettings isPassthrough="false" isSecureMemory="false">
+                    <audioStreamType>2</audioStreamType>
+                </avFilterSettings>
+            </filter>
+            <filter id="FILTER_VIDEO_DEFAULT" mainType="TS" subType="VIDEO"
+                    bufferSize="16777216" pid="256" useFMQ="false" monitorEventTypes="3">
+                <avFilterSettings isPassthrough="false" isSecureMemory="false">
+                    <videoStreamType>2</videoStreamType>
+                </avFilterSettings>
+            </filter>
+            <filter id="FILTER_TS_RECORD_0" mainType="TS" subType="RECORD"
+                    bufferSize="16777216" pid="257" useFMQ="false">
+                <recordFilterSettings tsIndexMask="1" scIndexType="NONE"/>
+            </filter>
+            <filter id="FILTER_IP_IP_0" mainType="IP" subType="IP" bufferSize="16777216" useFMQ="false">
+                <ipFilterConfig ipCid="1">
+                    <srcIpAddress isIpV4="true" ip="192 168 1 1"/>
+                    <destIpAddress isIpV4="true" ip="192 168 1 1"/>
+                </ipFilterConfig>
+            </filter>
+        </filters>
+        <!-- Dvr section:
+            This section contains configurations of all the dvrs that would be used in the tests.
+                - This section is optional and can be skipped if DVR is not supported.
+                - The users can configure 1 or more dvr elements in the dvrs sections.
+
+            Each dvr element contain the following attributes:
+                "id": unique id of the dvr that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "type": the dvr type.
+                "bufferSize": the dvr buffer size.
+                "statusMask": register callbacks of specific status.
+                "lowThreshold": the dvr status low threshold.
+                "highThreshold": the dvr status high threshold.
+                "dataFormat": the dvr data format.
+                "packetSize": the dvr packet size.
+                "inputFilePath": the dvr playback input file path. Only required in playback dvr.
+        -->
+        <dvrs>
+            <dvr id="DVR_PLAYBACK_0" type="PLAYBACK" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="TS" packetSize="188" inputFilePath="/data/local/tmp/segment000000.ts"/>
+            <dvr id="DVR_RECORD_0" type="RECORD" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="TS" packetSize="188"/>
+            <dvr id="DVR_PLAYBACK_1" type="PLAYBACK" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="ES" packetSize="188" inputFilePath="/data/local/tmp/test.es"/>
+        </dvrs>
+    </hardwareConfiguration>
+
+    <!-- Data flow configuration section connects each data flow under test to the ids of the
+        hardwares that would be used during the tests. -->
+    <dataFlowConfiguration>
+        <clearLiveBroadcast frontendConnection="FE_DEFAULT"
+                            audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                            videoFilterConnection="FILTER_VIDEO_DEFAULT"
+                            ipFilterConnection="FILTER_IP_IP_0"
+                            dvrSoftwareFeConnection="DVR_PLAYBACK_1"/>
+        <scan frontendConnection="FE_DEFAULT"/>
+        <dvrPlayback dvrConnection="DVR_PLAYBACK_1"
+                     audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                     videoFilterConnection="FILTER_VIDEO_DEFAULT"/>
+        <dvrRecord hasFrontendConnection="true"
+                   frontendConnection="FE_DEFAULT"
+                   recordFilterConnection="FILTER_TS_RECORD_0"
+                   dvrRecordConnection="DVR_RECORD_0"
+                   dvrSoftwareFeConnection="DVR_PLAYBACK_1"/>
+    </dataFlowConfiguration>
+</TunerConfiguration>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 6a04b7e..fc2827f 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -191,7 +191,7 @@
             <xs:enumeration value="IP"/>
             <xs:enumeration value="NTP"/>
             <xs:enumeration value="IP_PAYLOAD"/>
-            <xs:enumeration value="PAYLOAD_THROUGH"/>            
+            <xs:enumeration value="PAYLOAD_THROUGH"/>
         </xs:restriction>
     </xs:simpleType>
 
@@ -220,6 +220,7 @@
             <xs:element name="videoStreamType" type="xs:unsignedByte"/>
         </xs:choice>
         <xs:attribute name="isPassthrough" type="xs:boolean" use="required"/>
+        <xs:attribute name="isSecureMemory" type="xs:boolean" use="required"/>
     </xs:complexType>
     <xs:complexType name="sectionFilterSettings">
         <xs:attribute name="isCheckCrc" type="xs:boolean" use="required"/>